@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/mime.js CHANGED
@@ -18,6 +18,10 @@
18
18
 
19
19
  var C = require("./constants.js");
20
20
  var guard = require("./guard-all.js");
21
+ /** @internal The append every list here is built with: `push` stores at the index and a store
22
+ * consults a setter inherited there, and these lists become the headers and parts of a message
23
+ * body a signature is computed over. */
24
+ var _push = guard.list.append;
21
25
 
22
26
  var CRLF = Buffer.from("\r\n");
23
27
 
@@ -60,7 +64,7 @@ function _unfoldHeaders(headerText) {
60
64
  var ln = lines[i];
61
65
  if (ln === "") continue;
62
66
  if ((ln[0] === " " || ln[0] === "\t") && out.length) out[out.length - 1] += " " + _stripLeadingHtab(ln);
63
- else out.push(ln);
67
+ else _push(out,ln);
64
68
  }
65
69
  return out;
66
70
  }
@@ -103,10 +107,10 @@ function _splitSemicolons(s) {
103
107
  else if (ch === '"' && depth === 0) { inQ = !inQ; cur += ch; }
104
108
  else if (ch === "(" && !inQ) { depth++; cur += ch; }
105
109
  else if (ch === ")" && !inQ && depth > 0) { depth--; cur += ch; }
106
- else if (ch === ";" && !inQ && depth === 0) { out.push(cur); cur = ""; }
110
+ else if (ch === ";" && !inQ && depth === 0) { _push(out,cur); cur = ""; }
107
111
  else cur += ch;
108
112
  }
109
- out.push(cur);
113
+ _push(out,cur);
110
114
  return out;
111
115
  }
112
116
 
@@ -124,7 +128,7 @@ function parse(input, E, code) {
124
128
  if (colon < 0) throw new E(code, "a MIME header line has no colon: " + JSON.stringify(rawHeaders[i].slice(0, 40)));
125
129
  var nm = rawHeaders[i].slice(0, colon).trim();
126
130
  var body = rawHeaders[i].slice(colon + 1);
127
- headers.push({ name: nm, lname: nm.toLowerCase(), value: body.trim(), rawValue: body.charAt(0) === " " ? body.slice(1) : body });
131
+ _push(headers,{ name: nm, lname: nm.toLowerCase(), value: body.trim(), rawValue: body.charAt(0) === " " ? body.slice(1) : body });
128
132
  }
129
133
  function header(name) { var l = name.toLowerCase(); for (var j = 0; j < headers.length; j++) if (headers[j].lname === l) return headers[j].value; return null; }
130
134
  var ctv = header("content-type");
@@ -160,7 +164,7 @@ function splitMultipart(bodyBytes, boundary, E, code) {
160
164
  var partEnd = next;
161
165
  if (partEnd >= 2 && body[partEnd - 2] === 0x0d && body[partEnd - 1] === 0x0a) partEnd -= 2;
162
166
  else if (partEnd >= 1 && body[partEnd - 1] === 0x0a) partEnd -= 1;
163
- parts.push(body.subarray(pos, partEnd));
167
+ _push(parts,body.subarray(pos, partEnd));
164
168
  var afterDelim = next + delim.length;
165
169
  if (body[afterDelim] === 0x2d && body[afterDelim + 1] === 0x2d) break;
166
170
  pos = _afterLine(body, afterDelim, E, code);
package/lib/ocsp.js CHANGED
@@ -51,6 +51,9 @@ var ocspRequestVerify = require("./ocsp-request-verify");
51
51
  var webcrypto = require("./webcrypto");
52
52
  var subtle = webcrypto.webcrypto.subtle;
53
53
  var guard = require("./guard-all");
54
+ /** @internal The append every list here is built with: `push` stores at the index and a store
55
+ * consults a setter inherited there, and these lists become a signed request or response. */
56
+ var _push = guard.list.append;
54
57
  var constants = require("./constants");
55
58
  var frameworkError = require("./framework-error");
56
59
  var E = _err;
@@ -230,7 +233,7 @@ function _buildRequest(query, opts) {
230
233
  var singles = pkiBuild.reqDenseArray(q.singleRequestExtensions, "singleRequestExtensions", _err, "ocsp/bad-input");
231
234
  if (singles.length) {
232
235
  if (lightweight) throw _err("ocsp/bad-input", "the lightweight profile permits no singleRequestExtensions (RFC 5019 sec. 2.1.1)");
233
- reqChildren.push(b.explicit(0, b.sequence(singles)));
236
+ _push(reqChildren,b.explicit(0, b.sequence(singles)));
234
237
  }
235
238
  }
236
239
  return b.sequence(reqChildren);
@@ -238,15 +241,15 @@ function _buildRequest(query, opts) {
238
241
  }));
