Skip to content

fix(ctap2): pass through arbitrary COSE algorithm identifiers#228

Merged
AlfioEmanueleFresta merged 2 commits into
masterfrom
feat/cose-alg-passthrough
May 28, 2026
Merged

fix(ctap2): pass through arbitrary COSE algorithm identifiers#228
AlfioEmanueleFresta merged 2 commits into
masterfrom
feat/cose-alg-passthrough

Conversation

@AlfioEmanueleFresta
Copy link
Copy Markdown
Member

The COSE algorithm identifier type was a closed enum with a sentinel for unknown values. Any algorithm a relying party requested that wasn't one of three known values got silently rewritten to the sentinel before reaching the authenticator. Authenticators that supported RS256, ES384, PS256, secp256k1 or other algorithms never saw the requested algorithm.

The type now passes arbitrary algorithm identifiers through unchanged, with named constants for the IANA-registered values libwebauthn cares about. The -9 codepoint was historically misnamed for an internal use and is now aligned with RFC 9864 ESP256, the actual IANA assignment.

This is a breaking change on the public Rust API.

Closes #148.

Refactor Ctap2COSEAlgorithmIdentifier from a closed repr(i32) enum into a
transparent i32 newtype with associated constants for IANA-registered
values. Arbitrary algorithm integers now round-trip through CBOR without
being rewritten to a sentinel, so RPs requesting RS256, ES384, PS256 or
any future algorithm reach the authenticator unchanged.

The -9 codepoint, previously misnamed TOPT for a Trussed-internal use,
is renamed to ESP256 per RFC 9864.

Closes #148.
Copy link
Copy Markdown
Collaborator

@msirringhaus msirringhaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Comment thread libwebauthn/src/proto/ctap2/model.rs Outdated
@AlfioEmanueleFresta
Copy link
Copy Markdown
Member Author

Thanks! Addressed your comment.

@AlfioEmanueleFresta AlfioEmanueleFresta merged commit 48387f2 into master May 28, 2026
4 checks passed
@AlfioEmanueleFresta AlfioEmanueleFresta deleted the feat/cose-alg-passthrough branch May 28, 2026 17:37
AlfioEmanueleFresta added a commit that referenced this pull request May 28, 2026
The credential public key returned by an authenticator was being stored
in a closed Rust enum that only handled P-256 and Ed25519. Any
credential using RSA, P-384, secp256k1 or a post-quantum algorithm
failed to deserialise, so the whole registration response was rejected.

Credential public keys are now stored as raw COSE bytes. The platform
doesn't crypto-validate them, it forwards them to the relying party, so
the closed enum was over-modelling. The authenticator data parser
captures the COSE_Key bytes verbatim, preserving the attestation
signature's bit-identity for relying-party verification.

A small helper reads the mandatory `alg` parameter per WebAuthn L3
§6.5.2, which is what populates `publicKeyAlgorithm` in the JSON
response. The previous ES256 fallback when attested credential data was
missing is removed because the AT flag MUST be set per CTAP §6.1, and a
silent fallback was hiding real protocol violations.

The closed enum is still used for the ECDH-ES P-256 key agreement during
PIN/UV protocols, where the COSE shape is fixed by spec.

Stacked on top of #228.
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.

Passthrough unknown key algorithms

2 participants