def assertSignature( # pylint: disable=invalid-name self, chain: typing.Iterable[CertificateAuthority], cert: typing.Union[Certificate, CertificateAuthority], ) -> None: """Assert that `cert` is properly signed by `chain`. .. seealso:: http://stackoverflow.com/questions/30700348 """ store = X509Store() # set the time of the OpenSSL context - freezegun doesn't work, because timestamp comes from OpenSSL now = datetime.utcnow() store.set_time(now) for elem in chain: ca = load_certificate(FILETYPE_PEM, elem.pub.pem.encode()) store.add_cert(ca) # Verify that the CA itself is valid store_ctx = X509StoreContext(store, ca) self.assertIsNone(store_ctx.verify_certificate()) # type: ignore[func-returns-value] loaded_cert = load_certificate(FILETYPE_PEM, cert.pub.pem.encode()) store_ctx = X509StoreContext(store, loaded_cert) self.assertIsNone(store_ctx.verify_certificate()) # type: ignore[func-returns-value]
def verifyChainOfTrust(self, cert): if cert is None: return None storecontext = None certx509 = load_certificate(FILETYPE_PEM, cert) storecontext = X509StoreContext(self.ccStoreContext, certx509).verify_certificate() # try: # certx509 = load_certificate(FILETYPE_PEM, cert) # storecontext = X509StoreContext(self.ccStoreContext, certx509).verify_certificate() # except X509StoreContextError as strerror: # #print("Impossible to verify the certificate given for the store context: \n{:s}".format(strerror.__doc__)) # return False # except Error as strerror: # #print(ERROR,"The certificate to be verified wasn't loaded: \n Error Information:{:s}".format(strerror.__doc__)) # return False if storecontext is None: print("The smartcard was sucessfully verified") return True else: return False
def verify_chain(chain_path, cert_bytes_or_path): try: # If certificate bytes are passed load the certificate cert = load_certificate(FILETYPE_PEM, cert_bytes_or_path) except: # If certificate path is passed open the certificate and load it's bytes cert = load_certificate(FILETYPE_PEM, open(cert_bytes_or_path, 'rb').read()) chain_bytes = open(chain_path, 'rb').read() parts = chain_bytes.split(b'-----\n-----') n_certs = len(parts) store = X509Store() if n_certs == 1: store.add_cert(load_certificate(FILETYPE_PEM, parts[0])) else: cert_list = [] store.add_cert(load_certificate(FILETYPE_PEM, (parts[0] + b'-----\n'))) store.add_cert(load_certificate(FILETYPE_PEM, (b'-----' + parts[-1]))) for i in parts[1:-1]: store.add_cert( load_certificate(FILETYPE_PEM, (b'-----' + i + b'-----\n'))) store_ctx = X509StoreContext(store, cert) try: if store_ctx.verify_certificate() == None: return True except: return False
def validate_certificate(self, certificate: str, chain: str, crl: str = None) -> None: """ Tests if a certificate has been signed by the chain, is not revoked and has not yet been expired. :param certificate: the certificate to test as string :param chain: the certificate chain file content as string :param crl: the certificate revocation list file content as string :raises: InvalidCertificateException if the certificate is invalid :return: None """ # root and intermediary certificate need to be split cas = pem.parse(chain.encode()) store = X509Store() for ca in cas: store.add_cert(self._to_cert(str(ca))) cert = self._to_cert(certificate) if crl: parsed_crl = load_crl(FILETYPE_PEM, crl) store.set_flags(X509StoreFlags.CRL_CHECK) store.add_crl(parsed_crl) ctx = X509StoreContext(store, cert) err_msg = 'Certificate is invalid' try: result = ctx.verify_certificate() if result is not None: raise InvalidCertificateException(err_msg) except Exception as e: raise InvalidCertificateException('%s: %s' % (err_msg, str(e)))
def verify_key_chain(peer_cert): root_cert = Encrypt.get_root_cert() root_cert = crypto.X509.from_cryptography(root_cert) peer_cert = crypto.X509.from_cryptography(peer_cert) store = X509Store() store.add_cert(root_cert) store_ctx = X509StoreContext(store, peer_cert) store_ctx.verify_certificate()
def assertSignature(self, chain, cert): # see: http://stackoverflow.com/questions/30700348 store = X509Store() for elem in chain: store.add_cert(load_certificate(FILETYPE_PEM, elem.dump_certificate())) cert = load_certificate(FILETYPE_PEM, cert.dump_certificate()) store_ctx = X509StoreContext(store, cert) self.assertIsNone(store_ctx.verify_certificate())
def validate_cert(store, cert): store_ctx = X509StoreContext(store, cert) subject = cert.get_subject() try: store_ctx.verify_certificate() print('certificate %s is valid against CRL' % subject) except Exception as e: print('certificate %s is NOT valid against CRL' % subject) print(e)
def submitProxy(): """ Submit a proxy certificate of a user. This operation requires user to provide personal certificate as client certificate in request. Proxy certificate that is to be submitted should be provided as raw data in request body. Function first verifies user's personal certificate against a CA certificate. If verification is successful, it procedes to read proxy certificate in body and insert it to database. Returns: status 200: A string with ID of a proxy certificate. status 401 or 500: A string with error message. """ # The following validation procedure is done as per: # https://stackoverflow.com/questions/30700348/how-to-validate-verify-an-x509-certificate-chain-of-trust-in-python # user pem is client certificate in header user_pem = getCertString() if not user_pem: return 'Wrong or no client certificate', 401 # get pem for CA caPath = os.path.join(os.environ['PATH'].split(':')[-1], 'ca.pem') try: caFile = open(caPath, 'r') # TODO: ca.pem in bin directory except Exception as e: return 'Server error: {}'.format(str(e)), 500 else: root_pem = caFile.read() caFile.close() # verify root_cert = load_certificate(FILETYPE_PEM, root_pem) user_cert = load_certificate(FILETYPE_PEM, user_pem) store = X509Store() store.add_cert(root_cert) store_ctx = X509StoreContext(store, user_cert) try: store_ctx.verify_certificate() except Exception as e: return 'Client certificate verification failed', 401 pmgr = proxymgr.ProxyManager() # TODO: handle error with pmgr and jmgr try: # TODO: ARC API does not fail when given genproxy script as proxy!!!! proxyStr = request.get_data() dn, exp_time = pmgr.readProxyString(proxyStr) proxyid = pmgr.actproxy.updateProxy(proxyStr, dn, '', exp_time) except Exception as e: return 'Server error: {}'.format(str(e)), 500 else: return json.dumps(proxyid)
def assertSignature(self, chain, cert): # see: http://stackoverflow.com/questions/30700348 store = X509Store() # set the time of the OpenSSL context - freezegun doesn't work, because timestamp comes from OpenSSL now = datetime.utcnow() store.set_time(now) for elem in chain: ca = load_certificate(FILETYPE_PEM, elem.dump_certificate()) store.add_cert(ca) # Verify that the CA itself is valid store_ctx = X509StoreContext(store, ca) self.assertIsNone(store_ctx.verify_certificate()) cert = load_certificate(FILETYPE_PEM, cert.dump_certificate()) store_ctx = X509StoreContext(store, cert) self.assertIsNone(store_ctx.verify_certificate())
def verify_certs(certs, ca_certs): # Initialize trust store with CA certificates store = X509Store() for cert in ca_certs: store.add_cert(cert) # Incrementally build up trust by first checking intermedaries for cert in reversed(certs): store_ctx = X509StoreContext(store, cert) store_ctx.verify_certificate() # Add intermediary to trust store.add_cert(cert)
def verify_against_ca(self): if not hasattr(self, '_trusted_ca'): raise VerificationError(str(self), 'did not load trusted CA') store = X509Store() store.add_cert(self._trusted_ca._x509) store_ctx = X509StoreContext(store, self._x509) try: store_ctx.verify_certificate() except X509StoreContextError as e: # [20, 0, 'unable to get local issuer certificate'] raise VerificationError(str(self), *e.args)
def _add_cert_to_store(store, cert): from OpenSSL.crypto import X509StoreContext, X509StoreContextError, Error as OpenSSLCryptoError try: X509StoreContext(store, cert).verify_certificate() except X509StoreContextError as e: raise InvalidCertificate(e) try: store.add_cert(cert) return cert except OpenSSLCryptoError as e: if e.args == ([('x509 certificate routines', 'X509_STORE_add_cert', 'cert already in hash table')],): raise RedundantCert(e) raise
def verifyChainOfTrust(self, cert): if cert is None: return None cert = base64.b64decode(cert) storecontext = None certx509 = load_certificate(FILETYPE_PEM, cert) storecontext = X509StoreContext(self.ccStoreContext, certx509).verify_certificate() if storecontext is None: print("The smartcard was sucessfully verified") return True else: return False
def validate_chain(self, file_names, last_cert): store = X509Store() for cert_file in file_names: with open(cert_file, 'rb') as f: cert = load_certificate(FILETYPE_PEM, f.read()) store.add_cert(cert) store_ctx = X509StoreContext(store, load_certificate(FILETYPE_PEM, last_cert)) result = store_ctx.verify_certificate() if result is None: return True else: return False
def verify_chain_of_trust(cert, ccStoreContext): if cert is None: return None cert = base64.b64decode(cert) storecontext = None try: certx509 = load_certificate(FILETYPE_PEM, cert) storecontext = X509StoreContext(ccStoreContext, certx509).verify_certificate() except OpenSSL.crypto.X509StoreContextError as e: return False if storecontext is None: #print("The smartcard was sucessfully verified") return True else: return False
def is_self_signed(cert: X509) -> bool: """ Checks if a X509 certificate is self signed. """ store = X509Store() store.add_cert(cert) validfrom_time = cert.get_notBefore() validfrom_datetime = datetime.strptime(validfrom_time.decode("utf-8"), "%Y%m%d%H%M%SZ") store.set_time(validfrom_datetime) store_ctx = X509StoreContext(store, cert) try: store_ctx.verify_certificate() return True except X509StoreContextError: return False
def verify_certificate(self, crt=None, cacrt=None): try: cert = load_certificate(FILETYPE_PEM, crt) intermediate_cert = load_certificate(FILETYPE_PEM, cacrt) validation_cert = load_certificate(FILETYPE_PEM, cacrt) store = X509Store() store.add_cert(intermediate_cert) store.add_cert(cert) store_ctx = X509StoreContext(store, validation_cert) if (store_ctx.verify_certificate() == None): print "Certificate verification Passed on Client side" return True else: raise Exception( "Certificate Verification Failed on Client side") except Exception as e: raise Exception("Certificate Validation Failed on Client side", e)
def estissuer_create(spec, patch, body, **_): """validate and mark issuers as ready""" # Secret must exist and be the correct type secret = get_secret_from_resource(body) if secret is None: raise kopf.TemporaryError(f"{spec['secretName']} not found") baseUrl = f"https://{spec['host']}:{spec.get('port', 443)}" path = "/".join( i for i in [WELLKNOWN, spec.get("label"), "cacerts"] if i is not None) # fetch /cacerts using explicit TA cacert = base64.b64decode(spec["cacert"]) with tempfile.NamedTemporaryFile(suffix=".pem") as cafile: cafile.write(cacert) cafile.seek(0) session = requests.Session() session.mount(baseUrl, SSLContextAdapter()) try: response = session.get(baseUrl + path, verify=cafile.name) except ( requests.exceptions.SSLError, requests.exceptions.RequestException, ) as err: patch.metadata.annotations["estoperator-perm-fail"] = "yes" raise kopf.PermanentError(err) from err # 200 OK is good, anything else is an error if response.status_code != 200: raise kopf.TemporaryError( f"Unexpected response: {response.status}, {response.reason}", ) # configured cacert must be in EST portal bundle explicit = pem.parse(cacert) store = X509Store() for cert in explicit: store.add_cert(load_certificate(FILETYPE_PEM, cert.as_text())) try: for leaf in pkcs7.load_der_pkcs7_certificates( base64.b64decode(response.content)): context = X509StoreContext( store, load_certificate(FILETYPE_PEM, leaf.public_bytes(Encoding.PEM)), ) context.verify_certificate() except X509StoreContextError as err: raise kopf.PermanentError( f"Unable to verify /cacerts content: {err}") from err return {"Ready": "True"}
def validate_cert(chain, leaf): from datetime import timedelta from OpenSSL.crypto import X509, X509Store, X509StoreContext, X509StoreContextError store = X509Store() store.set_time(leaf.not_valid_before + timedelta(days=1)) for c in chain: store.add_cert(X509.from_cryptography(c)) x509_leaf = X509.from_cryptography(leaf) ctx = X509StoreContext(store, x509_leaf) try: ctx.verify_certificate() except X509StoreContextError as e: return False return True
def _verify_report(as_root_ca_cert_path: str, enclave_info_path: str, cert: Dict[str, Any], endpoint_name: str): if os.environ.get('SGX_MODE') == 'SW': return cert = x509.load_der_x509_certificate(cert, default_backend()) ext = json.loads(cert.extensions[0].value.value) # print("ext = ", ext) report = bytes(ext["report"]) signature = bytes(ext["signature"]) signing_cert = bytes(ext["signing_cert"]) signing_cert = load_certificate(FILETYPE_ASN1, signing_cert) # verify signing cert with AS root cert with open(as_root_ca_cert_path) as f: as_root_ca_cert = f.read() as_root_ca_cert = load_certificate(FILETYPE_PEM, as_root_ca_cert) store = X509Store() store.add_cert(as_root_ca_cert) store.add_cert(signing_cert) store_ctx = X509StoreContext(store, as_root_ca_cert) store_ctx.verify_certificate() # verify report's signature crypto.verify(signing_cert, signature, bytes(ext["report"]), 'sha256') report = json.loads(report) quote = report['isvEnclaveQuoteBody'] quote = base64.b64decode(quote) # get mr_enclave and mr_signer from the quote mr_enclave = quote[112:112 + 32].hex() mr_signer = quote[176:176 + 32].hex() # get enclave_info enclave_info = toml.load(enclave_info_path) # verify mr_enclave and mr_signer enclave_name = "teaclave_" + endpoint_name + "_service" if mr_enclave != enclave_info[enclave_name]["mr_enclave"]: raise Exception("mr_enclave error") if mr_signer != enclave_info[enclave_name]["mr_signer"]: raise Exception("mr_signer error")
def verify(cert_path, ca_path, fqdn=False, port=443): """ Verify a couple of certificate and CA """ if fqdn: st_cert = get_server_certificate((cert_path, port)) else: st_cert = open(cert_path, "rt").read() st_ca = open(ca_path, "rt").read() cert = load_certificate(FILETYPE_PEM, st_cert) ca_cert = load_certificate(FILETYPE_PEM, st_ca) store = X509Store() store.add_cert(ca_cert) store_ctx = X509StoreContext(store, cert) try: if store_ctx.verify_certificate() is None: print( color_message("Verification successful !", "green", bold=True)) except X509StoreContextError as error: print( color_message("Verification error: ", "red", bold=True) + str(error))
def _validate_cert(self, to_verify, fprint, context, interm_mode): """ Validates current certificate in the given context. Extension - different context for different validation method. :param to_verify: :param context: :return: """ try: # current trust store with previously validated intermediate certificates cur_store = self._new_ossl_store() for crt in context.verified_certs: cur_store.add_cert(crt[0]) # OSSL Verification w.r.t. base store store_ctx = X509StoreContext(cur_store, to_verify[0]) store_ctx.verify_certificate() # Add valid intermediate to the verified registers if interm_mode and fprint not in self.root_fprints and fprint not in context.verified_fprints: context.verified_certs.append(to_verify) context.verified_fprints.add(fprint) except X509StoreContextError as cex: # translate specific exception to our general exception self.trace_logger.log( cex, custom_msg='Exc in path validation, interm: %s. ' % interm_mode) # message - error, depth, message, certificate which caused an error ex = ValidationOsslException('Validation failed', cause=cex) try: ex.error_code = cex.message[0] ex.error_depth = cex.message[1] ex.error_msg = cex.message[2] ex.error_cert = cex.certificate except: pass raise ex
def _add_cert_to_store(store, cert): from OpenSSL.crypto import X509StoreContext, X509StoreContextError, Error as OpenSSLCryptoError # Added by Terry to capture cert expiry cert_expired = False try: X509StoreContext(store, cert).verify_certificate() except X509StoreContextError as e: # Terry: If certificate has expired, change cert_expired status to update functions outside if 'certificate has expired' in str(e): cert_expired = True else: raise InvalidCertificate(e) try: # This has already been changed store.add_cert(cert) return (cert, cert_expired) except OpenSSLCryptoError as e: if e.args == ([('x509 certificate routines', 'X509_STORE_add_cert', 'cert already in hash table')],): raise RedundantCert(e) raise
def verify_x509_cert_chain(cert_chain, ca_pem_file=None, ca_path=None): from OpenSSL import SSL from OpenSSL.crypto import X509StoreContext, X509StoreContextError, Error as OpenSSLCryptoError context = SSL.Context(SSL.TLSv1_METHOD) if ca_pem_file is None and ca_path is None: import certifi ca_pem_file = certifi.where() context.load_verify_locations(ensure_bytes(ca_pem_file), capath=ca_path) store = context.get_cert_store() for cert in cert_chain: try: X509StoreContext(store, cert).verify_certificate() except X509StoreContextError as e: raise InvalidCertificate(e) try: store.add_cert(cert) except OpenSSLCryptoError as e: if e.args == ([('x509 certificate routines', 'X509_STORE_add_cert', 'cert already in hash table')],): continue else: raise
import sys from OpenSSL.crypto import load_certificate, load_privatekey from OpenSSL.crypto import X509Store, X509StoreContext from OpenSSL.SSL import Context, TLSv1_METHOD, VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, OP_NO_SSLv2 from OpenSSL.crypto import load_certificate, FILETYPE_PEM # from six import u, b, binary_type, PY3 store = X509Store() i = 0 for file_name in sys.argv[1:]: with open(file_name, "rb") as f: pem_data = f.read() cert = load_certificate(FILETYPE_PEM, pem_data) # cert = x509.load_pem_x509_certificate(pem_data, default_backend()) # key = load_pem_private_key(pem_data, password=None, # backend=openssl_backend) i = i + 1 print(i, len(sys.argv), "Came here", file_name) if i < len(sys.argv) - 1: store.add_cert(cert) else: store_ctx = X509StoreContext(store, cert) print("Verifying certificate " + file_name) print(store_ctx.verify_certificate())
def passive_auth( efsod: bytes, ee_deviant_doc: bool = False, dump: bool = False ) -> Tuple[str, bytes, bytes, Optional[List[PassiveAuthenticationError]]]: """ Do Passive Authentication :returns: hash_alg that is used to hash DGs, data_group_hash_values """ exceptions: List[PassiveAuthenticationError] = [] # get root node i = asn1_node_root(efsod) # unpack application data 0x77 i = asn1_node_first_child(efsod, i) # unpack sequence i = asn1_node_first_child(efsod, i) # print id-signedData OBJECT IDENTIFIER if dump: print(dump_asn1(asn1_get_all(efsod, i))) # get 2nd item inside (SignedData EXPLICIT tagged) i = asn1_node_next(efsod, i) # unpack SignedData EXPLICIT tag i = asn1_node_first_child(efsod, i) # get 1st item inside (CMSVersion Value = v3) i = asn1_node_first_child(efsod, i) # get 2nd item (DigestAlgorithmIdentifiers) collection of message digest algorithm identifiers. # There MAY be any number of elements in the collection, including zero. i = asn1_node_next(efsod, i) # get 3rd item (EncapsulatedContentInfo) (LDS Document Security Object) i = asn1_node_next(efsod, i) # get 1st item inside (eContentType) # (OID joint-iso-itu-t (2) international(23) icao(136) mrtd(1) security(1) ldsSecurityObject(1)) j = asn1_node_first_child(efsod, i) e_content_type = asn1_get_all(efsod, j) # get the EXPLICIT tagged encoded contents of ldsSecurityObject j = asn1_node_next(efsod, j) # get the encoded contents of ldsSecurityObject j = asn1_node_first_child(efsod, j) # print the value of eContent hash encapsulated_content = asn1_get_value_of_type(efsod, j, "OCTET STRING") del j signer_infos, certificates, crls = None, None, None while signer_infos is None: # https://stackoverflow.com/a/52041365/6077951 # get 4th item i = asn1_node_next(efsod, i) if efsod[i[0]] == 0xA0: # Constructed, Context-Specific 0 certificates = i print("[+] CertificateSet exist") elif efsod[i[0]] == 0xA1: # Constructed, Context-Specific 1 crls = i print("[+] Crls exist") else: signer_infos = i # The inspection system SHALL build and validate a certification path # from a Trust Anchor to the Document Signer Certificate used to # sign the Document Security Object (SOD) according to Doc 9303-11. # store was already built in the first run store = build_store.store doc_sig_cert = asn1_get_value(efsod, certificates) if certificates is not None: if ee_deviant_doc: doc_sig_cert = add_seconds_to_certificate(doc_sig_cert, 43200) CDS = load_certificate(FILETYPE_ASN1, doc_sig_cert) store_ctx = X509StoreContext(store, CDS) try: if store_ctx.verify_certificate() is None: print( "[+] Document Signer Certificate is signed by a CSCA certificate" ) except X509StoreContextError as ex: exceptions.append( PassiveAuthenticationError( "[-] Document Signer Certificate is not signed " "by a CSCA certificate or is invalid!\n" + str(ex))) else: raise PassiveAuthenticationCriticalError( "[-] This application doesn't support this kind of document yet!") # get 1st signerInfo inside signerInfos i = asn1_node_first_child(efsod, signer_infos) # get 1st item inside 1st signerInfo (CMSVersion) i = asn1_node_first_child(efsod, i) signer_info_ver = int.from_bytes(asn1_get_value_of_type( efsod, i, "INTEGER"), byteorder="big") issuer_and_serial_number, subject_key_identifier = None, None # get 2nd item inside 1st signerInfo (SignerIdentifier) i = asn1_node_next(efsod, i) if signer_info_ver == 1: issuer_and_serial_number = i elif signer_info_ver == 3: subject_key_identifier = i if dump: print( dump_asn1( asn1_get_all( efsod, issuer_and_serial_number or subject_key_identifier))) # get 3rd item inside 1st signerInfo (DigestAlgorithmIdentifier) i = asn1_node_next(efsod, i) # get hash algorithm used for encapsulatedContent and SignedAttrs hash_alg = asn1_get_all(efsod, asn1_node_first_child(efsod, i)) try: hash_alg = get_digestalg_name(hash_alg) except ValueError as ex: raise PassiveAuthenticationCriticalError( "[-] Hash algorithm is not recognized.") from ex # get 4th item inside 1st signerInfo ([0] IMPLICIT SignedAttributes) i = asn1_node_next(efsod, i) # use EXPLICIT SET OF tag, rather than of the IMPLICIT [0] tag signed_attrs = asn1_get_all(efsod, i) signed_attrs = b"\x31" + signed_attrs[1:] # get the first Attribute from SignedAttributes j = asn1_node_first_child(efsod, i) content_type, signed_attrs_hash = None, None while content_type is None or signed_attrs_hash is None: # get the content-type and the message-digest k = asn1_node_first_child(efsod, j) # contentType if asn1_get_all(efsod, k) == encode_oid_string("1.2.840.113549.1.9.3"): # then the content-type attribute value MUST match # the SignedData encapContentInfo eContentType value. # checked in line 195 k = asn1_node_next(efsod, k) k = asn1_node_first_child(efsod, k) content_type = asn1_get_all(efsod, k) # messageDigest elif asn1_get_all(efsod, k) == encode_oid_string("1.2.840.113549.1.9.4"): k = asn1_node_next(efsod, k) k = asn1_node_first_child(efsod, k) signed_attrs_hash = asn1_get_value_of_type(efsod, k, "OCTET STRING") j = asn1_node_next(efsod, j) del k, j hash_object = hashlib.new(hash_alg) hash_object.update(encapsulated_content) e_content_hash = hash_object.digest() del hash_object # print("[+] Calculated hash of eContent =", eContent_hash.hex()) # print("[+] Hash of eContent in SignedAttributes =", signedAttrs_hash.hex()) if e_content_type == content_type: print( "[+] Content Type of eContent match with the Content Type in SignedAttributes" ) else: exceptions.append( PassiveAuthenticationError( "[-] Content Type of eContent DOES NOT " "match with the Content Type in SignedAttributes.")) if hmac.compare_digest(signed_attrs_hash, e_content_hash): print("[+] Hash of eContent match with the hash in SignedAttributes") else: exceptions.append( PassiveAuthenticationError( "[+] Hash of eContent DOES NOT match with the hash in SignedAttributes." )) # get 4th item inside 1st signerInfo (SignatureAlgorithmIdentifier) i = asn1_node_next(efsod, i) # get 5th item inside 1st signerInfo (SignatureValue) i = asn1_node_next(efsod, i) signature = asn1_get_value_of_type(efsod, i, "OCTET STRING") # Verify the signature with DS_cert using hash_alg try: if verify(CDS, signature, signed_attrs, hash_alg) is None: print("[+] The signature on EF_SOD is valid.") except ex: exceptions.append( PassiveAuthenticationError( "[-] The signature on EF_SOD is not valid or failed.")) i = asn1_node_root(encapsulated_content) i = asn1_node_first_child(encapsulated_content, i) i = asn1_node_next(encapsulated_content, i) i = asn1_node_next(encapsulated_content, i) data_group_hash_values = asn1_get_all(encapsulated_content, i) if len(exceptions) == 0: return hash_alg, data_group_hash_values, doc_sig_cert, None return hash_alg, data_group_hash_values, doc_sig_cert, exceptions
) store = X509Store() certs = { "csca_Estonia_2007.cer": FILETYPE_PEM, "csca_Estonia_2007-2009-link.cer": FILETYPE_PEM, "csca_Estonia_2009.crt": FILETYPE_ASN1, "csca_Estonia_2009-2012-link.cer": FILETYPE_PEM, "csca_Estonia_2012.cer": FILETYPE_ASN1, "csca_Estonia_2012-2015-link.crt": FILETYPE_ASN1, "csca_Estonia_2015.cer": FILETYPE_ASN1, "csca_Estonia_2015-2016-link.crt": FILETYPE_ASN1, "csca_Estonia_2016.cer": FILETYPE_ASN1, "csca_Estonia_2016-2019-link.crt": FILETYPE_ASN1, "csca_Estonia_2019.cer": FILETYPE_ASN1, "csca_Estonia_2019-2020-link.der": FILETYPE_ASN1, "csca_Estonia_2020.der": FILETYPE_ASN1, } for fn, ft in certs.items(): with open("CSCA_certs/" + fn, "rb") as infile: CSCA = load_certificate(ft, infile.read()) store.add_cert(CSCA) with open("CDS", "rb") as infile: CDS = load_certificate(FILETYPE_ASN1, infile.read()) store_ctx = X509StoreContext(store, CDS) if store_ctx.verify_certificate() is None: print("[+] Document Signer Certificate is signed by a CSCA certificate")
def roots(self, fname): """ One root file processing :param fname: :return: """ self.cur_file = fname before_file_certs_size = len(self.all_certs) with open(fname) as fh: for line in fh: try: if '"ca": false' in line: continue js = json.loads(line) fprint = None raw = None rawb = None if 'fprint' in js: fprint = js['fprint'] if 'ca' in js and not js['ca']: continue fprint_requires_raw = fprint is None or len(fprint) != 40 if fprint_requires_raw and 'raw' not in js: self.num_no_fprint_raw += 1 continue if fprint_requires_raw: raw = js['raw'] rawb = base64.b64decode(raw) fprint = hashlib.sha1(rawb).hexdigest() # Already seen in this round, may become valid in the next round. if fprint in self.chain_cert_db: continue # Already assigned to a trust category if fprint in self.assigned_fprints: continue if 'raw' not in js: self.num_no_raw += 1 continue if rawb is None: raw = js['raw'] rawb = base64.b64decode(raw) self.chain_cert_db.add(fprint) crypt_cert = load_der_x509_certificate(rawb, get_backend()) if not utils.try_is_ca(crypt_cert): if self.num_not_ca % 1000 == 0: logger.debug('Cert is not CA: %s (%d)' % (fprint, self.num_not_ca)) self.num_not_ca += 1 continue # Verify ossl_cert = load_certificate(FILETYPE_ASN1, rawb) self.cur_store.set_flags(0x200000) store_ctx = X509StoreContext(self.cur_store, ossl_cert) try: store_ctx.verify_certificate() self.interms[self.cur_depth].append(js) self.assigned_fprints.add(fprint) self.all_certs.append(ossl_cert) self.test_cert(crypt_cert, js) except X509StoreContextError as cex: self.trace_logger.log(cex, custom_msg='Exc in verification') if isinstance(cex.message, (types.ListType, types.TupleType)): if cex.message[0] == 10: self.num_expired += 1 self.test_cert(crypt_cert, js, 'Expired') except Exception as e: self.trace_logger.log( e, custom_msg='General Exc in verification') self.report() except Exception as e: logger.error('Exception in processing certs %s' % e) self.trace_logger.log(e) self.num_errs += 1 new_certs_size = len(self.all_certs) - before_file_certs_size logger.info('File %s contributed with %s certificates' % (fname, new_certs_size))
def validate_certificate_chain( *, x5c: List[bytes], pem_root_certs_bytes: Optional[List[bytes]] = None, ) -> bool: """Validate that the certificates in x5c chain back to a known root certificate Args: `x5c`: X5C certificates from a registration response's attestation statement (optional) `pem_root_certs_bytes`: Any additional (PEM-formatted) root certificates that may complete the certificate chain Raises: `helpers.exceptions.InvalidCertificateChain` if chain cannot be validated """ if pem_root_certs_bytes is None or len(pem_root_certs_bytes) < 1: # We have no root certs to chain back to, so just pass on validation return True # Make sure we have at least one certificate to try and link back to a root cert if len(x5c) < 1: raise InvalidCertificateChain("x5c was empty") # Prepare leaf cert try: leaf_cert_bytes = x5c[0] leaf_cert_crypto = load_der_x509_certificate(leaf_cert_bytes, default_backend()) leaf_cert = X509().from_cryptography(leaf_cert_crypto) except Exception as err: raise InvalidCertificateChain(f"Could not prepare leaf cert: {err}") # Prepare any intermediate certs try: # May be an empty array, that's fine intermediate_certs_bytes = x5c[1:] intermediate_certs_crypto = [ load_der_x509_certificate(cert, default_backend()) for cert in intermediate_certs_bytes ] intermediate_certs = [ X509().from_cryptography(cert) for cert in intermediate_certs_crypto ] except Exception as err: raise InvalidCertificateChain( f"Could not prepare intermediate certs: {err}") # Prepare a collection of possible root certificates root_certs_store = X509Store() try: for cert in pem_root_certs_bytes: root_certs_store.add_cert(pem_cert_bytes_to_open_ssl_x509(cert)) except Exception as err: raise InvalidCertificateChain(f"Could not prepare root certs: {err}") # Load certs into a "context" for validation context = X509StoreContext( store=root_certs_store, certificate=leaf_cert, chain=intermediate_certs, ) # Validate the chain (will raise if it can't) try: context.verify_certificate() except X509StoreContextError: raise InvalidCertificateChain( "Certificate chain could not be validated") return True