62 lines
2.0 KiB
Markdown
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.
|