diff --git a/python/src/trezorlib/authentication.py b/python/src/trezorlib/authentication.py index 4361e6d9d0a..ac3932b62ae 100644 --- a/python/src/trezorlib/authentication.py +++ b/python/src/trezorlib/authentication.py @@ -119,6 +119,22 @@ def verify_by(self, pubkey: ec.EllipticCurvePublicKey) -> None: algo_params, ) + @staticmethod + def _check_ca_extension(ext: x509.Extension) -> bool: + """Check that this extension is good for a Trezor CA. + + KeyUsage must be present and allow certificate signing. + BasicConstraints must be present, have the cA flag and a pathLenConstraint. + + Any unrecognized non-critical extension is allowed. Any unrecognized critical + extension is disallowed. + """ + if isinstance(ext.value, x509.KeyUsage): + return ext.value.key_cert_sign + if isinstance(ext.value, x509.BasicConstraints): + return ext.value.ca and ext.value.path_length is not None + return not ext.critical + def is_issued_by(self, issuer: "Certificate", path_len: int) -> bool: """Check if this certificate was issued by an issuer. @@ -134,29 +150,25 @@ def is_issued_by(self, issuer: "Certificate", path_len: int) -> bool: LOG.error("Certificate %s is not issued by %s.", self, issuer) return False - try: - # check issuer CA flag - ext = issuer.cert.extensions.get_extension_for_class(x509.BasicConstraints) - if ext.value.ca is not True: + for ext in issuer.cert.extensions: + if not self._check_ca_extension(ext): LOG.error("Issuer is not a valid CA: %s", issuer) return False - if ext.value.path_length is None: - LOG.error("Issuer is not a valid CA: %s", issuer) - return False - elif ext.value.path_length < path_len: - LOG.error( - "Issuer %s was not permitted to issue certificate %s", issuer, self - ) - return False + if isinstance(ext.value, x509.BasicConstraints): + assert ext.value.path_length is not None + if ext.value.path_length < path_len: + LOG.error( + "Issuer %s was not permitted to issue certificate %s", + issuer, + self, + ) + return False + try: pubkey = issuer.cert.public_key() assert isinstance(pubkey, ec.EllipticCurvePublicKey) self.verify_by(pubkey) return True - - except x509.ExtensionNotFound: - LOG.error("Issuer is not a valid CA: %s", issuer) - except exceptions.InvalidSignature: LOG.error("Issuer %s did not sign certificate %s.", issuer, self)