Skip to content

micro509/der ​

DER reading and writing primitives.

The building blocks every other entrypoint is made of, for the cases the typed APIs do not cover:

Reading accepts definite lengths and minimal length encodings, rejects the high-tag-number form, and applies a nesting-depth guard capped at DEFAULT_MAX_DER_DEPTH. BER-only constructs fail.

Readers and decoders take untrusted bytes, so each one comes as a pair:

Writers take typed input and throw, matching encodeName and pemEncode.

All operations are synchronous.

DecodeDerErrorCode ​

Machine-readable failure reason for the DER readers and decoders.

malformed is input that breaks DER or the decoder's ASN.1 type. unsupported is input the type may allow but micro509 does not decode: a TeletexString octet outside the X.690 §8.23.5.2 initial state. limit_exceeded is an implementation limit: an OBJECT IDENTIFIER sub-identifier encoded in more than 64 octets, a tag number of 2^53 or more, or DER nested deeper than 64 levels.

ts
type DecodeDerErrorCode = DecodeFailureCode

DecodeDerFailure ​

Structured failure payload for DER reading and decoding.

ts
interface DecodeDerFailure extends Micro509Error<DecodeDerErrorCode> {
	readonly ok: false;
}

Properties

  • readonly ok: false — Always false for failures.

DecodeDerResult ​

Success-or-failure result from a DER reader or decoder.

ts
type DecodeDerResult<TValue> = {
  readonly ok: true;
  readonly value: TValue
} | ErrorResult<DecodeDerErrorCode, Record<never, never>, DecodeDerFailure>

decodeDerBitString ​

Decodes a BIT STRING element (tag 0x03) into a DerBitString.

Unused trailing bits are returned as encoded, with a violation of X.690 §11.2.1 reported through DerBitString.nonZeroPadding, since certificates in the wild carry them.

ts
function decodeDerBitString(
	element: DerElement,
): DecodeDerResult<DerBitString>

Parameters

decodeDerBitStringOrThrow ​

Decodes a BIT STRING element (tag 0x03) into a DerBitString.

Unused trailing bits are returned as encoded, with a violation of X.690 §11.2.1 reported through DerBitString.nonZeroPadding, since certificates in the wild carry them.

ts
function decodeDerBitStringOrThrow(
	element: DerElement,
): DerBitString

Parameters

Throws

  • if element is mis-tagged, or claims more than seven unused bits.

decodeDerBoolean ​

Decodes a BOOLEAN element (tag 0x01).

ts
function decodeDerBoolean(
	element: DerElement,
): DecodeDerResult<boolean>

Parameters

decodeDerBooleanOrThrow ​

Decodes a BOOLEAN element (tag 0x01).

ts
function decodeDerBooleanOrThrow(
	element: DerElement,
): boolean

Parameters

Throws

  • if element is mis-tagged, or holds anything but 0x00 or 0xff.

decodeDerInteger ​

Decodes an INTEGER element (tag 0x02) into a number.

ts
function decodeDerInteger(
	element: DerElement,
): DecodeDerResult<number>

Parameters

decodeDerIntegerOrThrow ​

Decodes an INTEGER element (tag 0x02) into a number.

ts
function decodeDerIntegerOrThrow(
	element: DerElement,
): number

Parameters

Throws

  • if element is mis-tagged, negative, non-minimally encoded, or exceeds Number.MAX_SAFE_INTEGER.

decodeDerOctetString ​

Decodes an OCTET STRING element (tag 0x04) into its payload bytes.

ts
function decodeDerOctetString(
	element: DerElement,
): DecodeDerResult<Uint8Array>

Parameters

decodeDerOctetStringOrThrow ​

Decodes an OCTET STRING element (tag 0x04) into its payload bytes.

ts
function decodeDerOctetStringOrThrow(
	element: DerElement,
): Uint8Array

Parameters

Throws

decodeDerOid ​

Decodes an OBJECT IDENTIFIER element (tag 0x06) into dotted-decimal form.

ts
function decodeDerOid(
	element: DerElement,
): DecodeDerResult<string>

Parameters

decodeDerOidOrThrow ​

Decodes an OBJECT IDENTIFIER element (tag 0x06) into dotted-decimal form.

ts
function decodeDerOidOrThrow(
	element: DerElement,
): string

Parameters

Throws

  • if element is mis-tagged, or holds a malformed sub-identifier.

decodeDerString ​

Decodes a string element into text, dispatching on its tag.

Supports UTF8String, PrintableString, TeletexString, IA5String, UniversalString, and BMPString. A TeletexString decodes only in its X.690 §8.23.5.2 initial state.

