Schema engine

L2 of the ASN.1 stack — a declarative structure-schema engine. A schema is plain data ({kind, ...} descriptors built by the combinators here) and walk(schema, node, ctx) interprets it against a decoded DER node. The engine is where every cross-cutting structural rule lives ONCE: the shape assertion (SEQUENCE / SET / bare-constructed), bounds-checked positional reads, optional and context-tagged fields in strictly-increasing tag order, SET-OF uniqueness, and fail-closed typed errors. A format module declares a schema and calls walk under an error namespace ctx = { E, prefix, oid }; it never hand-rolls children[idx++], so the positional-read and duplicate-field bug classes are structurally retired. This is the shared base the certificate parser (and, later, CRL / CMS) composes.

pki.schema.engine.walk

since 0.1.7 experimental
pki.schema.engine.walk(schema, node, ctx) -> value

Interpret a declarative schema against a decoded DER node, enforcing the schema's structural rules (shape assertion, arity, optional / context-tagged fields in increasing tag order, SET-OF uniqueness) and returning the built value — or the match tree ({ node, fields | items }, with the build output on .result) for a structure with no build fn. ctx = { E, prefix, oid } supplies the typed-error constructor, the error-code family prefix, and the OID registry a build fn resolves names through.

The schema is assembled from the combinators this module exports — structural (seq / field / optional / explicit / trailing / seqOf / setOf / setOfUnique / choice) and value (oidLeaf / integerLeaf / boolean / octetString / bitString / any / decode / time).

Example

var S = pki.schema.engine;
var ALGID = S.seq([S.field("algorithm", S.oidLeaf())],
  { assert: "sequence", arity: { min: 1 }, code: "app/bad-alg" });
S.walk(ALGID, pki.asn1.decode(der), { prefix: "app", E: MyError, oid: pki.oid });

References