CBOR (deterministic)

A strict, fail-closed decoder for RFC 8949 Concise Binary Object Representation, restricted to the Core Deterministic Encoding profile (RFC 8949 sec. 4.2). It is the binary sibling of pki.asn1: an in-house codec that owns its stack, rejects every non-canonical shape before it returns a value, and bounds size and depth before it walks a byte.

Anything a lenient CBOR reader would tolerate -- an indefinite-length item, a non-minimal ("preferred") integer / length / tag argument, a non-shortest or non-canonical-NaN float, out-of-order or duplicate map keys, ill-formed UTF-8, or trailing bytes -- is a permanent CborError here, because deterministic CBOR is a canonical encoding and a producer that violates it produced invalid bytes. There is no lenient mode.

decode returns a navigable node tree with zero-copy bytes / content views (the raw ranges an external verifier hashes); the read.* leaf readers turn a node into a JS value (a BigInt for every integer, a Buffer for a byte string, a Date for an epoch time, a dotted string for a tagged OID). It is the primitive the CBOR-encoded PKI surfaces (C509 certificates, COSE / CWT) will compose.

pki.cbor.decode

since 0.1.27 experimental
pki.cbor.decode(bytes, opts?) -> node

Decode one Deterministically Encoded CBOR item into a navigable node tree. Every non-canonical shape is refused: an indefinite length, a non-minimal argument, unsorted or duplicate map keys, a non-shortest or non-canonical- NaN float, ill-formed UTF-8, a reserved additional-info value, or (unless allowTrailing) leftover bytes after the top-level item. Size, depth, and total item count are bounded, so a high-fanout container fails closed rather than exhausting memory. A node carries majorType, the argument (a lossless BigInt), a zero-copy content / bytes view, and children (array elements, map key/value pairs, or a tag's one inner item).

Options

maxBytes:       number,   // default: C.LIMITS.CBOR_MAX_BYTES (16 MiB)
maxDepth:       number,   // default: C.LIMITS.CBOR_MAX_DEPTH (64)
maxItems:       number,   // default: C.LIMITS.CBOR_MAX_ITEMS (1,000,000 total decoded items)
allowTrailing:  boolean,  // default: false -- true returns the first item and permits bytes after it (CBOR Sequence)
profile:        string,   // default: "deterministic" (the only value v1 accepts)

Example

var node = pki.cbor.decode(Buffer.from("83010203", "hex"));
node.majorType;                       // 4 (array)
pki.cbor.read.uint(node.children[0]); // 1n

References

pki.cbor.read.uint

since 0.1.27 experimental
pki.cbor.read.uint(node) -> 0n

The unsigned integer value of a major-type-0 node, as a BigInt (uniform for every magnitude, so the type never varies with the value). Throws cbor/unexpected-major on any other major type.

Example

pki.cbor.read.uint(node); // -> 0n

References

pki.cbor.read.nint

since 0.1.27 experimental
pki.cbor.read.nint(node) -> -1n

The negative integer value of a major-type-1 node, as a BigInt (value = -1 - argument). Throws cbor/unexpected-major otherwise.

Example

pki.cbor.read.nint(node); // -> -1n

References

pki.cbor.read.int

since 0.1.27 experimental
pki.cbor.read.int(node) -> -1n

The signed integer value of a major-type-0 or -1 node, as a BigInt. Throws cbor/unexpected-major on any other major type.

Example

pki.cbor.read.int(node); // -> -1n

References

pki.cbor.read.byteString

since 0.1.27 experimental
pki.cbor.read.byteString(node) -> Buffer

The zero-copy Buffer content of a major-type-2 byte string. Throws cbor/unexpected-major otherwise.

Example

pki.cbor.read.byteString(node); // -> <Buffer 01 02 03 04>

References

pki.cbor.read.textString

since 0.1.27 experimental
pki.cbor.read.textString(node) -> "text"

The string value of a major-type-3 text string (already validated as well-formed UTF-8 at decode). Throws cbor/unexpected-major otherwise.

Example

pki.cbor.read.textString(node); // -> "a"

References

pki.cbor.read.array

since 0.1.27 experimental
pki.cbor.read.array(node) -> [node, ...]

The element nodes of a major-type-4 array. Throws cbor/unexpected-major otherwise.

Example

pki.cbor.read.array(node); // -> [node, node, node]

References

pki.cbor.read.map

since 0.1.27 experimental
pki.cbor.read.map(node) -> [[keyNode, valueNode], ...]

The ordered key/value node pairs of a major-type-5 map (ordering and uniqueness already enforced at decode). Throws cbor/unexpected-major otherwise.

Example

pki.cbor.read.map(node); // -> [[keyNode, valueNode]]

References

pki.cbor.read.mapGet

since 0.2.20 experimental
pki.cbor.read.mapGet(node, key) -> valueNode | null

The value node of the map entry whose key equals key -- a text string (matched against text-string keys) or an integer (a safe-integer number or a BigInt, matched against integer keys, as COSE labels are) -- or null when the map has no such entry. Key matching never coerces across types: a text key only matches a text-string key node, an integer key only an integer key node. At most one entry can match -- decode already enforced key uniqueness. This is the single keyed-lookup home over a decoded map: a consumer composes it (or read.map) rather than walking children as pairs, so a lookup can never pair-index a non-map's children (single nodes, whose pair index reads undefined). Throws cbor/unexpected-major when node is not a map -- a lookup on a non-map is malformed input, never an absent-entry verdict -- and a TypeError for a key that is neither a text string nor an integer.

Example

pki.cbor.read.mapGet(node, "fmt"); // -> valueNode | null
pki.cbor.read.mapGet(node, 3);     // a COSE alg label -> valueNode | null

References

pki.cbor.read.boolean

since 0.1.27 experimental
pki.cbor.read.boolean(node) -> false

The boolean value of a simple-value node (false=20, true=21). Throws cbor/unexpected-major on a non-simple node, cbor/bad-simple on any other simple value.

Example

pki.cbor.read.boolean(node); // -> true

References

pki.cbor.read.nullValue

since 0.1.27 experimental
pki.cbor.read.nullValue(node) -> null

null for a simple-value-22 node. Throws cbor/unexpected-major on a non-simple node, cbor/bad-simple on any other simple value.

Example

pki.cbor.read.nullValue(node); // -> null

References

pki.cbor.read.undefinedValue

since 0.1.27 experimental
pki.cbor.read.undefinedValue(node) -> undefined

undefined for a simple-value-23 node. Throws cbor/unexpected-major on a non-simple node, cbor/bad-simple on any other simple value.

Example

pki.cbor.read.undefinedValue(node); // -> undefined

References

pki.cbor.read.float

since 0.1.27 experimental
pki.cbor.read.float(node) -> 1.5

The JS number (double) of a half / single / double float node (the shortest-form and canonical-NaN rules already enforced at decode). Throws cbor/unexpected-major on a non-major-7 node, cbor/bad-simple on a simple value that is not a float.

Example

pki.cbor.read.float(node); // -> 1.5

References

pki.cbor.read.biguint

since 0.1.27 experimental
pki.cbor.read.biguint(node) -> 18446744073709551616n

The BigInt value of a tag-2 unsigned bignum (a big-endian magnitude byte string, no sign octet). Enforces the byte cap (cbor/biguint-too-large), the no-leading-zero and prefer-basic-int minimality rules (cbor/non-minimal-biguint), and the wrapped content type (cbor/bad-tag-content); a wrong / absent tag throws cbor/unexpected-tag.

Example

pki.cbor.read.biguint(node); // -> 18446744073709551616n

References

pki.cbor.read.time

since 0.1.27 experimental
pki.cbor.read.time(node) -> Date

The Date of a tag-1 epoch time (seconds since 1970-01-01T00:00Z, integer). Throws cbor/unexpected-tag on a wrong / absent tag, cbor/bad-tag-content when tag 1 does not wrap an integer, cbor/bad-time on an out-of-range value.

Example

pki.cbor.read.time(node); // -> Date 2013-03-21T20:04:00.000Z

References

pki.cbor.read.oid

since 0.1.27 experimental
pki.cbor.read.oid(node) -> "2.5.4.3"

The dotted OID string of a tag-111 CBOR OID (a byte string carrying the BER object-identifier content octets, decoded through the shared asn1.decodeOidContent, so a malformed body surfaces the existing oid/* codes). Throws cbor/unexpected-tag on a wrong / absent tag, cbor/bad-tag-content when tag 111 does not wrap a byte string.

Example

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

References