@blamejs/pki 0.8.59 → 0.8.60

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 (63) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/lib/acme.js +15 -7
  3. package/lib/alt-sig.js +3 -1
  4. package/lib/asn1-der.js +82 -34
  5. package/lib/attrcert-sign.js +19 -16
  6. package/lib/byte-writer.js +63 -13
  7. package/lib/cbor-det.js +9 -3
  8. package/lib/cmc-build.js +12 -9
  9. package/lib/cmp-build.js +35 -33
  10. package/lib/cmp-session.js +19 -9
  11. package/lib/cms-decrypt.js +22 -8
  12. package/lib/cms-encrypt.js +23 -17
  13. package/lib/cms-sign.js +65 -43
  14. package/lib/cms-verify.js +8 -4
  15. package/lib/crl-sign.js +24 -17
  16. package/lib/csr-sign.js +5 -2
  17. package/lib/ct.js +27 -16
  18. package/lib/est.js +12 -9
  19. package/lib/guard-bytes.js +5 -1
  20. package/lib/guard-der.js +6 -1
  21. package/lib/guard-intrinsic.js +12 -4
  22. package/lib/guard-list.js +64 -0
  23. package/lib/guard-name.js +1 -1
  24. package/lib/hpke.js +10 -3
  25. package/lib/http-transport.js +12 -3
  26. package/lib/inspect.js +10 -2
  27. package/lib/jose.js +3 -1
  28. package/lib/lint.js +236 -152
  29. package/lib/mime.js +9 -5
  30. package/lib/ocsp.js +25 -22
  31. package/lib/path-validate.js +43 -13
  32. package/lib/pbes2.js +6 -2
  33. package/lib/pkcs11-uri.js +3 -1
  34. package/lib/pkcs12-build.js +14 -11
  35. package/lib/pki-build.js +14 -10
  36. package/lib/possession.js +3 -1
  37. package/lib/rc2.js +6 -2
  38. package/lib/revocation-fetch.js +78 -19
  39. package/lib/scep.js +14 -6
  40. package/lib/schema-attrcert.js +4 -2
  41. package/lib/schema-c509.js +94 -78
  42. package/lib/schema-cmc.js +5 -2
  43. package/lib/schema-cmp.js +6 -3
  44. package/lib/schema-cms.js +7 -4
  45. package/lib/schema-crl.js +1 -1
  46. package/lib/schema-crmf.js +1 -1
  47. package/lib/schema-csr.js +3 -3
  48. package/lib/schema-engine.js +36 -18
  49. package/lib/schema-pkcs1.js +7 -3
  50. package/lib/schema-pkcs12.js +9 -6
  51. package/lib/schema-pkix.js +19 -3
  52. package/lib/schema-sec1.js +4 -1
  53. package/lib/schema-tsp.js +4 -1
  54. package/lib/shbs.js +7 -3
  55. package/lib/smime.js +18 -14
  56. package/lib/tlog.js +17 -11
  57. package/lib/tuf.js +3 -1
  58. package/lib/validator-keydesc.js +4 -1
  59. package/lib/validator-tls.js +7 -2
  60. package/lib/webcrypto.js +9 -3
  61. package/lib/x509-sign.js +20 -15
  62. package/package.json +1 -1
  63. package/sbom.cdx.json +6 -6