ts
function decodeDerString(
	element: DerElement,
): DecodeDerResult<string>

Parameters

decodeDerStringOrThrow ​

Decodes a string element into text, dispatching on its tag.

Supports UTF8String, PrintableString, TeletexString, IA5String, UniversalString, and BMPString. A TeletexString decodes only in its X.690 §8.23.5.2 initial state.

ts
function decodeDerStringOrThrow(
	element: DerElement,
): string

Parameters

Throws

  • on every other string tag, and on a TeletexString octet outside that state.

decodeDerTime ​

Decodes a UTCTime (tag 0x17) or GeneralizedTime (tag 0x18) element into a Date.

ts
function decodeDerTime(
	element: DerElement,
): DecodeDerResult<Date>

Parameters

decodeDerTimeOrThrow ​

Decodes a UTCTime (tag 0x17) or GeneralizedTime (tag 0x18) element into a Date.

ts
function decodeDerTimeOrThrow(
	element: DerElement,
): Date

Parameters

Throws

  • if element carries any other tag, or a malformed time value.

derChildren ​

Reads the direct children of a constructed parent within source.

ts
function derChildren(
	source: Uint8Array,
	parent: DerElement,
): DecodeDerResult<DerElement[]>

Parameters

derChildrenOrThrow ​

Reads the direct children of a constructed parent within source.

ts
function derChildrenOrThrow(
	source: Uint8Array,
	parent: DerElement,
): DerElement[]

Parameters

Throws

  • if a child overflows parent, or data is left between the last child and its end.

readDerElement ​

Reads one TLV element from bytes starting at offset.

ts
function readDerElement(
	bytes: Uint8Array,
	offset: number,
): DecodeDerResult<DerElement>

Parameters

  • bytes: Uint8Array
  • offset: number — Byte position of the tag octet. Defaults to 0.

readDerElementOrThrow ​

Reads one TLV element from bytes starting at offset.

ts
function readDerElementOrThrow(
	bytes: Uint8Array,
	offset: number,
): DerElement

Parameters

  • bytes: Uint8Array
  • offset: number — Byte position of the tag octet. Defaults to 0.

Throws

  • if the element is truncated, indefinite-length, or non-minimally encoded.

readDerRoot ​

Reads the single top-level TLV element from bytes.

ts
function readDerRoot(
	bytes: Uint8Array,
	options?: ReadRootElementOptions,
): DecodeDerResult<DerElement>

Parameters

readDerRootOrThrow ​

Reads the single top-level TLV element from bytes.

ts
function readDerRootOrThrow(
	bytes: Uint8Array,
	options?: ReadRootElementOptions,
): DerElement

Parameters

Throws

  • if bytes carries trailing data, or nesting exceeds the depth guard.

readDerSequence ​

Reads a DER-encoded SEQUENCE from bytes and returns its direct children.

ts
function readDerSequence(
	bytes: Uint8Array,
	options?: ReadSequenceChildrenOptions,
): DecodeDerResult<DerElement[]>

Parameters

readDerSequenceOrThrow ​

Reads a DER-encoded SEQUENCE from bytes and returns its direct children.

ts
function readDerSequenceOrThrow(
	bytes: Uint8Array,
	options?: ReadSequenceChildrenOptions,
): DerElement[]

Parameters

Throws

  • if the root element is not a SEQUENCE, or if child boundaries are inconsistent.

DerBitString ​

A BIT STRING payload and the number of unused trailing bits in its final byte.

ts
interface DerBitString {
	readonly bytes: Uint8Array;
	readonly unusedBits: number;
	readonly nonZeroPadding: boolean;
}

Properties

  • readonly bytes: Uint8Array — Payload bytes, excluding the leading unused-bit count octet.
  • readonly unusedBits: number — Unused trailing bits in the final byte, 0 through 7.
  • readonly nonZeroPadding: boolean — true when the original encoding had non-zero padding bits (DER violation).

hexToBytes ​

Converts a hex string (even or odd length) to a Uint8Array. Odd-length strings are left-padded with a zero nibble.

ts
function hexToBytes(
	value: string,
): Uint8Array

Parameters

  • value: string

toHex ​

Converts raw bytes to a lowercase hex string with no separator.

ts
function toHex(
	bytes: Uint8Array,
): string

Parameters

  • bytes: Uint8Array

DerElement ​

A single parsed ASN.1 TLV element with byte-range metadata.

