attestation: harden error handling of challenge signing
What changed, and why it matters
This commit fixes a bug in the Blockstream Jade hardware wallet's attestation signing process. Previously, if signing the attestation challenge failed, the device would send an error message but then continue running the rest of the function anyway, potentially sending an invalid or uninitialized reply back to the caller. The fix ensures the function stops immediately after reporting the error.
Review whether any other RPC handlers in the codebase have similar missing-return-after-reject patterns. Consider whether output fields should be fully zero-initialized before use. No immediate user action is required beyond applying the patch.
Security signals we found
Missing return after error path allows fall-through to success-path reply
Uninitialized output.ext_signature_len could leak stack data or cause undefined behavior
Attestation signing failure could result in sending an invalid attestation reply
Fix is small and targeted (hardening of error handling)
Evidence from the diff
In sign_attestation_and_send_reply(), the function calls attestation_sign_challenge() and checks whether it succeeded. On failure it calls jade_process_reject_message() to send a CBOR_RPC_INTERNAL_ERROR response, but the original code did not return. Execution would fall through to the code that sends a normal attestation reply using output fields that may be uninitialized or only partially filled. The patch initializes output.ext_signature_len to 0 and adds a return after the reject message, preventing any further reply from being sent once an error has been reported.
Changed components
main/process/sign_attestation.csign_attestation_and_send_reply()Jade attestation protocolInspect captured patch +2 / −0
diff --git a/main/process/sign_attestation.c b/main/process/sign_attestation.c
index 54a1b80..bb2b323 100644
--- a/main/process/sign_attestation.c
+++ b/main/process/sign_attestation.c
@@ -38,11 +38,13 @@ void sign_attestation_and_send_reply(jade_process_t* process, const uint8_t* cha
// Compute the signature and send back to caller
size_t pem_written = 0;
attestation_reply_t output;
+ output.ext_signature_len = 0;
if (!attestation_sign_challenge(challenge, challenge_len, output.signature, sizeof(output.signature),
output.pubkey_pem, sizeof(output.pubkey_pem), &pem_written, output.ext_signature,
sizeof(output.ext_signature), &output.ext_signature_len)
|| !pem_written || !output.ext_signature_len) {
jade_process_reject_message(process, CBOR_RPC_INTERNAL_ERROR, "Failed to sign attestation");
+ return;
}
// Reply with pubkey and signatures
Why this scored 59/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.