7

I have two certificates, a root.crt that was used to sign client.crt.

I want to verify that the client.crt was indeed signed by root.key.

Using openssl on terminal, it works like this:

$ openssl verify -CAfile root.crt client.crt  
> client.crt: OK  

However using pyOpenSSL - following the documentation and this blog post - I tried something like this:

client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('client.crt').read())

root_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('root.crt').read())  

store = OpenSSL.crypto.X509Store()  
store.add_cert(root_cert)  

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()  

I get this error:

    > X509StoreContextError: [2, 1, 'unable to get issuer certificate']

What am I missing?

1 Answer 1

4

The issue is that my root.crt is not really root, but a chain of certificates:

-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- 
...
-----END CERTIFICATE-----

And OpenSSL.crypto.load_certificate just loads the first one.

The solution is to extract all certificates in the chain file and add them to the X509Store.

The code solution looks like this:

_PEM_RE = re.compile(b'-----BEGIN CERTIFICATE-----\r?.+?\r?-----END CERTIFICATE-----\r?\n?', re.DOTALL)


def parse_chain(chain):
    # returns a list of certificates
    return [c.group() for c in _PEM_RE.finditer(chain)]


client_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, file('server.crt').read())

store = OpenSSL.crypto.X509Store()
for cert in parse_chain(file('root.crt').read()):
    store.add_cert(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))

ctx = OpenSSL.crypto.X509StoreContext(store, client_cert)
ctx.verify_certificate()

Adapted from https://github.com/hynek/pem/blob/master/src/pem/_core.py#L115

Sign up to request clarification or add additional context in comments.

2 Comments

May I know what is cr in the store.add_cert command?
Updated the code sample, it was a typo. Thanks for noticing!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.