ts
interface DerElement {
	readonly tag: number;
	readonly tagNumber: number;
	readonly headerLength: number;
	readonly length: number;
	readonly start: number;
	readonly end: number;
	readonly value: Uint8Array;
}

Properties

  • readonly tag: number — Leading identifier octet (e.g. 0x30 for SEQUENCE, 0x02 for INTEGER, 0x9f for any context-specific primitive tag from 31 up).
  • readonly tagNumber: number — Tag number within the class, from the leading octet below 31 and from the subsequent identifier octets from 31 up.
  • readonly headerLength: number — Number of bytes occupied by the identifier and length octets.
  • readonly length: number — Byte length of the value portion (excluding tag and length octets).
  • readonly start: number — Byte offset where the value portion begins in the source buffer.
  • readonly end: number — Byte offset one past the last value byte. Equals the next element's header offset.
  • readonly value: Uint8Array — The raw value bytes (slice of the source buffer).

ReadRootElementOptions ​

Options for readRootElement.

ts
interface ReadRootElementOptions {
	readonly maxDepth?: number;
	readonly allowOpaqueConstructedTags?: readonly number[];
}

Properties

  • readonly maxDepth?: number — Maximum nesting depth for the DER depth check. @default DEFAULT_MAX_DER_DEPTH.
  • readonly allowOpaqueConstructedTags?: readonly number``[] — Constructed tags whose inner bytes may not parse as valid TLV children (e.g. opaque extension values).

ReadSequenceChildrenOptions ​

Options for readSequenceChildren.

ts
interface ReadSequenceChildrenOptions {
	readonly maxDepth?: number;
	readonly allowOpaqueConstructedTags?: readonly number[];
}

Properties

  • readonly maxDepth?: number — Maximum nesting depth for the DER depth check. @default DEFAULT_MAX_DER_DEPTH.
  • readonly allowOpaqueConstructedTags?: readonly number``[] — Constructed tags whose inner bytes may not parse as valid TLV children (e.g. opaque extension values).

assertDerMaxDepth ​

Walks the full DER tree rooted in bytes.

Constructed tags with content that cannot be parsed as valid children are tolerated when listed in allowOpaqueConstructedTags.

ts
function assertDerMaxDepth(
	bytes: Uint8Array,
	maxDepth: number,
	options?: {
  readonly allowOpaqueConstructedTags?: readonly number[]
},
): void

Parameters

  • bytes: Uint8Array
  • maxDepth: number
  • options?: { readonly allowOpaqueConstructedTags?: readonly number``[] }

Throws

derBitString ​

Encodes a DER BIT STRING (tag 0x03).

The value is prefixed with a single octet indicating how many trailing bits in the last byte are unused.

ts
function derBitString(
	value: Uint8Array,
	unusedBits: number,
): Uint8Array

Parameters

  • value: Uint8Array
  • unusedBits: number — Number of unused trailing bits (0–7). Defaults to 0.

derBmpString ​

Encodes a DER BMPString (tag 0x1e) as big-endian UTF-16.

ts
function derBmpString(
	value: string,
): Uint8Array

Parameters

  • value: string

Throws

  • on lone surrogates, on U+FFFE and U+FFFF, which X.680 §41.15 leaves out of BMPString, and on code points above the Basic Multilingual Plane.

derBoolean ​

Encodes a DER BOOLEAN (tag 0x01): true → 0xff, false → 0x00.

ts
function derBoolean(
	value: boolean,
): Uint8Array

Parameters

  • value: boolean

concatBytes ​

Concatenates multiple byte arrays into a single Uint8Array.

ts
function concatBytes(
	parts: readonly Uint8Array[],
): Uint8Array

Parameters

  • parts: readonly Uint8Array``[]

DEFAULT_MAX_DER_DEPTH ​

Maximum nesting depth allowed when recursively walking a DER structure.

Guards against stack exhaustion from pathologically nested input.

ts
const DEFAULT_MAX_DER_DEPTH: 64

derExplicitContext ​

Wraps a value in an explicit context-specific constructed tag (0xa0 + tag).

Used for optional SEQUENCE fields tagged with [tag] EXPLICIT.

ts
function derExplicitContext(
	tag: number,
	value: Uint8Array,
): Uint8Array

Parameters

  • tag: number
  • value: Uint8Array

derGeneralizedTime ​

Encodes a Date as a DER GeneralizedTime (tag 0x18), format YYYYMMDDHHMMSSZ.

Uses a four-digit year; required for dates outside the 1950–2049 range.

ts
function derGeneralizedTime(
	date: Date,
): Uint8Array

Parameters

  • date: Date