239
242
  return _ocspIntrinsic.chain(builtRequests, function (requests) {
240
243
  var tbsChildren = [];
241
- if (requestorNameDer !== null) tbsChildren.push(b.explicit(1, b.contextConstructed(4, requestorNameDer)));
242
- tbsChildren.push(b.sequence(requests));
244
+ if (requestorNameDer !== null) _push(tbsChildren,b.explicit(1, b.contextConstructed(4, requestorNameDer)));
245
+ _push(tbsChildren,b.sequence(requests));
243
246
  var reqExts = [];
244
247
  if (opts.nonce) {
245
248
  var nonceBytes = opts.nonce === true ? nodeCrypto.randomBytes(32) : opts.nonce;
246
249
  _assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
247
- reqExts.push(_nonceExt(nonceBytes));
250
+ _push(reqExts,_nonceExt(nonceBytes));
248
251
  }
249
- if (reqExts.length) tbsChildren.push(b.explicit(2, b.sequence(reqExts)));
252
+ if (reqExts.length) _push(tbsChildren,b.explicit(2, b.sequence(reqExts)));
250
253
  var tbsRequest = b.sequence(tbsChildren);
251
254
  if (signerCert === null) return _emitReq(b.sequence([tbsRequest]), opts);
252
255
  var scheme = signScheme.resolveSignScheme(signerCert, { combinedRsaSig: true }, true, _signE);
@@ -389,9 +392,9 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
389
392
  }
390
393
  var rdChildren = [ridNode, b.generalizedTime(_asEncodableDate(responseData.producedAt, "producedAt") || new Date()), b.sequence(srNodes)];
391
394
  var respExts = [];
392
- if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); respExts.push(_nonceExt(opts.nonce)); }
393
- if (opts.extendedRevoke || anyNonIssued) respExts.push(b.sequence([b.oid(OID_EXTENDED_REVOKE), b.octetString(b.nullValue())]));
394
- if (respExts.length) rdChildren.push(b.explicit(1, b.sequence(respExts)));
395
+ if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); _push(respExts,_nonceExt(opts.nonce)); }
396
+ if (opts.extendedRevoke || anyNonIssued) _push(respExts,b.sequence([b.oid(OID_EXTENDED_REVOKE), b.octetString(b.nullValue())]));
397
+ if (respExts.length) _push(rdChildren,b.explicit(1, b.sequence(respExts)));
395
398
  var responseDataDer = b.sequence(rdChildren);
396
399
  var scheme = signScheme.resolveSignScheme(respCert, { combinedRsaSig: true }, true, _signE);
397
400
  return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE), function (sig) {
@@ -401,7 +404,7 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
401
404
  var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(responseDataDer, sig, respCert.subjectPublicKeyInfo.bytes, scheme));
