Skip to content

noir_pasport: pubkey offset not bounds-checked against tbs_certificate_len; key can be extracted from the unsigned tail #381

@x-senpai-x

Description

@x-senpai-x

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions