Skip to content

Unable to read the cert store when Using openssl_pkcs12_read with OpenSSL 3.x #12128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JohnyRooke opened this issue Sep 5, 2023 · 11 comments
Closed

Comments

@JohnyRooke
Copy link

Description

The following code:

<?php
    if (!$cert_store = file_get_contents("/certs/file.p12")) {
        echo "Error: Unable to read the cert file.";
        exit;
    }

    if (openssl_pkcs12_read($cert_store, $cert_info, "my_secret_pass")) {
        echo "Certificate Information:";
        print_r($cert_info);
    } else {
        echo "Error: Unable to read the cert store.";
        exit;
    }
?>

Resulted in this output:

Error: Unable to read the cert store.

But I expected this output instead:

Certificate Information:
Array
(
    [cert] => -----BEGIN CERTIFICATE-----
ICAL0wDQYJKoZIhvcNAQELBQAwgYkxCzAJBgNVBAYTAk
-----END CERTIFICATE-----,
    [pkey] => -----BEGIN PRIVATE KEY-----
LyaH3FnQfJkGmc0CgGAV72ecpf06CRrUYVl5sBUcKcT67O
 -----END PRIVATE KEY-----
)
// The values are only examples.

The error does not occur in earlier versions, such as PHP 8.2.6 and 8.2.7, which utilize OpenSSL version 1.x. Starting from PHP version 8.2.8 onwards, OpenSSL 3.x is employed, and the error occurs as previously mentioned.

PHP Version

PHP 8.2.8

Operating System

Ubuntu 20.04

@SamuelSanzo
Copy link

I also get this error. Any solution?

@bukka
Copy link
Member

bukka commented Sep 24, 2023

I have been looking through openssl_pkcs12_read code and tried few tests but don't see an issue.

We also have got a basic test for openssl_pkcs12_read which works so it might be about the actual envelope and alrgorithms (specifically security level used). You can try to quickly verify it by lowering the security level. For Ubuntu 20.04 this might work.

If that doesn't help, could you check the errors using something like this in error section:

while ($msg = openssl_error_string()) {
    echo $msg . "\n";
}

If that doesn't help, please share it here. I might also need all the non secret details about the envelope and its key and cert. Or if you are able to provide a script generating the key and cert and creating envelope that is faling the openssl_pkcs12_read, that would be even better.

@JohnyRooke
Copy link
Author

I have write in the code block you provided, and the error that comes up is:
error:0308010C:digital envelope routines::unsupported

I have been reading the article about Ubuntu security. I'm sharing the values that appear in my terminal when I run "openssl version -a" in case it helps for guidance:

vbnet
Copy code
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
built on: Tue May 30 16:12:36 2023 UTC
platform: debian-amd64
options: bn(64,64)
compiler: gcc -fPIC -pthread -m64 -Wa,--noexecstack -Wall -fzero-call-used-regs=used-gpr -DOPENSSL_TLS_SECURITY_LEVEL=2 -Wa,--noexecstack -g -O2 -ffile-prefix-map=/build/openssl-HFEiK2/openssl-3.0.9=. -fstack-protector-strong -Wformat -Werror=format-security -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_BUILDING_OPENSSL -DNDEBUG -Wdate-time -D_FORTIFY_SOURCE=2
OPENSSLDIR: "/usr/lib/ssl"
ENGINESDIR: "/usr/lib/x86_64-linux-gnu/engines-3"
MODULESDIR: "/usr/lib/x86_64-linux-gnu/ossl-modules"
Seeding source: os-specific
CPUINFO: OPENSSL_ia32cap=0xfedab2035f8bffff:0x405f46f1bf27a9

I hope this helps to better understand the issue.

@JohnyRooke
Copy link
Author

I found the problem thanks to the error clue. It's because the certificate I'm using is encrypted with the RC2-40-CBC algorithm and SHA-1. In older versions of OpenSSL, this type of encryption was allowed, but in the newer ones, it's no longer permitted due to its insecurity.

I appreciate the assistance provided. I hope this can be of help to others facing the same issue.

@bukka
Copy link
Member

bukka commented Oct 20, 2023

So this is related to legacy provider not being enabled. There is also info how to currently enable it in #12369 which should be hopefully improved in the future minor or major PHP version. There is nothing else that can be done so will close this.

@bukka bukka closed this as completed Oct 20, 2023
@angeljqv
Copy link

angeljqv commented Oct 25, 2023

@bukka hi, I did enable "legacy provider" on openssl config, but still, it doesn't work, i'm using Windows 10 with PHP 8.2.11,
Any other suggestions?
It works on 8.1, I'm trying to upgrade

@fdelapena
Copy link

fdelapena commented Oct 25, 2023

@angeljqv hi, please take a look at #9890 and #12369.

@angeljqv
Copy link

It works now, thanks

vitormattos added a commit to LibreSign/libresign that referenced this issue Apr 12, 2024
backportbot-libresign bot pushed a commit to LibreSign/libresign that referenced this issue Apr 12, 2024
backportbot-libresign bot pushed a commit to LibreSign/libresign that referenced this issue Apr 12, 2024
vitormattos added a commit to JSignPdf/jsignpdf-php that referenced this issue Apr 23, 2024
Prevent error to read certificate generated with old version of
openssl and using a newest version of openssl.

To check the password is necessary to repack the certificate using
openssl command. If the command don't exists, will consider that
the password is invalid.

Reference:

php/php-src#12128
https://www.php.net/manual/en/function.openssl-pkcs12-read.php#128992

Signed-off-by: Vitor Mattos <[email protected]>
vitormattos added a commit to JSignPdf/jsignpdf-php that referenced this issue Apr 23, 2024
Prevent error to read certificate generated with old version of
openssl and using a newest version of openssl.

To check the password is necessary to repack the certificate using
openssl command. If the command don't exists, will consider that
the password is invalid.

Reference:

php/php-src#12128
https://www.php.net/manual/en/function.openssl-pkcs12-read.php#128992

Signed-off-by: Vitor Mattos <[email protected]>
vitormattos added a commit to JSignPdf/jsignpdf-php that referenced this issue Apr 23, 2024
Prevent error to read certificate generated with old version of
openssl and using a newest version of openssl.

To check the password is necessary to repack the certificate using
openssl command. If the command don't exists, will consider that
the password is invalid.

Reference:

php/php-src#12128
https://www.php.net/manual/en/function.openssl-pkcs12-read.php#128992

Signed-off-by: Vitor Mattos <[email protected]>
@MirceaZahan
Copy link

It works now, thanks

Would have been nice from you to actually enlighten us with the solution.

@angeljqv
Copy link

@MirceaZahan, It is so difficult to follow the line of discussion 😄😄

The solution was given to me by @fdelapena

@denisgianne
Copy link

denisgianne commented Apr 21, 2025

Issues with PFX in older versions

It is known that .pfx files with legacy versions like OpenSSL 1.0 can cause reading issues when used with OpenSSL v3.

To generate an updated .pfx file, you can follow these steps:

Extract the data from certificate.pfx, including both the main and intermediate certificates, using the legacy option:

openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes --legacy

Extract the key (using the extracted .pem):

openssl rsa -in certificate.pem -out key.pem

Generate the new .pfx using the files:

openssl pkcs12 -export -out new_certificate.pfx -inkey key.pem -in certificate.pem -certfile certificate.pem

Finally type your new password

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants