From 1e5aa31eb8c8f848d50120ba2499d07428808936 Mon Sep 17 00:00:00 2001 From: Ruben van Staveren Date: Tue, 11 Aug 2020 13:25:55 +0200 Subject: [PATCH] Instead of RSA exclusive moduled, compare public key output from provided certificate and private key. This also enables the use of non RSA cryptography (tested with EC) --- sort_certificate.py | 62 ++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/sort_certificate.py b/sort_certificate.py index 3dd29f5..8d6f851 100755 --- a/sort_certificate.py +++ b/sort_certificate.py @@ -66,45 +66,27 @@ def load_data(filenames): return datas -def get_pub_modulus(cert): +def get_cert_pubkey(cert): ''' - Get the modulus of a certificate - ''' - pub = cert.get_pubkey() - - # Only works for RSA (I think) - if pub.type() != crypto.TYPE_RSA: - logging.debug('Can only handle RSA crypto:' - '\n\tsubject=%s\n\tissuer%s\n\texpired=%s\n\ttype=%s', - cert.get_subject(), - cert.get_subject(), - cert.has_expired(), - pub.type()) - raise OnlyRSAKeyException('Can only handle RSA crypto') - - pub_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pub) - pub_der = asn1.DerSequence() - pub_der.decode(pub_asn1) - pub_modulus = pub_der[1] - - return pub_modulus - - -def get_priv_modulus(priv): - ''' - Get the modulus of a RSA private key + Get the pubkey of a certificate ''' - # Only works for RSA (I think) - if priv.type() != crypto.TYPE_RSA: - raise OnlyRSAKeyException('Can only handle RSA crypto') + cert_crypto = cert.to_cryptography() + pub = cert_crypto.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo) - priv_asn1 = crypto.dump_privatekey(crypto.FILETYPE_ASN1, priv) - priv_der = asn1.DerSequence() - priv_der.decode(priv_asn1) - priv_modulus = priv_der[1] + return pub - return priv_modulus + +def get_priv_pubkey(priv): + ''' + Get the pubkey of a RSA private key + ''' + + priv_crypto = priv.to_cryptography_key() + + pub = priv_crypto.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo) + + return pub def match_cert_privkey(cert, priv): @@ -113,7 +95,7 @@ def match_cert_privkey(cert, priv): and reworked ''' - return get_pub_modulus(cert) == get_priv_modulus(priv) + return get_cert_pubkey(cert) == get_priv_pubkey(priv) def find_root(x509_objects, root_issuers): @@ -131,7 +113,7 @@ def find_intermediate_root(x509_objects, root_issuers): # Some intermediates have the *same* subject as some root certificates. # blacklist them - # XXX better use modulus/hash for that, but can't find the appropriate + # XXX better use pubkey/hash for that, but can't find the appropriate # interface to that at the moment excluded_issuers = [str(x.get_subject()) for x in x509_objects if x.get_subject() != x.get_issuer()] @@ -225,11 +207,11 @@ def load_root_issuers(): for root_cert in root_certs: try: logging.debug('subject=%s\n\tissuer%s\n\t' - 'expired=%s\n\tmodulus=%s', + 'expired=%s\n\tpubkey=%s', root_cert.get_subject(), root_cert.get_issuer(), root_cert.has_expired(), - get_pub_modulus(root_cert)) + get_cert_pubkey(root_cert)) except OnlyRSAKeyException as onlyrsa_exception: logging.debug(onlyrsa_exception) continue @@ -351,7 +333,7 @@ def main(): raise CertificateComponentException('Provided certificate' ' and RSA private key do not match') else: - logging.info('OK: Modulus of provided certificate' + logging.info('OK: Public key of provided certificate' ' and RSA private key match') elif len(pk_objects) > 1: raise CertificateComponentException('More than one RSA private key found in input.' @@ -361,7 +343,7 @@ def main(): raise CertificateComponentException('Provided certificate' ' and private key do not match') else: - logging.info('OK: Modulus of provided certificate' + logging.info('OK: Public key of provided certificate' ' and private key match') if args.include_root: