@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
package/lib/est.js CHANGED
@@ -73,6 +73,9 @@ var crmfFmt = require("./schema-crmf");
73
73
  var frameworkError = require("./framework-error");
74
74
  var guard = require("./guard-all");
75
75
  var intrinsic = require("./guard-intrinsic");
76
+ /** @internal The append every list here is built with: `push` stores at the index and a store
77
+ * consults a setter inherited there, which takes the element being appended. */
78
+ var _push = intrinsic.append;
76
79
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
77
80
  var _strSlice = intrinsic.uncurry(String.prototype.slice);
78
81
  var _toLowerCase = intrinsic.uncurry(String.prototype.toLowerCase);
@@ -423,7 +426,7 @@ function findIssuedCert(certs, target) {
423
426
 
424
427
  function _recipientKeyIds(recipientInfos, kind) {
425
428
  var ids = [];
426
- function push(v) { if (Buffer.isBuffer(v)) ids.push(v); }
429
+ function push(v) { if (Buffer.isBuffer(v)) _push(ids,v); }
427
430
  (recipientInfos || []).forEach(function (r) {
428
431
  if (kind !== "symmetric") {
429
432
  if (r.rid) push(r.rid.subjectKeyIdentifier);
@@ -439,7 +442,7 @@ function _recipientKeyIds(recipientInfos, kind) {
439
442
 
440
443
  function _recipientIssuerSerials(recipientInfos) {
441
444
  var out = [];
442
- function push(rid) { if (rid && rid.issuer && Buffer.isBuffer(rid.issuer.bytes) && rid.serialNumber != null) out.push({ issuer: rid.issuer.bytes, serialNumber: rid.serialNumber }); }
445
+ function push(rid) { if (rid && rid.issuer && Buffer.isBuffer(rid.issuer.bytes) && rid.serialNumber != null) _push(out,{ issuer: rid.issuer.bytes, serialNumber: rid.serialNumber }); }
443
446
  (recipientInfos || []).forEach(function (r) {
444
447
  push(r.rid);
445
448
  if (r.kemri) push(r.kemri.rid);
@@ -758,7 +761,7 @@ function smimeCapabilitiesAttr(capabilities) {
758
761
  if (!Array.isArray(capabilities) || capabilities.length === 0) throw E("est/bad-input", "smimeCapabilitiesAttr requires a non-empty capability list");
759
762
  var caps = capabilities.map(function (c) {
760
763
  var seq = [asn1.build.oid(c.capabilityID)];
761
- if (c.parameters !== undefined && c.parameters !== null) seq.push(Buffer.isBuffer(c.parameters) ? c.parameters : asn1.build.oid(c.parameters));
764
+ if (c.parameters !== undefined && c.parameters !== null) _push(seq,Buffer.isBuffer(c.parameters) ? c.parameters : asn1.build.oid(c.parameters));
762
765
  return asn1.build.sequence(seq);
763
766
  });
764
767
  return _attr(OID_SMIME_CAPABILITIES, [asn1.build.sequence(caps)]);
@@ -780,7 +783,7 @@ function buildEnrollAttributes(csrattrsParsed) {
780
783
  if (plan.keyType) throw E("est/ambiguous-key-type", "a non-template CsrAttrs response must carry exactly one key-type attribute (RFC 9908 sec. 3.2)");
781
784
  plan.keyType = { type: it.name, curve: it.curve || null, keySize: it.keySize || null, values: it.values || [] };
782
785
  }
783
- else plan.unhandled.push({ kind: it.kind, oid: it.oid, name: it.name });
786
+ else _push(plan.unhandled,{ kind: it.kind, oid: it.oid, name: it.name });
784
787
  }
785
788
  return plan;
786
789
  }
@@ -1217,7 +1220,7 @@ function _correlateIssued(bag, wanted, arm) {
1217
1220
  function _allMatching(bag, key) {
1218
1221
  var rest = bag.slice(), out = [], hit;
1219
1222
  while ((hit = findIssuedCert(rest, key)) !== null) {
1220
- out.push(hit);
1223
+ _push(out,hit);
1221
1224
  rest = rest.filter(function (c) { return c !== hit; });
1222
1225
  }
1223
1226
  return out;
@@ -1240,7 +1243,7 @@ function _requestedPublicKeys(der) {
1240
1243
  try {
1241
1244
  if (r.certificationRequestBytes) {
1242
1245
  var spki = csr.parse(r.certificationRequestBytes).subjectPublicKeyInfo;
1243
- if (spki && Buffer.isBuffer(spki.bytes)) out.push(spki.bytes);
1246
+ if (spki && Buffer.isBuffer(spki.bytes)) _push(out,spki.bytes);
1244
1247
  if (out.length === before) _unreadableArm();
1245
1248
  return;
1246
1249
  }
@@ -1251,7 +1254,7 @@ function _requestedPublicKeys(der) {
1251
1254
  var pk = (tmpl && tmpl.publicKey) ||
1252
1255
  (msg0 && msg0.popo && msg0.popo.poposkInput && msg0.popo.poposkInput.publicKey);
1253
1256
  var pkBytes = Buffer.isBuffer(pk) ? pk : (pk && pk.bytes);
1254
- if (Buffer.isBuffer(pkBytes)) out.push(pkBytes);
1257
+ if (Buffer.isBuffer(pkBytes)) _push(out,pkBytes);
1255
1258
  if (out.length === before) _unreadableArm();
1256
1259
  }
1257
1260
  } catch (e) {
@@ -1299,7 +1302,7 @@ function _requestBinding(der) {
1299
1302
  var paths = [];
1300
1303
  intrinsic.forEach([body.requests, body.controls, body.cmsSequence, body.otherMsgs], function (list) {
1301
1304
  (list || []).forEach(function (el) {
1302
- if (el && el.bodyPartID != null) { ids.push(el.bodyPartID); paths.push([el.bodyPartID]); }
1305
+ if (el && el.bodyPartID != null) { _push(ids,el.bodyPartID); _push(paths,[el.bodyPartID]); }
1303
1306
  });
1304
1307
  });
1305
1308
  _collectNestedPaths(body.cmsSequence, [], paths, 0);
@@ -1344,7 +1347,7 @@ function _collectNestedPaths(list, prefix, out, depth) {
1344
1347
  if (!inner || inner.kind !== "pkiData") return;
1345
1348
  var path = prefix.concat([el.bodyPartID]);
1346
1349
  intrinsic.forEach([inner.requests, inner.controls, inner.cmsSequence, inner.otherMsgs], function (l) {
1347
- (l || []).forEach(function (e2) { if (e2 && e2.bodyPartID != null) out.push(path.concat([e2.bodyPartID])); });
1350
+ (l || []).forEach(function (e2) { if (e2 && e2.bodyPartID != null) _push(out,path.concat([e2.bodyPartID])); });
1348
1351
  });
1349
1352
  _collectNestedPaths(inner.cmsSequence, path, out, depth + 1);
1350
1353
  });
@@ -446,7 +446,11 @@ function _deep(v, ErrorClass, code, label, cap, depth, collect, work) {
446
446
  var element;
447
447
  try { element = v[k]; }
448
448
  catch (e) { throw _raise(ErrorClass, code, label + ": reading element " + k + " threw", e); }
449
- arr[k] = _deep(element, ErrorClass, code, label, cap, depth + 1, collect, work);
449
+ /** @internal The copy's slot is DEFINED, not stored at. The indices walked here are the ones
450
+ * the source holds of its own, so they can skip: a store at an index this copy has no own
451
+ * property at walks the prototype chain for a setter, which would take the copied element at
452
+ * the toolkit's own door for caller byte structures. */
453
+ _defineProperty(arr, k, { value: _deep(element, ErrorClass, code, label, cap, depth + 1, collect, work), writable: true, enumerable: true, configurable: true });
450
454
  });
451
455
  arr.length = vCount;
452
456
  _copyNamed(v, arr, ErrorClass, code, label, cap, depth, collect, work);
package/lib/guard-der.js CHANGED
@@ -9,6 +9,7 @@ var _sizeOf = require("./guard-intrinsic").sizeOf;
9
9
  var _create = require("./guard-intrinsic").create;
10
10
  var _isBuffer = require("./guard-intrinsic").isBuffer;
11
11
  var _isArray = require("./guard-intrinsic").isArray;
12
+ var _append = require("./guard-intrinsic").append;
12
13
 
13
14
  var asn1 = null;
14
15
  function _asn1() { if (asn1 === null) asn1 = require("./asn1-der"); return asn1; }
@@ -117,7 +118,11 @@ function _element(node, E, code, label) {
117
118
  throw E(code, label + " of universal constructed type " + tag + " has no strict DER structure validator here");
118
119
  }
119
120
  var n = kids.length, members = [];
120
- for (var i = 0; i < n; i++) members[i] = _element(kids[i], E, code, label);
121
+ /** @internal Appended by defining the index. A store at an index the list has no own property at
122
+ * consults a setter inherited from the array prototype, and the SET ordering below is checked
123
+ * over this list, so a member read back through such a hole is one the canonical-order check
124
+ * never saw. */
125
+ for (var i = 0; i < n; i++) _append(members, _element(kids[i], E, code, label));
121
126
  if (cls === "universal" && tag === C.SET && !setOrderOk(members)) {
122
127
  throw E(code, label + " has a SET whose members are in no canonical DER order (X.690 sec. 11.6 / X.680 sec. 8.6)");
123
128
  }
@@ -528,14 +528,24 @@ var _arrSort = uncurry(Array.prototype.sort);
528
528
  var _arrConcat = uncurry(Array.prototype.concat);
529
529
  var _arrSlice = uncurry(Array.prototype.slice);
530
530
  var _arrJoin = uncurry(Array.prototype.join);
531
- var _arrPush = uncurry(Array.prototype.push);
531
+ /** @internal `push` is NOT captured and NOT offered. Capturing it closes who `push` is, not what
532
+ * `push` DOES: it STORES at the index, and a store walks the prototype chain for a setter, so an
533
+ * accessor installed at an array index receives each element as it is appended and can define
534
+ * something else in its place. Measured through `pki.asn1.read.oid`: the content octets of `1.2.3`
535
+ * rendered `0.1.3` through a captured push. `append` below defines the index on the array itself,
536
+ * and `concatList` / `copyList` / `selectList` / `mapList` build their results the same way. With
537
+ * nothing to reach for, no module in lib/ can take the storing form. */
532
538
  /** @internal The mutators. A list is what a rule is enforced over, so an operation that drops or moves
533
539
  * an element decides whether the rule reaches it: a replaced `pop` that popped twice took a signed
534
540
  * note's last signature line away with the empty tail element, and the forged signature on that line
535
541
  * was never checked. */
542
+ /** @internal `unshift` is absent for the reason `push` is: it GROWS the list, so it stores at an
543
+ * index the array has no own property at, and a store walks the prototype chain for a setter. The
544
+ * mutators kept below move or drop elements that already have own slots, which reaches no accessor
545
+ * on a list this toolkit built by defining. A module prepending to a list counts its elements and
546
+ * appends them in order instead; `encodeLength` and `intToDer` in lib/asn1-der.js are the pattern. */
536
547
  var _arrPop = uncurry(Array.prototype.pop);
537
548
  var _arrShift = uncurry(Array.prototype.shift);
538
- var _arrUnshift = uncurry(Array.prototype.unshift);
539
549
  var _arrSplice = uncurry(Array.prototype.splice);
540
550
  var _arrReverse = uncurry(Array.prototype.reverse);
541
551
 
@@ -706,10 +716,8 @@ module.exports = Object.freeze({
706
716
  min: _mathMin,
707
717
  max: _mathMax,
708
718
  parseInt: _parseInt,
709
- push: _arrPush,
710
719
  pop: _arrPop,
711
720
  shift: _arrShift,
712
- unshift: _arrUnshift,
713
721
  splice: _arrSplice,
714
722
  reverse: _arrReverse,
715
723
  toUpperCase: _strToUpperCase,
package/lib/guard-list.js CHANGED
@@ -8,6 +8,7 @@ var _defineProperty = require("./guard-intrinsic").defineProperty;
8
8
  var _isArray = require("./guard-intrinsic").isArray;
9
9
  var _arrSort = require("./guard-intrinsic").sort;
10
10
  var _isSafeInteger = require("./guard-intrinsic").isSafeInteger;
11
+ var _hasOwn = require("./guard-intrinsic").hasOwn;
11
12
 
12
13
  var MAX_ARRAY_LENGTH = 4294967295;
13
14
 
@@ -76,6 +77,67 @@ function allMatch(list, predicate) {
76
77
  return true;
77
78
  }
78
79
 
80
+ /** @internal The first element a predicate selects, or null. Written as `list.filter(p)[0]`, the
81
+ * selection is a fresh array that is empty when nothing matched, and reading index 0 of an empty
82
+ * array answers from the array prototype: an accessor there becomes the selected element in a
83
+ * selection that selected nothing, which reads at every call site as "found one". `filter` also
84
+ * builds its result through the receiver's `Symbol.species`, so the array indexed is not necessarily
85
+ * one this toolkit made. This walks the own indexes and returns null when nothing matched, so a
86
+ * caller's `if (!found)` test answers for the list rather than for the prototype.
87
+ *
88
+ * @enforced-by behavioral -- `filter(...)[0]` has no rename-proof shape of its own beyond the method
89
+ * name, which the captured-operation budget already counts; the RED vectors are the empty-selection
90
+ * ones each consumer carries (a signedAttrs with no message-digest attribute, a certificate with no
91
+ * subject key identifier).
92
+ */
93
+ function firstMatch(list, predicate) {
94
+ if (!list) return null;
95
+ for (var i = 0, n = _count(list, "firstMatch"); i < n; i++) {
96
+ if (!_hasOwn(list, i)) continue;
97
+ /** @internal One read of the element, tested and returned. Read again after the predicate, an
98
+ * own accessor at the index answers the test with one value and the caller with another, and a
99
+ * getter that deletes its own slot leaves the second read falling through to the prototype. */
100
+ var element = list[i];
101
+ if (predicate(element, i)) return element;
102
+ }
103
+ return null;
104
+ }
105
+
106
+ /** @internal Remove the element at `index`, shifting the ones after it down by defining each slot
107
+ * and then truncating through the array's own `length`. `splice` is the ordinary way to write this
108
+ * and it is not usable here: it returns the removed elements, so it builds that result through
109
+ * `ArraySpeciesCreate`, which reads the receiver's `constructor` and then its `Symbol.species`. A
110
+ * getter installed on `Array.prototype.constructor` receives the real array as its `this`, which
111
+ * hands caller code a reference to the list being edited and to every record in it, in the middle of
112
+ * the edit. Nothing is returned here, so nothing is constructed.
113
+ *
114
+ * @enforced-by behavioral -- `splice(i, 1)` has no rename-proof shape beyond the method name, which
115
+ * the captured-operation budget counts; the RED vector is the policy-node removal driven with a
116
+ * `constructor` getter installed.
117
+ */
118
+ function removeAt(list, index) {
119
+ if (!_isArray(list)) throw new TypeError("guard.list.removeAt: the receiver must be an array");
120
+ var n = _count(list, "removeAt");
121
+ if (!_isSafeInteger(index) || index < 0 || index >= n) {
122
+ throw new RangeError("guard.list.removeAt: the index must be a position the array holds");
123
+ }
124
+ /** @internal A hole stays a hole, and is never read through. `splice` leaves an absent element
125
+ * absent, so a shift that defined every slot would turn one into an own `undefined`; and reading
126
+ * `list[i + 1]` at a hole answers from the prototype, which is the value this family exists to
127
+ * keep out. Each source slot is tested for own-ness once and read once. */
128
+ for (var i = index; i < n - 1; i++) {
129
+ if (_hasOwn(list, i + 1)) {
130
+ _defineProperty(list, i, { value: list[i + 1], writable: true, enumerable: true, configurable: true });
131
+ } else if (_hasOwn(list, i)) {
132
+ delete list[i];
133
+ }
134
+ }
135
+ /** @internal `length` is an array's own writable property, so assigning it consults no prototype
136
+ * and the assignment deletes the tail slot the shift left behind. */
137
+ list.length = n - 1;
138
+ return list;
139
+ }
140
+
79
141
  // @enforced-by caller-array-copied-live
80
142
  function snapshot(list) {
81
143
  if (!_isArray(list)) throw new TypeError("guard.list.snapshot: the receiver must be an array");
@@ -132,6 +194,8 @@ module.exports = _freeze({
132
194
  containsAll: containsAll,
133
195
  anyMatches: anyMatches,
134
196
  allMatch: allMatch,
197
+ firstMatch: firstMatch,
198
+ removeAt: removeAt,
135
199
  snapshot: snapshot,
136
200
  copyMap: copyMap,
137
201
  });
package/lib/guard-name.js CHANGED
@@ -177,7 +177,7 @@ function _reduceDpn(d, E, code, label) {
177
177
  for (var i = 0; i < len; i++) {
178
178
  var n = ownValue(names, i);
179
179
  if (!_isBuffer(n)) throw refuse("every fullName GeneralName must be its encoded bytes");
180
- taken[i] = n;
180
+ _append(taken, n);
181
181
  }
182
182
  return { kind: kind, names: taken };
183
183
  }
package/lib/hpke.js CHANGED
@@ -47,7 +47,10 @@ var oid = require("./oid");
47
47
  var _hasOwn = intrinsic.hasOwn;
48
48
  var _isBuffer = intrinsic.isBuffer, _bufferFrom = intrinsic.bufferFrom, _bufferAlloc = intrinsic.bufferAlloc;
49
49
  var _bufferConcat = intrinsic.bufferConcat, _bufferEquals = intrinsic.bufferEquals, _compare = intrinsic.compare;
50
- var _push = intrinsic.push;
50
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
51
+ * setter, so an accessor there takes the element being appended. The lists here become the byte
52
+ * strings a KEM's key schedule is computed over. `append` defines the index. */
53
+ var _push = intrinsic.append;
51
54
  var _subarray = intrinsic.subarray;
52
55
 
53
56
  var HpkeError = frameworkError.HpkeError;
@@ -76,7 +79,10 @@ function _pushPrefixed(parts, b, what) {
76
79
  throw _err("hpke/input-length", what + " is " + b.length + " bytes; a single-stage KDF accepts at " +
77
80
  "most " + MAX_PREFIXED + " (draft-ietf-hpke-hpke-05 sec. 7.2.1)");
78
81
  }
79
- _push(parts, i2osp(b.length, 2), b);
82
+ /** @internal Two appends, because `append` takes one value where `push` took many: the length
83
+ * prefix and the value it measures are both part of the byte string a KDF reads. */
84
+ _push(parts, i2osp(b.length, 2));
85
+ _push(parts, b);
80
86
  return parts;
81
87
  }
82
88
  /** @internal Through the capture, which is the whole point of this helper existing: every
@@ -346,7 +352,8 @@ function _derive(xof, input, outLen) {
346
352
  function _labeledDerive(xof, suiteId, ikm, label, context, outLen) {
347
353
  var lab = _bufferFrom(label, "latin1");
348
354
  var parts = _pushPrefixed([ikm, HPKE_V1, suiteId], lab, "a derive label");
349
- _push(parts, i2osp(outLen, 2), context);
355
+ _push(parts, i2osp(outLen, 2));
356
+ _push(parts, context);
350
357
  var labeledIkm = concat(parts);
351
358
  try { return _derive(xof, labeledIkm, outLen); }
352
359
  finally { guard.secret.zeroize(labeledIkm, HpkeError, "hpke/bad-input", "the labeled derive input"); }
@@ -128,7 +128,10 @@ var _toLowerCase = intrinsic.toLowerCase;
128
128
  var _fromCharCode = intrinsic.fromCharCode;
129
129
  var _isArray = intrinsic.isArray;
130
130
  var _arrIndexOf = intrinsic.indexOf;
131
- var _arrPush = intrinsic.push;
131
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
132
+ * setter, so an accessor there takes the element being appended, and this list is the peer chain a
133
+ * caller reads. `append` defines the index. */
134
+ var _arrPush = intrinsic.append;
132
135
  var _arrForEach = intrinsic.forEach;
133
136
  var _isBuffer = intrinsic.isBuffer;
134
137
  var _bufferFrom = intrinsic.bufferFrom;
@@ -348,7 +351,10 @@ function _makeGuardedLookup(lookupFn) {
348
351
  var entry = address[i];
349
352
  var one = { address: entry && entry.address, family: entry && entry.family };
350
353
  if (_isBlockedIp(one.address)) return callback(_blockedAddrErr(hostname, one.address));
351
- checked[i] = one;
354
+ /** @internal Appended by defining the index. Stored at, the store walks the prototype chain
355
+ * for a setter, so an accessor there took the checked entry and node read the address it
356
+ * connects to back from the getter instead: an address this check never saw. */
357
+ _arrPush(checked, one);
352
358
  }
353
359
  return callback(null, checked);
354
360
  }
@@ -448,7 +454,10 @@ function snapshotProxy(p) {
448
454
  var a = p.tls.anchors;
449
455
  if (_copyableArray(a)) {
450
456
  var copied = [];
451
- for (var i = 0; i < a.length; i++) copied[i] = _copyAnchor(a[i]);
457
+ /** @internal Appended by defining the index, for the reason the address list above is: these
458
+ * are the trust anchors the handshake runs under, and a store consults a setter inherited at
459
+ * the index. */
460
+ for (var i = 0; i < a.length; i++) _arrPush(copied, _copyAnchor(a[i]));
452
461
  out.tls.anchors = copied;
453
462
  } else if (typeof a === "string") out.tls.anchors = a;
454
463
  else if (a !== null && typeof a === "object" && !nodeUtil.types.isProxy(a) && _isBuffer(a)) out.tls.anchors = _bufferFrom(a);
package/lib/inspect.js CHANGED
@@ -1158,7 +1158,11 @@ function _joinAnd(list) {
1158
1158
  * door can validate to arbitrary depth, so a report must not fault on any shape it is handed. */
1159
1159
  function _list(v) { return Array.isArray(v) ? v : []; }
1160
1160
  /** @internal The same for a member a loop body dereferences. */
1161
- function _obj(v) { return (v !== null && typeof v === "object") ? v : {}; }
1161
+ /** @internal The stand-in for a value that is not a record has NO PROTOTYPE. Written as `{}`, it
1162
+ * inherits `Object.prototype`, so a field read off it answers with whatever a name planted there
1163
+ * holds and a report prints a value its subject does not carry. */
1164
+ var _EMPTY_RECORD = Object.create(null);
1165
+ function _obj(v) { return (v !== null && typeof v === "object") ? v : _EMPTY_RECORD; }
1162
1166
 
1163
1167
  /** @internal A serial reads the same wherever a report carries one, through the certificate report's own
1164
1168
  * presentation: small values as decimal with the hex beside them, long ones as wrapped colon-hex. Printed
@@ -1327,7 +1331,11 @@ function _someSignerUnmatched(signed) {
1327
1331
  }
1328
1332
  function _certMatchesSid(cert, sid) {
1329
1333
  if (Buffer.isBuffer(sid.subjectKeyIdentifier)) {
1330
- var ski = _list(cert.extensions).filter(function (e) { return _obj(e).oid === OID_SUBJECT_KEY_ID; })[0];
1334
+ /** @internal The selection returns the first matching row or null. `filter(...)[0]` indexes a
1335
+ * result that is EMPTY when the certificate carries no key identifier, and index 0 of an empty
1336
+ * array answers from the array prototype, which would report a signer match for a certificate
1337
+ * that carries nothing to match on. */
1338
+ var ski = guard.list.firstMatch(_list(cert.extensions), function (e) { return _obj(e).oid === OID_SUBJECT_KEY_ID; });
1331
1339
  if (!ski) return false;
1332
1340
  // allow:swallow-unverified drop-silent display fallback: an unreadable key id matches nothing
1333
1341
  try { return asn1.read.octetString(asn1.decode(_obj(ski).value)).equals(sid.subjectKeyIdentifier); }
package/lib/jose.js CHANGED
@@ -54,7 +54,9 @@ var _isBuffer = intrinsic.isBuffer;
54
54
  var _bufferFrom = intrinsic.bufferFrom;
55
55
  var _stringify = intrinsic.stringify;
56
56
  var _ObjectProto = intrinsic.ObjectProto;
57
- var _push = intrinsic.uncurry(Array.prototype.push);
57
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
58
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
59
+ var _push = intrinsic.append;
58
60
  var _join = intrinsic.join;
59
61
  var _map = intrinsic.map;
60
62
  var _bufToString = intrinsic.uncurry(Buffer.prototype.toString);