Skip to content

feat(webauthn): PRF with hybrid authenticators via the prf extension#267

Open
AlfioEmanueleFresta wants to merge 3 commits into
feat/surface-unsigned-extension-outputsfrom
feat/ctap2-prf-extension
Open

feat(webauthn): PRF with hybrid authenticators via the prf extension#267
AlfioEmanueleFresta wants to merge 3 commits into
feat/surface-unsigned-extension-outputsfrom
feat/ctap2-prf-extension

Conversation

@AlfioEmanueleFresta

Copy link
Copy Markdown
Member

Closes #266. Closes #168.

WebAuthn L3 defines prf as a client extension. Security keys do not implement it directly. The client maps the PRF inputs onto the CTAP hmac-secret extension, encrypting the salts with a shared secret negotiated over the PIN/UV protocol, and the outputs come back encrypted inside the signed authenticator data. This is the path libwebauthn already implements.

Phone authenticators reached over hybrid (caBLE) take a different approach. They advertise a prf extension in getInfo and consume the WebAuthn-shaped prf input directly at the CTAP level, with the salts pre-hashed (WebAuthn L3 §10.1.4) and sent in the clear, since the hybrid tunnel already provides an encrypted and authenticated channel. There is no shared secret involved, which matters because these authenticators expose no PIN/UV auth protocol at all. Outputs come back in unsignedExtensionOutputs (CTAP 2.3 §6.1 and §6.2) rather than in the signed authenticator data. This CTAP-level prf extension is not part of the published extension registry, but it is what Chromium implements and what Google Password Manager phones expect, and WebAuthn L3 explicitly allows PRF to be implemented by means other than hmac-secret.

This change makes the two mechanisms co-exist behind the same WebAuthn-level prf extension. When the authenticator advertises prf in getInfo, the input is sent as a CTAP prf extension and results are read from unsignedExtensionOutputs. Otherwise the existing hmac-secret mapping is used, unchanged. Callers see the same client extension output either way.

Also adds a webauthn_prf_cable example covering registration and assertion. Verified end to end against a Google Password Manager phone over caBLE: registration returns enabled true together with create-time results, and assertion returns both PRF outputs.

Stacked on #260.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant