noir_pasport: pubkey offset not bounds-checked against tbs_certificate_len; key can be extracted from the unsigned tail
Nobody has claimed this yet.
- Dominant language
- Noir
- Stars
- 138
- Forks
- 47
- Avg merge
- 1d 34m
- Merged PRs (30d)
- 6
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in noir-examples/noir-passport-monolithic/utils/data-check/tbs-pubkey/src/lib.nr at verify_rsa_pubkey_in_tbs, then inspect its call site in noir-examples/noir-passport-monolithic/utils/passport_validity_check/src/lib.nr. Thread tbs_certificate_len through the call and enforce that the public-key range stays within it before the byte comparison. Done means offsets into the unsigned tail are rejected.
Written by the indexing model from the issue text.
Assessment
- Domain
- cryptography, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100