def verify_crl(crl, certificate): ''' Checks if the signature of CRL is OK. ''' tbs = crl.getComponentByName("tbsCertList") # bad idea - encoding too time consuming # try to keep the encoded version of tbsCertlist tbs_encoded = encoder.encode(tbs) sig_alg = str(crl.getComponentByName("signatureAlgorithm")) sa_name = oid_map[sig_alg] if (sa_name == SHA1RSA_NAME): calculated_digest = calculate_digest(tbs_encoded, SHA1_NAME) elif (sa_name == SHA256RSA_NAME): calculated_digest = calculate_digest(tbs_encoded, SHA256_NAME) else: logger.error("Unknown certificate signature algorithm: %s" % sig_alg) raise Exception("Unknown certificate signature algorithm: %s" % sig_alg) alg, key_material = verifier._get_key_material(certificate) signature = crl.getComponentByName("signatureValue").toOctets() # compare calculated hash and decrypted signature try: res = rsa_verifier.rsa_verify(calculated_digest, signature, key_material) except: logger.error("RSA verification of CRL failed") return False return res
def verify_certificate(cert, trusted_ca_certs=[], check_crl=False, force_crl_download=False): """ Verifies the certificate - checks signature and date validity. """ results = { "TRUSTED_CERTS_EXIST": None, "SIGNING_ALG_OK": None, "TRUSTED_PARENT_FOUND": None, "CERT_TIME_VALIDITY_OK": None, "CERT_NOT_REVOKED": None, "CERT_SIGNATURE_OK": None, } if len(trusted_ca_certs) == 0: logger.error("No trusted certificate found") results["TRUSTED_CERTS_EXIST"] = False else: results["TRUSTED_CERTS_EXIST"] = True # extract tbs certificate tbs = cert_finder._get_tbs_certificate(cert) # encode tbs into der tbs_encoded = encoder.encode(tbs) # hash tbs with used digest algorithm sig_alg = str(cert.getComponentByName("signatureAlgorithm")) sa_name = oid_map[sig_alg] if sa_name == SHA1RSA_NAME: calculated_digest = calculate_digest(tbs_encoded, SHA1_NAME) results["SIGNING_ALG_OK"] = True elif sa_name == SHA256RSA_NAME: calculated_digest = calculate_digest(tbs_encoded, SHA256_NAME) results["SIGNING_ALG_OK"] = True else: msg = "Unknown certificate signature algorithm: %s" % sig_alg logger.error(msg) results["SIGNING_ALG_OK"] = False # we dont have to continue, if we do not know signing algorithm return results # look for signing certificate among certificates issuer = str(tbs.getComponentByName("issuer")) subject = str(tbs.getComponentByName("subject")) signing_cert = find_cert_by_subject(issuer, trusted_ca_certs) if not signing_cert: msg = "No certificate found for %s, needed to verify certificate of %s" % (issuer, subject) logger.error(msg) results["TRUSTED_PARENT_FOUND"] = False # we do not have to continue - there is no signing certificate, # therefore we have no key to verify this certificate return results else: results["TRUSTED_PARENT_FOUND"] = True # check validity of certificate - validity period etc. if not _verify_date(cert): msg = "Certificate out of validity period" logger.error(msg) # return False results["CERT_TIME_VALIDITY_OK"] = False else: results["CERT_TIME_VALIDITY_OK"] = True # if we want to download and check the crl of issuing authority # for certificate being checked if check_crl: is_ok = _check_crl(cert, signing_cert, force_download=force_crl_download) csn = tbs.getComponentByName("serialNumber")._value if not is_ok: msg = "Certificate %d issued by %s is revoked" % (csn, issuer) logger.error(msg) results["CERT_NOT_REVOKED"] = False else: logger.info("Certificate %d of %s is not on CRL" % (csn, issuer)) results["CERT_NOT_REVOKED"] = True # extract public key from matching certificate alg, key_material = verifier._get_key_material(signing_cert) # decrypt signature in explored certificate signature = cert.getComponentByName("signatureValue").toOctets() # compare calculated hash and decrypted signature res = rsa_verifier.rsa_verify(calculated_digest, signature, key_material) results["CERT_SIGNATURE_OK"] = res return results