Comments: I don't know if there's a way to convert it to another format so it can be parsed
You can convert PKCS#7
to PEM
using openssl
, PEM
is readable using PyOpenSSL
openssl pkcs7 -print_certs -in sample.p7b -out sample.cer
Question: ... how can I get the sha1 digest of the public key in the signature
It's not implemented, the Pull Request stalles since 2015.
Useing the code from the Pull Request you can doit.
From: GitHub pyca/pyopenssl:
implement getters for pkcs#7 certificates, crl's, and data #367
def get_certificates(self):
from OpenSSL.crypto import _lib, _ffi, X509
"""
https://github.com/pyca/pyopenssl/pull/367/files#r67300900
Returns all certificates for the PKCS7 structure, if present. Only
objects of type ``signedData`` or ``signedAndEnvelopedData`` can embed
certificates.
:return: The certificates in the PKCS7, or :const:`None` if
there are none.
:rtype: :class:`tuple` of :class:`X509` or :const:`None`
"""
certs = _ffi.NULL
if self.type_is_signed():
certs = self._pkcs7.d.sign.cert
elif self.type_is_signedAndEnveloped():
certs = self._pkcs7.d.signed_and_enveloped.cert
pycerts = []
for i in range(_lib.sk_X509_num(certs)):
pycert = X509.__new__(X509)
# pycert._x509 = _lib.sk_X509_value(certs, i)
# According to comment from @ Jari Turkia
# to prevent segfaults use '_lib.X509_dup('
pycert._x509 = _lib.X509_dup(_lib.sk_X509_value(certs, i))
pycerts.append(pycert)
if not pycerts:
return None
return tuple(pycerts)
Usage:
pkcs7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, open('signature.der', 'rb').read())
certs = get_certificates(pkcs7)
print(certs)
for cert in certs:
print('digest:{}'.format(cert.digest('sha256')))
Output:
(<OpenSSL.crypto.X509 object at 0xf671b62c>, <OpenSSL.crypto.X509 object at 0xf671b86c>)
digest:b'48:19:A4:2A:56:94:22:14:73:EC:2B:01:45:9E:0B:87:92:44:26:5E:57:AF:59:F5:4C:89:F3:79:83:14:11:A3'
digest:b'25:BC:AC:86:8F:51:8B:EE:47:CC:8B:A7:78:91:7E:86:09:56:19:4B:B9:C4:10:1B:DF:13:CA:A6:54:E1:F7:4C'
Tested with Python:3.4.2 - OpenSSL:17.1.0 - cryptography:1.9 - cffi:1.10.0
Use
OpenSSL.crypto.load_pkcs7_data(type, buffer)
Load pkcs7 data from the string buffer encoded with the type type.
The type type must either FILETYPE_PEM or FILETYPE_ASN1).