Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extract signed data from pkcs7 in python

i have a usb cryptotoken and able to sign data and pack it in pkcs file. then i can extract certificate and data from that file using openssl as follows:

openssl cms -verify -in signature.p7s -inform DER -noverify -outform DER -signer cert.pem -out textdata

so my question is how to do the same using python (pyopenssl)?

i've tried to do as described here, but there is different case - i have attached signature and do not have separate signature and certificate file - i have ASN.1 encoded file, which contains as certificates as data and signature

like image 685
borune Avatar asked Sep 15 '18 11:09

borune


People also ask

What is SignedData object in PKCS?

The SignedData object is the root structure for sending encrypted data in PKCS#7. A generic SignedData object. The SignedData object is defined in RFC2315 and RFC5652 (amongst others) and defines data that is signed by one or more signers.

What is ASN1 PKCS7 SignedData?

data ( asn1.pkcs7.SignedData) – The ASN.1 structure of the SignedData object Loads a SignedData object from raw data that contains ContentInfo. The SignerInfo class is defined in RFC2315 and RFC5652 (amongst others) and defines the per-signer information in a SignedData structure.

Is it possible to load a CMS file into a Python file?

Python package asn1crypto is an ASN.1 parser, but also has CMS support. So now we can load the CMS into a python representation. Thanks for contributing an answer to Stack Overflow! Please be sure to answer the question.

Does asn1crypto support CMS in Python?

Python package asn1crypto is an ASN.1 parser, but also has CMS support. So now we can load the CMS into a python representation. Thanks for contributing an answer to Stack Overflow!


1 Answers

There are several hurdles to overcome to achieve what you are looking for.

First, the pyopenssl binding itself is limited when it comes to its crypto module, where you desired functionality resides. In fact, the pyopenssl crypto documentation states: enter image description here The pyca/cryptography module mentioned is exposed via two internal attributes of the pyopenssl crypto module, with the names _lib and _ffi, which need to be used to get to the required functionality.

Then the CMS_verify() function that would be your logical choice for this is not included in the pyca/cryptography bindings either. However, for your purpose it is probably good enough to use PKCS7_verify() -- you can read all about that in a StackExchange question OpenSSL PKCS#7 vs. S/MIME. The function crypto.load_pkcs7_data() comes in handy.

All that said, the following code snippet might do it for you -- although from your description it is not clear to me whether the certificate of the signer is included in the .p7s file (in that case you do not have to give -signer as an argument to openssl cms -verify like you did). It worked for me, so give it a try:

from OpenSSL import crypto
from OpenSSL._util import (
    ffi as _ffi,
    lib as _lib,
)

# Or, alternatively:
# from cryptography.hazmat.bindings.openssl.binding import Binding
# _lib = Binding.lib
# _ffi = Binding.ffi

with open('message_der.p7s', 'rb') as f:
    p7data = f.read()
p7 = crypto.load_pkcs7_data(crypto.FILETYPE_ASN1, p7data)

bio_out =crypto._new_mem_buf()
res = _lib.PKCS7_verify(p7._pkcs7, _ffi.NULL, _ffi.NULL, _ffi.NULL, bio_out, _lib.PKCS7_NOVERIFY)
if res == 1:
    databytes = crypto._bio_to_string(bio_out)
    print(databytes)
else:
    errno = _lib.ERR_get_error()
    errstrlib = _ffi.string(_lib.ERR_lib_error_string(errno))
    errstrfunc = _ffi.string(_lib.ERR_func_error_string(errno))
    errstrreason = _ffi.string(_lib.ERR_reason_error_string(errno)) 

In case you decide to use this approach, here is a caveat about using this OpenSSL bindings module directly: enter image description here

like image 68
Reinier Torenbeek Avatar answered Oct 01 '22 15:10

Reinier Torenbeek