Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract certificate from a PKCS7 signature in php

I need to extract the user certificate from a pkcs7 signature file. I can do it via the command line using the following:

openssl pkcs7 -in somesign.pks7 -inform PEM -print_certs

This will give me the entire certificate chain and I can process the resulting file to extract what I want.

Is there any way to do that with the openssl_pkcs7_ commands? I saw that openssl_pkcs7_verify has the $outfilename where the certs would be stored but I don't have the signed message, but it seems the $filename should have both the signature and the message, which is not my case (signature is in a separate file).

like image 281
user2761778 Avatar asked Sep 09 '13 14:09

user2761778


2 Answers

I'm not aware of a PHP library with straightforward API for this.

I've implemented several libraries however that could help with the task. asn1, crypto-util and x509 are available via composer.

Here's a barebones proof of concept that extracts all certificates from a PKCS7 PEM file:

<?php

use ASN1\Element;
use ASN1\Type\Constructed\Sequence;
use CryptoUtil\PEM\PEM;
use X509\Certificate\Certificate;

require __DIR__ . "/vendor/autoload.php";

$pem = PEM::fromFile("path-to-your.p7b");
// ContentInfo: https://tools.ietf.org/html/rfc2315#section-7
$content_info = Sequence::fromDER($pem->data());
// SignedData: https://tools.ietf.org/html/rfc2315#section-9.1
$signed_data = $content_info->getTagged(0)->asExplicit()->asSequence();
// ExtendedCertificatesAndCertificates: https://tools.ietf.org/html/rfc2315#section-6.6
$ecac = $signed_data->getTagged(0)->asImplicit(Element::TYPE_SET)->asSet();
// ExtendedCertificateOrCertificate: https://tools.ietf.org/html/rfc2315#section-6.5
foreach ($ecac->elements() as $ecoc) {
    $cert = Certificate::fromASN1($ecoc->asSequence());
    echo $cert->toPEM() . "\n";
}

ASN.1 handling is very error-prone. I've omitted all sanity checks from the above example, but the underlying library will throw exceptions on errors.

I hope this gives some pointers in case someone needs to parse PKCS #7 structures without relying on external programs.

like image 137
Joe Avatar answered Oct 11 '22 10:10

Joe


I have already using it via exec() function.

exec('../../apache/bin/openssl.exe pkcs7 -in D:/mypkcs7.p7b -inform DER -print_certs').

But I think, the best choise is to use the structure of SMIME files. You can obtain the structure by analysing the source code of OpenSSL. Finding it maybe tough,but once you find it,you can use it anywhere. OpenSSL GitHub source code is available here

like image 23
Junaid Jamil Avatar answered Oct 11 '22 10:10

Junaid Jamil