Skip to content

Commit

Permalink
fixup! feat(python): implement full certificate verification in trezo…
Browse files Browse the repository at this point in the history
…rctl (fixes #3364)
  • Loading branch information
matejcik committed Jun 24, 2024
1 parent 27b8f27 commit bf22aa3
Showing 1 changed file with 28 additions and 16 deletions.
44 changes: 28 additions & 16 deletions python/src/trezorlib/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)

Expand Down

0 comments on commit bf22aa3

Please sign in to comment.