@blamejs/pki 0.6.13 → 0.6.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +1 -1
  3. package/index.js +1 -1
  4. package/lib/acme.js +59 -815
  5. package/lib/asn1-der.js +7 -245
  6. package/lib/attrcert-sign.js +12 -260
  7. package/lib/attrcert-verify.js +1 -7
  8. package/lib/byte-reader.js +0 -8
  9. package/lib/byte-writer.js +0 -11
  10. package/lib/cbor-det.js +0 -54
  11. package/lib/cmc-build.js +15 -357
  12. package/lib/cmc-verify.js +6 -239
  13. package/lib/cmp-build.js +41 -317
  14. package/lib/cmp-session.js +73 -760
  15. package/lib/cmp-verify.js +32 -488
  16. package/lib/cms-compress.js +3 -32
  17. package/lib/cms-decrypt.js +29 -294
  18. package/lib/cms-encrypt.js +14 -234
  19. package/lib/cms-sign.js +29 -324
  20. package/lib/cms-verify.js +9 -500
  21. package/lib/composite-kem.js +2 -102
  22. package/lib/composite-sig.js +1 -77
  23. package/lib/constants.js +0 -249
  24. package/lib/crl-sign.js +9 -237
  25. package/lib/crl-verify.js +1 -10
  26. package/lib/crmf-sign.js +19 -198
  27. package/lib/crmf-verify.js +1 -12
  28. package/lib/csr-sign.js +3 -34
  29. package/lib/csr-verify.js +1 -12
  30. package/lib/ct.js +28 -253
  31. package/lib/edwards-point.js +10 -44
  32. package/lib/est.js +28 -764
  33. package/lib/framework-error.js +4 -182
  34. package/lib/guard-all.js +1 -58
  35. package/lib/guard-async.js +1 -36
  36. package/lib/guard-bytes.js +6 -650
  37. package/lib/guard-compress.js +5 -102
  38. package/lib/guard-crypto.js +1 -40
  39. package/lib/guard-der.js +2 -93
  40. package/lib/guard-encoding.js +2 -60
  41. package/lib/guard-header.js +1 -36
  42. package/lib/guard-identifier.js +7 -531
  43. package/lib/guard-intrinsic.js +1 -150
  44. package/lib/guard-json.js +10 -73
  45. package/lib/guard-limits.js +1 -77
  46. package/lib/guard-list.js +1 -49
  47. package/lib/guard-name.js +3 -209
  48. package/lib/guard-parsed.js +7 -335
  49. package/lib/guard-range.js +1 -71
  50. package/lib/guard-secret.js +1 -102
  51. package/lib/guard-text.js +1 -64
  52. package/lib/guard-time.js +1 -97
  53. package/lib/hpke.js +3 -105
  54. package/lib/http-digest.js +14 -142
  55. package/lib/http-retry-after.js +1 -47
  56. package/lib/http-transport.js +21 -131
  57. package/lib/inspect.js +30 -284
  58. package/lib/ip-utils.js +6 -47
  59. package/lib/jose.js +7 -142
  60. package/lib/key.js +2 -67
  61. package/lib/lint.js +9 -194
  62. package/lib/merkle.js +1 -27
  63. package/lib/mime.js +9 -82
  64. package/lib/ocsp-request-verify.js +1 -14
  65. package/lib/ocsp-verify.js +1 -82
  66. package/lib/ocsp.js +11 -169
  67. package/lib/oid.js +5 -337
  68. package/lib/path-validate.js +103 -1492
  69. package/lib/pbes2.js +2 -89
  70. package/lib/pkcs12-build.js +31 -379
  71. package/lib/pki-build.js +64 -290
  72. package/lib/rc2.js +2 -18
  73. package/lib/rfc3339.js +4 -27
  74. package/lib/scep.js +59 -233
  75. package/lib/schema-all.js +0 -122
  76. package/lib/schema-attrcert.js +4 -146
  77. package/lib/schema-c509.js +153 -802
  78. package/lib/schema-cmc.js +5 -220
  79. package/lib/schema-cmp.js +2 -223
  80. package/lib/schema-cms.js +13 -427
  81. package/lib/schema-crl.js +5 -68
  82. package/lib/schema-crmf.js +6 -167
  83. package/lib/schema-csr.js +1 -54
  84. package/lib/schema-csrattrs.js +2 -87
  85. package/lib/schema-engine.js +0 -152
  86. package/lib/schema-ocsp.js +0 -117
  87. package/lib/schema-pkcs12.js +2 -93
  88. package/lib/schema-pkcs8.js +3 -35
  89. package/lib/schema-pkix.js +24 -655
  90. package/lib/schema-smime.js +0 -54
  91. package/lib/schema-tsp.js +3 -99
  92. package/lib/schema-x509.js +4 -63
  93. package/lib/shbs.js +11 -95
  94. package/lib/sign-scheme.js +2 -97
  95. package/lib/sigstore.js +9 -169
  96. package/lib/sleep.js +2 -8
  97. package/lib/smime.js +15 -408
  98. package/lib/tls-cert-compress.js +0 -62
  99. package/lib/trust.js +19 -185
  100. package/lib/tsp-sign.js +16 -270
  101. package/lib/validator-all.js +1 -30
  102. package/lib/validator-attcert.js +2 -46
  103. package/lib/validator-cose.js +2 -153
  104. package/lib/validator-keydesc.js +1 -37
  105. package/lib/validator-sig.js +1 -46
  106. package/lib/validator-tls.js +1 -88
  107. package/lib/validator-tpm.js +19 -122
  108. package/lib/verify-seam.js +1 -24
  109. package/lib/webauthn-mds.js +3 -400
  110. package/lib/webauthn.js +12 -833
  111. package/lib/webcrypto.js +5 -485
  112. package/lib/x509-sign.js +4 -108
  113. package/package.json +1 -1
  114. package/sbom.cdx.json +6 -6
package/lib/asn1-der.js CHANGED
@@ -35,30 +35,17 @@ var constants = require("./constants");
35
35
  var frameworkError = require("./framework-error");
36
36
  var guard = require("./guard-all");
37
37
  var intrinsic = require("./guard-intrinsic");
38
- // The list test at each builder door decides whether a caller's argument is refused. Read at the
39
- // moment it runs, a replacement answering true admits a non-list and the door it guards is gone.
40
38
  var _isArray = intrinsic.isArray;
41
39
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
42
40
 
43
41
  var Asn1Error = frameworkError.Asn1Error;
44
42
  var OidError = frameworkError.OidError;
45
43
 
46
- // (code, message) -> Asn1Error, the factory shape the composed guards throw
47
- // through so a malformed codec argument keeps the asn1/* typed verdict.
48
44
  function _asn1Error(c, m) { return new Asn1Error(c, m); }
49
45
 
50
- // (code, message) -> OidError, the factory the OID string guard throws through
51
- // so build.oid keeps its oid/* typed verdict (oid/bad-input, oid/bad-arc).
52
46
  function _oidErr(c, m) { return new OidError(c, m); }
53
47
 
