# `jwk` ## Purpose Round-trip converter between RFC 9052 `COSE_Key` instances and RFC 7517 JWK shapes. WebAuthn attestation flows often need to hand a public key to a WebCrypto-style verifier that consumes JWK; conversely, server-issued JWK-formatted keys may need to land in a CBOR-encoded COSE structure. The two conversions preserve every field that has a defined cross-format mapping. ## Features - `coseKeyToJwk(key)` — accepts any `CoseKey` discriminant (EC2, OKP, RSA, Symmetric) and emits the matching JWK (`EC`, `OKP`, `RSA`, `oct`). - `jwkToCoseKey(jwk)` — reverse mapping with full byte-string round-trip. - Byte-string fields use RFC 4648 §5 base64url encoding without padding. - `kid` is treated as UTF-8 bytes on the COSE side and a string on the JWK side; conversion is lossy only if a non-UTF-8 kid is in play (rare, and RFC 9052 §3.1 documents the convention). - `alg` round-trips through a fixed COSE↔JWK label table so the typed algorithm lands consistently on either side. ## Usage: Basic Example ```ts import { coseKeyToJwk, jwkToCoseKey } from "@suaveplan/cbor/cose"; const jwk = coseKeyToJwk(coseKey); const back = jwkToCoseKey(jwk); ``` ## Usage: Advanced Example ```ts import { decodeCoseKey, coseKeyToJwk } from "@suaveplan/cbor/cose"; // Attestation key from CTAP2 const cose = decodeCoseKey(attestationKeyBytes); const jwk = coseKeyToJwk(cose); // Hand off to WebCrypto const cryptoKey = await crypto.subtle.importKey( "jwk", jwk, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"], ); ``` ## API Reference - `coseKeyToJwk(key: CoseKey): Jwk` — discriminator-aware conversion to JWK. - `jwkToCoseKey(jwk: Jwk): CoseKey` — reverse conversion. - `Jwk = Ec2Jwk | OkpJwk | RsaJwk | SymmetricJwk` (typed union). Throws `CborError(UNEXPECTED_TYPE)` for incompatible curves (EC2 with a non-P curve, OKP with a non-Ed/X curve), unknown JWK `alg` strings, and malformed base64url input via the underlying `atob`. ## Implementation Notes base64url encoding is implemented inline with `btoa`/`atob` rather than pulling in `@suaveplan/crypto-utils` so this module stays free of crypto deps. Standard base64 padding (`=`) is stripped on output and re-padded on input — the RFC 4648 §5 spec allows omission of padding and major JWK producers do strip it. RSA JWKs use lowercase param names (`dp`, `dq`, `qi`) per RFC 7518 §6.3.2; COSE_Key uses the labels from RFC 8230 §4 (`-6`, `-7`, `-8`). The bridge preserves the field-by-field correspondence.