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,71 @@
# `cose-key`
## Purpose
Decodes and encodes RFC 9052 §7 `COSE_Key` structures. The decoder maps an
RFC-encoded CBOR map onto a typed discriminated union (`Ec2Key | OkpKey |
RsaKey | SymmetricKey`); the encoder reverses the mapping with deterministic
encoding so two keys with identical fields always produce byte-identical
output. WebAuthn attestation public keys, COSE_Sign1 signing keys, and CWT
verification keys all flow through this module.
## Features
- Discriminated union by `kty` — TypeScript narrows on `key.kty === "EC2"`
etc. without explicit casts.
- Per-key-type field validation: EC2 (`crv` + `x` + `y` + optional `d`),
OKP (`crv` + `x` + optional `d`), RSA (`n` + `e` + optional `d`/`p`/`q`/
`dP`/`dQ`/`qInv`), Symmetric (`k`).
- Common fields (`alg`, `kid`, `key_ops`, `baseIV`) parsed once and applied
uniformly across all key types.
- Throws `CborError(UNEXPECTED_TYPE)` for malformed maps, unknown labels,
wrong inner types, and missing required fields.
- Encoder uses RFC 8949 §4.2 deterministic encoding so the byte output is
stable across runs — required for COSE structures that include the key
bytes in signed/verified payloads.
## Usage: Basic Example
```ts
import { decodeCoseKey, encodeCoseKey } from "@suaveplan/cbor/cose";
const key = decodeCoseKey(bytes);
if (key.kty === "EC2") {
console.log("ES256 public key", key.x, key.y);
}
const wire = encodeCoseKey(key);
```
## Usage: Advanced Example
```ts
import { decodeCoseKey } from "@suaveplan/cbor/cose";
import { coseAlgToCryptoAlg } from "@suaveplan/cbor/cose";
// WebAuthn attestation flow
const attestationKey = decodeCoseKey(authData.credentialPublicKey);
if (attestationKey.kty !== "EC2") {
throw new Error("expected EC2 attestation key");
}
const cryptoAlg = coseAlgToCryptoAlg(attestationKey.alg ?? "ES256");
// Hand off to @suaveplan/crypto-curve to verify the signature.
```
## API Reference
- `decodeCoseKey(bytes: Uint8Array): CoseKey` — decode a CBOR-encoded
`COSE_Key` byte string into the typed union. Throws `CborError` for any
structural defect.
- `encodeCoseKey(key: CoseKey): Uint8Array` — deterministic-encode the key.
- See `cose.types.ts` for `CoseKey`, `Ec2Key`, `OkpKey`, `RsaKey`,
`SymmetricKey`, `CoseAlg`, `CoseCurve`, `CoseKeyOp`.
## Implementation Notes
The decoder tolerates extra map entries — RFC 9052 §7.1 explicitly permits
forward-compatible additions, and rejecting unknown labels would break
forward compatibility. The encoder, by contrast, emits only the fields
defined in the typed shape so it cannot accidentally leak extension data
that was never modelled. Common fields are read once into a small `CommonOut`
record and spread into every key shape — this avoids drift between the four
per-kty readers when a new common field is added in the future.