derIa5String ​

Encodes a DER IA5String (tag 0x16).

ts
function derIa5String(
	value: string,
): Uint8Array

Parameters

  • value: string

Throws

  • if the input contains any non-ASCII character (code point > 0x7f).

derImplicitConstructedContext ​

Wraps a value in an implicit context-specific constructed tag (0xa0 + tag).

Used for [tag] IMPLICIT fields whose underlying type is constructed (e.g. SEQUENCE).

ts
function derImplicitConstructedContext(
	tag: number,
	value: Uint8Array,
): Uint8Array

Parameters

  • tag: number
  • value: Uint8Array

derImplicitPrimitiveContext ​

Wraps a value in an implicit context-specific primitive tag (0x80 + tag).

Used for [tag] IMPLICIT fields whose underlying type is primitive (e.g. OCTET STRING).

ts
function derImplicitPrimitiveContext(
	tag: number,
	value: Uint8Array,
): Uint8Array

Parameters

  • tag: number
  • value: Uint8Array

derInteger ​

Encodes raw big-endian bytes as a DER INTEGER (tag 0x02).

Strips leading zero bytes for minimal encoding and prepends a zero byte when the high bit is set to keep the value non-negative.

ts
function derInteger(
	bytes: Uint8Array,
): Uint8Array

Parameters

  • bytes: Uint8Array

derIntegerFromNumber ​

Encodes a non-negative JavaScript number as a DER INTEGER.

ts
function derIntegerFromNumber(
	value: number,
): Uint8Array

Parameters

  • value: number

Throws

  • if the value is not a non-negative safe integer.

derNull ​

Produces a DER NULL element (tag 0x05, zero-length value).

ts
function derNull(): Uint8Array

derOid ​

Encodes a dotted-decimal OID string as a DER OBJECT IDENTIFIER (tag 0x06).

Validates arc constraints per X.660 §7.6: the root arc must be 0–2, and under roots 0 and 1 the second arc must be 0–39. X.690 §8.19.4 defines the (X*40)+Y packing of the first two arcs into one subidentifier.
Sub-identifiers are encoded with base-128 continuation.

ts
function derOid(
	oid: string,
): Uint8Array

Parameters

  • oid: string

derOctetString ​

Wraps raw bytes in an OCTET STRING element (tag 0x04).

ts
function derOctetString(
	value: Uint8Array,
): Uint8Array

Parameters

  • value: Uint8Array

derPrintableString ​

Encodes a DER PrintableString (tag 0x13).

ts
function derPrintableString(
	value: string,
): Uint8Array

Parameters

  • value: string

Throws

  • if the input contains characters outside the ITU-T X.680 §41.4 Table 10 PrintableString set.

derSequence ​

Wraps concatenated children in a SEQUENCE (tag 0x30).

ts
function derSequence(
	parts: readonly Uint8Array[],
): Uint8Array

Parameters

  • parts: readonly Uint8Array``[]

derSet ​

Wraps children in a SET (tag 0x31) after DER-sorting them lexicographically by encoded bytes, as required by X.690 DER.

ts
function derSet(
	parts: readonly Uint8Array[],
): Uint8Array

Parameters

  • parts: readonly Uint8Array``[]

derTime ​

Encodes a Date as the appropriate DER time type per RFC 5280.

  • utcTime for 1950–2049
  • generalizedTime otherwise
ts
function derTime(
	date: Date,
): Uint8Array

Parameters

  • date: Date

derTlv ​

Builds a complete DER TLV (tag-length-value) element:

  • one tag octet,
  • the DER-encoded length, then
  • the raw value bytes.
ts
function derTlv(
	tag: number,
	value: Uint8Array,
): Uint8Array

Parameters

  • tag: number
  • value: Uint8Array

derUniversalString ​

Encodes a DER UniversalString (tag 0x1c) as big-endian UTF-32.

ts
function derUniversalString(
	value: string,
): Uint8Array

Parameters

  • value: string

Throws

  • on lone surrogates.

derUtcTime ​

Encodes a Date as a DER UTCTime (tag 0x17), format YYMMDDHHMMSSZ.

Only the two-digit year is stored; suitable for dates in 1950–2049.

ts
function derUtcTime(
	date: Date,
): Uint8Array

Parameters

  • date: Date

derUtf8String ​

Encodes a DER UTF8String (tag 0x0c).

ts
function derUtf8String(
	value: string,
): Uint8Array

Parameters

  • value: string

Throws

  • on a lone surrogate, which has no UTF-8 encoding.

Released under the MIT License.