first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
# COSE_Key parser
## Purpose
Decodes a `COSE_Key` byte string (RFC 9052 §7) into the typed `CoseKey` discriminated union supplied by `@suaveplan/cbor/cose`. The WebAuthn package never re-implements CBOR — the parser is a thin error-translation wrapper plus an inline `parseCoseKeyOne` helper that the authenticator-data parser uses to extract the embedded credential public key without knowing its CBOR-encoded length up-front.
## Features
- Strict-mode delegation to `@suaveplan/cbor/cose#decodeCoseKey` for fully-sized buffers.
- `parseCoseKeyOne` for inline streams: uses `@suaveplan/cbor#decodeOne` to compute the consumed-byte count, slices the head, and re-validates via `decodeCoseKey`.
- Cause-chain preservation — every `CborError` raised by `@suaveplan/cbor` is captured on `.cause` of the surfaced `WebAuthnError(MALFORMED_RESPONSE)`.
- `resolveCoseAlg(label)` maps numeric COSE alg labels to the named identifiers (`ES256`, `ES384`, `ES512`, `EdDSA`, `RS256`) the assertion verifier dispatches on. Unknown labels throw `WEBAUTHN.SIGNATURE_INVALID` — an unverifiable algorithm cannot be accepted.
## Usage: Basic Example
```ts
import { parseCoseKey } from "@suaveplan/webauthn/parser";
const key = parseCoseKey(coseKeyBytes);
if (key.kty === "EC2") {
console.log(key.crv, key.x.byteLength, key.y.byteLength);
}
```
## Usage: Advanced Example
```ts
import {
parseCoseKeyOne,
resolveCoseAlg,
} from "@suaveplan/webauthn/parser";
const { key, consumed } = parseCoseKeyOne(authDataAfterPrefix);
const remaining = authDataAfterPrefix.subarray(consumed);
if (key.alg !== undefined) {
const alg = resolveCoseAlg(coseAlgLabel(key.alg));
// alg is now "ES256" | "ES384" | ...
}
```
## API Reference
- `parseCoseKey(bytes: Uint8Array): CoseKey` — full-buffer decode; throws `WEBAUTHN.MALFORMED_RESPONSE` on failure.
- `parseCoseKeyOne(bytes: Uint8Array): { key: CoseKey, consumed: number }` — inline decode; returns consumed-byte count for cursor advancement.
- `SUPPORTED_COSE_ALG_LABELS` — frozen map `{ ES256: -7, ES384: -35, ES512: -36, EdDSA: -8, RS256: -257 }`.
- `SupportedCoseAlg` / `SupportedCoseAlgLabel` — narrowed literal types.
- `resolveCoseAlg(label: number): SupportedCoseAlg` — numeric → named; throws `WEBAUTHN.SIGNATURE_INVALID` on unknown.
## Implementation Notes
- The package supports exactly the five algorithms required by W3C WebAuthn L3 §5.10.5 for the typical authenticator: ES256 / ES384 / ES512 (NIST curves), EdDSA (Ed25519), and RS256 (RSA-PKCS1-v1.5). PS256 is not supported because no production authenticator emits it; consumers that need PS256 can wire a custom assertion verifier via the pluggable registry.
- `parseCoseKeyOne` uses `decodeOne` to learn the encoded length first, then re-decodes via `decodeCoseKey` so the strict-mode validation in the underlying library runs. The double-decode cost is negligible (microseconds) and keeps the cbor / cose abstraction sealed.
- `resolveCoseAlg` throws rather than returning `undefined` because the caller (`verifyAssertion`) cannot proceed without knowing the algorithm — surfacing an unsupported alg as a verification failure is the safer default than passing it down to a generic fallback verifier.