GPG_Public_Key::__construct PHP Méthode

__construct() public méthode

public __construct ( $asc )
    function __construct($asc)
    {
        $found = 0;
        // normalize line breaks
        $asc = str_replace("\r\n", "\n", $asc);
        if (strpos($asc, "-----BEGIN PGP PUBLIC KEY BLOCK-----\n") === false) {
            throw new Exception("Missing header block in Public Key");
        }
        if (strpos($asc, "\n\n") === false) {
            throw new Exception("Missing body delimiter in Public Key");
        }
        if (strpos($asc, "\n-----END PGP PUBLIC KEY BLOCK-----") === false) {
            throw new Exception("Missing footer block in Public Key");
        }
        // get rid of everything except the base64 encoded key
        $headerbody = explode("\n\n", str_replace("\n-----END PGP PUBLIC KEY BLOCK-----", "", $asc), 2);
        $asc = trim($headerbody[1]);
        $len = 0;
        $s = base64_decode($asc);
        $sa = str_split($s);
        for ($i = 0; $i < strlen($s);) {
            $tag = ord($sa[$i++]);
            // echo 'TAG=' . $tag . '/';
            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) {
                        $oc1 = isset($sa[++$i]) ? $sa[$i] : NULL;
                        $oc2 = isset($sa[++$i]) ? $sa[$i] : NULL;
                        $oc3 = isset($sa[++$i]) ? $sa[$i] : NULL;
                        $oc4 = isset($sa[++$i]) ? $sa[$i] : NULL;
                        if ($oc1 !== NULL) {
                            $len = ord($oc1) * pow(2, 24);
                        } else {
                            $len = 0 * pow(2, 24);
                        }
                        if ($oc2 !== NULL) {
                            $len += ord($oc2) * pow(2, 16);
                        } else {
                            $len += 0 * pow(2, 16);
                        }
                        if ($oc3 !== NULL) {
                            $len += ord($oc3) * pow(2, 8);
                        } else {
                            $len += 0 * pow(2, 8);
                        }
                        if ($oc4 !== NULL) {
                            $len += ord($oc4);
                        } else {
                            $len += 0;
                        }
                    } 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) {
                            $oc1 = isset($sa[++$i]) ? $sa[$i] : NULL;
                            $oc2 = isset($sa[++$i]) ? $sa[$i] : NULL;
                            $oc3 = isset($sa[++$i]) ? $sa[$i] : NULL;
                            $oc4 = isset($sa[++$i]) ? $sa[$i] : NULL;
                            if ($oc1 !== NULL) {
                                $len = ord($oc1) * pow(2, 24);
                            } else {
                                $len = 0 * pow(2, 24);
                            }
                            if ($oc2 !== NULL) {
                                $len += ord($oc2) * pow(2, 16);
                            } else {
                                $len += 0 * pow(2, 16);
                            }
                            if ($oc3 !== NULL) {
                                $len += ord($oc3) * pow(2, 8);
                            } else {
                                $len += 0 * pow(2, 8);
                            }
                            if ($oc4 !== NULL) {
                                $len += ord($oc4);
                            } else {
                                $len += 0;
                            }
                            // $len = (ord($sa[$i++])* pow(2,24)) + (ord($sa[$i++]) * pow(2,16)) + (0 * pow(2,8)) + 0;
                        } else {
                            $len = strlen($s) - 1;
                        }
                    }
                }
            }
            // echo $tag . ' ';
            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) {
                            // https://tools.ietf.org/html/rfc4880#section-12
                            $headerPos = strpos($s, chr(0x4));
                            // TODO: is this always the correct starting point for the pulic key packet 'version' field?
                            $delim = chr(0x1) . chr(0x0);
                            // TODO: is this the correct delimiter for the end of the public key packet?
                            $delimPos = strpos($s, $delim) + (3 - $headerPos);
                            // echo "POSITION: $delimPos\n";
                            // this does not work, tried it with RSA 1024 and RSA 4096 keys generated by GnuPG v2 (2.0.29) on Windows running Apache and PHP 5.6.3
                            // $pkt = chr(0x99) . chr($delimPos >> 8) . chr($delimPos & 255) . substr($s, $headerPos, $delimPos);
                            // this is the original signing string which seems to have only worked for key lengths of 1024 or less
                            $pkt = chr(0x99) . chr($len >> 8) . chr($len & 255) . substr($s, $k, $len);
                            // use this for now
                            $fp = sha1($pkt);
                            $this->fp = $fp;
                            $this->key_id = substr($fp, strlen($fp) - 16, 16);
                            // uncomment to debug the start point for the signing string
                            // 						for ($ii = 5; $ii > -1; $ii--) {
                            // 							$pkt = chr(0x99) . chr($ii >> 8) . chr($ii & 255) . substr($s, $headerPos, $ii);
                            // 							$fp = sha1($pkt);
                            // 							echo "LENGTH=" . $headerPos . '->' . $ii . " CHR(" . ord(substr($s,$ii, 1)) . ") = " . substr($fp, strlen($fp) - 16, 16) . "\n";
                            // 						}
                            // 						echo "\n";
                            // uncomment to debug the end point for the signing string
                            // 						for ($ii = strlen($s); $ii > 1; $ii--) {
                            // 							$pkt = chr(0x99) . chr($ii >> 8) . chr($ii & 255) . substr($s, $headerPos, $ii);
                            // 							$fp = sha1($pkt);
                            // 							echo "LENGTH=" . $headerPos . '->' . $ii . " CHR(" . ord(substr($s,$ii, 1)) . ") = " . substr($fp, strlen($fp) - 16, 16) . "\n";
                            // 						}
                        } else {
                            throw new Exception('GPG Key Version ' . $version . ' is not supported');
                        }
                    }
                    $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));
                        // TODO: should this be adjusted as it was for RSA (above)..?
                        $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 = "";
        }
    }