feat(tests): test serial numbers in certificates match
What changed, and why it matters
This commit adds a new automated test that checks whether the serial numbers embedded in three different security certificates inside a Trezor device all match. It does not change any production firmware code, fix a bug, or alter device behavior. It only adds a test and a corresponding test fixture entry.
No security action required. Treat as a normal test-coverage commit. If reviewing a related security issue, look for separate commits that actually modify certificate generation or validation logic.
Security signals we found
Adds a regression test for certificate serial-number consistency
No changes to firmware, cryptography, or authentication logic
No changelog entry (marked [no changelog])
Evidence from the diff
The diff adds test_certificate_subject_serial_numbers_match in tests/device_tests/test_authenticate_device.py. The test calls device.authenticate(session, b""), parses the first certificate from each of optiga_certificates, tropic_certificates, and mcu_certificates, extracts the X.509 subject SERIAL_NUMBER attribute using the cryptography library, and asserts all three values are equal. The test is skipped on safe3 and safe5 models because they do not use Tropic. A UI test fixture hash is added for the new test on T3W1.
Changed components
tests/device_tests/test_authenticate_device.pytests/ui_tests/fixtures.jsonInspect captured patch +24 / −0
diff --git a/tests/device_tests/test_authenticate_device.py b/tests/device_tests/test_authenticate_device.py
index a5c8ac9e..68a56f5f 100644
--- a/tests/device_tests/test_authenticate_device.py
+++ b/tests/device_tests/test_authenticate_device.py
@@ -1,4 +1,5 @@
import pytest
+from cryptography import x509
from trezorlib import device, exceptions, messages
from trezorlib.debuglink import DebugSession as Session
@@ -160,6 +161,28 @@ def test_authenticate_device_invalid_range_offset(
)
+@pytest.mark.models(skip=["safe3", "safe5"], reason="Not using Tropic")
+def test_certificate_subject_serial_numbers_match(
+ session: Session,
+) -> None:
+ if not session.features.bootloader_locked:
+ pytest.xfail("unlocked bootloader")
+
+ proof = device.authenticate(session, b"")
+
+ def serial_number(cert_der: bytes) -> str:
+ cert = x509.load_der_x509_certificate(cert_der)
+ attrs = cert.subject.get_attributes_for_oid(x509.oid.NameOID.SERIAL_NUMBER)
+ assert attrs
+ return attrs[0].value
+
+ optiga_sn = serial_number(proof.optiga_certificates[0])
+ tropic_sn = serial_number(proof.tropic_certificates[0])
+ mcu_sn = serial_number(proof.mcu_certificates[0])
+
+ assert optiga_sn == tropic_sn == mcu_sn
+
+
def test_authenticate_device_unexpected(
session: Session, proof_sizes: messages.AuthenticityProofSizes
) -> None:
diff --git a/tests/ui_tests/fixtures.json b/tests/ui_tests/fixtures.json
index 43436647..e2e978ee 100644
--- a/tests/ui_tests/fixtures.json
+++ b/tests/ui_tests/fixtures.json
@@ -40375,6 +40375,7 @@
"T3W1_en_test_authenticate_device.py::test_authenticate_device_tropic[hello_world-1024]": "fd6c57e10b64ae0c1f964e0c5e2bd4bfc5b92d222a9370d51e9afefe37875b0d",
"T3W1_en_test_authenticate_device.py::test_authenticate_device_tropic[hello_world-16]": "fd6c57e10b64ae0c1f964e0c5e2bd4bfc5b92d222a9370d51e9afefe37875b0d",
"T3W1_en_test_authenticate_device.py::test_authenticate_device_unexpected": "fd6c57e10b64ae0c1f964e0c5e2bd4bfc5b92d222a9370d51e9afefe37875b0d",
+"T3W1_en_test_authenticate_device.py::test_certificate_subject_serial_numbers_match": "fd6c57e10b64ae0c1f964e0c5e2bd4bfc5b92d222a9370d51e9afefe37875b0d",
"T3W1_en_test_autolock.py::test_apply_auto_lock_delay": "27c3e0de0fde6a010bba328fa8ac0ccda58e3d7faad43c32f521ac1a5306d934",
"T3W1_en_test_autolock.py::test_apply_auto_lock_delay_out_of_range[0]": "c3ed9c0cfce604e341f0f0384f7ce044186240dd8ee993ced8766c3f4a9bb75c",
"T3W1_en_test_autolock.py::test_apply_auto_lock_delay_out_of_range[1]": "c3ed9c0cfce604e341f0f0384f7ce044186240dd8ee993ced8766c3f4a9bb75c",
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.