I build my own certificates chain and try to verify it.
When I have only 2 certificates (the root CA and the to-be-verified): it works fine.
When I have 3 (the root CA, an intermediate, and the to-be-verified): I get the message "invalid CA certificate".
Here is a minimalist code :
import OpenSSL
def create_cert_chain ( nb ):
chain = []
issuer_key = None
issuer_name = None
is_root = True
for i in range( nb ):
my_name = b'certificate #%d'%i # certificate #0 is the root CA
cert = OpenSSL.crypto.X509()
my_key = OpenSSL.crypto.PKey()
my_key . generate_key( OpenSSL.crypto.TYPE_RSA,2048 )
if is_root :
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",subject=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",issuer=cert)])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"basicConstraints", False, b"CA:TRUE,pathlen:5")])
cert.add_extensions( [OpenSSL.crypto.X509Extension(b"keyUsage", False, b"keyCertSign, cRLSign")])
cert.get_subject().O = my_name
cert.get_issuer().O = my_name if is_root else issuer_name
cert.gmtime_adj_notBefore( 0 )
cert.gmtime_adj_notAfter( 365*24*60*60 )
cert.set_pubkey( my_key )
cert.sign( my_key if is_root else issuer_key,'sha256' )
chain += [cert]
issuer_key = my_key
issuer_name = my_name
is_root = False
return chain
def check_chain ( nb ):
chain = create_cert_chain( nb )
store = OpenSSL.crypto.X509Store()
for cert in chain[:-1] :
print( 'store certificate%s'%cert.get_subject().O )
store.add_cert( cert )
print( 'check certificate%s'%chain[-1].get_subject().O )
ctx = OpenSSL.crypto.X509StoreContext( store,chain[-1] )
ctx.verify_certificate()
print('ok')
check_chain( 2 ) # works fine
check_chain( 3 ) # fails with "invalid CA certificate"
What do I wrong ?
I suspect a mistake about the extensions but I can't figure out what it is...
And by the way, why does it works with only 2 certificates ?