Beispiel #1
0
def parse_crls(crls: BinaryIO, store: X509Store) -> None:
    """
    Parse CRLs from the ICAO PKD DSC-CRL ldif
    """
    parser = LDIFRecordList(crls)
    parser.parse_entry_records()
    for record in parser.all_records:
        if "certificateRevocationList;binary" in record[1]:
            CRL = load_crl(FILETYPE_ASN1, record[1]["certificateRevocationList;binary"][0])
            print(f"\t[+] Loaded CRL: {record[1]['cn'][0]}")
            store.add_crl(CRL)
Beispiel #2
0
    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]
Beispiel #3
0
def ccStore(rootCerts, trustedCerts, crlList):
    try:
        store = X509Store()
        i = 0
        for root in rootCerts:
            store.add_cert(root)
            i += 1
        # print("Root Certificates Added to the X509 Store Context description : {:d}".format(i))
        i = 0
        for trusted in trustedCerts:
            store.add_cert(trusted)
            i += 1
        # print("Trusted Authentication Certificates Added to the X509 Store Context description : {:d}".format(i))

        i = 0
        for crl in crlList:
            store.add_crl(crl)
            i += 1
        # print("Certificates Revocation Lists Added to the X509 Store Context description : {:d}".format(i))
        store.set_flags(X509StoreFlags.CRL_CHECK
                        | X509StoreFlags.IGNORE_CRITICAL)
    except X509StoreContext:
        print("Store Context description failed")
        return None
    else:
        return store
Beispiel #4
0
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 __init__(self):
        self.roots = None
        self.root_store = X509Store()
        self.root_certs = []
        self.root_fprints = set()  # sha256 root fingerprints

        self.trace_logger = Tracelogger(logger)
Beispiel #6
0
    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)))
Beispiel #7
0
    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 _new_ossl_store(self):
     """
     Creates a new root store for cert verification
     :return: 
     """
     cur_store = X509Store()
     for crt in self.root_certs:
         cur_store.add_cert(crt)
     return cur_store
 def new_store(self):
     """
     Creates a new store
     # define X509_V_FLAG_NO_CHECK_TIME               0x200000
     :return: 
     """
     store = X509Store()
     store.set_flags(0x200000)
     return store
    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()
Beispiel #11
0
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)
Beispiel #12
0
    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)
Beispiel #13
0
    def extractcertchains(self, timestamp):
        store = X509Store()
        for cert in self.certificates.values():
            cert_X509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                            ssl.DER_cert_to_PEM_cert(der_encoder.encode(cert)))
            OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_X509)

            fw = open(cert_X509.digest('sha1').decode('UTF-8').replace(':', ''), 'wb')
            fw.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_X509))
            fw.close()

        pass
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)
Beispiel #15
0
 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
Beispiel #16
0
    def get_cert_store(self):
        """
        Get the certificate store for the context.

        :return: A X509Store object or None if it does not have one.
        """
        store = _lib.SSL_CTX_get_cert_store(self._context)
        if store == _ffi.NULL:
            # TODO: This is untested.
            return None

        pystore = X509Store.__new__(X509Store)
        pystore._store = store
        return pystore
Beispiel #17
0
    def get_cert_store(self):
        """
        Get the certificate store for the context.

        :return: A X509Store object or None if it does not have one.
        """
        store = _lib.SSL_CTX_get_cert_store(self._context)
        if store == _ffi.NULL:
            # TODO: This is untested.
            return None

        pystore = X509Store.__new__(X509Store)
        pystore._store = store
        return pystore
Beispiel #18
0
def parse_csca_certs(master_list: BinaryIO, store: X509Store) -> None:
    """
    Parse CSCA certificates from the ICAO PKD ML ldif
    """
    parser = LDIFRecordList(master_list)
    parser.parse_entry_records()

    unique_certs: List[X509] = []

    for record in parser.all_records:
        if "CscaMasterListData" not in record[1]:
            continue
        print(f"\t[i] Reading {record[1]['cn'][0]}")
        cmd = "openssl cms -inform der -noverify -verify"
        (signed_data, err) = execute(cmd, record[1]["CscaMasterListData"][0])

        if err.decode("utf8").strip() != "Verification successful":
            # print(f"\t[-] [{err.decode('utf8')}]")
            print("\t[-] Verification of Masterlist data failed\n")
            continue
        print("\t[+] MasterList Verification successful")

        cert_list = extract_certificates(signed_data)

        print("\t[i] Removing duplicates")
        unique_certs_from_ml = [x for x in cert_list if unique_hash(x)]

        print(f"\t[i] Removed {len(cert_list)-len(unique_certs_from_ml)} duplicate certificates\n")
        unique_certs = unique_certs + unique_certs_from_ml

    print(f"\t[i] Total unique entries: {len(unique_certs)}\n")

    for cert in unique_certs:
        if is_self_signed(cert):
            print(f"\t[+] Loaded certificate: {cert.get_subject().countryName}")
            print_valid_time("\t\t", cert)
            store.add_cert(cert)
