Getting PKCS7 signer chain in python
Asked Answered
M

1

15

I have PKCS7 message which is signed. It contains a data and a signing certificate (with the whole chain of trust).

I have a code which uses m2crypto to get a certificate out of it.

bio = BIO.MemoryBuffer(pkcs7message)
p7 = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr()))
sk = X509.X509_Stack()
certStack = p7.get0_signers(sk)

It works. However, certStack returns only one certificate (instead of returning the whole chain of certificates.

Two questions:

  • Am I missing something (may be there is an option to let it know that I need the whole chain)
  • Are there other methods how to get the whole chain (may be using pyopenssl)?
Microcurie answered 6/1, 2016 at 3:43 Comment(0)
N
5

I guess you are making a confusion between signers and certificate chain of a signer. PKCS7_get0_signers return the list of signers.

In order to building a PKCS7 message with 2 signers, you can use following steps:

  1. Build key and certificate for first signer:

    openssl genrsa -out key1.pem
    openssl req -new -key key1.pem -subj "/CN=key1" | openssl x509 -req -signkey key1.pem -out cert1.pem
    
  2. Build key and certificate for second signer:

    openssl genrsa -out key2.pem
    openssl req -new -key key2.pem -subj "/CN=key2" | openssl x509 -req -signkey key2.pem -out cert2.pem
    
  3. Create an PKCS7 message using both signers :

    echo "Hello" | openssl smime -sign -nodetach \
      -out signature.der -outform DER \
      -inkey key1.pem -signer cert1.pem -inkey key2.pem -signer cert2.pem 
    

Then signers could be printed running your python script:

from M2Crypto import *

bio=BIO.File(open('signature.der'))
smime_object = SMIME.PKCS7(m2.pkcs7_read_bio_der(bio._ptr()))    
signers = smime_object.get0_signers(X509.X509_Stack())

for cert in signers:
    print(cert.get_issuer().as_text())

It give the signers' issuer:

CN=key1
CN=key2

Nada answered 12/1, 2016 at 22:30 Comment(3)
I am aware of the difference between a signer and signer certificate chain. The code which you have is generally equivalent of my code (to extract signers). However, it doesn't do anything to certificate chains. I got my PKCS7 and was able to extract chain using "openssl pkcs7 print_certs" command (which shows that certificate chain is stored somewhere there). Generally speaking my question is how to extract (in python code) these certificate chain out of PKCS7Microcurie
@VictorRonin in order to get certificate chain openssl pkcs7 -print_certs (see pkcs7.c ) use p7->d.sign->certs. This is not accessible through the m2crypto interface directly, perhaps it could be retrieved using asn1 parsing...Nada
@Nada please write this down as an answer, this comment helped me a lotDebar

© 2022 - 2024 — McMap. All rights reserved.