Initial Commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# `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`.
|
||||
Reference in New Issue
Block a user