ASN.1 / DER

A strict DER (Distinguished Encoding Rules) codec — the byte layer every X.509 / PKCS / CMS structure is built on. The decoder is fail-closed: it rejects the BER shapes DER forbids (indefinite length, non-minimal length or integer encodings, trailing garbage, constructed strings) and refuses input past a size or nesting cap before it walks a single byte, so a hostile length prefix can't turn into a decoder denial-of-service.

decode(bytes) returns a navigable node tree; the read.* helpers turn a node into a JS value (BigInt, dotted OID, Date, string); the build.* helpers construct canonical DER from JS values. Because DER is canonical, each value the build.* helpers emit has exactly one valid encoding — byte-identical to any other conformant DER encoder's output — and decoding it reproduces the value it was built from.

pki.asn1.decode

since 0.1.0 stable
pki.asn1.decode(bytes, opts?) -> node

Parse DER into a node tree. Each node is { tagClass, constructed, tagNumber, header, length, content, children, bytes }content is the primitive value slice, children the decoded sub-nodes of a constructed node, and bytes the full TLV slice (all zero-copy views over the input).

Throws Asn1Error on any non-DER shape: indefinite length, a non-minimal length or a length that overruns the buffer, trailing bytes after the top-level value (unless allowTrailing), or exceeding the size / depth caps.

Options

maxBytes:       number,   // default: C.LIMITS.DER_MAX_BYTES (16 MiB)
maxDepth:       number,   // default: C.LIMITS.DER_MAX_DEPTH (64)
allowTrailing:  boolean,  // default: false — allow bytes after the top TLV

Example

var node = pki.asn1.decode(der);
node.tagNumber === pki.asn1.TAGS.SEQUENCE;

References

  • spec X.690
  • spec ISO/IEC 8825-1
  • defends ASN.1-parser-DoS (CWE-400)

pki.asn1.readOid

since 0.1.0 stable
pki.asn1.read.oid(node) -> "1.2.840.113549.1.1.11"

Decode an OBJECT IDENTIFIER node to its dotted-decimal string, enforcing the minimal base-128 sub-identifier encoding DER requires.

Example

pki.asn1.read.oid(node); // -> "2.5.4.3"

References

pki.asn1.encode

since 0.1.0 stable
pki.asn1.encode(classBits, constructed, tagNumber, content) -> Buffer

Low-level TLV encoder — prepend the identifier + DER length to a content buffer. Most callers use the higher-level build.* helpers; this is the escape hatch for context-tagged and implicitly-tagged constructions.

Example

pki.asn1.encode(0x00, false, pki.asn1.TAGS.NULL, Buffer.alloc(0));

References

  • spec X.690
  • spec ISO/IEC 8825-1

pki.asn1.build

since 0.1.0 stable
pki.asn1.build.sequence([ ...tlvBuffers ]) -> Buffer

Canonical-DER value builders. Each returns the full TLV Buffer for one value; sequence / set / setOf take arrays of already-built child TLVs. setOf sorts its members by their DER encoding as X.690 requires.

Example

var rdn = pki.asn1.build.sequence([
  pki.asn1.build.oid("2.5.4.3"),
  pki.asn1.build.utf8("example.com"),
]);

References

  • spec X.690
  • spec ISO/IEC 8825-1