Bug #50713 [PATCH]: openssl_pkcs7_verify() may ignore untrusted CAs
| From: | cmb@php.net | Date: | Thu, 29 Apr 2021 12:25:04 +0000 |
| Subject: | Bug #50713 [PATCH]: openssl_pkcs7_verify() may ignore untrusted CAs | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-233619@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=50713&edit=1
ID: 50713
Patch added by: cmb@php.net
Reported by: dark-tranquillity at yandex dot ru
Summary: openssl_pkcs7_verify() may ignore untrusted CAs
Status: Assigned
Type: Bug
Package: OpenSSL related
Operating System: Win32
PHP Version: 7.4
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
The following pull request has been associated:
Patch Name: Fix #50713: openssl_pkcs7_verify() may ignore untrusted CAs
On GitHub: https://github.com/php/php-src/pull/6927
Patch: https://github.com/php/php-src/pull/6927.patch
Previous Comments:
------------------------------------------------------------------------
[2021-04-29 12:24:20] cmb@php.net
I haven't been able to reproduce openssl_pkcs7_verify() to return
true in this case, but still, ignoring untrusted CAs appears to be
a bug.
------------------------------------------------------------------------
[2016-03-14 08:59:59] allesbesser at gmail dot com
The problem comes from the $outfilename argument which allows you to have PHP save the certificates
used to sign the message.
The PHP source is here:
https://github.com/php/php-src/blob/420c7979d5743a4621b334f569c7ae8686f4f85f/ext/openssl/openssl.c
First, the function does what it should do and calls PKCS7_verify(). This function verifies the
signature using the internal and $extracerts by calling:
signers = PKCS7_get0_signers(p7, others, (int)flags);
others are the $extracerts. Now, as you speified $extracerts, you also had to specify $outfilename.
Hence, the PHP function makes another function call:
signers = PKCS7_get0_signers(p7, NULL, (int)flags);
this time without the extra certs. Now, as the internal certificates are empty, this function raises
an error as there are no certificates.
There are several ways to fix this (apart from ignoring the error when $extracerts is not empty):
- Modify the OpenSSL code so that it does not raise the error when getting certificates
- Change the way PHP gets the certificates so that the error is not raised anymore
- Allow $outfilename to be NULL so that the function is not even called
Personally, I think passing NULL as $outfilename should be accepted in these OpenSSL functions.
------------------------------------------------------------------------
[2010-01-10 11:52:57] dark-tranquillity at yandex dot ru
Description:
------------
I have a private key & self-signed certificate.
1) create a signature (openssl_pkcs7_sign)
2) verify the signature: function openssl_pkcs7_verify returns TRUE (Verification successful),
but openssl_error_string() - returns an error message (error:2107C080:PKCS7
routines:PKCS7_get0_signers:signer certificate not found)
3) in the command line are no errors
openssl smime -sign -nocerts -signer proc.crt -inkey proc.key -in in.txt -out signed.txt
openssl smime -verify -noverify -nointern -nochain -in signed.txt -certfile proc.crt
Reproduce code:
---------------
<?
file_put_contents("in.txt", "demo text");
$certfname='./proc.crt';
$crt =file_get_contents($certfname);
$priv_key =file_get_contents('./proc.key');
if(openssl_pkcs7_sign("in.txt", "signed.txt", $crt, $priv_key, array(),
PKCS7_NOCERTS))
{
$status=openssl_pkcs7_verify("signed.txt",
PKCS7_NOVERIFY|PKCS7_NOINTERN|PKCS7_NOCHAIN, "1.tmp", array(), $certfname);
while($msg=openssl_error_string()) echo "$msg\n";
echo "status=$status\n";
}
else die('failed openssl_pkcs7_sign');
?>
Expected result:
----------------
status=1
Actual result:
--------------
error:2107C080:PKCS7 routines:PKCS7_get0_signers:signer certificate not found
status=1
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=50713&edit=1