[Digital Credentials] Validate OpenID4VP requests and hand them to the picker
Component: WebCore Digital Credentials | dcbc358
LayoutTests/http/wpt/identity/formats/openid4vp/openid4vp-roundtrip.https-expected.txt
LayoutTests/http/wpt/identity/digital-credential-openid4vp-disabled-by-default.https.html
The Digital Credentials API lets a page call navigator.credentials.get() with protocol-tagged requests (org-iso-mdoc, openid4vp-v1-signed, …). WebContent parses and validates them; the UI process shows the picker and talks to platform identity-document services, receiving validated data as IPC-serialized DigitalCredentialsRequestData, so the UI-process decoder is the trust boundary. Raw requests also go to the document provider, which identifies them by position.
WebContent now validates each OpenID4VP request into a ValidatedOpenID4VPRequest (protocol, DCQL query, verifier identities from signatures) and serializes it alongside mdoc data; the picker maps it to a WKIdentityDocumentPresentmentOpenID4VPRequest. mdoc takes precedence, only one OpenID4VP protocol is presented, and raw requests for the provider match presented ones exactly, in order, all or nothing. Requests failing validation are still forwarded so a virtual wallet can answer them; otherwise the picker rejects them. The preference defaults on where HAVE(DIGITAL_CREDENTIALS_OPENID4VP).
Significance
Page-controlled JSON now flows from the sandboxed WebContent process into the UI process and on to the system document provider, on by default. That includes DCQL queries, claim paths, trusted-authority lists and certificate data.
Audit directions
- Decode-time limit parity. A compromised WebContent skips the builder and sends the struct directly, so
isWithinOpenID4VPRequestLimits, string-length, element-count and max-presented bounds must hold in the IPC decoder for every nested container. - Unvalidated forwarding. Check what the UI process assumes about fields on the failed-validation path and whether virtual-wallet and picker-reject branches treat them consistently.
- Positional matching. Raw requests pair with presented ones by index; probe off-by-one and mismatch cases around mdoc precedence, protocol selection and truncation (the new
RejectsValidationThatDoesNotCoverEveryRequesttest points at a count mismatch). Confirm responses are accepted only for an actually-requested protocol. - Bridging layers. Review
mapClaimsQuery,mapStringSets,mapCertificateChain,buildValidatedOpenID4VPRequestObject,convertClaimPathComponentandconvertClaimValuefor lifetime, nil handling and variant type confusion, plus behavior when soft-linked WebKitSwift symbols or WebKitAdditions are missing.