Beispiel #19
0
 def cc_store(self):
     rootCerts, trustedCerts, crlList = self.load_ca()
     try:
         cc_store = X509Store()
         for root in rootCerts:
             cc_store.add_cert(root)
         for trusted in trustedCerts:
             cc_store.add_cert(trusted)
         for crl in crlList:
             cc_store.add_crl(crl)
         cc_store.set_flags(X509StoreFlags.CRL_CHECK
                            | X509StoreFlags.IGNORE_CRITICAL)
         return cc_store
     except X509StoreContext:
         print("Store Context description failed")
         return None
Beispiel #20
0
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
Beispiel #21
0
    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
Beispiel #22
0
 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)
Beispiel #23
0
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"}
Beispiel #24
0
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")
Beispiel #25
0
    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())
Beispiel #26
0
    def check_certificates_on_disk(self):
        """ this function checks certificates stored on disk """
        self.log.info('reading certificates')
        with open(self.ca_path, 'r') as f:
            ca_certificate = load_certificate(FILETYPE_PEM, f.read())

        with open(self.clientcert_path, 'r') as f:
            client_certificate = load_certificate(FILETYPE_PEM, f.read())
        store = X509Store()
        store.add_cert(ca_certificate)
        now = datetime.utcnow().replace(tzinfo=pytz.UTC)
        client_cert_notafter_date = (datetime.strptime(
            client_certificate.get_notAfter().decode('utf-8'),
            "%Y%m%d%H%M%SZ").replace(tzinfo=pytz.UTC))
        ca_notafter_date = (datetime.strptime(
            ca_certificate.get_notAfter().decode('utf-8'),
            "%Y%m%d%H%M%SZ").replace(tzinfo=pytz.UTC))

        return ((client_cert_notafter_date - now).days,
                (ca_notafter_date - now).days)
Beispiel #27
0
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 build_store(CSCA_certs_dir: Path, crls_dir: Path, ml_dir: Path,
                dsccrl_dir: Path) -> X509Store:
    """
    Add CSCA certificates and CRLs into the store
    """
    if "store" in build_store.__dict__:
        return build_store.store
    else:
        build_store.store = X509Store()

    # Add CA certificates to the store
    # https://www2.politsei.ee/en/nouanded/isikut-toendavad-dokumendid/cert.dot
    print("[↳] Loading up CSCA certificates")

    # Load individual CSCA certificates
    for file in os.listdir(CSCA_certs_dir):
        with open(os.path.join(CSCA_certs_dir, file), "rb") as infile:
            cert = infile.read()
            if not cert.startswith(b"-----BEGIN CERTIFICATE-----"):
                try:
                    CSCA = load_certificate(FILETYPE_ASN1, cert)
                except:
                    print(
                        f"\t[-] Error while reading {os.path.join(CSCA_certs_dir, file)}, skipping..."
                    )
                    continue
                if is_self_signed(CSCA):
                    build_store.store.add_cert(CSCA)
                    print(
                        f"\t[+] Loaded certificate: {CSCA.get_subject().countryName}"
                    )
                    print_valid_time("\t\t", CSCA)
                continue
            for onecert in cert.split(b"-----END CERTIFICATE-----"):
                onecert = onecert.strip()
                if not onecert.startswith(b"-----BEGIN CERTIFICATE-----"):
                    continue
                try:
                    CSCA = load_certificate(
                        FILETYPE_PEM, onecert + b"\n-----END CERTIFICATE-----")
                except:
                    print(
                        f"\t[-] Error while reading {os.path.join(CSCA_certs_dir, file)}, skipping..."
                    )
                    continue
                if is_self_signed(CSCA):
                    build_store.store.add_cert(CSCA)
                    print(
                        f"\t[+] Loaded certificate: {CSCA.get_subject().countryName}"
                    )
                    print_valid_time("\t\t", CSCA)
    # Load CSCA certificates from ICAO PKD ML ldif
    ml_items = os.listdir(ml_dir)
    latest_ml = max(ml_items)
    with open(os.path.join(ml_dir, latest_ml), "rb") as infile:
        parse_csca_certs(infile, build_store.store)

    print("[↳] Loading up CRLs")
    # Load individual CRLs
    for file in os.listdir(crls_dir):
        with open(os.path.join(crls_dir, file), "rb") as infile:
            try:
                CRL = load_crl(FILETYPE_ASN1, infile.read())
            except:
                print(
                    f"\t[-] Error while reading {os.path.join(crls_dir, file)}, skipping..."
                )
                continue
            build_store.store.add_crl(CRL)
            print(f"\t[+] Loaded CRL: {file}")

    # Load CRLs from ICAO PKD DSC-CRL ldif
    dsccrl_items = os.listdir(dsccrl_dir)
    latest_dsccrl = max(dsccrl_items)
    with open(os.path.join(dsccrl_dir, latest_dsccrl), "rb") as infile:
        parse_crls(infile, build_store.store)

    # store.set_flags(X509StoreFlags.CRL_CHECK | X509StoreFlags.CRL_CHECK_ALL)
    # some countries don't have CRL in ICAO PKD
    build_store.store.set_flags(X509StoreFlags.CRL_CHECK_ALL)

    return build_store.store
#!/usr/bin/env python3
"""Small test script for CDS verification"""

from OpenSSL.crypto import (
    load_certificate,
    FILETYPE_ASN1,
    FILETYPE_PEM,
    X509Store,
    X509StoreContext,
)

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())
Beispiel #30
0
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