Files
skills/docs/security-stack/crypto/crypto-rsa/src/pem/pem-codec.md
2026-05-29 08:20:56 +01:00

62 lines
2.0 KiB
Markdown

# `pem/pem-codec`
## Purpose
Underlying RFC 7468 textual-encoding codec used by the four PEM
parse/serialise entry points in this module. Splits the codec from the
public-key-specific dispatchers so the parser logic (label whitelist,
mismatched BEGIN/END detection, base64 strict-grammar enforcement) lives
in exactly one place.
## Features
- `decodePem(pem, allowedLabels)` — line-tolerant scan for matching
BEGIN/END armor, label whitelist enforcement, body base64 round-trip.
- `encodePem(label, body)` — canonical 64-char body line emission with
trailing newline.
- All failure modes raise `CryptoRsaError(CRYPTO_RSA.PEM_MALFORMED)`.
## Usage: Basic Example
```ts
import { decodePem, encodePem } from "@suaveplan/crypto-rsa/pem";
const decoded = decodePem(pemString, ["PUBLIC KEY"]);
const back = encodePem("PUBLIC KEY", decoded.body);
```
## Usage: Advanced Example
```ts
import { decodePem } from "@suaveplan/crypto-rsa/pem";
const { label, body } = decodePem(input, ["PUBLIC KEY", "RSA PUBLIC KEY"]);
// Dispatch on label to the appropriate DER parser.
```
## API Reference
### `decodePem(pem: string, allowedLabels: readonly string[]): DecodedPem`
Returns `{ label, body }`. Throws `PEM_MALFORMED` on missing BEGIN line,
unknown label, missing matching END line, empty body, non-base64 body
characters, or base64-decode failure.
### `encodePem(label: string, body: Uint8Array): string`
Returns the canonical PEM block.
### `interface DecodedPem { readonly label: string; readonly body: Uint8Array }`
## Implementation Notes
The body grammar is enforced before base64 decoding because some base64
implementations silently accept non-canonical characters (whitespace, `_`,
`-`) that violate strict RFC 7468. We require the strict alphabet
`[A-Za-z0-9+/=]` to ensure round-trip determinism.
The codec accepts both LF and CRLF line endings on parse but always emits
LF — the canonical form recommended by RFC 7468 §2 for systems with
flexible line-ending support. CRLF emission is left to the consumer (e.g.
HTTP frameworks) as a transport-layer concern.