What changed, and why it matters
This commit only adds extra checks inside test code for verifying certificate chain identifiers. It does not change the actual Trezor firmware or device behavior, so it does not introduce or fix a security vulnerability in the product itself.
No security action required; treat as routine test-hardening. If reviewing a broader certificate-handling change, ensure the production code already enforces equivalent chain validation.
Security signals we found
Adds test-level certificate chain validation (AKI/SKI matching)
No changes to firmware or production code paths
No changelog entry (explicit [no changelog])
Evidence from the diff
The diff modifies tests/device_tests/certificate.py, a test helper, to assert that an AuthorityKeyIdentifier (AKI) in a certificate matches the SubjectKeyIdentifier (SKI) of its issuing CA/root public key. The additions are in test verification routines (check_signature_optiga, check_signature_tropic, verify_cert_chain). No firmware runtime code is changed.
Changed components
tests/device_tests/certificate.pyInspect captured patch +39 / −0
diff --git a/tests/device_tests/certificate.py b/tests/device_tests/certificate.py
index 397c1225..8144386d 100644
--- a/tests/device_tests/certificate.py
+++ b/tests/device_tests/certificate.py
@@ -49,6 +49,17 @@ def verify_cert_chain(certs, model_name):
except ext.ExtensionNotFound:
pass
+ try:
+ ski = ca_cert.extensions.get_extension_for_class(
+ ext.SubjectKeyIdentifier
+ ).value
+ aki = cert.extensions.get_extension_for_class(
+ ext.AuthorityKeyIdentifier
+ ).value
+ assert aki.key_identifier == ski.key_identifier
+ except ext.ExtensionNotFound:
+ pass
+
ca_public_key = ca_cert.public_key()
if isinstance(ca_public_key, ed25519.Ed25519PublicKey):
ca_public_key.verify(
@@ -86,6 +97,20 @@ def check_signature_optiga(
certs[-1].signature_algorithm_parameters,
)
+ # 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 the signature of the challenge.
@@ -112,6 +137,20 @@ def check_signature_tropic(
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 the signature of the challenge.
Why this scored 12/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.