refactor(tests): refactor `verify_cert_chain()`
What changed, and why it matters
This commit is a code cleanup in the test suite. It merges two nearly identical certificate-verification routines into one shared helper and removes duplicated code. There is no change to the actual security checks performed, no change to the firmware that runs on Trezor devices, and no indication of a security fix or vulnerability.
No security action required. Treat as normal test-code refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors tests/device_tests/certificate.py. A new nested helper verify_cert_signature() is added to handle Ed25519 and ECDSA public-key signature verification. The existing verify_cert_chain() function now accepts a root_public_key parameter and uses that helper both for intermediate CA signatures and for the final trust-anchor signature. The previously duplicated trust-anchor verification and authority-key-identifier checks in check_signature_optiga() and check_signature_tropic() are removed and replaced by a single call to verify_cert_chain(…, root_public_key). The actual cryptographic operations, public-key constants, and assertions remain unchanged; only code structure and duplication are affected.
Changed components
tests/device_tests/certificate.pyInspect captured patch +30 / −53
diff --git a/tests/device_tests/certificate.py b/tests/device_tests/certificate.py
index 2330d54c..b0eb0be2 100644
--- a/tests/device_tests/certificate.py
+++ b/tests/device_tests/certificate.py
@@ -31,7 +31,19 @@ TROPIC_ROOT_PUBLIC_KEY = {
}
-def verify_cert_chain(certs, model_name):
+def verify_cert_chain(certs, model_name, root_public_key):
+ def verify_cert_signature(public_key, cert):
+ if isinstance(public_key, ed25519.Ed25519PublicKey):
+ public_key.verify(cert.signature, cert.tbs_certificate_bytes)
+ elif isinstance(public_key, ec.EllipticCurvePublicKey):
+ public_key.verify(
+ cert.signature,
+ cert.tbs_certificate_bytes,
+ cert.signature_algorithm_parameters,
+ )
+ else:
+ raise ValueError("Unsupported public key type")
+
# Verify that the common name matches the Trezor model.
common_name = certs[0].subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)[
0
@@ -62,38 +74,10 @@ def verify_cert_chain(certs, model_name):
except ext.ExtensionNotFound:
pass
- ca_public_key = ca_cert.public_key()
- if isinstance(ca_public_key, ed25519.Ed25519PublicKey):
- ca_public_key.verify(
- cert.signature,
- cert.tbs_certificate_bytes,
- )
- else:
- ca_public_key.verify(
- cert.signature,
- cert.tbs_certificate_bytes,
- cert.signature_algorithm_parameters,
- )
-
-
-def check_signature_optiga(
- signature: bytes,
- certificate_chain: Sequence[bytes],
- model: TrezorModel,
- data: bytes,
-) -> None:
- certs = [x509.load_der_x509_certificate(cert) for cert in certificate_chain]
- assert len(certs) >= 2 # at least one root and one device cert from Optiga
+ verify_cert_signature(ca_cert.public_key(), cert)
# Verify the last certificate in the certificate chain against trust anchor.
- root_public_key = ec.EllipticCurvePublicKey.from_encoded_point(
- ec.SECP256R1(), OPTIGA_ROOT_PUBLIC_KEY[model]
- )
- root_public_key.verify(
- certs[-1].signature,
- certs[-1].tbs_certificate_bytes,
- certs[-1].signature_algorithm_parameters,
- )
+ verify_cert_signature(root_public_key, certs[-1])
# Verify the authority key identifier in the last certificate.
try:
@@ -109,7 +93,20 @@ def check_signature_optiga(
except ext.ExtensionNotFound:
pass
- verify_cert_chain(certs, model.internal_name)
+
+def check_signature_optiga(
+ signature: bytes,
+ certificate_chain: Sequence[bytes],
+ model: TrezorModel,
+ data: bytes,
+) -> None:
+ certs = [x509.load_der_x509_certificate(cert) for cert in certificate_chain]
+ assert len(certs) >= 2 # at least one root and one device cert from Optiga
+
+ root_public_key = ec.EllipticCurvePublicKey.from_encoded_point(
+ ec.SECP256R1(), OPTIGA_ROOT_PUBLIC_KEY[model]
+ )
+ verify_cert_chain(certs, model.internal_name, root_public_key)
# Verify the signature of the challenge.
certs[0].public_key().verify(signature, data, ec.ECDSA(hashes.SHA256()))
@@ -126,30 +123,10 @@ def check_signature_tropic(
# If this fails, make sure the emulator was built with DISABLE_TROPIC=0
assert len(certs) >= 2 # at least one root and one device cert from Tropic
- # Verify the last certificate in the certificate chain against trust anchor.
root_public_key = ed25519.Ed25519PublicKey.from_public_bytes(
TROPIC_ROOT_PUBLIC_KEY[model]
)
- root_public_key.verify(
- certs[-1].signature,
- certs[-1].tbs_certificate_bytes,
- )
-
- # Verify the authority key identifier in the last certificate.
- try:
- aki = (
- certs[-1]
- .extensions.get_extension_for_class(ext.AuthorityKeyIdentifier)
- .value
- )
- assert (
- aki.key_identifier
- == ext.SubjectKeyIdentifier.from_public_key(root_public_key).key_identifier
- )
- except ext.ExtensionNotFound:
- pass
-
- verify_cert_chain(certs, model.internal_name)
+ verify_cert_chain(certs, model.internal_name, root_public_key)
# Verify the signature of the challenge.
certs[0].public_key().verify(signature, bytearray(data))
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.