Description
verify_rsa_pubkey_in_tbs accepts an arbitrary prover-supplied pubkey_offset and verifies that the DSC modulus bytes appear at that offset. It does not assert:
pubkey_offset + DSC_KEY_SIZE <= tbs_certificate_len
A prover can point the offset into the unsigned (zero-padded) tail of the 1300-byte buffer, extract attacker-controlled bytes, and have them "verified" against the CSCA signature — even though those bytes were never signed by the CSCA.
Root Cause
verify_rsa_pubkey_in_tbs takes tbs: [u8; N] and pubkey_offset: u32 but has no access to the signed length. The function only checks that modulus bytes match at the offset, with no upper-bound constraint on the offset relative to the authenticated region.
Affected file(s):
| File |
Notes |
noir-examples/noir-passport-monolithic/utils/data-check/tbs-pubkey/src/lib.nr |
verify_rsa_pubkey_in_tbs — missing bound check |
noir-examples/noir-passport-monolithic/utils/passport_validity_check/src/lib.nr |
call site — must thread tbs_certificate_len through |
Fix
Add a tbs_certificate_len: u32 parameter to verify_rsa_pubkey_in_tbs and assert the bound before the byte comparison loop:
assert(pubkey_offset + DSC_KEY_SIZE <= tbs_certificate_len);
The call site in passport_validity_check/src/lib.nr must be updated to thread tbs_certificate_len through accordingly.
Description
verify_rsa_pubkey_in_tbsaccepts an arbitrary prover-suppliedpubkey_offsetand verifies that the DSC modulus bytes appear at that offset. It does not assert:A prover can point the offset into the unsigned (zero-padded) tail of the 1300-byte buffer, extract attacker-controlled bytes, and have them "verified" against the CSCA signature — even though those bytes were never signed by the CSCA.
Root Cause
verify_rsa_pubkey_in_tbstakestbs: [u8; N]andpubkey_offset: u32but has no access to the signed length. The function only checks that modulus bytes match at the offset, with no upper-bound constraint on the offset relative to the authenticated region.Affected file(s):
noir-examples/noir-passport-monolithic/utils/data-check/tbs-pubkey/src/lib.nrverify_rsa_pubkey_in_tbs— missing bound checknoir-examples/noir-passport-monolithic/utils/passport_validity_check/src/lib.nrtbs_certificate_lenthroughFix
Add a
tbs_certificate_len: u32parameter toverify_rsa_pubkey_in_tbsand assert the bound before the byte comparison loop:The call site in
passport_validity_check/src/lib.nrmust be updated to threadtbs_certificate_lenthrough accordingly.