feat(core/prodtest): Check device certificate chain before storing it.
What changed, and why it matters
This commit moves a certificate-chain validation check so it runs before a device certificate is permanently stored in secure hardware, rather than after. Previously, an invalid device certificate could be written to the chip before the code noticed and rejected it. The change is in factory production-test tools (prodtest), not normal user wallet firmware, so it mainly affects manufacturing/ provisioning rather than end-user devices in the field.
Treat as a low-to-moderate hardening fix in manufacturing tooling. Verify that check_device_cert_chain() itself is robust and that no other certificate types or code paths write certificates without equivalent pre-write validation. No urgent end-user action is indicated because prodtest is not shipped on consumer devices.
Security signals we found
Certificate validation moved before persistent write to secure element
Applies to device certificate provisioning in production-test code
Prevents storing an invalid/untrusted certificate before rejection
No new cryptographic checks introduced; only ordering change
Evidence from the diff
In both prodtest_optiga.c and prodtest_tropic.c, the call to check_device_cert_chain() is relocated from after optiga_set_data_object()/data_write() to before it. The function validates the supplied device certificate chain. By checking before storage, the code prevents a malformed or untrusted certificate from being committed to the secure element’s certificate slot. The diff is small and only reorders existing logic; it does not add new validation rules. No CVE, advisory, or vendor security framing is present in the supplied materials.
Changed components
core/embed/projects/prodtest/cmd/prodtest_optiga.ccore/embed/projects/prodtest/cmd/prodtest_tropic.cOPTIGA secure element device certificate provisioningTropic secure element device certificate provisioningInspect captured patch +11 / −10
diff --git a/core/embed/projects/prodtest/cmd/prodtest_optiga.c b/core/embed/projects/prodtest/cmd/prodtest_optiga.c
index 256f2a30..88b75bc7 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_optiga.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_optiga.c
@@ -412,6 +412,11 @@ static void cert_write(cli_t* cli, uint16_t oid) {
return;
}
+ if (oid == OID_CERT_DEV && !check_device_cert_chain(cli, data_bytes, len)) {
+ // Error returned by check_device_cert_chain().
+ return;
+ }
+
optiga_result ret = optiga_set_data_object(oid, false, data_bytes, len);
if (OPTIGA_SUCCESS != ret) {
cli_error(cli, CLI_ERROR, "optiga_set_data error %d for 0x%04x.", ret, oid);
@@ -429,11 +434,6 @@ static void cert_write(cli_t* cli, uint16_t oid) {
return;
}
- if (oid == OID_CERT_DEV && !check_device_cert_chain(cli, cert, cert_size)) {
- // Error returned by check_device_cert_chain().
- return;
- }
-
cli_ok(cli, "");
}
diff --git a/core/embed/projects/prodtest/cmd/prodtest_tropic.c b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
index ffbfe158..4764e250 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_tropic.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
@@ -1502,6 +1502,12 @@ static void cert_write(cli_t* cli, uint16_t first_slot, uint16_t slots_count) {
goto cleanup;
}
+ if (first_slot == TROPIC_DEVICE_CERT_FIRST_SLOT &&
+ !check_device_cert_chain(cli, certificate, certificate_length)) {
+ // Error returned by check_device_cert_chain().
+ goto cleanup;
+ }
+
ret = data_write(tropic_handle, first_slot, slots_count, certificate,
certificate_length);
if (ret != LT_OK) {
@@ -1518,11 +1524,6 @@ static void cert_write(cli_t* cli, uint16_t first_slot, uint16_t slots_count) {
goto cleanup;
}
- if (first_slot == TROPIC_DEVICE_CERT_FIRST_SLOT &&
- !check_device_cert_chain(cli, certificate, certificate_length)) {
- // Error returned by check_device_cert_chain().
- return;
- }
// TODO: call `check_device_cert_chain()` for FIDO certificate
cli_ok(cli, "");
Why this scored 42/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.