402
405
  return _ocspIntrinsic.chain(selfChecked, function () {
403
406
  var basicChildren = [responseDataDer, scheme.sigAlgId, b.bitString(sig, 0)];
404
- if (opts.embedCert !== false) basicChildren.push(b.explicit(0, b.sequence([b.raw(respCertDer)])));
407
+ if (opts.embedCert !== false) _push(basicChildren,b.explicit(0, b.sequence([b.raw(respCertDer)])));
405
408
  var responseBytes = b.sequence([b.oid(OID_OCSP_BASIC), b.octetString(b.sequence(basicChildren))]);
406
409
  var der = b.sequence([b.enumerated(0n), b.explicit(0, responseBytes)]);
407
410
  return opts.pem ? ocspSchema.pemEncode(der, "OCSP RESPONSE") : der;
@@ -426,7 +429,7 @@ function _asEncodableDate(d, which) {
426
429
  function _snapshotSignerKey(key, owned) {
427
430
  if (Buffer.isBuffer(key) || key instanceof Uint8Array) { // allow:byte-source-narrow -- responder private key on the key-ownership contract (Buffer / Uint8Array / PEM / CryptoKey); widening keys is a separate root decision
428
431
  var copy = guard.bytes.snapshot(key, OcspError, "ocsp/bad-input", "the responder key");
429
- owned.push(copy);
432
+ _push(owned,copy);
430
433
  return copy;
431
434
  }
432
435
  if (key && typeof key === "object" && (key.mldsa != null || key.trad != null)) {
@@ -482,10 +485,10 @@ function _buildSingleResponse(r, opts) {
482
485
  var statusNode = _certStatusNode(r.status, opts);
483
486
  var nonIssued = _isNonIssuedStatus(r.status);
484
487
  var srChildren = [certID, statusNode, b.generalizedTime(thisUpdate)];
485
- if (nextUpdate !== null) srChildren.push(b.explicit(0, b.generalizedTime(nextUpdate)));
488
+ if (nextUpdate !== null) _push(srChildren,b.explicit(0, b.generalizedTime(nextUpdate)));
486
489
  if (r.singleExtensions != null) {
487
490
  var singleDer = _singleExtensionsDer(r.singleExtensions, nonIssued);
488
- if (singleDer.length) srChildren.push(b.explicit(1, b.sequence(singleDer)));
491
+ if (singleDer.length) _push(srChildren,b.explicit(1, b.sequence(singleDer)));
489
492
  }
490
493
  return { node: b.sequence(srChildren), nonIssued: nonIssued };
491
494
  });
@@ -558,7 +561,7 @@ function _singleExtensionsDer(spec, nonIssued) {
558
561
  var out = [];
559
562
  if (spec.archiveCutoff != null) {
560
563
  guard.time.assertEncodable(spec.archiveCutoff, _err, "ocsp/bad-input", "singleExtensions archiveCutoff");
561
- out.push(b.sequence([b.oid(oid.byName("ocspArchiveCutoff")), b.octetString(b.generalizedTime(spec.archiveCutoff))]));
564
+ _push(out,b.sequence([b.oid(oid.byName("ocspArchiveCutoff")), b.octetString(b.generalizedTime(spec.archiveCutoff))]));
562
565
  }
563
566
  if (spec.crlReferences != null) {
564
567
  if (nonIssued) throw _err("ocsp/bad-input", NON_ISSUED_FORBIDDEN);
@@ -575,18 +578,18 @@ function _singleExtensionsDer(spec, nonIssued) {
575
578
  for (var j = 0; j < c.crlUrl.length; j++) {
576
579
  if (c.crlUrl.charCodeAt(j) > 0x7f) throw _err("ocsp/bad-input", "crlReferences crlUrl must be 7-bit ASCII (an IA5String, RFC 6960 sec. 4.4.2)");
577
580
  }
578
- fields.push(b.explicit(0, b.ia5(c.crlUrl)));
581
+ _push(fields,b.explicit(0, b.ia5(c.crlUrl)));
579
582
  }
580
583
  if (c.crlNum != null) {
581
584
  var num = guard.range.authoredInteger(c.crlNum, _err, "ocsp/bad-input", "crlReferences crlNum");
582
585
  if (num < 0n) throw _err("ocsp/bad-input", "crlReferences crlNum must be non-negative (it is a cRLNumber, RFC 5280 sec. 5.2.3)");
583
- fields.push(b.explicit(1, b.integer(num)));
586
+ _push(fields,b.explicit(1, b.integer(num)));
584
587
  }
585
588
  if (c.crlTime != null) {
586
589
  guard.time.assertEncodable(c.crlTime, _err, "ocsp/bad-input", "crlReferences crlTime");
587
- fields.push(b.explicit(2, b.generalizedTime(c.crlTime)));
590
+ _push(fields,b.explicit(2, b.generalizedTime(c.crlTime)));
588
591
  }
589
- out.push(b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
592
+ _push(out,b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
590
593
  }
591
594
  return out;
592
595
  }
@@ -600,7 +603,7 @@ function _certStatusNode(status, opts) {
600
603
  if (status.revocationReason != null) {
601
604
  var code = typeof status.revocationReason === "number" ? status.revocationReason : REASON_CODE[guard.text.keyOf(status.revocationReason)];
602
605
  if (code == null) throw _err("ocsp/bad-input", "unknown revocationReason " + guard.text.showValue(status.revocationReason));
603
- ri.push(b.explicit(0, b.enumerated(BigInt(code))));
606
+ _push(ri,b.explicit(0, b.enumerated(BigInt(code))));
604
607
  }
605
608
  return b.contextConstructed(1, Buffer.concat(ri));
606
609
  }
@@ -744,14 +747,14 @@ function _reqVerdict(parsed, extra) {
744
747
  async function _findRequestSigners(candidates, strict, parsed, sig, sigBits) {
745
748
  var parsedList = [];
746
749
  for (var i = 0; i < candidates.length; i++) {
747
- try { parsedList.push({ der: candidates[i], cert: x509.parse(candidates[i]) }); }
750
+ try { _push(parsedList,{ der: candidates[i], cert: x509.parse(candidates[i]) }); }
748
751
  catch (e) { if (strict) throw _err("ocsp/bad-signer-cert", "an opts.certs entry does not parse as an X.509 certificate", e); }
749
752
  }
750
753
  var parseable = parsedList.map(function (p) { return p.der; });
751
754
  var matches = [];
752
755
  for (var j = 0; j < parsedList.length; j++) {
753
756
  if (await ocspRequestVerify.verifyRequestSignature(sig.signatureAlgorithm, sigBits, parsedList[j].cert.subjectPublicKeyInfo.bytes, parsed.tbsRequestBytes)) {
754
- matches.push({ der: parsedList[j].der, subject: parsedList[j].cert.subject });
757
+ _push(matches,{ der: parsedList[j].der, subject: parsedList[j].cert.subject });
755
758
  }
756
759
  }
757
760
  return { matches: matches, parseable: parseable };
@@ -770,7 +773,7 @@ function _requestorNamed(parsed, matches) {
770
773
  if (!rn.value.rdns.length) return { named: [], reason: "the signed OCSP request's requestorName is an empty distinguished name, which names nobody (RFC 6960 sec. 4.1.2)" };
771
774
  var named = [];
772
775
  for (var i = 0; i < matches.length; i++) {
773
- if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) named.push(matches[i]);
776
+ if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) _push(named,matches[i]);
774
777
  }
775
778
  if (named.length) return { named: named, reason: null };
776
779
  return { named: [], reason: "the requestorName " + guard.text.showValue(rn.value.dn) + " is not the subject of a certificate that signed the request (RFC 6960 sec. 4.1.2)" };
@@ -866,7 +869,7 @@ async function verifyRequest(request, opts) {
866
869
  var suppliedCerts = [];
867
870
  if (opts.certs != null) {
868
871
  var list = pkiBuild.reqDenseArray(opts.certs, "opts.certs", _err, "ocsp/bad-input");
869
- for (var i = 0; i < list.length; i++) suppliedCerts.push(_normCertDer(list[i], "an opts.certs entry"));
872
+ for (var i = 0; i < list.length; i++) _push(suppliedCerts,_normCertDer(list[i], "an opts.certs entry"));
870
873
  }
871
874
  if (!suppliedCerts.length) {
872
875
  return _reqVerdict(parsed, { signed: true, signatureValid: false,
@@ -57,7 +57,6 @@ var guard = require("./guard-all");
57
57
  var intrinsic = require("./guard-intrinsic");
58
58
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
59
59
  var _pop = intrinsic.pop;
60
- var _splice = intrinsic.splice;
61
60
  var _strSlice = intrinsic.uncurry(String.prototype.slice);
62
61
  var _strIndexOf = intrinsic.uncurry(String.prototype.indexOf);
63
62
  /** @internal The case fold a name constraint is compared under. Read off the live prototype, it is
@@ -761,9 +760,17 @@ function absorbNameConstraints(state, decoded) {
761
760
  * `state.policyIndex[depth]` maps a policy identifier to the one node at that depth, so the "is there
762
761
  * already a node here for this policy" question every step asks is a lookup rather than a walk.
763
762
  */
763
+ /** @internal The predicate for "the first element this list holds", so a selection reads one slot
764
+ * once rather than testing it and then reading it. */
765
+ function _anyElement() { return true; }
764
766
  function graphRoot() {
765
767
  return { depth: 0, validPolicy: OID.anyPolicy, qualifierSet: [], expectedPolicySet: [OID.anyPolicy], children: [], parents: [] };
766
768
  }
769
+ /** @internal `policyIndex` has NO PROTOTYPE, because it is keyed by depth and holds nothing at a
770
+ * depth no node has been placed at yet. Held in an array, every such depth was a hole: reading one
771
+ * answered from the array prototype, so a value installed at an index was taken for the layer at
772
+ * that depth and the lookups below read their nodes, and the expected policy sets those nodes carry,
773
+ * out of it. Creating the layer was a store at the same index, which runs an inherited setter. */
767
774
  function policyLayer(state, depth) {
768
775
  var layer = state.policyIndex[depth];
769
776
  if (layer === undefined) { layer = intrinsic.create(null); state.policyIndex[depth] = layer; }
@@ -805,13 +812,20 @@ function removePolicyNode(state, node) {
805
812
  /** @internal The unlinking walks come from the captures. Removing a node is how a policy stops
806
813
  * being valid for the chain, so a walk that skips an edge leaves the node reachable and the policy
807
814
  * still counted after the step that disqualified it. */
815
+ /** @internal The removal goes through `guard.list.removeAt`, not `splice`. `splice` RETURNS what it
816
+ * removed, so it builds that result through `ArraySpeciesCreate`, which reads the receiver's
817
+ * `constructor` and then its `Symbol.species`: a getter installed on `Array.prototype.constructor`
818
+ * is handed the real `children` array as its `this`, which gives caller code a reference to the
819
+ * policy-node records mid-edit and a window to change a surviving node's expected-policy set
820
+ * before the walk reads it. Capturing `splice` closes which function runs, not the protocol it
821
+ * consults. `removeAt` returns nothing and constructs nothing. */
808
822
  intrinsic.forEach(node.parents, function (p) {
809
- var idx = intrinsic.indexOf(p.children, node);
810
- if (idx !== -1) _splice(p.children, idx, 1);
823
+ var idx = intrinsic.ownIndexOf(p.children, node);
824
+ if (idx !== -1) guard.list.removeAt(p.children, idx);
811
825
  });
812
826
  intrinsic.forEach(node.children, function (c) {
813
- var idx = intrinsic.indexOf(c.parents, node);
814
- if (idx !== -1) _splice(c.parents, idx, 1);
827
+ var idx = intrinsic.ownIndexOf(c.parents, node);
828
+ if (idx !== -1) guard.list.removeAt(c.parents, idx);
815
829
  });
816
830
  node.parents = [];
817
831
  var layer = state.policyIndex[node.depth];
@@ -1007,7 +1021,7 @@ function _initialState(certs, params, seeds, anchor, n, ta, policySwitches) {
1007
1021
  var anchorPathLen = ta.pathLenConstraint;
1008
1022
  return {
1009
1023
  validPolicyGraph: graphRoot(),
1010
- policyIndex: [],
1024
+ policyIndex: intrinsic.create(null),
1011
1025
  policyNodeCount: 1,
1012
1026
  maxPolicyNodes: params.maxPolicyNodes !== undefined ? params.maxPolicyNodes : constants.LIMITS.PATH_MAX_POLICY_NODES,
1013
1027
  minRsaModulusBits: params.minRsaModulusBits !== undefined ? params.minRsaModulusBits : constants.LIMITS.RSA_MIN_MODULUS_BITS,
@@ -1250,7 +1264,12 @@ function applyPolicyMappings(state, mappings, i) {
1250
1264
  if (anyHere === null) return;
1251
1265
  var anyPrev = nodeAt(state, i - 1, OID.anyPolicy);
1252
1266
  if (anyPrev === null) return;
1253
- addPolicyNode(state, i, idp, anyHere.qualifierSet[0] || null, intrinsic.copyList(mappedFrom[idp]), [anyPrev]);
1267
+ /** @internal The qualifier is the first element the list HOLDS, in one read. `qualifierSet[0]`
1268
+ * on an empty list answers from the array prototype, so a value installed there would become
1269
+ * the qualifier of a node this step generates; an own-slot test followed by a read is two
1270
+ * reads of one slot, which an accessor answers twice. */
1271
+ var anyQual = guard.list.firstMatch(anyHere.qualifierSet, _anyElement);
1272
+ addPolicyNode(state, i, idp, anyQual, intrinsic.copyList(mappedFrom[idp]), [anyPrev]);
1254
1273
  });
1255
1274
  return;
1256
1275
  }
@@ -1575,7 +1594,10 @@ async function _validate(path, opts, run, scope) {
1575
1594
  var preNc = _precaptureAnchorNameConstraints(anchorEntries, "validate");
1576
1595
  var tuples = [];
1577
1596
  for (var ti = 0; ti < anchorEntries.length; ti++) {
1578
- tuples[ti] = toAnchor(anchorEntries[ti], "validate");
1597
+ /** @internal Appended by defining the index. A store at an index this list has no own property
1598
+ * at consults a setter inherited from the array prototype, and these are the trust anchors each
1599
+ * attempt below is run against. */
1600
+ guard.list.append(tuples, toAnchor(anchorEntries[ti], "validate"));
1579
1601
  if (preNc[ti] !== undefined) intrinsic.defineProperty(tuples[ti], "nameConstraints", { value: preNc[ti], enumerable: true, configurable: true, writable: true });
1580
1602
  }
1581
1603
  /** @internal Each anchor is a separate attempt and the later ones run after an await, so the
@@ -2953,19 +2975,27 @@ function _copyAtv(atv) {
2953
2975
  return out;
2954
2976
  }
2955
2977
 
2978
+ /** @internal Each count is read ONCE and each element is read once. `isArray` is satisfied by a
2979
+ * Proxy over an array, so a `length` trap answers afresh on every read: the length the result was
2980
+ * sized to and the length the walk ran to could differ, and an element read three times for a type
2981
+ * test, a copy and a fallback could be three different values, which is a copy of something the test
2982
+ * never saw. This is the door a caller's own distinguished name comes through. */
2956
2983
  function _copyRdnsDeep(rdns) {
2957
2984
  if (!intrinsic.isArray(rdns)) return rdns;
2958
2985
  var out = [];
2959
- out.length = rdns.length;
2960
- for (var i = 0; i < rdns.length; i++) {
2986
+ var n = guard.list.count(rdns, "name rdns");
2987
+ out.length = n;
2988
+ for (var i = 0; i < n; i++) {
2961
2989
  if (!intrinsic.hasOwn(rdns, i)) continue;
2962
2990
  var rdn = rdns[i], val;
2963
2991
  if (intrinsic.isArray(rdn)) {
2964
2992
  var rdnOut = [];
2965
- rdnOut.length = rdn.length;
2966
- for (var j = 0; j < rdn.length; j++) {
2993
+ var m = guard.list.count(rdn, "a name rdn");
2994
+ rdnOut.length = m;
2995
+ for (var j = 0; j < m; j++) {
2967
2996
  if (!intrinsic.hasOwn(rdn, j)) continue;
2968
- var atv = (rdn[j] !== null && typeof rdn[j] === "object") ? _copyAtv(rdn[j]) : rdn[j];
2997
+ var raw = rdn[j];
2998
+ var atv = (raw !== null && typeof raw === "object") ? _copyAtv(raw) : raw;
2969
2999
  intrinsic.defineProperty(rdnOut, j, { value: atv, enumerable: true, configurable: true, writable: true });
2970
3000
  }
2971
3001
  val = rdnOut;
package/lib/pbes2.js CHANGED
@@ -8,6 +8,10 @@ var asn1 = require("./asn1-der");
8
8
  var oid = require("./oid");
9
9
  var webcrypto = require("./webcrypto");
10
10
  var guard = require("./guard-all");
11
+ /** @internal The append every list here is built with: `push` stores at the index and a store
12
+ * consults a setter inherited there, and these lists become the key-derivation parameters an
13
+ * encrypted structure declares. */
14
+ var _push = guard.list.append;
11
15
  var C = require("./constants");
12
16
 
13
17
  var b = asn1.build;
@@ -48,7 +52,7 @@ function prfNodeByOid(oidStr, E, prefix) { if (!PRF_NODE_BY_OID[oidStr]) throw E
48
52
 
49
53
  function pbkdf2ParamsSeq(salt, iterations, prf) {
50
54
  var kids = [b.octetString(salt), b.integer(BigInt(iterations))];
51
- if (prf !== "hmacWithSHA1") kids.push(b.sequence([b.oid(O(prf)), b.nullValue()]));
55
+ if (prf !== "hmacWithSHA1") _push(kids,b.sequence([b.oid(O(prf)), b.nullValue()]));
52
56
  return b.sequence(kids);
53
57
  }
54
58
 
@@ -158,7 +162,7 @@ function _hmacAlgId(name) { return b.sequence([b.oid(O(name)), b.nullValue()]);
158
162
 
159
163
  function pbmac1AlgId(desc) {
160
164
  var pbkdf2Params = [b.octetString(desc.salt), b.integer(BigInt(desc.iterationCount)), b.integer(BigInt(desc.keyLength))];
161
- if (desc.prfName !== "hmacWithSHA1") pbkdf2Params.push(_hmacAlgId(desc.prfName));
165
+ if (desc.prfName !== "hmacWithSHA1") _push(pbkdf2Params,_hmacAlgId(desc.prfName));
162
166
  var pbkdf2AlgId = b.sequence([b.oid(O("pbkdf2")), b.sequence(pbkdf2Params)]);
163
167
  return b.sequence([b.oid(O("pbmac1")), b.sequence([pbkdf2AlgId, _hmacAlgId(desc.macName)])]);
164
168
  }
package/lib/pkcs11-uri.js CHANGED
@@ -57,7 +57,9 @@ var _assign = intrinsic.assign;
57
57
  var _hasOwn = intrinsic.hasOwn;
58
58
  var _keys = intrinsic.keys;
59
59
  var _forEach = intrinsic.forEach;
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 _join = intrinsic.join;
62
64
  var _String = intrinsic.String;
63
65
  var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
@@ -34,6 +34,9 @@ var pkix = require("./schema-pkix");
34
34
  var pkiBuild = require("./pki-build");
35
35
  var guard = require("./guard-all");
36
36
  var intrinsic = require("./guard-intrinsic");
37
+ /** @internal The append every list here is built with: `push` stores at the index and a store
38
+ * consults a setter inherited there, and these lists become the bags a PFX carries under its MAC. */
39
+ var _push = intrinsic.append;
37
40
  var _toLower = intrinsic.uncurry(String.prototype.toLowerCase);
38
41
  var frameworkError = require("./framework-error");
39
42
  var C = require("./constants");
@@ -197,11 +200,11 @@ function _bagAttributes(bag) {
197
200
  if (typeof bag.friendlyName !== "string") {
198
201
  throw _err("pkcs12/bad-input", "a bag's friendlyName must be a string, since it is the text a key store lists the bag under");
199
202
  }
200
- attrs.push(b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
203
+ _push(attrs,b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
201
204
  }
202
205
  if (bag.localKeyId != null) {
203
206
  if (bag.localKeyId === "ski") throw _err("pkcs12/bad-input", "localKeyId 'ski' auto-derivation is not yet supported -- supply an explicit Buffer");
204
- attrs.push(b.sequence([b.oid(O("localKeyId")), b.set([b.octetString(_bytes(bag.localKeyId, "localKeyId"))])]));
207
+ _push(attrs,b.sequence([b.oid(O("localKeyId")), b.set([b.octetString(_bytes(bag.localKeyId, "localKeyId"))])]));
205
208
  }
206
209
  return attrs.length ? b.set(attrs) : null;
207
210
  }
@@ -214,7 +217,7 @@ function _secretTypeOid(id) {
214
217
  function _safeBag(bagName, bagValueDer, bag) {
215
218
  var children = [b.oid(O(bagName)), b.explicit(0, bagValueDer)];
216
219
  var attrs = _bagAttributes(bag);
217
- if (attrs) children.push(attrs);
220
+ if (attrs) _push(children,attrs);
218
221
  return b.sequence(children);
219
222
  }
220
223
 
@@ -485,18 +488,18 @@ function _normalizeSpec(spec, opts, form) {
485
488
  var enveloped = recipientCerts != null;
486
489
  if (enveloped && (!intrinsic.isArray(recipientCerts) || !recipientCerts.length)) throw _err("pkcs12/bad-input", "opts.recipientCerts must be a non-empty array of recipient certificates");
487
490
  var certBags = [];
488
- if (spec.cert != null) certBags.push({ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
491
+ if (spec.cert != null) _push(certBags,{ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
489
492
  if (spec.ca != null && !Array.isArray(spec.ca)) throw _err("pkcs12/bad-input", "spec.ca must be an array of certificates");
490
- (spec.ca || []).forEach(function (ca) { certBags.push({ type: "cert", cert: ca }); });
493
+ (spec.ca || []).forEach(function (ca) { _push(certBags,{ type: "cert", cert: ca }); });
491
494
  var sc = [];
492
495
  if (enveloped) {
493
496
  var bags = certBags.slice();
494
- if (spec.key != null) bags.push({ type: "key", key: spec.key, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
495
- sc.push({ recipients: recipientCerts.map(function (c) { return { cert: c }; }), bags: bags });
497
+ if (spec.key != null) _push(bags,{ type: "key", key: spec.key, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
498
+ _push(sc,{ recipients: recipientCerts.map(function (c) { return { cert: c }; }), bags: bags });
496
499
  return sc;
497
500
  }
498
- if (certBags.length) sc.push({ encrypt: { password: opts.password }, bags: certBags });
499
- if (spec.key != null) sc.push({ bags: [{ type: "shroudedKey", key: spec.key, encrypt: { password: opts.password }, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId }] });
501
+ if (certBags.length) _push(sc,{ encrypt: { password: opts.password }, bags: certBags });
502
+ if (spec.key != null) _push(sc,{ bags: [{ type: "shroudedKey", key: spec.key, encrypt: { password: opts.password }, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId }] });
500
503
  return sc;
501
504
  }
502
505
  throw _err("pkcs12/bad-input", "spec must be { safeContents: [...] } or { key, cert, ca? }");
@@ -584,7 +587,7 @@ async function _build(spec, opts) {
584
587
  if (safeContentsSpecs.length > C.LIMITS.PKCS12_MAX_ELEMENTS) throw _err("pkcs12/bad-input", "the AuthenticatedSafe exceeds the element cap " + C.LIMITS.PKCS12_MAX_ELEMENTS + " (safeContents entries)");
585
588
  await _assertKeyPairs(spec, form, safeContentsSpecs);
586
589
  var elements = [];
587
- for (var i = 0; i < safeContentsSpecs.length; i++) elements.push(await _buildAuthSafeElement(safeContentsSpecs[i], opts));
590
+ for (var i = 0; i < safeContentsSpecs.length; i++) _push(elements,await _buildAuthSafeElement(safeContentsSpecs[i], opts));
588
591
  var authSafeDer = b.sequence(elements);
589
592
 
590
593
  var pfx;
@@ -619,7 +622,7 @@ async function _build(spec, opts) {
619
622
  : "");
620
623
  });
621
624
  }
622
- if (opts.mac !== false) pfxChildren.push(await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
625
+ if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
623
626
  pfx = b.sequence(pfxChildren);
624
627
  }
625
628
 
package/lib/pki-build.js CHANGED
@@ -8,6 +8,10 @@ var schema = require("./schema-engine");
8
8
  var compositeSig = require("./composite-sig");
9
9
  var guard = require("./guard-all");
10
10
  var intrinsic = require("./guard-intrinsic");
11
+ /** @internal The append every list here is built with: `push` stores at the index and a store
12
+ * consults a setter inherited there, and these lists become the extension and name structures
13
+ * every signing verb embeds. */
14
+ var _push = intrinsic.append;
11
15
  var _isArray = intrinsic.isArray;
12
16
  var _bufferFrom = intrinsic.bufferFrom;
13
17
  var _bufferEquals = intrinsic.bufferEquals;
@@ -632,8 +636,8 @@ function makeBuilder(ctx) {
632
636
  }
633
637
  function extBasicConstraints(spec) {
634
638
  var children = [];
635
- if (spec.cA === true) children.push(b.boolean(true));
636
- if (spec.pathLen != null) children.push(b.integer(pathLen(spec.pathLen)));
639
+ if (spec.cA === true) _push(children,b.boolean(true));
640
+ if (spec.pathLen != null) _push(children,b.integer(pathLen(spec.pathLen)));
637
641
  return b.sequence(children);
638
642
  }
639
643
  function pathLen(v) {
@@ -1238,8 +1242,8 @@ function makeBuilder(ctx) {
1238
1242
  }
1239
1243
  function ext(oidStr, critical, valueDer) {
1240
1244
  var children = [b.oid(oidStr)];
1241
- if (critical) children.push(b.boolean(true));
1242
- children.push(b.octetString(valueDer));
1245
+ if (critical) _push(children,b.boolean(true));
1246
+ _push(children,b.octetString(valueDer));
1243
1247
  return b.sequence(children);
1244
1248
  }
1245
1249
 
@@ -1353,13 +1357,13 @@ function makeBuilder(ctx) {
1353
1357
  var out = [];
1354
1358
  if (extSpec.subjectKeyIdentifier != null) {
1355
1359
  if (extSpec.subjectKeyIdentifier === true && spki == null) throw E("bad-input", "subjectKeyIdentifier auto-derive (true) requires the public key -- supply a Buffer key id, or include the public key");
1356
- out.push(ext(O("subjectKeyIdentifier"), false, extSki(skiKeyId(extSpec.subjectKeyIdentifier, spki))));
1360
+ _push(out,ext(O("subjectKeyIdentifier"), false, extSki(skiKeyId(extSpec.subjectKeyIdentifier, spki))));
1357
1361
  }
1358
- if (extSpec.keyUsage != null) out.push(ext(O("keyUsage"), extSpec.keyUsageCritical !== false, extKeyUsage(extSpec.keyUsage)));
1359
- if (extSpec.extendedKeyUsage != null) out.push(ext(O("extKeyUsage"), !!extSpec.extendedKeyUsageCritical, extExtKeyUsage(extSpec.extendedKeyUsage)));
1360
- if (extSpec.basicConstraints != null) { validateBcSpec(extSpec.basicConstraints); out.push(ext(O("basicConstraints"), extSpec.basicConstraints.critical !== false, extBasicConstraints(extSpec.basicConstraints))); }
1361
- if (extSpec.subjectAltName != null) out.push(ext(O("subjectAltName"), false, extSan(extSpec.subjectAltName)));
1362
- if (extSpec.certificatePolicies != null) out.push(ext(O("certificatePolicies"), !!extSpec.certificatePoliciesCritical, extCertPolicies(extSpec.certificatePolicies)));
1362
+ if (extSpec.keyUsage != null) _push(out,ext(O("keyUsage"), extSpec.keyUsageCritical !== false, extKeyUsage(extSpec.keyUsage)));
1363
+ if (extSpec.extendedKeyUsage != null) _push(out,ext(O("extKeyUsage"), !!extSpec.extendedKeyUsageCritical, extExtKeyUsage(extSpec.extendedKeyUsage)));
1364
+ if (extSpec.basicConstraints != null) { validateBcSpec(extSpec.basicConstraints); _push(out,ext(O("basicConstraints"), extSpec.basicConstraints.critical !== false, extBasicConstraints(extSpec.basicConstraints))); }
1365
+ if (extSpec.subjectAltName != null) _push(out,ext(O("subjectAltName"), false, extSan(extSpec.subjectAltName)));
1366
+ if (extSpec.certificatePolicies != null) _push(out,ext(O("certificatePolicies"), !!extSpec.certificatePoliciesCritical, extCertPolicies(extSpec.certificatePolicies)));
1363
1367
  /** @internal RFC 5280 sec. 4.2.1.10 fixes this extension critical, in a request as in the certificate. */
1364
1368
  if (extSpec.nameConstraints != null) guard.list.append(out, ext(O("nameConstraints"), true, extNameConstraints(extSpec.nameConstraints)));
1365
1369
  if (extSpec.authorityInfoAccess != null) guard.list.append(out, ext(O("authorityInfoAccess"), false, extAuthorityInfoAccess(extSpec.authorityInfoAccess)));
package/lib/possession.js CHANGED
@@ -78,7 +78,9 @@ var _promiseResolve = intrinsic.uncurry(intrinsic.promiseResolve);
78
78
  * while its signature certificate chained to an untrusted CA, which is the RFC 9883 sec. 4 MUST this
79
79
  * verb exists to apply. */
80
80
  var _Promise = intrinsic.Promise;
81
- var _push = intrinsic.push;
81
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
82
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
83
+ var _push = intrinsic.append;
82
84
  var _join = intrinsic.join;
83
85
  var _every = intrinsic.every;
84
86
  var _filter = intrinsic.filter;
package/lib/rc2.js CHANGED
@@ -22,15 +22,19 @@ var PITABLE = [
22
22
  0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad,
23
23
  ];
24
24
 
25
+ /** @internal Both schedules are TYPED arrays. `new Array(n)` has no own property at any index, so
26
+ * every write below was a store the prototype chain is walked for, and an accessor at one of those
27
+ * indexes would take a byte of the expanded key and answer with its own in its place. A typed array
28
+ * handles its own integer-indexed writes, holds the widths these values need, and starts zeroed. */
25
29
  function _expandKey(key, effectiveBits) {
26
- var T = key.length, L = new Array(128);
30
+ var T = key.length, L = new Uint8Array(128);
27
31
  for (var i = 0; i < T; i++) L[i] = key[i];
28
32
  for (i = T; i < 128; i++) L[i] = PITABLE[(L[i - 1] + L[i - T]) & 0xff];
29
33
  var T8 = (effectiveBits + 7) >>> 3;
30
34
  var TM = 0xff >>> ((8 - (effectiveBits & 7)) & 7);
31
35
  L[128 - T8] = PITABLE[L[128 - T8] & TM];
32
36
  for (i = 127 - T8; i >= 0; i--) L[i] = PITABLE[L[i + 1] ^ L[i + T8]];
33
- var K = new Array(64);
37
+ var K = new Uint16Array(64);
34
38
  for (i = 0; i < 64; i++) K[i] = L[2 * i] + (L[2 * i + 1] << 8);
35
39
  return K;
36
40
  }