Conversation
…RPRC)
ETSI TS 119 602 is the successor trusted-list data model whose EU profiles
carry the EUDI wallet anchor lists: Annex F (WRPAC providers) and Annex G
(WRPRC providers, the registrar anchors verify_rp_registration_certificate
consumes). One interface, two encodings: parse_lote / consume_lote /
walk_lote distil into the same TrustAnchorSet as walk_lotl.
A JSON LoTE travels as a compact JAdES baseline-B JWS, so verification runs
on the existing JOSE primitives: the {ES256, ES384, EdDSA, Ed25519}
allow-list before any crypto, the WRPRC lane's allow-listed crit, the x5c
signer authenticated against caller-pinned certificates, plus the clause
6.8 DN binding (organizationName / countryName vs the scheme). Parsing is
strict and fail-closed on every field feeding a trust decision; the EU
profiles enforce Tables F.1-G.3, including the spec's literal
WRPRCrovidersList StatusDetn typo (accepted alongside the corrected
spelling). Self-made signed vectors pin the behaviour until the Commission
publishes the real lists.
Closes #135
M1 (medium): a profiled walk_lote now defaults its selection to the profile's issuance service types — the review proved a WRPRC signed under a provider's REVOCATION-service CA validated end-to-end through the documented walk -> .certificates -> verify flow. It also only follows pointers whose qualifier LoTEType matches the profile and consumes pointed lists under the same profile, so a foreign list type cannot leak anchors into a profiled walk. Explicit select=None remains the deliberate everything switch. L1 (low): a far-future ListIssueDateTime (year 9999) made _plus_months raise an uncaught ValueError that crashed consume_lote and walk_lote; now a typed TrustListProfileError / a staged problem. L2 (low): "ServiceStatus": "" slipped the profile's shall-not-be-used gate (truthiness check); presence is now the violation, read from the wire object like StatusStartingTime. I2 (info): _datetime_z accepted looser ISO forms than its docstring claimed; date-times are now pinned to the exact YYYY-MM-DDThh:mm:ssZ form clause 6.1.3 mandates. L3 was assessed a false positive (Table G.3's History row imposes no additional requirements and clause 6.7 requires StatusStartingTime inside history instances); L4 (consume_lote does no freshness check) is the documented 119 612-lane split, now stated in the docstring. Regression tests named for each attack; wiki + CHANGELOG updated.
|
Adversarial review (2026-07-22, pre-merge) — verdict: the core trust decision held (authentication, alg-binding, SSRF, walk caps: every probe in those categories failed closed, ~120 hostile parser inputs produced only the typed error family); 1 medium + 2 low confirmed with repros, fixed in d37c082 with a regression test named for each attack:
Confirmed fail-closed under attack (no change needed): ES256-header/Ed25519-leaf and every other alg/key confusion, |
feat(trustlist): consume TS 119 602 LoTE (JSON trusted lists, WRPAC/WRPRC)
ETSI TS 119 602 is the successor trusted-list data model whose EU profiles
carry the EUDI wallet anchor lists: Annex F (WRPAC providers) and Annex G
(WRPRC providers, the registrar anchors verify_rp_registration_certificate
consumes). One interface, two encodings: parse_lote / consume_lote /
walk_lote distil into the same TrustAnchorSet as walk_lotl.
A JSON LoTE travels as a compact JAdES baseline-B JWS, so verification runs
on the existing JOSE primitives: the {ES256, ES384, EdDSA, Ed25519}
allow-list before any crypto, the WRPRC lane's allow-listed crit, the x5c
signer authenticated against caller-pinned certificates, plus the clause
6.8 DN binding (organizationName / countryName vs the scheme). Parsing is
strict and fail-closed on every field feeding a trust decision; the EU
profiles enforce Tables F.1-G.3, including the spec's literal
WRPRCrovidersList StatusDetn typo (accepted alongside the corrected
spelling). Self-made signed vectors pin the behaviour until the Commission
publishes the real lists.
Closes #135