/** * @todo This can be simplified once Responses are created by a factory. */ public function testHandleReturnsResponseIfSuccessful() { $pathToResponderCert = vfsStream::newFile('issuerCert.pem')->at(vfsStream::setUp())->withContent($this->getCertInPem())->url(); $process = $this->getMockProcess(); $process->method('isSuccessful')->willReturn(true); $process->method('setCommandLine')->will($this->returnCallback(function ($commandLine) { // NB! This assumes the outfile is the last argument. If things go // south, assume somone has fiddled with the argument order. $commandLine = explode('-respout', $commandLine); $fileName = trim(end($commandLine), '\' '); $parser = new Asn1Parser(); $asn1 = new Asn1(); file_put_contents($fileName, $parser->encodeDER(array('responseStatus' => Asn1::OCSP_SUCCESSFUL, 'responseBytes' => array('responseType' => Asn1::OID_ID_PKIX_OCSP_BASIC, 'response' => 'MIICOTCCASGhgYYwgYMxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMQ0wCwYDVQQLDARPQ1NQMScwJQYDVQQDDB5URVNUIG9mIFNLIE9DU1AgUkVTUE9OREVSIDIwMTExGDAWBgkqhkiG9w0BCQEWCXBraUBzay5lZRgPMjAxNDEyMjYyMzE1NDVaMGAwXjBJMAkGBSsOAwIaBQAEFJ8hzI+QiAAqq1ikY3MvViFZKzWuBBR7avJVUFy42XoIh0Gu+qIrPVtXdgIQH/v/rqwJX11SX33gZ4PrfYAAGA8yMDE0MTIyNjIzMTU0NVqhIzAhMB8GCSsGAQUFBzABAgQSBBDXw6pZv+/fMYQlxV3ACvKZMA0GCSqGSIb3DQEBBQUAA4IBAQBxe4hdQYCqR+O5wLFP1nY5HiP4w348YXfFiEvVmC9JCoaoSqmXdoner0sJxYdnOleu7/WdRAvO+hAnl73aOm0l+woGpm1fud8pl7Bz0F8cIiYL4g5xorArkdHZLwMmxi09ZzhBgM93xyOtpUj1c2onIXLEyV4ENv6DPBIAPNOVVTiaeFBVGba7g4RZxgvHWeuO+OmCAezjYJNZfXaYshvudAxaqmrhBCd3xDAYjgQlarhRn6aXpNsVRZG8NK4XW6+rH+4q+9S2ZsA6KTVkfGC218unYUkA0FswJH1JO7D+G9kooZHGIuV7SL5l4bpGwNxcbtdu+xYtNqNr4xSkHBTn')), $asn1->OCSPResponse)); })); $responder = new Responder('http://example.com', $pathToResponderCert, null, $process); $response = $responder->handle($this->getMockRequest()); $this->assertInstanceOf('KG\\DigiDoc\\OCSP\\Response', $response); }
/** * Wrap a public key appropriately * * @access public * @param string $key * @return string */ static function wrapPublicKey($key, $algorithm) { $asn1 = new ASN1(); $key = ['publicKeyAlgorithm' => ['algorithm' => $algorithm, 'parameters' => null], 'publicKey' => Base64::encode("" . $key)]; $key = $asn1->encodeDER($key, PublicKeyInfo); return "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(Base64::encode($key), 64) . "-----END PUBLIC KEY-----"; }
/** * Save a SPKAC CSR request * * @param array $csr * @param int $format optional * @access public * @return string */ function saveSPKAC($spkac, $format = self::FORMAT_PEM) { if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { return false; } $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); switch (true) { case !$algorithm: case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): break; default: switch ($algorithm) { case 'rsaEncryption': $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']))); } } $asn1 = new ASN1(); $asn1->loadOIDs($this->oids); $spkac = $asn1->encodeDER($spkac, $this->SignedPublicKeyAndChallenge); switch ($format) { case self::FORMAT_DER: return $spkac; // case self::FORMAT_PEM: default: // OpenSSL's implementation of SPKAC requires the SPKAC be preceeded by SPKAC= and since there are pretty much // no other SPKAC decoders phpseclib will use that same format return 'SPKAC=' . base64_encode($spkac); } }
private function getSignature() { if ($this->signature) { return $this->signature; } $response = $this->getResponseMapped(); $parser = new Asn1Parser(); // @todo the signature is 0-padded, are there any exceptions? $dataToSign = $parser->encodeDER($response['tbsResponseData'], $this->asn1->ResponseData); $dataSigned = substr(base64_decode($response['signature']), 1); $algorithm = $this->asn1->getX509Asn1()->getValueForOid($response['signatureAlgorithm']['algorithm']); return $this->signature = new Signature($dataToSign, $dataSigned, $algorithm); }
/** * Get the Distinguished Name for a certificates subject * * @param Mixed $format optional * @param Array $dn optional * @access public * @return Boolean */ function getDN($format = FILE_X509_DN_ARRAY, $dn = null) { if (!isset($dn)) { $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; } switch ((int) $format) { case FILE_X509_DN_ARRAY: return $dn; case FILE_X509_DN_ASN1: $asn1 = new ASN1(); $asn1->loadOIDs($this->oids); $filters = array(); $filters['rdnSequence']['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING); $asn1->loadFilters($filters); return $asn1->encodeDER($dn, $this->Name); case FILE_X509_DN_OPENSSL: $dn = $this->getDN(FILE_X509_DN_STRING, $dn); if ($dn === false) { return false; } $attrs = preg_split('#((?:^|, *|/)[a-z][a-z0-9]*=)#i', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); $dn = array(); for ($i = 1; $i < count($attrs); $i += 2) { $prop = trim($attrs[$i], ', =/'); $value = $attrs[$i + 1]; if (!isset($dn[$prop])) { $dn[$prop] = $value; } else { $dn[$prop] = array_merge((array) $dn[$prop], array($value)); } } return $dn; case FILE_X509_DN_CANON: // No SEQUENCE around RDNs and all string values normalized as // trimmed lowercase UTF-8 with all spacing as one blank. $asn1 = new ASN1(); $asn1->loadOIDs($this->oids); $filters = array(); $filters['value'] = array('type' => FILE_ASN1_TYPE_UTF8_STRING); $asn1->loadFilters($filters); $result = ''; foreach ($dn['rdnSequence'] as $rdn) { foreach ($rdn as &$attr) { if (is_array($attr['value'])) { foreach ($attr['value'] as $type => $v) { $type = array_search($type, $asn1->ANYmap, true); if ($type !== false && isset($asn1->stringTypeSize[$type])) { $v = $asn1->convert($v, $type); if ($v !== false) { $v = preg_replace('/\\s+/', ' ', $v); $attr['value'] = strtolower(trim($v)); break; } } } } } $result .= $asn1->encodeDER($rdn, $this->RelativeDistinguishedName); } return $result; case FILE_X509_DN_HASH: $dn = $this->getDN(FILE_X509_DN_CANON, $dn); $hash = new Hash('sha1'); $hash = $hash->_hash($dn); extract(unpack('Vhash', $hash)); return strtolower(bin2hex(pack('N', $hash))); } // Defaut is to return a string. $start = true; $output = ''; $asn1 = new ASN1(); foreach ($dn['rdnSequence'] as $field) { $prop = $field[0]['type']; $value = $field[0]['value']; $delim = ', '; switch ($prop) { case 'id-at-countryName': $desc = 'C='; break; case 'id-at-stateOrProvinceName': $desc = 'ST='; break; case 'id-at-organizationName': $desc = 'O='; break; case 'id-at-organizationalUnitName': $desc = 'OU='; break; case 'id-at-commonName': $desc = 'CN='; break; case 'id-at-localityName': $desc = 'L='; break; case 'id-at-surname': $desc = 'SN='; break; case 'id-at-uniqueIdentifier': $delim = '/'; $desc = 'x500UniqueIdentifier='; break; default: $delim = '/'; $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop) . '='; } if (!$start) { $output .= $delim; } if (is_array($value)) { foreach ($value as $type => $v) { $type = array_search($type, $asn1->ANYmap, true); if ($type !== false && isset($asn1->stringTypeSize[$type])) { $v = $asn1->convert($v, $type); if ($v !== false) { $value = $v; break; } } } if (is_array($value)) { $value = array_pop($value); // Always strip data type. } } $output .= $desc . $value; $start = false; } return $output; }
/** * Convert a public key to the appropriate format * * @access public * @param \phpseclib\Math\BigInteger $n * @param \phpseclib\Math\BigInteger $e * @return string */ static function savePublicKey(BigInteger $n, BigInteger $e) { $key = ['modulus' => $n, 'publicExponent' => $e]; $asn1 = new ASN1(); $key = $asn1->encodeDER($key, RSAPublicKey); return self::wrapPublicKey($key, 'RSA'); }
/** * Creates a DER response for testing * * @param mixed $source * * @return string */ private function createDerResponse($source) { $parser = new Asn1Parser(); $asn1 = new Asn1(); return $parser->encodeDER($source, $asn1->OCSPResponse); }