# `keys/parse-spki` ## Purpose Parses an X.509 `SubjectPublicKeyInfo` per RFC 5280 §4.1 + Appendix A and unwraps the inner PKCS#1 `RSAPublicKey`. SPKI is the canonical wire format for RSA public keys in TLS certificates (`Certificate.tbsCertificate.subjectPublicKeyInfo`), JWK headers (`x5c`/`x5t#S256` reference chains), and the WebAuthn TPM attestation statement. The parser enforces the `1.2.840.113549.1.1.1` `rsaEncryption` algorithm OID and the canonical `NULL` algorithm parameters per RFC 3279 §2.3.1. ## Features - DER outer-SEQUENCE → AlgorithmIdentifier → BIT STRING walk. - Algorithm OID equality check against `OID_RSA_ENCRYPTION`. - `NULL` algorithm-parameters enforcement (RFC 3279 §2.3.1). - Delegates inner PKCS#1 parse to `parseRsaPublicKeyPkcs1`. ## Usage: Basic Example ```ts import { parseRsaPublicKeySpki } from "@suaveplan/crypto-rsa"; const key = parseRsaPublicKeySpki(spkiDerBytes); ``` ## Usage: Advanced Example ```ts import { parseRsaPublicKeySpki } from "@suaveplan/crypto-rsa"; // SPKI carrying an EC OID rejects with UNSUPPORTED_FORMAT. try { parseRsaPublicKeySpki(ecSpkiBytes); } catch (error) { if (error instanceof CryptoRsaError && error.code === "CRYPTO_RSA.UNSUPPORTED_FORMAT") { // dispatch to @suaveplan/crypto-curve } } ``` ## API Reference ### `parseRsaPublicKeySpki(bytes: Uint8Array): RsaPublicKey` Throws `CryptoRsaError(CRYPTO_RSA.UNSUPPORTED_FORMAT)` for non-RSA OIDs. Throws `CryptoRsaError(CRYPTO_RSA.INVALID_KEY)` on structural problems (missing fields, trailing data, unused-bits ≠ 0 in the `BIT STRING`). ## Implementation Notes The `BIT STRING` payload is copied (defensive copy in `DerReader.readBitString`) so the inner PKCS#1 reader never aliases the input buffer. This costs one allocation per parse but eliminates a class of subtle bugs where downstream mutation of the inner buffer would corrupt the SPKI input. `alg.assertEnd()` and `outer.assertEnd()` together guarantee no extra fields slipped through. RFC 3279 forbids extra parameters in the `rsaEncryption` algorithm identifier, and RFC 5280 forbids extra fields in `SubjectPublicKeyInfo`.