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

2.0 KiB

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

import { decodePem, encodePem } from "@suaveplan/crypto-rsa/pem";

const decoded = decodePem(pemString, ["PUBLIC KEY"]);
const back = encodePem("PUBLIC KEY", decoded.body);

Usage: Advanced Example

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.