/** * Compute a public key identifier. * * Although key identifiers may be set to any unique value, this function * computes key identifiers from public key according to the two * recommended methods (4.2.1.2 RFC 3280). * Highly polymorphic: try to accept all possible forms of key: * - Key object * - X509 object with public or private key defined * - Certificate or CSR array * - ASN1_Element object * - PEM or DER string * * @param Mixed $key optional * @param Integer $method optional * @access public * @return String binary key identifier */ function computeKeyIdentifier($key = null, $method = 1) { if (is_null($key)) { $key = $this; } switch (true) { case is_string($key): break; case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method); case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method); case !is_object($key): return false; case strtolower(get_class($key)) == 'ASN1_element': // Assume the element is a bitstring-packed key. $asn1 = new ASN1(); $decoded = $asn1->decodeBER($key->element); if (empty($decoded)) { return false; } $raw = $asn1->asn1map($decoded[0], array('type' => ASN1_TYPE_BIT_STRING)); if (empty($raw)) { return false; } $raw = base64_decode($raw); // If the key is private, compute identifier from its corresponding public key. if (!class_exists('Crypt_RSA')) { include_once 'Crypt/RSA.php'; } $key = new Crypt_RSA(); if (!$key->loadKey($raw)) { return false; // Not an unencrypted RSA key. } if ($key->getPrivateKey() !== false) { // If private. return $this->computeKeyIdentifier($key, $method); } $key = $raw; // Is a public key. break; case strtolower(get_class($key)) == 'X509': if (isset($key->publicKey)) { return $this->computeKeyIdentifier($key->publicKey, $method); } if (isset($key->privateKey)) { return $this->computeKeyIdentifier($key->privateKey, $method); } if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) { return $this->computeKeyIdentifier($key->currentCert, $method); } return false; default: // Should be a key object (i.e.: Crypt_RSA). $key = $key->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_PKCS1); break; } // If in PEM format, convert to binary. $key = $this->_extractBER($key); // Now we have the key string: compute its sha-1 sum. if (!class_exists('Crypt_Hash')) { include_once 'Crypt/Hash.php'; } $hash = new Crypt_Hash('sha1'); $hash = $hash->hash($key); if ($method == 2) { $hash = substr($hash, -8); $hash[0] = chr(ord($hash[0]) & 0xf | 0x40); } return $hash; }
/** * Parse a timestamp response * @param string $data the response * @return array the parsed response */ public static function parseResponseFromData($data) { $tsr = ASN1::decodeDER($data, static::$response); if (in_array($tsr['status']['status'], ['granted', 'grantedWithMods']) && isset($tsr['timeStampToken']) && isset($tsr['timeStampToken']["signedData"]) && isset($tsr['timeStampToken']["signedData"]["tokenInfo"]) && isset($tsr['timeStampToken']["signedData"]["tokenInfo"][1])) { $tsr['timeStampToken']["signedData"]["tokenInfo"] = ASN1::decodeDER($tsr['timeStampToken']["signedData"]["tokenInfo"][1], static::$tokenInfo); } return $tsr; }