@@ -98,7 +98,7 @@ function isResourceRefusal(e) {
98
98
  function withResources(ns, source) {
99
99
  if (!source || (source.caps == null && source.budget == null)) return ns;
100
100
  var out = Object.create(null);
101
- var keys = Object.keys(ns);
101
+ var keys = intrinsic.keys(ns);
102
102
  for (var i = 0; i < keys.length; i++) out[keys[i]] = ns[keys[i]];
103
103
  out.caps = source.caps;
104
104
  out.budget = source.budget;
@@ -146,11 +146,11 @@ function integerLeaf() { return { kind: "leaf", read: asn1.read.integer, writ
146
146
  function boolean() { return { kind: "leaf", read: asn1.read.boolean, write: function (v) { return asn1.build.boolean(v); } }; }
147
147
  function octetString() { return { kind: "leaf", read: asn1.read.octetString, write: function (v) { return asn1.build.octetString(v); } }; }
148
148
  function bitString() { return { kind: "leaf", read: function (n) { var b = asn1.read.bitString(n); return { unusedBits: b.unusedBits, bytes: b.bytes }; }, write: function (v) { return asn1.build.bitString(v.bytes, v.unusedBits); } }; }
149
- function implicitBitString(tag) { return { kind: "leaf", read: function (n) { var b = asn1.read.bitStringImplicit(n, tag); return { unusedBits: b.unusedBits, bytes: b.bytes }; }, write: function (v) { return asn1.build.contextPrimitive(tag, Buffer.concat([Buffer.from([v.unusedBits]), v.bytes])); } }; }
149
+ function implicitBitString(tag) { return { kind: "leaf", read: function (n) { var b = asn1.read.bitStringImplicit(n, tag); return { unusedBits: b.unusedBits, bytes: b.bytes }; }, write: function (v) { return asn1.build.contextPrimitive(tag, intrinsic.bufferConcat([intrinsic.bufferFrom([v.unusedBits]), v.bytes])); } }; }
150
150
  function implicitOctetString(tag) { return { kind: "leaf", read: function (n) { return asn1.read.octetStringImplicit(n, tag); }, write: function (v) { return asn1.build.contextPrimitive(tag, v); } }; }
151
- function implicitNull(tag) { return { kind: "leaf", read: function (n) { return asn1.read.nullImplicit(n, tag); }, write: function () { return asn1.build.contextPrimitive(tag, Buffer.alloc(0)); } }; }
151
+ function implicitNull(tag) { return { kind: "leaf", read: function (n) { return asn1.read.nullImplicit(n, tag); }, write: function () { return asn1.build.contextPrimitive(tag, intrinsic.bufferAlloc(0)); } }; }
152
152
  function implicitInteger(tag) { return { kind: "leaf", read: function (n) { return asn1.read.integerImplicit(n, tag); }, write: function (v) { return asn1.build.contextPrimitive(tag, _implicitIntContent(v)); } }; }
153
- function implicitBoolean(tag) { return { kind: "leaf", read: function (n) { return asn1.read.booleanImplicit(n, tag); }, write: function (v) { return asn1.build.contextPrimitive(tag, Buffer.from([v ? 0xff : 0x00])); } }; }
153
+ function implicitBoolean(tag) { return { kind: "leaf", read: function (n) { return asn1.read.booleanImplicit(n, tag); }, write: function (v) { return asn1.build.contextPrimitive(tag, intrinsic.bufferFrom([v ? 0xff : 0x00])); } }; }
154
154
  function any() { return { kind: "any" }; }
155
155
  function decode(fn, write) { return { kind: "decode", fn: fn, write: write }; }
156
156
 
@@ -328,7 +328,14 @@ function _walkRepeat(schema, node, ctx) {
328
328
  if (seen.has(key)) _fail(ctx, schema.dupCode || schema.code, "duplicate element " + key);
329
329
  seen.add(key);
330
330
  }
331
- items.push(item);
331
+ /** @internal The element is APPENDED by defining its index. `push` stores, and a store walks the
332
+ * prototype chain for a setter, so an accessor at an array index received each element as the
333
+ * repeat was walked and left the list a hole that reads back whatever its getter answers.
334
+ * `m.items` is what every build() reads its elements out of, and a DN is a SEQUENCE OF RDN:
335
+ * measured, a certificate whose subject is `C=US, ST=California, O=blamejs pki, OU=Test,
336
+ * CN=pkijs.com` parsed with the accessor's value in place of its first RDN, and the parse threw
337
+ * a bare TypeError rather than a typed refusal. */
338
+ intrinsic.append(items, item);
332
339
  }
333
340
  var match = { kind: "repeat", node: node, items: items };
334
341
  if (schema.build) match.result = schema.build(match, ctx);
@@ -336,7 +343,7 @@ function _walkRepeat(schema, node, ctx) {
336
343
  }
337
344
 
338
345
  function _equalsDefault(value, def) {
339
- if (Buffer.isBuffer(value) && Buffer.isBuffer(def)) return value.equals(def);
346
+ if (intrinsic.isBuffer(value) && intrinsic.isBuffer(def)) return intrinsic.bufferEquals(value, def);
340
347
  return value === def;
341
348
  }
342
349
 
@@ -439,7 +446,7 @@ function _encFail(message) { throw new Error("schema.encode: " + message); }
439
446
  function encode(schema, value, ctx) {
440
447
  switch (schema.kind) {
441
448
  case "leaf": return schema.write(value);
442
- case "any": return Buffer.isBuffer(value) ? value : value.bytes;
449
+ case "any": return intrinsic.isBuffer(value) ? value : value.bytes;
443
450
  case "decode":
444
451
  if (typeof schema.write !== "function") _encFail("this decode leaf has no paired encoder (decode(fn, write))");
445
452
  return schema.write(value, ctx);
@@ -453,7 +460,7 @@ function encode(schema, value, ctx) {
453
460
  }
454
461
 
455
462
  function _wrapConstructed(schema, parts) {
456
- if (schema.implicitTag != null) return asn1.build.contextConstructed(schema.implicitTag, Buffer.concat(parts));
463
+ if (schema.implicitTag != null) return asn1.build.contextConstructed(schema.implicitTag, intrinsic.bufferConcat(parts));
457
464
  var mode = schema.assert || "sequence";
458
465
  if (mode === "set") return asn1.build.set(parts);
459
466
  if (mode === "sequence" || mode === "constructed") return asn1.build.sequence(parts);
@@ -469,13 +476,17 @@ function _encodeSeq(schema, value, ctx) {
469
476
  for (var f = 0; f < schema.fields.length; f++) {
470
477
  var fld = schema.fields[f];
471
478
  if (fld.fkind === "required") {
472
- parts.push(encode(fld.schema, value[fld.name], ctx));
479
+ /** @internal Each field is APPENDED by defining its index, for the reason the repeat walk is:
480
+ * `push` stores, a store consults a setter inherited at the index, and these parts are
481
+ * concatenated in order into the structure this encoder emits. Measured, an accessor at
482
+ * index 0 put its own TLV where the first field belongs. */
483
+ intrinsic.append(parts, encode(fld.schema, value[fld.name], ctx));
473
484
  } else if (fld.fkind === "optional") {
474
485
  if (_present(value[fld.name])) {
475
486
  var enc = encode(fld.schema, value[fld.name], ctx);
476
487
  var isDefault = fld.hasDefault && fld.def !== undefined &&
477
- enc.equals(encode(fld.schema, fld.def, ctx));
478
- if (!isDefault) parts.push(fld.explicit ? asn1.build.explicit(fld.tag, enc) : enc);
488
+ intrinsic.bufferEquals(enc, encode(fld.schema, fld.def, ctx));
489
+ if (!isDefault) intrinsic.append(parts, fld.explicit ? asn1.build.explicit(fld.tag, enc) : enc);
479
490
  }
480
491
  } else if (fld.fkind === "trailing") {
481
492
  var members = guardList.sortedCopy(fld.members, function (a, b) { return a.tag - b.tag; });
@@ -483,7 +494,7 @@ function _encodeSeq(schema, value, ctx) {
483
494
  var mm = members[i];
484
495
  if (_present(value[mm.name])) {
485
496
  var menc = encode(mm.schema, value[mm.name], ctx);
486
- parts.push(mm.explicit ? asn1.build.explicit(mm.tag, menc) : menc);
497
+ intrinsic.append(parts, mm.explicit ? asn1.build.explicit(mm.tag, menc) : menc);
487
498
  }
488
499
  }
489
500
  } else {
@@ -494,17 +505,21 @@ function _encodeSeq(schema, value, ctx) {
494
505
  }
495
506
 
496
507
  function _encodeRepeat(schema, items, ctx) {
497
- if (!Array.isArray(items)) _encFail("a repeat value must be an array");
508
+ if (!intrinsic.isArray(items)) _encFail("a repeat value must be an array");
498
509
  if (schema.min != null && items.length < schema.min) {
499
510
  _encFail("this repeat requires at least " + schema.min + " element(s) but got " + items.length);
500
511
  }
501
512
  if (schema.max != null && items.length > schema.max) {
502
513
  _encFail("this repeat caps at " + schema.max + " element(s) but got " + items.length);
503
514
  }
504
- var parts = items.map(function (it) { return encode(schema.item, it, ctx); });
515
+ /** @internal The elements are mapped through the captured operation, which builds its result by
516
+ * defining each index on a plain array. `Array.prototype.map` is replaceable and reads the
517
+ * receiver's `Symbol.species` to construct what it returns, so a caller's array could both
518
+ * choose the encoded elements and hand this encoder a result object of its own class. */
519
+ var parts = intrinsic.mapList(items, function (it) { return encode(schema.item, it, ctx); });
505
520
  if (schema.unique) {
506
521
  var seen = new Set();
507
- parts.forEach(function (tlv) {
522
+ intrinsic.forEach(parts, function (tlv) {
508
523
  // allow:bare-decode a round trip through the codec on a TLV this encoder just produced.
509
524
  var item = { node: asn1.decode(tlv) };
510
525
  item.value = walk(schema.item, item.node, ctx);
@@ -517,7 +532,7 @@ function _encodeRepeat(schema, items, ctx) {
517
532
  * is the engine's own SET OF emission, so whatever decides "before" decides the bytes every schema
518
533
  * built on it emits. */
519
534
  if (schema.derSetOrder) parts = guardList.sortedCopy(parts, intrinsic.compare);
520
- if (schema.implicitTag != null) return asn1.build.contextConstructed(schema.implicitTag, Buffer.concat(parts));
535
+ if (schema.implicitTag != null) return asn1.build.contextConstructed(schema.implicitTag, intrinsic.bufferConcat(parts));
521
536
  return schema.assert === "set" ? asn1.build.set(parts) : asn1.build.sequence(parts);
522
537
  }
523
538
 
@@ -586,11 +601,14 @@ function isUniversal(node, tagNumber) {
586
601
  function isContext(node, tagNumber) {
587
602
  return !!node && node.tagClass === "context" && node.tagNumber === tagNumber;
588
603
  }
604
+ /** @internal Both read the OWN elements of the tag list. `indexOf` is specified in terms of
605
+ * HasProperty, so a list with a hole at an index answers from the array prototype, and the list
606
+ * here is an allow-list deciding whether a node's tag is one a schema accepts. */
589
607
  function isUniversalOneOf(node, tagNumbers) {
590
- return !!node && node.tagClass === "universal" && tagNumbers.indexOf(node.tagNumber) !== -1;
608
+ return !!node && node.tagClass === "universal" && intrinsic.ownIndexOf(tagNumbers, node.tagNumber) !== -1;
591
609
  }
592
610
  function isContextOneOf(node, tagNumbers) {
593
- return !!node && node.tagClass === "context" && tagNumbers.indexOf(node.tagNumber) !== -1;
611
+ return !!node && node.tagClass === "context" && intrinsic.ownIndexOf(tagNumbers, node.tagNumber) !== -1;
594
612
  }
595
613
  function isContextInRange(node, min, max) {
596
614
  return !!node && node.tagClass === "context" && node.tagNumber >= min && node.tagNumber <= max;
@@ -264,11 +264,15 @@ function encode(key) {
264
264
  var infos = key.otherPrimeInfos;
265
265
  if (intrinsic.isArray(infos) && infos.length > 0) {
266
266
  var rows = [];
267
+ /** @internal Both appends define the index. A store at an index a list has no own property at
268
+ * walks the prototype chain for a setter, so an accessor there took the element and the list
269
+ * read back whatever its getter answers; `kids` holds nine own slots here, so index nine is
270
+ * such a store. These are the bytes a private key encodes to. */
267
271
  for (var i = 0; i < infos.length; i++) {
268
- rows[i] = asn1.build.sequence([asn1.build.integer(infos[i].prime),
269
- asn1.build.integer(infos[i].exponent), asn1.build.integer(infos[i].coefficient)]);
272
+ intrinsic.append(rows, asn1.build.sequence([asn1.build.integer(infos[i].prime),
273
+ asn1.build.integer(infos[i].exponent), asn1.build.integer(infos[i].coefficient)]));
270
274
  }
271
- kids[9] = asn1.build.sequence(rows);
275
+ intrinsic.append(kids, asn1.build.sequence(rows));
272
276
  }
273
277
  return asn1.build.sequence(kids);
274
278
  }
@@ -47,6 +47,9 @@ var cms = require("./schema-cms.js");
47
47
  var pkcs8 = require("./schema-pkcs8.js");
48
48
  var frameworkError = require("./framework-error.js");
49
49
  var guard = require("./guard-all.js");
50
+ /** @internal The append this module's lists are built with: `push` stores at the index and a store
51
+ * consults a setter inherited there, which takes the element being appended. */
52
+ var _push = guard.list.append;
50
53
 
51
54
  var Pkcs12Error = frameworkError.Pkcs12Error;
52
55
  var PemError = frameworkError.PemError;
@@ -181,7 +184,7 @@ var SAFE_BAG = schema.seq([
181
184
  var items = m.fields.bagAttributes.value.items;
182
185
  for (var i = 0; i < items.length; i++) {
183
186
  var a = items[i].value.result;
184
- attributes.push(a);
187
+ _push(attributes, a);
185
188
  if (a.type === OID_FRIENDLY_NAME) {
186
189
  if (seen[a.type] || a.values.length !== 1) throw ctx.E("pkcs12/bad-friendly-name", "friendlyName carries exactly one BMPString value (PKCS#9 SINGLE VALUE)");
187
190
  friendlyName = _bmpValue(a.values[0], ctx);
@@ -319,7 +322,7 @@ function walkSafeContents(der, ctx) {
319
322
  var walked = schema.walk(SAFE_CONTENTS, pkix.decodeNested(der, ns, "a SafeContents", { ber: true }), ns);
320
323
  var state = { budget: { remaining: C.LIMITS.PKCS12_MAX_REDECODES }, bagDepth: 0 };
321
324
  var bags = [];
322
- for (var i = 0; i < walked.items.length; i++) bags.push(_buildBag(walked.items[i].value.result, state, ns));
325
+ for (var i = 0; i < walked.items.length; i++) _push(bags, _buildBag(walked.items[i].value.result, state, ns));
323
326
  return bags;
324
327
  }
325
328
 
@@ -334,12 +337,12 @@ function _dispatchSafes(asMatch, state, ctx) {
334
337
  budget: state.budget, budgetCode: "pkcs12/too-deep",
335
338
  });
336
339
  for (var j = 0; j < contents.items.length; j++) {
337
- safeBags.push(_buildBag(contents.items[j].value.result, state, ctx));
340
+ _push(safeBags, _buildBag(contents.items[j].value.result, state, ctx));
338
341
  }
339
342
  } else if (el.contentType === OID_ENCRYPTED_DATA) {
340
- encryptedSafes.push({ type: "encryptedData", content: _privacySafe(cms.walkEncryptedData(el.innerNode, ctx), ctx) });
343
+ _push(encryptedSafes, { type: "encryptedData", content: _privacySafe(cms.walkEncryptedData(el.innerNode, ctx), ctx) });
341
344
  } else if (el.contentType === OID_ENVELOPED_DATA) {
342
- encryptedSafes.push({ type: "envelopedData", content: _privacySafe(cms.walkEnvelopedData(el.innerNode, ctx), ctx), envelopedDataDer: el.innerNode.bytes });
345
+ _push(encryptedSafes, { type: "envelopedData", content: _privacySafe(cms.walkEnvelopedData(el.innerNode, ctx), ctx), envelopedDataDer: el.innerNode.bytes });
343
346
  } else {
344
347
  throw ctx.E("pkcs12/bad-safe-contentinfo-type", "an AuthenticatedSafe element must be id-data, id-encryptedData, or id-envelopedData (RFC 7292 sec. 4.1), got " +
345
348
  (ctx.oid.name(el.contentType) || el.contentType));
@@ -391,7 +394,7 @@ function _buildBag(rec, state, ctx) {
391
394
  bag.nested = [];
392
395
  var nestedMatch = schema.walk(SAFE_CONTENTS, rec.valueNode, ctx);
393
396
  for (var i = 0; i < nestedMatch.items.length; i++) {
394
- bag.nested.push(_buildBag(nestedMatch.items[i].value.result, nestedState, ctx));
397
+ _push(bag.nested, _buildBag(nestedMatch.items[i].value.result, nestedState, ctx));
395
398
  }
396
399
  return bag;
397
400
  }
@@ -11,8 +11,17 @@ var intrinsic = require("./guard-intrinsic");
11
11
  var frameworkError = require("./framework-error");
12
12
  var _hasOwn = intrinsic.hasOwn;
13
13
  var _forEach = intrinsic.forEach;
14
- var _map = intrinsic.map;
15
- var _push = intrinsic.push;
14
+ /** @internal `mapList`, not the captured `map`. `Array.prototype.map` is specified to build its
15
+ * result through `ArraySpeciesCreate`, which reads the receiver's `constructor` and then that
16
+ * constructor's `Symbol.species`, so a getter installed on `Array.prototype.constructor` runs
17
+ * caller code with the list being mapped as its `this` on every call. Capturing the method closes
18
+ * which function runs, not the protocol it consults. Measured on a certificate parse: the
19
+ * extension-list build was reached that way. `mapList` defines each index on a plain array. */
20
+ var _map = intrinsic.mapList;
21
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
22
+ * setter, so an accessor there takes the element being appended. The lists built here are the parsed
23
+ * members every format module reads its fields from. `append` defines the index. */
24
+ var _push = intrinsic.append;
16
25
  var _join = intrinsic.join;
17
26
  var _stringify = intrinsic.stringify;
18
27
  var _String = intrinsic.String;
@@ -51,7 +60,14 @@ function _hasNonWhitespace(s) {
51
60
  for (var i = 0; i < s.length; i++) { if (!_isJsWhitespace(_charCodeAt(s, i))) return true; }
52
61
  return false;
53
62
  }
54
- function _charTable(chars) { var t = []; for (var i = 0; i < chars.length; i++) t[_charCodeAt(chars, i)] = true; return t; }
63
+ /** @internal The table has NO PROTOTYPE, because it is deliberately sparse: it holds an entry for
64
+ * each character it allows and nothing at the codes it does not, and `_allCharsIn` below reads it at
65
+ * the code of each character it is asked about. Built as an array literal, every code outside the
66
+ * allowed set was a hole, so a value installed at that index on `Array.prototype` answered the
67
+ * check: measured, `Array.prototype[47] = true` made `pki.acme.keyAuthorization` accept a challenge
68
+ * token containing `/`, which the base64url set does not allow, instead of refusing it with
69
+ * `acme/bad-token`. The same helper in lib/guard-name.js has always been written this way. */
70
+ function _charTable(chars) { var t = _create(null); for (var i = 0; i < chars.length; i++) t[_charCodeAt(chars, i)] = true; return t; }
55
71
  function _allCharsIn(s, table) {
56
72
  if (s.length === 0) return false;
57
73
  for (var i = 0; i < s.length; i++) { if (!table[_charCodeAt(s, i)]) return false; }
@@ -210,7 +210,10 @@ function encode(key) {
210
210
  asn1.build.octetString(key.privateKey),
211
211
  asn1.build.explicit(0, asn1.build.oid(curveOid))];
212
212
  if (key.publicKey !== undefined && key.publicKey !== null) {
213
- kids[3] = asn1.build.explicit(1, asn1.build.bitString(key.publicKey, 0));
213
+ /** @internal Appended by defining the index. `kids` holds three own slots above, so assigning at
214
+ * index three is a store, and a store walks the prototype chain for a setter: an accessor there
215
+ * would take the public key out of the structure this encodes. */
216
+ intrinsic.append(kids, asn1.build.explicit(1, asn1.build.bitString(key.publicKey, 0)));
214
217
  }
215
218
  return asn1.build.sequence(kids);
216
219
  }
package/lib/schema-tsp.js CHANGED
@@ -43,6 +43,9 @@ var smime = require("./schema-smime");
43
43
  var cms = require("./schema-cms");
44
44
  var frameworkError = require("./framework-error");
45
45
  var guard = require("./guard-all");
46
+ /** @internal The append this module's lists are built with: `push` stores at the index and a store
47
+ * consults a setter inherited there, which takes the element being appended. */
48
+ var _push = guard.list.append;
46
49
 
47
50
  var TspError = frameworkError.TspError;
48
51
  var PemError = frameworkError.PemError;
@@ -196,7 +199,7 @@ function _namedBits(bytes) {
196
199
  if ((bytes[i >> 3] >> (7 - (i & 7))) & 1) {
197
200
  var nm = FAILURE_BITS[i];
198
201
  if (!nm) throw NS.E("tsp/bad-failinfo", "unsupported PKIFailureInfo bit " + i + " (RFC 3161 sec. 2.4.2)");
199
- out.push(nm);
202
+ _push(out, nm);
200
203
  }
201
204
  }
202
205
  return out;
package/lib/shbs.js CHANGED
@@ -24,6 +24,10 @@
24
24
  var nodeCrypto = require("crypto");
25
25
  var frameworkError = require("./framework-error");
26
26
  var guard = require("./guard-all");
27
+ /** @internal The append every list here is built with: `push` stores at the index and a store
28
+ * consults a setter inherited there, and these lists are the authentication path and the one-time
29
+ * values a hash-based signature is formed from. */
30
+ var _push = guard.list.append;
27
31
  var constants = require("./constants");
28
32
 
29
33
  var ShbsError = frameworkError.ShbsError;
@@ -124,7 +128,7 @@ function _lmotsKc(otsSet, I, q, C, y, message) {
124
128
  var a = _coef(Qc, i, w);
125
129
  var tmp = y[i];
126
130
  for (var j = a; j < (1 << w) - 1; j++) tmp = _hash(f, n, [I, qb, u16(i), u8(j), tmp]);
127
- z.push(tmp);
131
+ _push(z,tmp);
128
132
  }
129
133
  return _hash(f, n, z);
130
134
  }
@@ -148,11 +152,11 @@ function _lmsVerify(pubBytes, message, sigBytes) {
148
152
  var n = otsSet.n, p = otsSet.p;
149
153
  var C = sr.take(n);
150
154
  var y = [];
151
- for (var yi = 0; yi < p; yi++) y.push(sr.take(n));
155
+ for (var yi = 0; yi < p; yi++) _push(y,sr.take(n));
152
156
  var sigLmsType = sr.u32();
153
157
  if (sigLmsType !== lmsSet.code) return false;
154
158
  var path = [];
155
- for (var pi = 0; pi < h; pi++) path.push(sr.take(m));
159
+ for (var pi = 0; pi < h; pi++) _push(path,sr.take(m));
156
160
  if (!sr.atEnd()) throw _err("shbs/bad-signature", "LMS signature has " + sr.remaining() + " trailing byte(s)");
157
161
  if (q >= Math.pow(2, h)) return false;
158
162
 
package/lib/smime.js CHANGED
@@ -41,6 +41,10 @@ var schemaX509 = require("./schema-x509.js");
41
41
  var pkix = require("./schema-pkix.js");
42
42
  var oid = require("./oid.js");
43
43
  var guard = require("./guard-all.js");
44
+ /** @internal The append every list here is built with: `push` stores at the index and a store
45
+ * consults a setter inherited there, and these lists become the headers and parts a signed or
46
+ * encrypted message carries. */
47
+ var _push = guard.list.append;
44
48
  var pkiBuild = require("./pki-build.js");
45
49
  var C = require("./constants.js");
46
50
  var nodeUtil = require("util");
@@ -118,13 +122,13 @@ function _hpHeaderList(headers) {
118
122
  if (!h || typeof h !== "object") throw _err("smime/bad-input", "each opts.headers entry must be { name, value }");
119
123
  var name = h.name, v = h.value;
120
124
  if (typeof name !== "string") throw _err("smime/bad-input", "each opts.headers entry must be { name, value }");
121
- out.push({ name: name, value: v == null ? "" : String(v) });
125
+ _push(out,{ name: name, value: v == null ? "" : String(v) });
122
126
  });
123
127
  } else if (typeof headers === "object") {
124
128
  var hn = guard.identifier.optionNames(headers);
125
129
  for (var hi = 0; hi < hn.length; hi++) {
126
130
  var hv = headers[hn[hi]];
127
- out.push({ name: hn[hi], value: hv == null ? "" : String(hv) });
131
+ _push(out,{ name: hn[hi], value: hv == null ? "" : String(hv) });
128
132
  }
129
133
  } else {
130
134
  throw _err("smime/bad-input", "opts.headers must be an object or an array of { name, value }");
@@ -155,9 +159,9 @@ function _outerHeaderList(list, mode, hcp) {
155
159
  list.forEach(function (h) {
156
160
  if (mode === "cipher") {
157
161
  var v = _applyHcp(h.name, h.value, policy);
158
- if (v !== null) out.push({ name: h.name, value: v });
162
+ if (v !== null) _push(out,{ name: h.name, value: v });
159
163
  } else {
160
- out.push({ name: h.name, value: h.value });
164
+ _push(out,{ name: h.name, value: h.value });
161
165
  }
162
166
  });
163
167
  return out;
@@ -171,9 +175,9 @@ function _protectedInnerEntity(content, opts, mode, hpList, outerList) {
171
175
  if (cty != null && mime.hasParam(cty, "hp")) throw _err("smime/bad-input", "opts.contentType must not set the hp parameter -- header protection sets it (hp=" + guard.text.showValue(mode) + ")");
172
176
  var ct = (cty || "text/plain; charset=utf-8") + "; hp=\"" + mode + "\"";
173
177
  var fields = [{ name: "Content-Type", value: ct }, { name: "Content-Transfer-Encoding", value: _is7bit(raw) ? "7bit" : "8bit" }];
174
- hpList.forEach(function (h) { fields.push(h); });
178
+ hpList.forEach(function (h) { _push(fields,h); });
175
179
  if (mode === "cipher") {
176
- outerList.forEach(function (h) { fields.push({ name: "HP-Outer", value: h.name + ": " + h.value }); });
180
+ outerList.forEach(function (h) { _push(fields,{ name: "HP-Outer", value: h.name + ": " + h.value }); });
177
181
  }
178
182
  return mime.buildEntity(fields, raw, SmimeError, "smime/bad-header");
179
183
  }
@@ -227,7 +231,7 @@ function _contentTypeLines(s) {
227
231
  var lines = [], lineStart = 0;
228
232
  while (lineStart <= s.length) {
229
233
  var line = _contentTypeLineAt(s, lineStart);
230
- if (line !== null) lines.push(line);
234
+ if (line !== null) _push(lines,line);
231
235
  var nl = s.indexOf("\n", lineStart);
232
236
  if (nl === -1) break;
233
237
  lineStart = nl + 1;
@@ -274,11 +278,11 @@ function _extractProtected(headerList) {
274
278
  if (_isStructural(h.lname)) return;
275
279
  if (h.lname === "hp-outer") {
276
280
  var ci = h.rawValue.indexOf(":");
277
- if (ci >= 0) refouter.push({ name: h.rawValue.slice(0, ci).trim().toLowerCase(), value: h.rawValue.slice(ci + 1).trim() });
281
+ if (ci >= 0) _push(refouter,{ name: h.rawValue.slice(0, ci).trim().toLowerCase(), value: h.rawValue.slice(ci + 1).trim() });
278
282
  return;
279
283
  }
280
284
  var val = _utf8Header(h.rawValue);
281
- entries.push({ name: h.name, value: val, raw: h.rawValue });
285
+ _push(entries,{ name: h.name, value: val, raw: h.rawValue });
282
286
  if (seen[h.lname]) { dup = h.name; if (RFC5322_SINGLETON.has(h.lname)) dupSingleton = h.name; }
283
287
  seen[h.lname] = 1;
284
288
  protectedHeaders[h.name] = val;
@@ -297,7 +301,7 @@ function _computeConfidential(entries, refouter) {
297
301
  entries.forEach(function (e) {
298
302
  var m = byName.get(e.name.toLowerCase()), val = e.raw.trim(), n = (m && m.get(val)) || 0;
299
303
  if (n > 0) { m.set(val, n - 1); return; }
300
- if (!seen[e.name]) { seen[e.name] = 1; confidential.push(e.name); }
304
+ if (!seen[e.name]) { seen[e.name] = 1; _push(confidential,e.name); }
301
305
  });
302
306
  return confidential;
303
307
  }
@@ -305,7 +309,7 @@ function _computeConfidential(entries, refouter) {
305
309
  function _computeFromMismatch(innerFrom, outerEnt) {
306
310
  if (innerFrom == null) return null;
307
311
  var outerFroms = [];
308
- outerEnt.headers.forEach(function (h) { if (h.lname === "from") outerFroms.push(h.value.trim()); });
312
+ outerEnt.headers.forEach(function (h) { if (h.lname === "from") _push(outerFroms,h.value.trim()); });
309
313
  return outerFroms.length !== 1 || outerFroms[0] !== innerFrom.trim();
310
314
  }
311
315
 
@@ -315,7 +319,7 @@ function _isCryptoLayer(type) {
315
319
 
316
320
  function _outerRefouter(outerEnt) {
317
321
  var r = [];
318
- outerEnt.headers.forEach(function (h) { if (!_isStructural(h.lname) && h.lname !== "hp-outer") r.push({ name: h.lname, value: h.rawValue.trim() }); });
322
+ outerEnt.headers.forEach(function (h) { if (!_isStructural(h.lname) && h.lname !== "hp-outer") _push(r,{ name: h.lname, value: h.rawValue.trim() }); });
319
323
  return r;
320
324
  }
321
325
 
@@ -572,7 +576,7 @@ function _cmsSignOpts(opts, detached) {
572
576
  function _micName(name) { return name ? (MICALG[name] || name) : null; }
573
577
  function _micalgSet(value) {
574
578
  var seen = [];
575
- String(value).split(",").forEach(function (m) { var t = m.trim().toLowerCase(); if (t && seen.indexOf(t) < 0) seen.push(t); });
579
+ String(value).split(",").forEach(function (m) { var t = m.trim().toLowerCase(); if (t && seen.indexOf(t) < 0) _push(seen,t); });
576
580
  return seen.sort().join(",");
577
581
  }
578
582
  function _micalgOf(p7Der) {
@@ -582,7 +586,7 @@ function _micalgOf(p7Der) {
582
586
  var out = [];
583
587
  (parsed.signerInfos || []).forEach(function (si) {
584
588
  var mic = _micName(si.digestAlgorithm && si.digestAlgorithm.name);
585
- if (mic && out.indexOf(mic) < 0) out.push(mic);
589
+ if (mic && out.indexOf(mic) < 0) _push(out,mic);
586
590
  });
587
591
  return out.length ? out.sort().join(",") : null;
588
592
  }
package/lib/tlog.js CHANGED
@@ -69,9 +69,10 @@ var _strSlice = intrinsic.uncurry(String.prototype.slice);
69
69
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
70
70
  var _arrSlice = intrinsic.arraySlice;
71
71
  var _join = intrinsic.join;
72
- var _push = intrinsic.push;
72
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
73
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
74
+ var _push = intrinsic.append;
73
75
  var _pop = intrinsic.pop;
74
- var _unshift = intrinsic.unshift;
75
76
  var _bufToString = intrinsic.bufToString;
76
77
  var _bufferFrom = intrinsic.bufferFrom;
77
78
  var _byteLength = intrinsic.byteLength;
@@ -798,20 +799,25 @@ var MAX_INDEX_SEGMENTS = (function () {
798
799
  return count;
799
800
  })();
800
801
 
802
+ /** @internal The segments are counted and then APPENDED most-significant first, by defining each
803
+ * index. Prepending STORES at an index, and a store walks the prototype chain for a setter, so an
804
+ * accessor inherited at an array index took each segment and left the list reading back its getter's
805
+ * value; the `x` prefix was then applied by a read-modify-write through the same hole. These
806
+ * segments are the path a tile is requested from, so the list decides which bytes a verification
807
+ * reads. */
801
808
  function _indexPath(index) {
802
809
  var n = guard.range.uint64(index, _err, "tlog/bad-tile", "a tile index");
803
- var segments = [];
804
- var rest = n;
805
810
  var thousand = 1000n;
806
- for (;;) {
807
- var part = rest % thousand;
808
- var text = _stringOf(part);
811
+ var count = 1;
812
+ for (var probe = n / thousand; probe > 0n; probe = probe / thousand) count++;
813
+ var segments = [];
814
+ for (var k = count - 1; k >= 0; k--) {
815
+ var scale = 1n;
816
+ for (var p = 0; p < k; p++) scale = scale * thousand;
817
+ var text = _stringOf((n / scale) % thousand);
809
818
  while (text.length < TILE_SEGMENT_DIGITS) text = "0" + text;
810
- _unshift(segments, text);
811
- rest = rest / thousand;
812
- if (rest === 0n) break;
819
+ _push(segments, k === 0 ? text : "x" + text);
813
820
  }
814
- for (var i = 0; i < segments.length - 1; i++) segments[i] = "x" + segments[i];
815
821
  return _join(segments, "/");
816
822
  }
817
823
 
package/lib/tuf.js CHANGED
@@ -57,7 +57,9 @@ var _hasOwn = intrinsic.hasOwn;
57
57
  var _bufferFrom = intrinsic.bufferFrom;
58
58
  var _bufferConcat = intrinsic.bufferConcat;
59
59
  var _bufToString = intrinsic.bufToString;
60
- var _push = intrinsic.push;
60
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
61
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
62
+ var _push = intrinsic.append;
61
63
  var _strSlice = intrinsic.uncurry(String.prototype.slice);
62
64
  var _codePointAt = intrinsic.uncurry(String.prototype.codePointAt);
63
65
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
@@ -4,6 +4,9 @@
4
4
  // @internal
5
5
 
6
6
  var asn1 = require("./asn1-der");
7
+ /** @internal The append this module's list is built with: `push` stores at the index and a store
8
+ * consults a setter inherited there, which takes the element being appended. */
9
+ var _push = require("./guard-list").append;
7
10
 
8
11
  function _alGet(seqNode, tag) {
9
12
  if (!seqNode || !seqNode.children) return null;
@@ -23,7 +26,7 @@ function _purposeUnion(a, b, E, code) {
23
26
  var out = [];
24
27
  [a, b].forEach(function (list) {
25
28
  var p = _alGet(list, 1);
26
- if (p && p.children) p.children.forEach(function (c) { var v = _alInt(c, E, code); if (out.indexOf(v) === -1) out.push(v); });
29
+ if (p && p.children) p.children.forEach(function (c) { var v = _alInt(c, E, code); if (out.indexOf(v) === -1) _push(out,v); });
27
30
  });
28
31
  return out;
29
32
  }
@@ -5,6 +5,11 @@
5
5
 
6
6
  var C = require("./constants");
7
7
  var ByteReader = require("./byte-reader");
8
+ /** @internal The append every list here is built with. `push` STORES at the index and a store walks
9
+ * the prototype chain for a setter, so an accessor inherited at an array index takes the element
10
+ * being appended. Taken from `guard-list` rather than `guard-intrinsic`, since this module needs the
11
+ * one primitive and not the captures. */
12
+ var _push = require("./guard-list").append;
8
13
 
9
14
  var MAX_VECTOR_24 = 0xffffff;
10
15
  var MAX_VECTOR_16 = 0xffff;
@@ -36,7 +41,7 @@ function _extensionRecords(view, E, codes) {
36
41
  type + " (RFC 8446 sec. 4.2)");
37
42
  }
38
43
  seen[type] = true;
39
- out.push({ type: type, data: Buffer.from(data) });
44
+ _push(out,{ type: type, data: Buffer.from(data) });
40
45
  }
41
46
  return out;
42
47
  }
@@ -68,7 +73,7 @@ function certificateMessage(view, E, codes, certificateType) {
68
73
  };
69
74
  if (certificateType === "RawPublicKey") entry.spki = Buffer.from(data);
70
75
  else entry.certData = Buffer.from(data);
71
- entries.push(entry);
76
+ _push(entries,entry);
72
77
  }
73
78
  return { certificateRequestContext: Buffer.from(context), entries: entries };
74
79
  }
package/lib/webcrypto.js CHANGED
@@ -89,7 +89,9 @@ var _subarray = intrinsic.subarray;
89
89
  var _arrayBufferSlice = intrinsic.arrayBufferSlice;
90
90
  var _numberToString = intrinsic.numberToString;
91
91
  var _bigIntToString = intrinsic.bigIntToString;
92
- var _push = intrinsic.push;
92
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
93
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
94
+ var _push = intrinsic.append;
93
95
  var _concat = intrinsic.concat;
94
96
  var _resolve = intrinsic.uncurry(intrinsic.promiseResolve);
95
97
  /** @internal The promise constructor, captured at load. `promiseResolve` builds its promise from the
@@ -222,7 +224,11 @@ function CryptoKey(type, extractable, algorithm, usages, handle) {
222
224
  if (usages != null && !_isArray(usages)) {
223
225
  throw new WebCryptoError("webcrypto/syntax", "usages must be an array of key-usage strings");
224
226
  }
225
- this.usages = usages ? _arraySlice(usages) : [];
227
+ /** @internal `copyList`, not the captured `slice`. `Array.prototype.slice` builds its result
228
+ * through `ArraySpeciesCreate`, which reads the receiver's `constructor` and then its
229
+ * `Symbol.species`, so the copy of a caller's usage list ran a lookup the caller could answer.
230
+ * `copyList` defines each index on a plain array. */
231
+ this.usages = usages ? intrinsic.copyList(usages) : [];
226
232
  _defineProperty(this, "_handle", { value: handle, enumerable: false });
227
233
  }
228
234
 
@@ -647,7 +653,7 @@ function _pbkdf2Async(pw, salt, iterations, keylen, digest) {
647
653
  try { nodeCrypto.pbkdf2(pw, salt, iterations, keylen, digest, done); }
648
654
  catch (e) { done(e); }
649
655
  }
650
- if (_pbkdf2InFlight < _PBKDF2_MAX_CONCURRENT) start(); else _pbkdf2Waiters.push(start);
656
+ if (_pbkdf2InFlight < _PBKDF2_MAX_CONCURRENT) start(); else _push(_pbkdf2Waiters,start);
651
657
  });
652
658
  }
653
659