Skip to content
Advertisement

PHP OpenSSL openssl_pkcs7_verify() not working, even if openssl from shell works

I’m trying to use the OpenSSL built in PHP library to get the content of a p7m signed file (an XML file, particularly a fattura elettronica for the italians out there). I don’t need to check the sign/certificate, I need only the content.

I’m trying to “translate” this using openssl_pkcs7_verify():

openssl smime -verify -noverify -in file.xml.p7m -inform DER -out file.xml

This is the PHP line that does so:

$result = openssl_pkcs7_verify('file.xml.p7m', PKCS7_NOVERIFY, 'file.xml');

The problem is that $result is -1 and openssl_error_string() gives me this error:

error:0B065068:x509 certificate routines:BY_FILE_CTRL:loading defaults

And no, I can’t use exec() nor shell_exec() etc.
I saw that OpenSSL PHP library needs S/MIME and not DER so I found this function to get the file as S/MIME:

function der2smime($file) {
$to=<<<TXT
MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=signed-data;name="smime.p7m"
Content-Transfer-Encoding: base64
n
TXT;
    $from=file_get_contents($file);
    $to.=chunk_split(base64_encode($from));
    return file_put_contents($file,$to);
}

But it doesn’t work either using this before using openssl.
How can I fix that? Thanks in advance!

Advertisement

Answer

Okay I’ve solved it this way:
First I had to extract the certificate of the signer from the file with

openssl_pkcs7_verify($input, PKCS7_NOVERIFY | PKCS7_NOSIGS, $signer);

It extracts the certificate and it saves it in $signer.

Then I’ve used

openssl_pkcs7_verify($input, PKCS7_NOVERIFY | PKCS7_NOSIGS, $signer, [], $signer, $output);

to extract the content from the signed file in $output using the signer’s certificate.
Of course I still needed to convert the input from DER to SMIME using that function (der2smime()).
Hope it helps!

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement