function GPG_Public_Key($asc) { $found = 0; $i = strpos($asc, "-----BEGIN PGP PUBLIC KEY BLOCK-----"); if ($i === false) { throw new Exception("Missing block header in Public Key"); } // normalize line breaks $asc = str_replace("\r\n", "\n", $asc); // remove all "comment" lines which we should ignore $lines = explode("\n", $asc); for ($ln = 0; $ln < count($lines); $ln++) { $line = $lines[$ln]; if (GPG_Utility::starts_with(strtolower(trim($line)), "comment:")) { echo "REMOVING LINE\n"; unset($lines[$ln]); } } $asc = implode("\n", $lines); $a = strpos($asc, "\n", $i); if ($a > 0) { $a = strpos($asc, "\n", $a + 1); } $e = strpos($asc, "\n=", $i); if ($a > 0 && $e > 0) { $asc = substr($asc, $a + 2, $e - $a - 2); } else { throw new Exception("Unsupported Public Key format"); } $len = 0; $s = base64_decode($asc); $sa = str_split($s); for ($i = 0; $i < strlen($s);) { $tag = ord($sa[$i++]); if (($tag & 128) == 0) { break; } if ($tag & 64) { $tag &= 63; $len = ord($sa[$i++]); if ($len > 191 && $len < 224) { $len = ($len - 192 << 8) + ord($sa[$i++]); } else { if ($len == 255) { $len = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]); } else { if ($len > 223 && len < 255) { $len = 1 << ($len & 0x1f); } } } } else { $len = $tag & 3; $tag = $tag >> 2 & 15; if ($len == 0) { $len = ord($sa[$i++]); } else { if ($len == 1) { $len = (ord($sa[$i++]) << 8) + ord($sa[$i++]); } else { if ($len == 2) { $len = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]); } else { $len = strlen($s) - 1; } } } } if ($tag == 6 || $tag == 14) { $k = $i; $version = ord($sa[$i++]); $found = 1; $this->version = $version; $time = (ord($sa[$i++]) << 24) + (ord($sa[$i++]) << 16) + (ord($sa[$i++]) << 8) + ord($sa[$i++]); if ($version == 2 || $version == 3) { $valid = ord($sa[$i++]) << 8 + ord($sa[$i++]); } $algo = ord($sa[$i++]); if ($algo == 1 || $algo == 2) { $m = $i; $lm = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8); $i += $lm + 2; $mod = substr($s, $m, $lm + 2); $le = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8); $i += $le + 2; $this->public_key = base64_encode(substr($s, $m, $lm + $le + 4)); $this->type = "RSA"; if ($version == 3) { $this->fp = ''; $this->key_id = bin2hex(substr($mod, strlen($mod) - 8, 8)); } else { if ($version == 4) { $pkt = chr(0x99) . chr($len >> 8) . chr($len & 255) . substr($s, $k, $len); $fp = sha1($pkt); $this->fp = $fp; $this->key_id = substr($fp, strlen($fp) - 16, 16); } else { $this->fp = ""; $this->key_id = ""; } } $found = 2; } else { if (($algo == 16 || $algo == 20) && $version == 4) { $m = $i; $lp = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8); $i += $lp + 2; $lg = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8); $i += $lg + 2; $ly = floor((ord($sa[$i]) * 256 + ord($sa[$i + 1]) + 7) / 8); $i += $ly + 2; $this->public_key = base64_encode(substr($s, $m, $lp + $lg + $ly + 6)); $pkt = chr(0x99) . chr($len >> 8) . chr($len & 255) . substr($s, $k, $len); $fp = sha1($pkt); $this->fp = $fp; $this->key_id = substr($fp, strlen($fp) - 16, 16); $this->type = "ELGAMAL"; $found = 3; } else { $i = $k + $len; } } } else { if ($tag == 13) { $this->user = substr($s, $i, $len); $i += $len; } else { $i += $len; } } } if ($found < 2) { throw new Exception("Unable to parse Public Key"); // $this->version = ""; // $this->fp = ""; // $this->key_id = ""; // $this->user = ""; // $this->public_key = ""; } }