2.4 KiB
2.4 KiB
fido-u2f attestation verifier
(no submodules)
Purpose
Implements the W3C WebAuthn L3 §8.6 fido-u2f attestation format, retained from the legacy CTAP1/U2F protocol so that existing U2F-only authenticators (early Yubikeys, hardware tokens predating CTAP2) remain interoperable with WebAuthn relying parties. The format is intentionally rigid: a single ECDSA-P256 attestation certificate, a SHA-256-then-sign signature over a fixed five-segment byte string, and a credential public key constrained to EC2 P-256.
Features
- Strict single-element
x5cenforcement. - Credential-key type check: P-256 EC2 only.
- Fixed-format signed payload:
0x00 || rpIdHash || clientDataHash || credentialId || (0x04 || x || y)per W3C §8.6 step 3. - Constant-time
rpIdHashcompare. - Attestation cert's public key extracted via
@suaveplan/x509#parseCertificate— no inline ASN.1 walking. - DER-encoded ECDSA signature converted to compact
r||sviadecodeEcdsaSignaturefrom@suaveplan/x509.
Usage: Basic Example
import { verifyFidoU2fAttestation } from "@suaveplan/webauthn/attestation/fido-u2f";
const result = await verifyFidoU2fAttestation({
attestationObject,
clientDataHash,
expectedRpIdHash,
});
Usage: Advanced Example
import {
type AttestationFormatRegistry,
verifyFidoU2fAttestation,
} from "@suaveplan/webauthn";
function registryWithFidoOnly(): AttestationFormatRegistry {
return new Map([["fido-u2f", verifyFidoU2fAttestation]]);
}
API Reference
verifyFidoU2fAttestation: AttestationFormatVerifier— the format verifier.
Implementation Notes
- The format pre-dates WebAuthn and shipped with one specific signature variant; we reject any payload that does not conform rather than trying to be lenient.
x5c.length === 1is enforced because the U2F spec issues exactly one attestation cert per device; multi-cert chains in this slot indicate either a mis-bundled response or an attempt to chain-validate via a non-U2F format.- The package does NOT bind the attestation cert back to the FIDO U2F attestation-root pool — that policy belongs to the caller via FIDO MDS3 lookup on the returned
trustPath. - The function is synchronous-shaped (no awaits inside) but typed as
Promise-returning to match theAttestationFormatVerifiercontract so callers can register either variant uniformly.