54
- // ---- Tag constants (universal class) --------------------------------
55
48
 
56
- // L1 -- the ASN.1 universal-type descriptor registry: the single source of
57
- // truth for the codec's type metadata. Each entry is DECLARATIVE DATA --
58
- // { tag, form } where form is the DER encoding form ("primitive" or
59
- // "constructed", X.690 sec. 8/sec. 10.2). TAGS and the two structural type-sets below
60
- // are all DERIVED from it, so registering a universal type is one descriptor
61
- // entry and the decoder's form checks (below) cover it automatically.
62
49
  var UNIVERSAL_TYPES = {
63
50
  BOOLEAN: { tag: 0x01, form: "primitive" },
64
51
  INTEGER: { tag: 0x02, form: "primitive" },
@@ -84,8 +71,6 @@ var UNIVERSAL_TYPES = {
84
71
  BMP_STRING: { tag: 0x1e, form: "primitive" },
85
72
  };
86
73
 
87
- // TAGS { name: tag }, derived from the registry; the public constant consumers
88
- // read (pki.asn1.TAGS.INTEGER, ...).
89
74
  var TAGS = {};
90
75
  Object.keys(UNIVERSAL_TYPES).forEach(function (k) { TAGS[k] = UNIVERSAL_TYPES[k].tag; });
91
76
 
@@ -95,15 +80,6 @@ var CLASS_CONTEXT = 0x80;
95
80
  var CLASS_PRIVATE = 0xc0;
96
81
  var CONSTRUCTED_BIT = 0x20;
97
82
 
98
- // X.690 sec. 8.9.1 / sec. 8.11.1 / sec. 10.2 (DER), the mirror rules: an
99
- // always-constructed universal type (SEQUENCE, SET, and the SEQUENCE-based
100
- // EXTERNAL / EMBEDDED PDV / unrestricted CHARACTER STRING) MUST be encoded
101
- // constructed, and every other universal type MUST be encoded primitive. The
102
- // constructed-capable set is derived from the registry above and keyed by tag
103
- // for an O(1) decode-time form check. It is a whitelist: a universal tag
104
- // outside it, a registered primitive type and an unregistered one
105
- // (GeneralString, ObjectDescriptor, REAL, ...) alike, has no
106
- // DER constructed form, so the default is reject.
107
83
  var CONSTRUCTED_ONLY_UNIVERSAL_TAGS = Object.create(null);
108
84
  Object.keys(UNIVERSAL_TYPES).forEach(function (k) {
109
85
  var d = UNIVERSAL_TYPES[k];
@@ -116,7 +92,6 @@ function _className(bits) {
116
92
  case CLASS_APPLICATION: return "application";
117
93
  case CLASS_CONTEXT: return "context";
118
94
  case CLASS_PRIVATE: return "private";
119
- // Coverage residual -- tagClassBits is (first & 0xc0), always one of the 4 enumerated class values; the default arm is unreachable defensive code.
120
95
  default: return "universal";
121
96
  }
122
97
  }
@@ -125,7 +100,6 @@ function _asBuffer(input, who) {
125
100
  return guard.bytes.view(input, Asn1Error, "asn1/not-buffer", who);
126
101
  }
127
102
 
128
- // ---- Decoder --------------------------------------------------------
129
103
 
130
104
  /**
131
105
  * @primitive pki.asn1.decode
@@ -169,15 +143,8 @@ function _asBuffer(input, who) {
169
143
  function decode(input, opts) {
170
144
  opts = opts || {};
171
145
  var buf = _asBuffer(input, "decode");
172
- // A size/depth cap opt: absent means the constants.LIMITS default; a provided
173
- // value must be a non-negative integer (guard.limits.cap). depthCap also
174
- // refuses a maxDepth above the stack-safe ceiling so a raised cap cannot drive
175
- // recursive descent into a bare RangeError instead of the typed asn1/too-deep.
176
146
  var maxBytes = guard.limits.cap(opts.maxBytes, "maxBytes", constants.LIMITS.DER_MAX_BYTES);
177
147
  var maxDepth = guard.limits.depthCap(opts.maxDepth, "maxDepth", constants.LIMITS.DER_MAX_DEPTH);
178
- // Total decoded-node ceiling: the eager node tree lets a dense run of tiny TLVs
179
- // amplify a small input into a huge tree, so a per-node counter fails closed at
180
- // the cap (the memory-fanout class the CBOR codec closed with CBOR_MAX_ITEMS).
181
148
  var maxItems = guard.limits.cap(opts.maxItems, "maxItems", constants.LIMITS.DER_MAX_ITEMS);
182
149
  if (buf.length > maxBytes) {
183
150
  throw new Asn1Error("asn1/too-large", "input " + buf.length + " bytes exceeds cap " + maxBytes);
@@ -194,7 +161,7 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
194
161
  if (depth > maxDepth) {
195
162
  throw new Asn1Error("asn1/too-deep", "nesting exceeds depth cap " + maxDepth);
196
163
  }
197
- if (ctr) ctr.tick(); // one decoded node -> one tick (memory-fanout cap)
164
+ if (ctr) ctr.tick();
198
165
  var p = start;
199
166
  if (p >= limit) throw new Asn1Error("asn1/truncated", "expected an identifier octet");
200
167
  var first = buf[p]; p += 1;
@@ -203,7 +170,6 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
203
170
  var tagNumber = first & 0x1f;
204
171
 
205
172
  if (tagNumber === 0x1f) {
206
- // High-tag-number form: base-128, minimal (no leading 0x80).
207
173
  tagNumber = 0;
208
174
  var seen = 0;
209
175
  for (;;) {
@@ -222,29 +188,10 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
222
188
  }
223
189
  }
224
190
 
225
- // X.690 8.9.1 / 8.11.1 -- an always-constructed universal type (SEQUENCE, SET,
226
- // EXTERNAL, EMBEDDED PDV, CHARACTER STRING) is always constructed; a
227
- // primitive-tagged one is not valid DER (and would decode to a leaf that
228
- // constructed-structure consumers dereference as a parent). Driven by the
229
- // registry-derived set, not a hardcoded tag list.
230
191
  if (tagClassBits === CLASS_UNIVERSAL && CONSTRUCTED_ONLY_UNIVERSAL_TAGS[tagNumber] && !constructed) {
231
192
  throw new Asn1Error("asn1/bad-tlv", "a universal constructed-only type (SEQUENCE/SET/EXTERNAL/EMBEDDED PDV/CHARACTER STRING) must be constructed");
232
193
  }
233
194
 
234
- // X.690 sec. 8.x / sec. 10.2 -- the mirror rule: a universal type other than
235
- // SEQUENCE/SET (INTEGER, OID, BOOLEAN, every restricted string type --
236
- // registered or not -- times, BIT/OCTET STRING, REAL, ...) encoded
237
- // constructed is not valid DER. Without this a constructed string tag
238
- // decodes to a childless node that later paths (an X.509 DN attribute
239
- // value) would hex-render or dereference instead of failing closed; the
240
- // constructed-capable set is a whitelist so an UNREGISTERED string type
241
- // (a constructed GeneralString) cannot slip past the form check either.
242
- // The ber mode licenses exactly one constructed primitive-only type -- the
243
- // OCTET STRING (the streamed content carrier RFC 7292 sec. 4.1 permits); its
244
- // segments are reassembled below. Every other primitive-only type stays
245
- // primitive even in BER. Reassembly re-copies each nesting level's payload,
246
- // so nesting is capped on the way down: real producers segment one level
247
- // deep, and a deep chain multiplies transient memory without carrying data.
248
195
  if (tagClassBits === CLASS_UNIVERSAL && constructed && !CONSTRUCTED_ONLY_UNIVERSAL_TAGS[tagNumber]) {
249
196
  if (!(ber && tagNumber === TAGS.OCTET_STRING)) {
250
197
  throw new Asn1Error("asn1/constructed-primitive-type", "a universal primitive-only type must be encoded primitive in DER");
@@ -261,8 +208,6 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
261
208
  if (lenByte < 0x80) {
262
209
  length = lenByte;
263
210
  } else if (lenByte === 0x80) {
264
- // X.690 sec. 8.1.3.6 -- indefinite length is only defined for a constructed
265
- // encoding; the value runs to the end-of-contents octets.
266
211
  if (!ber || !constructed) {
267
212
  throw new Asn1Error("asn1/indefinite-length", "indefinite length is not valid DER");
268
213
  }
@@ -326,12 +271,6 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
326
271
  bytes: buf.subarray(start, end),
327
272
  };
328
273
 
329
- // BER reassembly: a constructed OCTET STRING's segments concatenate into
330
- // one primitive content, so every downstream reader sees the value a
331
- // single-segment encoding would carry; `bytes` keeps the original wire
332
- // range for raw round-trip surfaces. Nested constructed segments arrive
333
- // already reassembled by the recursion (their nesting depth is capped on
334
- // the way down -- see the strDepth check above).
335
274
  if (ber && constructed && tagClassBits === CLASS_UNIVERSAL && tagNumber === TAGS.OCTET_STRING) {
336
275
  var segments = [];
337
276
  for (var s = 0; s < children.length; s++) {
@@ -344,17 +283,12 @@ function _decodeTLV(buf, start, limit, depth, maxDepth, ber, strDepth, ctr) {
344
283
  node.constructed = false;
345
284
  node.children = null;
346
285
  }
347
- // A context-tagged constructed node from a ber decode may be an IMPLICIT
348
- // streamed string (the tag hides the underlying type), which only the
349
- // schema-driven typed reader can identify -- mark it so readers reassemble
350
- // exactly those nodes and a strict decode's verdicts never change.
351
286
  if (ber && constructed && tagClassBits === CLASS_CONTEXT && node.children) {
352
287
  node.ber = true;
353
288
  }
354
289
  return { node: node, end: end };
355
290
  }
356
291
 
357
- // ---- Node assertions ------------------------------------------------
358
292
 
359
293
  function _expectUniversal(node, tag, who) {
360
294
  if (node.tagClass !== "universal" || node.tagNumber !== tag) {
@@ -367,7 +301,6 @@ function _expectPrimitive(node, who) {
367
301
  if (node.constructed) throw new Asn1Error("asn1/expected-primitive", who + ": expected a primitive encoding");
368
302
  }
369
303
 
370
- // ---- Typed readers --------------------------------------------------
371
304
 
372
305
  function readBoolean(node) {
373
306
  _expectUniversal(node, TAGS.BOOLEAN, "readBoolean");
@@ -379,21 +312,10 @@ function readBoolean(node) {
379
312
  throw new Asn1Error("asn1/bad-boolean", "DER BOOLEAN must be 0x00 or 0xFF, got 0x" + v.toString(16));
380
313
  }
381
314
 
382
- // INTEGER and ENUMERATED share DER content encoding (a two's-complement big-endian
383
- // value) but are DISTINCT universal types. This decodes that shared content -- the
384
- // caller asserts the tag first. `typeName` names the type in error messages; the
385
- // stable error codes stay the integer family (a caller switching on `code` treats
386
- // both alike since the encoding is identical).
387
315
  function _readIntegerLikeContent(node, typeName, who) {
388
316
  _expectPrimitive(node, who);
389
317
  var c = node.content;
390
318
  if (c.length === 0) throw new Asn1Error("asn1/bad-integer", typeName + " must have at least 1 content octet");
391
- // Defense-in-depth: refuse an over-cap magnitude before touching BigInt.
392
- // A one-shot hex parse is linear, but the length still bounds worst-case
393
- // work -- reject a hostile length prefix up front. The cap bounds the
394
- // MAGNITUDE; a positive INTEGER whose top bit is set carries one leading
395
- // 0x00 DER sign octet, so allow cap + 1 content bytes (an RSA-131072
396
- // modulus is 16384 magnitude bytes plus that sign pad).
397
319
  if (c.length > constants.LIMITS.DER_MAX_INTEGER_BYTES + 1) {
398
320
  throw new Asn1Error("asn1/integer-too-large",
399
321
  typeName + " content " + c.length + " bytes exceeds cap " + (constants.LIMITS.DER_MAX_INTEGER_BYTES + 1));
@@ -403,32 +325,20 @@ function _readIntegerLikeContent(node, typeName, who) {
403
325
  if (c[0] === 0xff && (c[1] & 0x80) !== 0) throw new Asn1Error("asn1/non-minimal-integer", "non-minimal negative " + typeName);
404
326
  }
405
327
  var neg = (c[0] & 0x80) !== 0;
406
- // Coverage residual -- the c.length===0 guard above throws, so c.length is always >=1 here; the 0n alternate is unreachable.
407
328
  var mag = c.length ? BigInt("0x" + Buffer.from(c).toString("hex")) : 0n;
408
329
  return neg ? mag - (1n << BigInt(c.length * 8)) : mag;
409
330
  }
410
331
 
411
- // read.integer is STRICT on the tag: an ENUMERATED node (which shares INTEGER's
412
- // content encoding) is NOT accepted here. Coercing an ENUMERATED to an INTEGER is a
413
- // type confusion -- an INTEGER-pinned field (a certificate/CSR version, a serial
414
- // number, a cRLNumber) encoded as ENUMERATED would slip past a lenient reader.
415
- // Read ENUMERATED values with read.enumerated.
416
332
  function readInteger(node) {
417
333
  _expectUniversal(node, TAGS.INTEGER, "readInteger");
418
334
  return _readIntegerLikeContent(node, "INTEGER", "readInteger");
419
335
  }
420
336
 
421
- // read.enumerated reads an ENUMERATED value; its content rules are identical to
422
- // INTEGER (non-empty, minimally encoded, magnitude within the cap).
423
337
  function readEnumerated(node) {
424
338
  _expectUniversal(node, TAGS.ENUMERATED, "readEnumerated");
425
339
  return _readIntegerLikeContent(node, "ENUMERATED", "readEnumerated");
426
340
  }
427
341
 
428
- // Read a [tag] IMPLICIT INTEGER -- a context-class PRIMITIVE node whose content is an
429
- // integer body (the IMPLICIT tag replaces the universal INTEGER tag). Same minimal
430
- // two's-complement content rules as a universal INTEGER. The integer counterpart of
431
- // readBitStringImplicit, for the RFC 3161 Accuracy millis [0] / micros [1] fields.
432
342
  function readIntegerImplicit(node, tag) {
433
343
  if (node.tagClass !== "context" || node.tagNumber !== tag) {
434
344
  throw new Asn1Error("asn1/unexpected-tag", "readIntegerImplicit: expected context tag [" + tag +
@@ -437,9 +347,6 @@ function readIntegerImplicit(node, tag) {
437
347
  return _readIntegerLikeContent(node, "INTEGER", "readIntegerImplicit");
438
348
  }
439
349
 
440
- // The BIT STRING content decoder (the leading unused-bit octet + body, with the
441
- // DER zero-pad rule). Shared by the universal reader and the IMPLICIT
442
- // context-tagged reader -- the caller asserts the tag first.
443
350
  function _readBitStringContent(node, who) {
444
351
  _expectPrimitive(node, who);
445
352
  var c = node.content;
@@ -447,8 +354,6 @@ function _readBitStringContent(node, who) {
447
354
  var unusedBits = c[0];
448
355
  if (unusedBits > 7) throw new Asn1Error("asn1/bad-bit-string", "unused-bit count " + unusedBits + " > 7");
449
356
  if (unusedBits > 0 && c.length === 1) throw new Asn1Error("asn1/bad-bit-string", "unused bits declared over an empty body");
450
- // X.690 11.2.1 -- the declared unused low bits of the final octet must be
451
- // zero in DER.
452
357
  if (unusedBits > 0 && c.length > 1) {
453
358
  var mask = (1 << unusedBits) - 1;
454
359
  if ((c[c.length - 1] & mask) !== 0) throw new Asn1Error("asn1/bad-bit-string", "DER requires unused bits to be zero");
@@ -461,10 +366,6 @@ function readBitString(node) {
461
366
  return _readBitStringContent(node, "readBitString");
462
367
  }
463
368
 
464
- // Read a [tag] IMPLICIT BIT STRING -- a context-class PRIMITIVE node whose content
465
- // is a bit-string body (identical content rules to a universal BIT STRING). The
466
- // IMPLICIT tag replaces the universal one, so there is no inner universal node.
467
- // Used for the PKCS#8 OneAsymmetricKey publicKey [1] (RFC 5958 sec. 2).
468
369
  function readBitStringImplicit(node, tag) {
469
370
  if (node.tagClass !== "context" || node.tagNumber !== tag) {
470
371
  throw new Asn1Error("asn1/unexpected-tag", "readBitStringImplicit: expected context tag [" + tag +
@@ -479,16 +380,6 @@ function readOctetString(node) {
479
380
  return node.content;
480
381
  }
481
382
 
482
- // Read a [tag] IMPLICIT OCTET STRING -- a context-class PRIMITIVE node whose
483
- // content is the octet-string body (the IMPLICIT tag replaces the universal one,
484
- // so there is no inner universal node). Primitive-only, like its universal
485
- // counterpart, so a strict decode's constructed/streamed form is rejected.
486
- // A node from a ber decode (the `ber` marker) may carry the streamed form --
487
- // the context tag hides the underlying type from the decoder, so THIS reader
488
- // is where a [tag] IMPLICIT OCTET STRING's segments reassemble (the shape CMS
489
- // ciphertext streams as). Used for the CMS SignerIdentifier
490
- // subjectKeyIdentifier [0] (RFC 5652 sec. 5.3) and EncryptedContentInfo
491
- // encryptedContent [0] (sec. 6.1).
492
383
  function readOctetStringImplicit(node, tag) {
493
384
  if (node.tagClass !== "context" || node.tagNumber !== tag) {
494
385
  throw new Asn1Error("asn1/unexpected-tag", "readOctetStringImplicit: expected context tag [" + tag +
@@ -516,10 +407,6 @@ function readNull(node) {
516
407
  return null;
517
408
  }
518
409
 
519
- // Read a [tag] IMPLICIT BOOLEAN -- a context-class PRIMITIVE node whose single
520
- // content octet obeys the DER BOOLEAN rules (0x00 FALSE / 0xFF TRUE; anything
521
- // else rejected). The IMPLICIT tag replaces the universal BOOLEAN tag. Used for
522
- // the RFC 5280 sec. 5.2.5 IssuingDistributionPoint scope flags.
523
410
  function readBooleanImplicit(node, tag) {
524
411
  if (node.tagClass !== "context" || node.tagNumber !== tag) {
525
412
  throw new Asn1Error("asn1/unexpected-tag", "readBooleanImplicit: expected context tag [" + tag +
@@ -533,10 +420,6 @@ function readBooleanImplicit(node, tag) {
533
420
  throw new Asn1Error("asn1/bad-boolean", "DER BOOLEAN must be 0x00 or 0xFF, got 0x" + v.toString(16));
534
421
  }
535
422
 
536
- // Read a [tag] IMPLICIT NULL -- a context-class PRIMITIVE node with empty content.
537
- // The IMPLICIT tag replaces the universal NULL tag, so there is no inner universal
538
- // node. The empty-content and primitive-form rules of a universal NULL still hold.
539
- // Used for the OCSP CertStatus good [0] / unknown [2] arms (RFC 6960 sec. 4.2.1).
540
423
  function readNullImplicit(node, tag) {
541
424
  if (node.tagClass !== "context" || node.tagNumber !== tag) {
542
425
  throw new Asn1Error("asn1/unexpected-tag", "readNullImplicit: expected context tag [" + tag +
@@ -576,16 +459,11 @@ function decodeOidContent(buf) {
576
459
  for (var i = 0; i < buf.length; i++) {
577
460
  var b = buf[i];
578
461
  if (i === arcStart && b === 0x80) throw new OidError("oid/non-minimal", "non-minimal sub-identifier (leading 0x80)");
579
- // Cap the continuation-byte run so a single arc can't drive unbounded
580
- // BigInt growth before it terminates.
581
462
  if (i - arcStart >= constants.LIMITS.OID_MAX_SUBIDENTIFIER_BYTES) {
582
463
  throw new OidError("oid/subidentifier-too-large",
583
464
  "OID sub-identifier exceeds " + constants.LIMITS.OID_MAX_SUBIDENTIFIER_BYTES + " octets");
584
465
  }
585
466
  if ((b & 0x80) === 0) {
586
- // Terminal octet: fold the whole [arcStart..i] slice base-128 in one
587
- // bounded pass (the run is capped above), no per-bit accumulation
588
- // across the full OID content.
589
467
  var value = 0n;
590
468
  for (var k = arcStart; k <= i; k++) value = value * 128n + BigInt(buf[k] & 0x7f);
591
469
  arcs.push(value);
@@ -607,7 +485,6 @@ function _decodeText(buf, encoding) {
607
485
  return buf.toString(encoding);
608
486
  }
609
487
 
610
- // IA5String is 7-bit ASCII (T.50 / IA5) -- every content octet is 0x00..0x7F.
611
488
  function _decodeIa5(buf) {
612
489
  for (var i = 0; i < buf.length; i++) {
613
490
  if (buf[i] > 0x7F) throw new Asn1Error("asn1/bad-ia5-string", "IA5String requires 7-bit ASCII");
@@ -615,8 +492,6 @@ function _decodeIa5(buf) {
615
492
  return buf.toString("latin1");
616
493
  }
617
494
 
618
- // VisibleString (ISO 646 IRV / X.690) is the printable ASCII range 0x20..0x7E
619
- // -- no control characters and no bytes with the high bit set.
620
495
  function _decodeVisible(buf) {
621
496
  for (var i = 0; i < buf.length; i++) {
622
497
  if (buf[i] < 0x20 || buf[i] > 0x7E) throw new Asn1Error("asn1/bad-visible-string", "VisibleString must be 0x20..0x7E");
@@ -624,23 +499,12 @@ function _decodeVisible(buf) {
624
499
  return buf.toString("latin1");
625
500
  }
626
501
 
627
- // PrintableString is restricted to A-Z a-z 0-9 space and ' ( ) + , - . / : = ?
628
502
  function _decodePrintable(buf) {
629
503
  var s = buf.toString("latin1");
630
504
  if (!isPrintableString(s)) throw new Asn1Error("asn1/bad-printable-string", "PrintableString has characters outside the restricted set");
631
505
  return s;
632
506
  }
633
507
 
634
- // NumericString (X.680 sec. 41, Table 9) permits ONLY the digits and SPACE. It carries the X.520 syntax of the
635
- // x121Address and internationalISDNNumber directory attributes.
636
- //
637
- // It is read through its OWN reader, deliberately NOT through readString. Every type readString returns a
638
- // plain string for enters the RFC 5280 sec. 7.1 name-comparison identity class, and
639
- // guard.name.dnEqual -- the single choke point for name chaining, revocation-issuer matching and name
640
- // constraints -- compares the strings it returns. Admitting NumericString there would make a NumericString
641
- // attribute value compare EQUAL to a PrintableString / UTF8String one with the same characters, silently
642
- // widening distinguished-name identity across the whole toolkit. A caller that genuinely wants this type asks
643
- // for it by name.
644
508
  function readNumericString(node) {
645
509
  _expectUniversal(node, TAGS.NUMERIC_STRING, "readNumericString");
646
510
  _expectPrimitive(node, "readNumericString");
@@ -649,8 +513,6 @@ function readNumericString(node) {
649
513
  return s;
650
514
  }
651
515
 
652
- // UTF8String must be well-formed UTF-8; a lenient decoder substitutes U+FFFD
653
- // for invalid sequences, silently mangling hostile input into valid text.
654
516
  function _decodeUtf8Strict(buf) {
655
517
  try {
656
518
  return new TextDecoder("utf-8", { fatal: true }).decode(buf);
@@ -677,8 +539,6 @@ function readString(node) {
677
539
 
678
540
  function _decodeUtf16be(buf) {
679
541
  if (buf.length % 2 !== 0) throw new Asn1Error("asn1/bad-bmp-string", "BMPString length must be even");
680
- // BMPString encodes BMP scalar values only; a UTF-16 surrogate code unit
681
- // here is a lone surrogate, not valid text.
682
542
  for (var i = 0; i < buf.length; i += 2) {
683
543
  var u = (buf[i] << 8) | buf[i + 1];
684
544
  if (u >= 0xD800 && u <= 0xDFFF) throw new Asn1Error("asn1/bad-bmp-string", "code point out of range");
@@ -693,8 +553,6 @@ function _decodeUtf32be(buf) {
693
553
  var out = "";
694
554
  for (var i = 0; i < buf.length; i += 4) {
695
555
  var cp = (buf[i] * 0x1000000) + (buf[i + 1] << 16) + (buf[i + 2] << 8) + buf[i + 3];
696
- // Reject non-scalar values (> U+10FFFF or a surrogate) before
697
- // String.fromCodePoint would throw a bare RangeError / emit a lone surrogate.
698
556
  if (cp > 0x10FFFF || (cp >= 0xD800 && cp <= 0xDFFF)) {
699
557
  throw new Asn1Error("asn1/bad-universal-string", "code point out of range");
700
558
  }
@@ -703,9 +561,6 @@ function _decodeUtf32be(buf) {
703
561
  return out;
704
562
  }
705
563
 
706
- // Exactly `count` ASCII digits at `start`, as an integer, or null on any non-digit or short read.
707
- // Character-scanned so no regex match protocol -- a live, replaceable `exec` -- stands between the
708
- // codec and the time field it slices out.
709
564
  function _digitsToInt(s, start, count) {
710
565
  if (start + count > s.length) return null;
711
566
  var v = 0;
@@ -717,12 +572,6 @@ function _digitsToInt(s, start, count) {
717
572
  return v;
718
573
  }
719
574
 
720
- // The fixed DER time layout, scanned into its components, or null on any format violation:
721
- // yearLen digits (2 for UTCTime YY, 4 for GeneralizedTime YYYY), then MM DD HH MM SS, then --
722
- // when allowFrac -- the X.690 sec. 11.7 fractional-seconds profile (a "." decimal separator, never
723
- // ",", and a non-empty fraction), then a terminating "Z" as the final character with nothing after.
724
- // `ms` is the first three fraction digits right-zero-padded (matching (frac + "000").slice(0,3));
725
- // `fracLastIsZero` carries the sec. 11.7.3 trailing-zero check the caller enforces.
726
575
  function _scanTimeFields(s, yearLen, allowFrac) {
727
576
  var pos = 0;
728
577
  var year = _digitsToInt(s, pos, yearLen); if (year === null) return null; pos += yearLen;
@@ -733,7 +582,7 @@ function _scanTimeFields(s, yearLen, allowFrac) {
733
582
  var sec = _digitsToInt(s, pos, 2); if (sec === null) return null; pos += 2;
734
583
  var hasFrac = false, ms = 0, fracLastIsZero = false;
735
584
  if (allowFrac) {
736
- if (_charCodeAt(s, pos) !== 46) return null; // "."
585
+ if (_charCodeAt(s, pos) !== 46) return null;
737
586
  pos += 1;
738
587
  var f = [0, 0, 0], fi = 0;
739
588
  while (pos < s.length) {
@@ -742,21 +591,16 @@ function _scanTimeFields(s, yearLen, allowFrac) {
742
591
  if (fi < 3) f[fi] = c - 48;
743
592
  fi += 1; pos += 1;
744
593
  }
745
- if (fi === 0) return null; // a non-empty fraction is required
594
+ if (fi === 0) return null;
746
595
  hasFrac = true;
747
596
  fracLastIsZero = _charCodeAt(s, pos - 1) === 48;
748
597
  ms = f[0] * 100 + f[1] * 10 + f[2];
749
598
  }
750
- if (pos !== s.length - 1 || _charCodeAt(s, pos) !== 90) return null; // trailing "Z", nothing after
599
+ if (pos !== s.length - 1 || _charCodeAt(s, pos) !== 90) return null;
751
600
  return { year: year, month: month, day: day, hour: hour, min: min, sec: sec,
752
601
  hasFrac: hasFrac, ms: ms, fracLastIsZero: fracLastIsZero };
753
602
  }
754
603
 
755
- // readTime(node, opts?) -- opts.allowFractional enables the RFC 3161 / X.690 sec. 11.7
756
- // fractional-seconds GeneralizedTime profile. Fractional is OFF by default because
757
- // most profiles (RFC 5280 certificate/CRL Validity, sec. 4.1.2.5.2) require the integer-
758
- // second YYYYMMDDHHMMSSZ form and MUST NOT include a fraction; only callers that
759
- // permit sub-second precision (TSP genTime) pass allowFractional.
760
604
  function readTime(node, opts) {
761
605
  if (node.tagClass !== "universal") throw new Asn1Error("asn1/expected-time", "readTime: not a universal time type");
762
606
  _expectPrimitive(node, "readTime");
@@ -766,7 +610,6 @@ function readTime(node, opts) {
766
610
  t = _scanTimeFields(s, 2, false);
767
611
  if (!t) throw new Asn1Error("asn1/bad-utctime", "UTCTime must be YYMMDDHHMMSSZ, got " + JSON.stringify(s));
768
612
  year = t.year;
769
- // RFC 5280 sec. 4.1.2.5.1 -- YY < 50 => 20YY, else 19YY.
770
613
  year += (year < 50) ? 2000 : 1900;
771
614
  } else if (node.tagNumber === TAGS.GENERALIZED_TIME) {
772
615
  t = _scanTimeFields(s, 4, false);
@@ -774,13 +617,6 @@ function readTime(node, opts) {
774
617
  if (!(opts && opts.allowFractional)) throw new Asn1Error("asn1/bad-generalizedtime", "GeneralizedTime must be YYYYMMDDHHMMSSZ, got " + JSON.stringify(s));
775
618
  t = _scanTimeFields(s, 4, true);
776
619
  if (!t) throw new Asn1Error("asn1/bad-generalizedtime", "GeneralizedTime must be YYYYMMDDHHMMSS[.fraction]Z, got " + JSON.stringify(s));
777
- // X.690 sec. 11.7.3 -- the fractional part MUST NOT end in a zero (and is non-empty
778
- // by the scan). ".5Z" is valid; ".50Z" and ".500Z" are non-canonical. X.690
779
- // sec. 11.7 places NO cap on the fraction length (RFC 3161 sec. 2.4.2 gives the 5-digit
780
- // example 19990609001326.34352Z), so a fraction of any length is accepted; the
781
- // returned Date is millisecond-precision, and a caller needing the exact fraction
782
- // reads it from node.content (the raw bytes, surfaced losslessly like the OID /
783
- // serial paths).
784
620
  if (t.fracLastIsZero) throw new Asn1Error("asn1/bad-generalizedtime", "GeneralizedTime fraction must not have trailing zeros, got " + JSON.stringify(s));
785
621
  }
786
622
  year = t.year;
@@ -792,22 +628,11 @@ function readTime(node, opts) {
792
628
  var hour = t.hour;
793
629
  var min = t.min;
794
630
  var sec = t.sec;
795
- // Build from the LITERAL year via setUTCFullYear: the Date.UTC() / new Date()
796
- // constructors remap a year in 0..99 to 1900..1999, which would corrupt a
797
- // GeneralizedTime year below 100 (0099 -> 1999). setUTCFullYear(year, ...)
798
- // takes the year literally and uses that year's own calendar, so years
799
- // below 100 and proleptic leap years are handled correctly.
800
- // A fractional GeneralizedTime carries sub-second precision; surface it on the
801
- // Date at millisecond resolution (the first three fraction digits, zero-padded).
802
631
  var ms = (node.tagNumber === TAGS.GENERALIZED_TIME && t.hasFrac) ? t.ms : 0;
803
632
  var d = new Date(0);
804
633
  d.setUTCFullYear(year, month - 1, day);
805
634
  d.setUTCHours(hour, min, sec, ms);
806
- // Coverage residual -- scan-validated fields are finite integers and Date rolls over (never NaN); out-of-range is caught by the component round-trip check below.
807
635
  if (isNaN(guard.time.instantOf(d))) throw new Asn1Error("asn1/bad-time", "unparseable time " + JSON.stringify(s));
808
- // Date/setUTC* silently roll over out-of-range fields (Feb 30 -> Mar 2,
809
- // month 13 -> next Jan, hour 25 -> +1 day). Reject unless every component
810
- // round-trips exactly.
811
636
  if (d.getUTCFullYear() !== year || d.getUTCMonth() !== month - 1 || d.getUTCDate() !== day ||
812
637
  d.getUTCHours() !== hour || d.getUTCMinutes() !== min || d.getUTCSeconds() !== sec) {
813
638
  throw new Asn1Error("asn1/bad-time", "time component out of range " + JSON.stringify(s));
@@ -815,7 +640,6 @@ function readTime(node, opts) {
815
640
  return d;
816
641
  }
817
642
 
818
- // ---- Encoder / builders ---------------------------------------------
819
643
 
820
644
  function encodeLength(n) {
821
645
  if (typeof n !== "number" || !isFinite(n) || n < 0 || Math.floor(n) !== n) {
@@ -829,24 +653,12 @@ function encodeLength(n) {
829
653
  return Buffer.concat([Buffer.from([0x80 | bytes.length]), Buffer.from(bytes)]);
830
654
  }
831
655
 
832
- // The DER of a universal SEQUENCE recovered from a decoded IMPLICIT [n] SEQUENCE
833
- // `node`, whose context tag replaced the universal 0x30 on the wire (e.g. an RFC
834
- // 4211 CertTemplate publicKey [6] SubjectPublicKeyInfo, or a POPOSigningKey
835
- // poposkInput [0]): the field's value is imported / signed as a standalone SEQUENCE,
836
- // not as the context-tagged wire form. A constructed node exposes its content as
837
- // `children` (not `content`), so the content is those children's DER concatenated;
838
- // the identifier becomes the SEQUENCE tag and the length is canonical DER.
839
656
  function sequenceTlv(node) {
840
- // Coverage residual -- a decoded node with content==null is always constructed with a children array; the || [] guards a non-decoder-built node and is unreachable via decode.
841
657
  var content = node.content != null ? node.content : Buffer.concat((node.children || []).map(function (c) { return c.bytes; }));
842
658
  return Buffer.concat([Buffer.from([TAGS.SEQUENCE | CONSTRUCTED_BIT]), encodeLength(content.length), content]);
843
659
  }
844
660
 
845
661
  function encodeIdentifier(classBits, constructed, tagNumber) {
846
- // Mirror encodeLength's input guard: a negative tag corrupts the identifier
847
- // octet (-1 emits 0xff..), and a fractional tag is silently bit-truncated to
848
- // a DIFFERENT tag -- an entry-point builder handed a bad tag throws instead
849
- // of emitting malformed or non-round-trippable DER.
850
662
  if (typeof tagNumber !== "number" || !isFinite(tagNumber) || tagNumber < 0 || Math.floor(tagNumber) !== tagNumber) {
851
663
  throw new Asn1Error("asn1/bad-tag", "tag number must be a non-negative integer");
852
664
  }
@@ -855,8 +667,6 @@ function encodeIdentifier(classBits, constructed, tagNumber) {
855
667
  var body = [];
856
668
  var v = tagNumber;
857
669
  do { body.unshift(v & 0x7f); v = Math.floor(v / 128); } while (v > 0);
858
- // Symmetric with the decoder's 4-octet high-tag-number cap, so the encoder
859
- // can't emit an identifier decode() refuses as hostile.
860
670
  if (body.length > 4) throw new Asn1Error("asn1/tag-too-large", "high-tag-number too large");
861
671
  for (var i = 0; i < body.length - 1; i++) body[i] |= 0x80;
862
672
  return Buffer.concat([Buffer.from([lead | 0x1f]), Buffer.from(body)]);
@@ -878,9 +688,6 @@ function encodeIdentifier(classBits, constructed, tagNumber) {
878
688
  * pki.asn1.encode(0x00, false, pki.asn1.TAGS.NULL, Buffer.alloc(0));
879
689
  */
880
690
  function encodeTLV(classBits, constructed, tagNumber, content) {
881
- // A Buffer content is re-viewed so a detached backing store fails closed with a
882
- // typed asn1/not-buffer instead of a raw TypeError out of Buffer.concat; an
883
- // array / undefined content stays the normal builder path.
884
691
  var body = Buffer.isBuffer(content) ? guard.bytes.view(content, Asn1Error, "asn1/not-buffer", "encodeTLV content") : Buffer.from(content || []);
885
692
  var id = encodeIdentifier(classBits, constructed, tagNumber);
886
693
  return Buffer.concat([id, encodeLength(body.length), body]);
@@ -912,9 +719,6 @@ function intToDer(v) {
912
719
  }
913
720
 
914
721
  function encodeOidContent(dotted) {
915
- // Canonical dotted-decimal + X.660 arc bounds live in the one string-OID guard,
916
- // so build.oid cannot emit bytes that decode to a DIFFERENT OID than the string
917
- // names (a leading-zero arc) or an arc that can never DER-encode.
918
722
  guard.identifier.assertCanonicalOid(dotted, _oidErr, "oid/bad-input", "OID", "oid/bad-arc");
919
723
  var arcs = dotted.split(".").map(function (p) { return BigInt(p); });
920
724
  var a1 = arcs[0], a2 = arcs[1];
@@ -924,8 +728,6 @@ function encodeOidContent(dotted) {
924
728
  var body = [];
925
729
  var v = subids[s];
926
730
  do { body.unshift(Number(v & 0x7fn)); v >>= 7n; } while (v > 0n);
927
- // Keep the encoder symmetric with the decoder's per-arc cap so build.oid
928
- // can't emit a sub-identifier read.oid would reject as hostile.
929
731
  if (body.length > constants.LIMITS.OID_MAX_SUBIDENTIFIER_BYTES) {
930
732
  throw new OidError("oid/subidentifier-too-large",
931
733
  "OID sub-identifier exceeds " + constants.LIMITS.OID_MAX_SUBIDENTIFIER_BYTES + " octets");
@@ -936,13 +738,11 @@ function encodeOidContent(dotted) {
936
738
  return Buffer.from(out);
937
739
  }
938
740
 
939
- // PrintableString (X.680): A-Z a-z 0-9 space and ' ( ) + , - . / : = ? -- checked by character scan (no
940
- // regex). NumericString: digits and space only.
941
741
  function _isPrintableChar(c) {
942
- if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122) || (c >= 48 && c <= 57)) return true; // A-Z a-z 0-9
742
+ if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122) || (c >= 48 && c <= 57)) return true;
943
743
  switch (c) {
944
- case 32: case 39: case 40: case 41: case 43: case 44: case 45: case 46: case 47: // space ' ( ) + , - . /
945
- case 58: case 61: case 63: // : = ?
744
+ case 32: case 39: case 40: case 41: case 43: case 44: case 45: case 46: case 47:
745
+ case 58: case 61: case 63:
946
746
  return true;
947
747
  default: return false;
948
748
  }
@@ -960,8 +760,6 @@ function _isNumericString(s) {
960
760
  function _fmtTwo(n) { return (n < 10 ? "0" : "") + n; }
961
761
 
962
762
  function _generalizedTimeString(date) {
963
- // GeneralizedTime is YYYYMMDDHHMMSSZ -- a year below 1000 must still emit
964
- // four digits, or read.time rejects the short (12-14 char) content.
965
763
  var y = date.getUTCFullYear();
966
764
  if (y < 0 || y > 9999) throw new Asn1Error("asn1/bad-generalizedtime", "GeneralizedTime year " + y + " outside 0000..9999");
967
765
  var yyyy = ("000" + y).slice(-4);
@@ -971,8 +769,6 @@ function _generalizedTimeString(date) {
971
769
  }
972
770
 
973
771
  function _utcTimeString(date) {
974
- // RFC 5280 sec. 4.1.2.5.1 restricts UTCTime to 1950..2049; a year outside that
975
- // wraps to the wrong century (2050 -> "50" -> decodes as 1950).
976
772
  var y = date.getUTCFullYear();
977
773
  if (y < 1950 || y > 2049) throw new Asn1Error("asn1/bad-utctime", "UTCTime year " + y + " outside 1950..2049; use GeneralizedTime");
978
774
  var yy = y % 100;
@@ -1007,27 +803,15 @@ var build = {
1007
803
  oid: function (dotted) { return _universal(TAGS.OBJECT_IDENTIFIER, false, encodeOidContent(dotted)); },
1008
804
  octetString: function (buf) { return _universal(TAGS.OCTET_STRING, false, _asBuffer(buf, "build.octetString")); },
1009
805
  bitString: function (buf, unusedBits) {
1010
- // An integer in 0..7 (X.690 sec. 8.6.2.2). A fractional / non-finite count
1011
- // would be silently bit-truncated into a DIFFERENT value when written into
1012
- // the leading octet -- the shared integer cap rejects it like the other
1013
- // numeric builder inputs (encodeLength, the tag number).
1014
806
  var u = guard.limits.cap(unusedBits == null ? 0 : unusedBits, "unusedBits", 0, { E: _asn1Error, code: "asn1/bad-bit-string", min: 0, max: 7 });
1015
807
  var body = _asBuffer(buf, "build.bitString");
1016
- // X.690 8.6.2.3: an empty BIT STRING has no content octets, so its
1017
- // unused-bit count must be zero -- there are no bits to leave unused.
1018
808
  if (u > 0 && body.length === 0) throw new Asn1Error("asn1/bad-bit-string", "empty BIT STRING must declare zero unused bits");
1019
- // Stay canonical: refuse a tail whose declared unused low bits are set.
1020
809
  if (u > 0 && body.length > 0) {
1021
810
  var mask = (1 << u) - 1;
1022
811
  if ((body[body.length - 1] & mask) !== 0) throw new Asn1Error("asn1/bad-bit-string", "unused bits must be zero");
1023
812
  }
1024
813
  return _universal(TAGS.BIT_STRING, false, Buffer.concat([Buffer.from([u]), body]));
1025
814
  },
1026
- // A minimal DER NamedBitList BIT STRING (X.690 sec. 11.2.2): the asserted `positions` (0-based bit
1027
- // indices, 0 = the MSB of the first octet) with every trailing zero bit removed and the unused-bit
1028
- // count set below the last set bit. The single home the keyUsage / PKIFailureInfo / any named-bit
1029
- // encoder composes, so the minimal-encoding rule lives once (the CHECK side is
1030
- // schema.assertMinimalNamedBits). No bits asserted -> the empty BIT STRING.
1031
815
  namedBitString: function (positions) {
1032
816
  if (!_isArray(positions)) throw new Asn1Error("asn1/bad-bit-string", "namedBitString requires an array of bit positions");
1033
817
  var hi = -1, i, p;
@@ -1043,9 +827,6 @@ var build = {
1043
827
  },
1044
828
  utf8: function (s) { return _universal(TAGS.UTF8_STRING, false, Buffer.from(String(s), "utf8")); },
1045
829
  ia5: function (s) {
1046
- // Validate the INPUT code points, not the latin1 output bytes: latin1
1047
- // truncates a code point > 0xFF to its low byte (U+0141 -> 0x41), which
1048
- // would silently pass a non-IA5 character through as a different one.
1049
830
  s = String(s);
1050
831
  for (var i = 0; i < s.length; i++) {
1051
832
  if (_charCodeAt(s, i) > 0x7F) throw new Asn1Error("asn1/bad-ia5-string", "IA5String requires 7-bit ASCII");
@@ -1058,9 +839,6 @@ var build = {
1058
839
  return _universal(TAGS.PRINTABLE_STRING, false, Buffer.from(s, "latin1"));
1059
840
  },
1060
841
  bmpString: function (s) {
1061
- // BMPString (UCS-2, X.680) encodes each character as a 2-byte big-endian BMP scalar value -- the exact
1062
- // inverse of _decodeUtf16be. A surrogate code unit (U+D800..U+DFFF), whether lone or half of a >U+FFFF
1063
- // pair, cannot be a BMPString character, so it is rejected rather than silently emitted.
1064
842
  s = String(s);
1065
843
  var out = Buffer.alloc(s.length * 2);
1066
844
  for (var i = 0; i < s.length; i++) {
@@ -1075,7 +853,6 @@ var build = {
1075
853
  generalizedTime: function (date) { return _universal(TAGS.GENERALIZED_TIME, false, Buffer.from(_generalizedTimeString(date), "latin1")); },
1076
854
  sequence: function (children) { return _universal(TAGS.SEQUENCE, true, Buffer.concat(_asBufferArray(children, "build.sequence"))); },
1077
855
  set: function (children) {
1078
- // DER (X.690 11.6) requires SET component encodings in ascending order.
1079
856
  var arr = _asBufferArray(children, "build.set").slice();
1080
857
  arr.sort(Buffer.compare);
1081
858
  return _universal(TAGS.SET, true, Buffer.concat(arr));
@@ -1085,14 +862,9 @@ var build = {
1085
862
  arr.sort(Buffer.compare);
1086
863
  return _universal(TAGS.SET, true, Buffer.concat(arr));
1087
864
  },
1088
- // Context-tagged constructions for [n] EXPLICIT / IMPLICIT tagging.
1089
865
  explicit: function (tagNumber, inner) { return encodeTLV(CLASS_CONTEXT, true, tagNumber, _asBuffer(inner, "build.explicit")); },
1090
866
  contextPrimitive: function (tagNumber, content) { return encodeTLV(CLASS_CONTEXT, false, tagNumber, _asBuffer(content, "build.contextPrimitive")); },
1091
867
  contextConstructed: function (tagNumber, content) { return encodeTLV(CLASS_CONTEXT, true, tagNumber, _asBuffer(content, "build.contextConstructed")); },
1092
- // IMPLICIT [tag] retag of an already-encoded UNIVERSAL TLV: replace the source's tag with a context-class
1093
- // [tag] identifier, PRESERVING the source's primitive/constructed bit and content octets (X.680 sec. 30.6).
1094
- // A single home for the tag replacement so no format module re-inlines the P/C-bit handling (a decode of
1095
- // the source validates it is exactly one well-formed TLV; its content is the trailing `length` octets).
1096
868
  implicit: function (tagNumber, tlv) {
1097
869
  var buf = _asBuffer(tlv, "build.implicit");
1098
870
  var node = decode(buf);
@@ -1100,14 +872,8 @@ var build = {
1100
872
  },
1101
873
  raw: function (buf) { return _asBuffer(buf, "build.raw"); },
1102
874
  };
1103
- // Frozen at load so a builder method cannot be replaced afterward: every format module captures `build`
1104
- // and calls its methods to produce emitted DER, so a mutable `build.contextPrimitive` (or any builder)
1105
- // would let co-resident code steer the bytes a certificate carries. Freezing closes that once, toolkit-wide.
1106
875
  intrinsic.freeze(build);
1107
876
 
1108
- // A raw INTEGER/ENUMERATED content Buffer must satisfy the same DER shape
1109
- // read.integer enforces: non-empty and minimally encoded (no redundant sign
1110
- // octet). A BigInt/number goes through intToDer, which is minimal by build.
1111
877
  function _intContent(v, who) {
1112
878
  if (Buffer.isBuffer(v)) {
1113
879
  if (v.length === 0) throw new Asn1Error("asn1/bad-integer", who + ": INTEGER content is empty");
@@ -1117,8 +883,6 @@ function _intContent(v, who) {
1117
883
  }
1118
884
  }
1119
885
  var content = Buffer.isBuffer(v) ? v : intToDer(v);
1120
- // Symmetric with read.integer's per-value ceiling (magnitude + DER sign
1121
- // octet), so a builder can't emit an INTEGER the decoder would refuse.
1122
886
  if (content.length > constants.LIMITS.DER_MAX_INTEGER_BYTES + 1) {
1123
887
  throw new Asn1Error("asn1/integer-too-large", who + ": INTEGER content " + content.length + " bytes exceeds cap " + (constants.LIMITS.DER_MAX_INTEGER_BYTES + 1));
1124
888
  }
@@ -1134,8 +898,6 @@ module.exports = {
1134
898
  TAGS: TAGS,
1135
899
  decode: decode,
1136
900
  isPrintableString: isPrintableString,
1137
- // `encode` is the documented public name for the low-level TLV encoder;
1138
- // `encodeTLV` remains as the descriptive alias.
1139
901
  encode: encodeTLV,
1140
902
  encodeTLV: encodeTLV,
1141
903
  encodeLength: encodeLength,