Fix #50713: openssl_pkcs7_verify() may ignore untrusted CAs

Closes GH-12499
This commit is contained in:
Jakub Zelenka 2023-10-23 13:51:03 +01:00 committed by Ben Ramsey
parent 2b4a47ccec
commit 55e0748487
No known key found for this signature in database
GPG key ID: F9C39DC0B9698544
4 changed files with 85 additions and 39 deletions

4
NEWS
View file

@ -12,6 +12,10 @@ PHP NEWS
- LibXML:
. Fixed bug GH-12702 (libxml2 2.12.0 issue building from src). (nono303)
- OpenSSL:
. Fixed bug #50713 (openssl_pkcs7_verify() may ignore untrusted CAs).
(Jakub Zelenka)
- PCRE:
. Fixed bug GH-12628 (The gh11374 test fails on Alpinelinux). (nielsdos)

View file

@ -5382,7 +5382,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
signersfilename, signersfilename_len, 3, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY));
if (certout) {
int i;
signers = PKCS7_get0_signers(p7, NULL, (int)flags);
signers = PKCS7_get0_signers(p7, others, (int)flags);
if (signers != NULL) {
for (i = 0; i < sk_X509_num(signers); i++) {

View file

@ -85,8 +85,8 @@ class CertificateGenerator
openssl_x509_export_to_file($this->ca, $file);
}
public function saveNewCertAndKey(
$commonNameForCert, $certFile, $keyFile, $keyLength = null, $subjectAltName = null
private function generateCertAndKey(
$commonNameForCert, $file, $keyLength = null, $subjectAltName = null
) {
$dn = [
'countryName' => 'BY',
@ -117,51 +117,53 @@ $subjectAltNameConfig
basicConstraints = CA:FALSE
$subjectAltNameConfig
CONFIG;
$configFile = $certFile . '.cnf';
$configFile = $file . '.cnf';
file_put_contents($configFile, $configCode);
try {
$config = [
'config' => $configFile,
'req_extensions' => 'v3_req',
'x509_extensions' => 'usr_cert',
];
$config = [
'config' => $configFile,
'req_extensions' => 'v3_req',
'x509_extensions' => 'usr_cert',
];
$this->lastKey = self::generateKey($keyLength);
$csr = openssl_csr_new($dn, $this->lastKey, $config);
$this->lastCert = openssl_csr_sign(
$csr,
$this->ca,
$this->caKey,
/* days */ 2,
$config,
);
if (!$this->lastCert) {
throw new Exception('Failed to create certificate');
}
$this->lastKey = self::generateKey($keyLength);
$csr = openssl_csr_new($dn, $this->lastKey, $config);
$this->lastCert = openssl_csr_sign(
$csr,
$this->ca,
$this->caKey,
/* days */ 2,
$config,
);
$certText = '';
openssl_x509_export($this->lastCert, $certText);
$keyText = '';
openssl_pkey_export($this->lastKey, $keyText, null, $config);
if ($certFile === $keyFile) {
file_put_contents($certFile, $certText . PHP_EOL . $keyText);
} else {
file_put_contents($certFile, $certText);
file_put_contents($keyFile, $keyText);
}
} finally {
unlink($configFile);
}
return $config;
}
public function saveNewCertAsFileWithKey(
$commonNameForCert, $file, $keyLength = null, $subjectAltName = null
) {
$this->saveNewCertAndKey($commonNameForCert, $file, $file, $keyLength, $subjectAltName);
$config = $this->generateCertAndKey($commonNameForCert, $file, $keyLength, $subjectAltName);
$certText = '';
openssl_x509_export($this->lastCert, $certText);
$keyText = '';
openssl_pkey_export($this->lastKey, $keyText, null, $config);
file_put_contents($file, $certText . PHP_EOL . $keyText);
unlink($config['config']);
}
public function saveNewCertAndKey(
$commonNameForCert, $certFile, $keyFile, $keyLength = null, $subjectAltName = null
) {
$config = $this->generateCertAndKey($commonNameForCert, $certFile, $keyLength, $subjectAltName);
openssl_x509_export_to_file($this->lastCert, $certFile);
openssl_pkey_export_to_file($this->lastKey, $keyFile, null, $config);
unlink($config['config']);
}
public function getCertDigest($algo)

View file

@ -0,0 +1,40 @@
--TEST--
Bug #50713 (openssl_pkcs7_verify() may ignore untrusted CAs)
--EXTENSIONS--
openssl
--FILE--
<?php
$inFile = __DIR__ . "/plain.txt";
$outFile = __DIR__ . '/bug50713-out.pem';
$signersFile = __DIR__ . '/bug50713-signers.pem';
$keyFile = __DIR__ . '/bug50713-key.pem';
$certFile = __DIR__ . '/bug50713-crt.pem';
$cacertFile = __DIR__ . '/bug50713-ca.pem';
include 'CertificateGenerator.inc';
$certificateGenerator = new CertificateGenerator();
$certificateGenerator->saveCaCert($cacertFile);
$certificateGenerator->saveNewCertAndKey('bug50713', $certFile, $keyFile, 1024);
var_dump(openssl_pkcs7_sign($inFile, $outFile, 'file://' . $certFile, 'file://' . $keyFile, [], PKCS7_NOCERTS));
var_dump(openssl_pkcs7_verify($outFile, 0, $signersFile, [$cacertFile], $certFile));
var_dump(strlen(file_get_contents($signersFile)) > 0);
?>
--CLEAN--
<?php
$outFile = __DIR__ . '/bug50713-out.pem';
$signersFile = __DIR__ . '/bug50713-signers.pem';
$keyFile = __DIR__ . '/bug50713-key.pem';
$certFile = __DIR__ . '/bug50713-crt.pem';
$cacertFile = __DIR__ . '/bug50713-ca.pem';
@unlink($signersFile);
@unlink($outFile);
@unlink($keyFile);
@unlink($certFile);
@unlink($cacertFile);
?>
--EXPECT--
bool(true)
bool(true)
bool(true)