4.5 KiB
Capability Spec Delta: webauthn (webauthn)
Package: @suaveplan/webauthn
Status: PROPOSED (companion delta of add-webauthn-mds3)
Every requirement below carries a
**Verified by:**line at authoring time. No exceptions.
MODIFIED Requirements
Requirement: Attestation verification dispatch
The package SHALL export verifyAttestation(input: VerifyAttestationInput): Promise<AttestationVerifyResult> from the ./verifier subpath. The function SHALL dispatch on input.attestationObject.fmt to the per-format verifier registered in input.registry, throwing WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED when no verifier is registered. VerifyAttestationInput SHALL accept an optional metadata?: MetadataResolver field (typed via import type from @suaveplan/webauthn-mds3 — runtime-optional) and an optional revokedStatuses?: ReadonlySet<AuthenticatorStatus> field. AttestationVerifyResult SHALL carry an optional metadata?: MetadataLookup field. When input.metadata is undefined the returned AttestationVerifyResult SHALL be byte-identical to the pre-modification contract (strict back-compat). When input.metadata is supplied, after the per-format verifier returns, verifyAttestation SHALL resolve the AAGUID — or, for fmt === "fido-u2f" or an all-zero AAGUID, the SHA-1 SKI of the leaf attestation certificate (FIDO MDS3 §3.1.6) — call resolveByAaguid / resolveByAttestationCertificateKeyId on the supplied resolver, set result.metadata to the returned MetadataLookup (or omit when undefined), and downgrade result.trusted to false when the lookup's currentStatus is in revokedStatuses ?? DEFAULT_REVOCATION_STATUSES.
Scenario: dispatches to registered format verifier
- WHEN
verifyAttestation({ attestationObject: { fmt: "packed", ... }, registry: defaultAttestationRegistry(), ... })is called - THEN the result is produced by the
packedverifier and includestrustPath,attestationType,trusted
Scenario: throws WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED on unknown fmt
- WHEN
verifyAttestation({ attestationObject: { fmt: "unknown-fmt", ... }, registry: emptyRegistry })is called - THEN the call rejects with
WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED
Scenario: omits metadata field when no resolver injected (back-compat)
- WHEN
verifyAttestation(input)is called withinput.metadata === undefined - THEN the resolved
AttestationVerifyResulthasmetadata === undefinedand is byte-for-byte identical to the legacy (pre-modification) result for the same inputs
Scenario: augments result with metadata when resolver injected
- GIVEN a
MetadataResolverwhoseresolveByAaguidreturns aMetadataLookupwithcurrentStatus === "FIDO_CERTIFIED_L1" - WHEN
verifyAttestation({ ..., metadata: resolver })is called against apackedattestation carrying a known AAGUID - THEN
result.metadatadeep-equals the lookup andresult.trustedis the verifier's original value (unchanged)
Scenario: downgrades trusted=false when currentStatus is revoked
- GIVEN a
MetadataResolverwhoseresolveByAaguidreturns aMetadataLookupwithcurrentStatus === "REVOKED" - WHEN
verifyAttestation({ ..., metadata: resolver })is called and the per-format verifier returnedtrusted: true - THEN the merged
result.trustedisfalseandresult.metadata.currentStatus === "REVOKED"
Scenario: resolves U2F by attestation-cert SKI
- GIVEN a
MetadataResolverand afido-u2fattestation whose leaf cert has SKI0xDEAD… - WHEN
verifyAttestation({ ..., metadata: resolver })is called - THEN the resolver's
resolveByAttestationCertificateKeyId(0xDEAD…)is invoked exactly once andresolveByAaguidis never called
Verified by: packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"dispatches to registered format verifier" AND packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"throws WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED on unknown fmt" AND packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"omits metadata field when no resolver injected (back-compat)" AND packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"augments result with metadata when resolver injected" AND packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"downgrades trusted=false when currentStatus is revoked" AND packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"resolves U2F by attestation-cert SKI"