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!