diff --git a/ext/openssl/tests/CertificateGenerator.inc b/ext/openssl/tests/CertificateGenerator.inc index 12764c8b63d2c..6fd73e0e9bed1 100644 --- a/ext/openssl/tests/CertificateGenerator.inc +++ b/ext/openssl/tests/CertificateGenerator.inc @@ -4,26 +4,33 @@ class CertificateGenerator { const CONFIG = __DIR__. DIRECTORY_SEPARATOR . 'openssl.cnf'; - /** @var OpenSSLCertificate */ - private $ca; + /** @var OpenSSLCertificate|false */ + private $ca = false; - /** @var resource */ - private $caKey; + /** @var OpenSSLAsymmetricKey|false */ + private $caKey = false; - /** @var resource|null */ + /** @var bool */ + private $useSelfSignedCert; + + /** @var OpenSSLCertificate|null */ private $lastCert; - /** @var resource|null */ + /** @var OpenSSLAsymmetricKey|null */ private $lastKey; - public function __construct() + public function __construct(bool $useSelfSignedCert = false) { if (!extension_loaded('openssl')) { throw new RuntimeException( 'openssl extension must be loaded to generate certificates' ); } - $this->generateCa(); + $this->useSelfSignedCert = $useSelfSignedCert; + + if (!$this->useSelfSignedCert) { + $this->generateCa(); + } } /** @@ -54,40 +61,32 @@ class CertificateGenerator 'commonName' => 'CA for PHP Tests' ]; - $this->ca = openssl_csr_sign( - openssl_csr_new( - $dn, - $this->caKey, - [ - 'x509_extensions' => 'v3_ca', - 'config' => self::CONFIG, - ] - ), - null, - $this->caKey, - 2, - [ - 'config' => self::CONFIG, - ] - ); + $csr = openssl_csr_new($dn, $this->caKey, ['config' => self::CONFIG]); + $this->ca = openssl_csr_sign($csr, null, $this->caKey, 365, ['config' => self::CONFIG]); } public function getCaCert() { + if ($this->useSelfSignedCert) { + throw new RuntimeException("CA is not generated in self-signed mode."); + } + $output = ''; openssl_x509_export($this->ca, $output); - return $output; } public function saveCaCert($file) { + if ($this->useSelfSignedCert) { + throw new RuntimeException("CA is not available in self-signed mode."); + } + openssl_x509_export_to_file($this->ca, $file); } - private function generateCertAndKey( - $commonNameForCert, $file, $keyLength = null, $subjectAltName = null - ) { + private function generateCertAndKey($commonNameForCert, $file, $keyLength = null, $subjectAltName = null) + { $dn = [ 'countryName' => 'BY', 'stateOrProvinceName' => 'Minsk', @@ -98,8 +97,7 @@ class CertificateGenerator $dn['commonName'] = $commonNameForCert; } - $subjectAltNameConfig = - $subjectAltName ? "subjectAltName = $subjectAltName" : ""; + $subjectAltNameConfig = $subjectAltName ? "subjectAltName = $subjectAltName" : ""; $configCode = <<lastKey = self::generateKey($keyLength); $csr = openssl_csr_new($dn, $this->lastKey, $config); + + // If in self-signed mode, sign with the same key, otherwise use CA + $signingCert = $this->useSelfSignedCert ? null : $this->ca; + $signingKey = $this->useSelfSignedCert ? $this->lastKey : $this->caKey; + $this->lastCert = openssl_csr_sign( $csr, - $this->ca, - $this->caKey, - /* days */ 2, - $config, + $signingCert, + $signingKey, + 365, // 1 year validity + $config ); return $config; @@ -166,6 +169,22 @@ CONFIG; unlink($config['config']); } + public function saveNewCertAndPubKey( + $commonNameForCert, $certFile, $pubKeyFile, $keyLength = null, $subjectAltName = null + ) { + $config = $this->generateCertAndKey($commonNameForCert, $certFile, $keyLength, $subjectAltName); + + openssl_x509_export_to_file($this->lastCert, $certFile); + + $keyDetails = openssl_pkey_get_details($this->lastKey); + if ($keyDetails === false || !isset($keyDetails['key'])) { + throw new RuntimeException("Failed to extract public key."); + } + + file_put_contents($pubKeyFile, $keyDetails['key']); + unlink($config['config']); + } + public function getCertDigest($algo) { return openssl_x509_fingerprint($this->lastCert, $algo); diff --git a/ext/openssl/tests/openssl_x509_verify.phpt b/ext/openssl/tests/openssl_x509_verify.phpt index 083d4669c4229..4b6e758857d27 100644 --- a/ext/openssl/tests/openssl_x509_verify.phpt +++ b/ext/openssl/tests/openssl_x509_verify.phpt @@ -4,16 +4,24 @@ openssl_x509_verify() tests openssl --FILE-- saveNewCertAndPubKey('openssl-x509-verify-server', $certFile, $keyFile); + +$fp = fopen($certFile,"r"); $a = fread($fp, 8192); fclose($fp); -$fp = fopen(__DIR__ . "/public.key","r"); +$fp = fopen($keyFile,"r"); $b = fread($fp, 8192); fclose($fp); -$cert = "file://" . __DIR__ . "/cert.crt"; -$key = "file://" . __DIR__ . "/public.key"; +$cert = "file://" . $certFile; +$key = "file://" . $keyFile; $wrongKey = "file://" . __DIR__ . "/public_rsa_2048.key"; var_dump(openssl_x509_verify($cert, $key)); @@ -23,6 +31,11 @@ var_dump(openssl_x509_verify("", "")); var_dump(openssl_x509_verify(openssl_x509_read($a), $b)); var_dump(openssl_x509_verify($cert, $wrongKey)); ?> +--CLEAN-- + --EXPECT-- int(1) int(-1)