# `signature/verify` — Signature verify dispatch over crypto-rsa and crypto-curve ## Purpose The `signature/verify` module is part of the certificate signature-verify pipeline. Together with the rest of the `signature/` directory it converts an X.509 `signatureAlgorithm` OID into a concrete verifier dispatch and runs that verifier against the TBSCertificate bytes the certificate parser captured. RSA-SHA{256,384,512} and RSA-PSS verifies are delegated to `@suaveplan/crypto-rsa` (the just-shipped sibling package); ECDSA-P{256,384,521} and Ed25519 verifies are delegated to `@suaveplan/crypto-curve`'s `p256`, `p384`, `p521`, and `ed25519` namespaces. ## Features - Pure OID-keyed table — no string parsing, no fallbacks, no implicit defaults. - Strict OID lookup; unknown OIDs throw `X509Error(SIGNATURE_ALG_UNSUPPORTED)` with the offending OID in `error.context`. - Async verify boundary so future engines (e.g. WebCrypto via `crypto-browser`) can plug in without API changes. - Failed verify is converted to `X509Error(SIGNATURE_INVALID)` so consumers branch on the typed code rather than a boolean return. - ECDSA signature is decoded once at the verify boundary; the compact `r || s` form is then handed to the curve primitive. ## Usage: Basic Example ```ts import { resolveSignatureAlgorithm, verifyCertificateSignature } from "@suaveplan/x509/signature"; import { parseCertificate } from "@suaveplan/x509/certificate"; const child = parseCertificate(childBytes); const parent = parseCertificate(parentBytes); const ok = await verifyCertificateSignature( child.tbsCertificateBytes, child.signatureAlgorithm.oid, child.signatureValue, parent.tbs.subjectPublicKeyInfo ); ``` ## Usage: Advanced Example ```ts import { resolveSignatureAlgorithm, decodeEcdsaSignature, } from "@suaveplan/x509/signature"; const alg = resolveSignatureAlgorithm("1.2.840.10045.4.3.2"); if (alg.family === "ecdsa") { const compact = decodeEcdsaSignature(rawSignatureValue, 32); // pass compact into the curve-specific verifier of your choice } ``` ## API Reference - `resolveSignatureAlgorithm(oid: string): SignatureAlgorithm` — typed lookup. - `verifyCertificateSignature(tbsBytes, sigAlgOid, signature, parentSpki): Promise`. - `decodeEcdsaSignature(bytes, fieldLen): Uint8Array` — DER SEQUENCE-of-INTEGERs to compact `r || s`. ## Implementation Notes - The verify dispatcher catches non-`X509Error` throws from the underlying crypto engines and wraps them as `SIGNATURE_INVALID` with the original error as `cause` — this prevents bigint range errors or noble's internal exceptions from leaking to consumers. - ECDSA INTEGER decoding strips a single leading `0x00` when followed by a byte with its high bit set (the canonical positive-INTEGER prefix per X.690 paragraph 8.3.2). - RSA SPKI parsing is delegated to `@suaveplan/crypto-rsa`'s `parseRsaPublicKey({format: "spki"})` — re-implementing RSA-SPKI parse inline would duplicate code already at 100% coverage in that package. - Ed448 is recognised by the OID map but the curve primitive is not yet available in `@suaveplan/crypto-curve`; verifying an Ed448-signed certificate throws `SIGNATURE_ALG_UNSUPPORTED` with the OID. This is honest behaviour — silently returning `false` would mask the missing primitive.