@blamejs/pki 0.8.59 → 0.8.61

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 (75) hide show
  1. package/CHANGELOG.md +57 -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 +26 -18
  9. package/lib/cmp-build.js +35 -33
  10. package/lib/cmp-session.js +19 -9
  11. package/lib/cms-decrypt.js +37 -23
  12. package/lib/cms-digest.js +2 -3
  13. package/lib/cms-encrypt.js +38 -33
  14. package/lib/cms-sign.js +65 -43
  15. package/lib/cms-verify.js +8 -4
  16. package/lib/composite-kem.js +28 -29
  17. package/lib/crl-sign.js +24 -17
  18. package/lib/crmf-sign.js +11 -17
  19. package/lib/csr-sign.js +5 -2
  20. package/lib/ct.js +38 -25
  21. package/lib/est.js +12 -9
  22. package/lib/guard-bytes.js +5 -1
  23. package/lib/guard-crypto.js +506 -14
  24. package/lib/guard-der.js +6 -1
  25. package/lib/guard-intrinsic.js +12 -4
  26. package/lib/guard-list.js +64 -0
  27. package/lib/guard-name.js +1 -1
  28. package/lib/guard-secret.js +3 -2
  29. package/lib/hpke.js +34 -27
  30. package/lib/http-digest.js +5 -7
  31. package/lib/http-transport.js +12 -3
  32. package/lib/inspect.js +10 -2
  33. package/lib/jose.js +3 -1
  34. package/lib/key.js +41 -29
  35. package/lib/lint.js +236 -152
  36. package/lib/mime.js +9 -5
  37. package/lib/ocsp.js +26 -24
  38. package/lib/path-validate.js +43 -13
  39. package/lib/pbes2.js +12 -9
  40. package/lib/pkcs11-uri.js +3 -1
  41. package/lib/pkcs12-build.js +19 -17
  42. package/lib/pki-build.js +17 -13
  43. package/lib/possession.js +3 -1
  44. package/lib/rc2.js +6 -2
  45. package/lib/revocation-fetch.js +78 -19
  46. package/lib/scep.js +21 -14
  47. package/lib/schema-attrcert.js +4 -2
  48. package/lib/schema-c509.js +94 -78
  49. package/lib/schema-cmc.js +5 -2
  50. package/lib/schema-cmp.js +6 -3
  51. package/lib/schema-cms.js +7 -4
  52. package/lib/schema-crl.js +1 -1
  53. package/lib/schema-crmf.js +1 -1
  54. package/lib/schema-csr.js +3 -3
  55. package/lib/schema-engine.js +36 -18
  56. package/lib/schema-pkcs1.js +7 -3
  57. package/lib/schema-pkcs12.js +9 -6
  58. package/lib/schema-pkix.js +19 -3
  59. package/lib/schema-sec1.js +4 -1
  60. package/lib/schema-tsp.js +7 -4
  61. package/lib/shbs.js +10 -9
  62. package/lib/sign-scheme.js +2 -2
  63. package/lib/sigstore.js +9 -9
  64. package/lib/smime.js +19 -16
  65. package/lib/tlog.js +20 -13
  66. package/lib/tuf.js +7 -4
  67. package/lib/validator-cose.js +2 -2
  68. package/lib/validator-keydesc.js +4 -1
  69. package/lib/validator-tls.js +7 -2
  70. package/lib/webauthn-mds.js +3 -7
  71. package/lib/webauthn.js +4 -11
  72. package/lib/webcrypto.js +70 -49
  73. package/lib/x509-sign.js +20 -15
  74. package/package.json +1 -1
  75. 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
@@ -23,7 +23,6 @@
23
23
  * @card Build, sign, and verify RFC 6960 OCSP requests + responses (a responder + a relying party).
24
24
  */
25
25
 
26
- var nodeCrypto = require("crypto");
27
26
  var asn1 = require("./asn1-der");
28
27
  var pkiBuild = require("./pki-build");
29
28
  var _ocspIntrinsic = require("./guard-intrinsic");
@@ -51,6 +50,9 @@ var ocspRequestVerify = require("./ocsp-request-verify");
51
50
  var webcrypto = require("./webcrypto");
52
51
  var subtle = webcrypto.webcrypto.subtle;
53
52
  var guard = require("./guard-all");
53
+ /** @internal The append every list here is built with: `push` stores at the index and a store
54
+ * consults a setter inherited there, and these lists become a signed request or response. */
55
+ var _push = guard.list.append;
54
56
  var constants = require("./constants");
55
57
  var frameworkError = require("./framework-error");
56
58
  var E = _err;
@@ -230,7 +232,7 @@ function _buildRequest(query, opts) {
230
232
  var singles = pkiBuild.reqDenseArray(q.singleRequestExtensions, "singleRequestExtensions", _err, "ocsp/bad-input");
231
233
  if (singles.length) {
232
234
  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)));
235
+ _push(reqChildren,b.explicit(0, b.sequence(singles)));
234
236
  }
235
237
  }
236
238
  return b.sequence(reqChildren);
@@ -238,15 +240,15 @@ function _buildRequest(query, opts) {
238
240
  }));
239
241
  return _ocspIntrinsic.chain(builtRequests, function (requests) {
240
242
  var tbsChildren = [];
241
- if (requestorNameDer !== null) tbsChildren.push(b.explicit(1, b.contextConstructed(4, requestorNameDer)));
242
- tbsChildren.push(b.sequence(requests));
243
+ if (requestorNameDer !== null) _push(tbsChildren,b.explicit(1, b.contextConstructed(4, requestorNameDer)));
244
+ _push(tbsChildren,b.sequence(requests));
243
245
  var reqExts = [];
244
246
  if (opts.nonce) {
245
- var nonceBytes = opts.nonce === true ? nodeCrypto.randomBytes(32) : opts.nonce;
247
+ var nonceBytes = opts.nonce === true ? guard.crypto.randomBytes(32) : opts.nonce;
246
248
  _assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
247
- reqExts.push(_nonceExt(nonceBytes));
249
+ _push(reqExts,_nonceExt(nonceBytes));
248
250
  }
249
- if (reqExts.length) tbsChildren.push(b.explicit(2, b.sequence(reqExts)));
251
+ if (reqExts.length) _push(tbsChildren,b.explicit(2, b.sequence(reqExts)));
250
252
  var tbsRequest = b.sequence(tbsChildren);
251
253
  if (signerCert === null) return _emitReq(b.sequence([tbsRequest]), opts);
252
254
  var scheme = signScheme.resolveSignScheme(signerCert, { combinedRsaSig: true }, true, _signE);
@@ -389,9 +391,9 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
389
391
  }
390
392
  var rdChildren = [ridNode, b.generalizedTime(_asEncodableDate(responseData.producedAt, "producedAt") || new Date()), b.sequence(srNodes)];
391
393
  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)));
394
+ if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); _push(respExts,_nonceExt(opts.nonce)); }
395
+ if (opts.extendedRevoke || anyNonIssued) _push(respExts,b.sequence([b.oid(OID_EXTENDED_REVOKE), b.octetString(b.nullValue())]));
396
+ if (respExts.length) _push(rdChildren,b.explicit(1, b.sequence(respExts)));
395
397
  var responseDataDer = b.sequence(rdChildren);
396
398
  var scheme = signScheme.resolveSignScheme(respCert, { combinedRsaSig: true }, true, _signE);
397
399
  return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE), function (sig) {
@@ -401,7 +403,7 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
401
403
  var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(responseDataDer, sig, respCert.subjectPublicKeyInfo.bytes, scheme));
402
404
  return _ocspIntrinsic.chain(selfChecked, function () {
403
405
  var basicChildren = [responseDataDer, scheme.sigAlgId, b.bitString(sig, 0)];
404
- if (opts.embedCert !== false) basicChildren.push(b.explicit(0, b.sequence([b.raw(respCertDer)])));
406
+ if (opts.embedCert !== false) _push(basicChildren,b.explicit(0, b.sequence([b.raw(respCertDer)])));
405
407
  var responseBytes = b.sequence([b.oid(OID_OCSP_BASIC), b.octetString(b.sequence(basicChildren))]);
406
408
  var der = b.sequence([b.enumerated(0n), b.explicit(0, responseBytes)]);
407
409
  return opts.pem ? ocspSchema.pemEncode(der, "OCSP RESPONSE") : der;
@@ -426,7 +428,7 @@ function _asEncodableDate(d, which) {
426
428
  function _snapshotSignerKey(key, owned) {
427
429
  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
430
  var copy = guard.bytes.snapshot(key, OcspError, "ocsp/bad-input", "the responder key");
429
- owned.push(copy);
431
+ _push(owned,copy);
430
432
  return copy;
431
433
  }
432
434
  if (key && typeof key === "object" && (key.mldsa != null || key.trad != null)) {
@@ -482,10 +484,10 @@ function _buildSingleResponse(r, opts) {
482
484
  var statusNode = _certStatusNode(r.status, opts);
483
485
  var nonIssued = _isNonIssuedStatus(r.status);
484
486
  var srChildren = [certID, statusNode, b.generalizedTime(thisUpdate)];
485
- if (nextUpdate !== null) srChildren.push(b.explicit(0, b.generalizedTime(nextUpdate)));
487
+ if (nextUpdate !== null) _push(srChildren,b.explicit(0, b.generalizedTime(nextUpdate)));
486
488
  if (r.singleExtensions != null) {
487
489
  var singleDer = _singleExtensionsDer(r.singleExtensions, nonIssued);
488
- if (singleDer.length) srChildren.push(b.explicit(1, b.sequence(singleDer)));
490
+ if (singleDer.length) _push(srChildren,b.explicit(1, b.sequence(singleDer)));
489
491
  }
490
492
  return { node: b.sequence(srChildren), nonIssued: nonIssued };
491
493
  });
@@ -558,7 +560,7 @@ function _singleExtensionsDer(spec, nonIssued) {
558
560
  var out = [];
559
561
  if (spec.archiveCutoff != null) {
560
562
  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))]));
563
+ _push(out,b.sequence([b.oid(oid.byName("ocspArchiveCutoff")), b.octetString(b.generalizedTime(spec.archiveCutoff))]));
562
564
  }
563
565
  if (spec.crlReferences != null) {
564
566
  if (nonIssued) throw _err("ocsp/bad-input", NON_ISSUED_FORBIDDEN);
@@ -575,18 +577,18 @@ function _singleExtensionsDer(spec, nonIssued) {
575
577
  for (var j = 0; j < c.crlUrl.length; j++) {
576
578
  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
579
  }
578
- fields.push(b.explicit(0, b.ia5(c.crlUrl)));
580
+ _push(fields,b.explicit(0, b.ia5(c.crlUrl)));
579
581
  }
580
582
  if (c.crlNum != null) {
581
583
  var num = guard.range.authoredInteger(c.crlNum, _err, "ocsp/bad-input", "crlReferences crlNum");
582
584
  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)));
585
+ _push(fields,b.explicit(1, b.integer(num)));
584
586
  }
585
587
  if (c.crlTime != null) {
586
588
  guard.time.assertEncodable(c.crlTime, _err, "ocsp/bad-input", "crlReferences crlTime");
587
- fields.push(b.explicit(2, b.generalizedTime(c.crlTime)));
589
+ _push(fields,b.explicit(2, b.generalizedTime(c.crlTime)));
588
590
  }
589
- out.push(b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
591
+ _push(out,b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
590
592
  }
591
593
  return out;
592
594
  }
@@ -600,7 +602,7 @@ function _certStatusNode(status, opts) {
600
602
  if (status.revocationReason != null) {
601
603
  var code = typeof status.revocationReason === "number" ? status.revocationReason : REASON_CODE[guard.text.keyOf(status.revocationReason)];
602
604
  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))));
605
+ _push(ri,b.explicit(0, b.enumerated(BigInt(code))));
604
606
  }
605
607
  return b.contextConstructed(1, Buffer.concat(ri));
606
608
  }
@@ -744,14 +746,14 @@ function _reqVerdict(parsed, extra) {
744
746
  async function _findRequestSigners(candidates, strict, parsed, sig, sigBits) {
745
747
  var parsedList = [];
746
748
  for (var i = 0; i < candidates.length; i++) {
747
- try { parsedList.push({ der: candidates[i], cert: x509.parse(candidates[i]) }); }
749
+ try { _push(parsedList,{ der: candidates[i], cert: x509.parse(candidates[i]) }); }
748
750
  catch (e) { if (strict) throw _err("ocsp/bad-signer-cert", "an opts.certs entry does not parse as an X.509 certificate", e); }
749
751
  }
750
752
  var parseable = parsedList.map(function (p) { return p.der; });
751
753
  var matches = [];
752
754
  for (var j = 0; j < parsedList.length; j++) {
753
755
  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 });
756
+ _push(matches,{ der: parsedList[j].der, subject: parsedList[j].cert.subject });
755
757
  }
756
758
  }
757
759
  return { matches: matches, parseable: parseable };
@@ -770,7 +772,7 @@ function _requestorNamed(parsed, matches) {
770
772
  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
773
  var named = [];
772
774
  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]);
775
+ if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) _push(named,matches[i]);
774
776
  }
775
777
  if (named.length) return { named: named, reason: null };
776
778
  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 +868,7 @@ async function verifyRequest(request, opts) {
866
868
  var suppliedCerts = [];
867
869
  if (opts.certs != null) {
868
870
  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"));
871
+ for (var i = 0; i < list.length; i++) _push(suppliedCerts,_normCertDer(list[i], "an opts.certs entry"));
870
872
  }
871
873
  if (!suppliedCerts.length) {
872
874
  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
@@ -3,11 +3,14 @@
3
3
  "use strict";
4
4
  // @internal
5
5
 
6
- var nodeCrypto = require("crypto");
7
6
  var asn1 = require("./asn1-der");
8
7
  var oid = require("./oid");
9
8
  var webcrypto = require("./webcrypto");
10
9
  var guard = require("./guard-all");
10
+ /** @internal The append every list here is built with: `push` stores at the index and a store
11
+ * consults a setter inherited there, and these lists become the key-derivation parameters an
12
+ * encrypted structure declares. */
13
+ var _push = guard.list.append;
11
14
  var C = require("./constants");
12
15
 
13
16
  var b = asn1.build;
@@ -48,7 +51,7 @@ function prfNodeByOid(oidStr, E, prefix) { if (!PRF_NODE_BY_OID[oidStr]) throw E
48
51
 
49
52
  function pbkdf2ParamsSeq(salt, iterations, prf) {
50
53
  var kids = [b.octetString(salt), b.integer(BigInt(iterations))];
51
- if (prf !== "hmacWithSHA1") kids.push(b.sequence([b.oid(O(prf)), b.nullValue()]));
54
+ if (prf !== "hmacWithSHA1") _push(kids,b.sequence([b.oid(O(prf)), b.nullValue()]));
52
55
  return b.sequence(kids);
53
56
  }
54
57
 
@@ -98,11 +101,11 @@ function parsePbkdf2Params(paramsDer, opts, E, prefix, strictPrf) {
98
101
  }
99
102
 
100
103
  function cbcEncrypt(key, iv, plaintext, keyBits, E, code) {
101
- var c = nodeCrypto.createCipheriv("aes-" + keyBits + "-cbc", key, iv);
104
+ var c = guard.crypto.cipher("aes-" + keyBits + "-cbc", key, iv);
102
105
  return guard.secret.cipherFinish(c, plaintext, E, code, "a content-encryption intermediate");
103
106
  }
104
107
  function cbcDecrypt(key, iv, ct, keyBits, E, code) {
105
- var d = nodeCrypto.createDecipheriv("aes-" + keyBits + "-cbc", key, iv);
108
+ var d = guard.crypto.decipher("aes-" + keyBits + "-cbc", key, iv);
106
109
  return guard.secret.cipherFinish(d, ct, E, code, "the partially recovered plaintext");
107
110
  }
108
111
 
@@ -114,9 +117,9 @@ function pbes2Encrypt(pwBytes, plaintext, opts, E, prefix) {
114
117
  var prf = opts.prf || "hmacWithSHA256";
115
118
  var prfNode = prfNodeByName(prf, E, prefix);
116
119
  var iterations = assertIterations(opts.iterations == null ? 2048 : opts.iterations, E, prefix);
117
- var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : nodeCrypto.randomBytes(16);
118
- var iv = opts.iv != null ? opts.iv : nodeCrypto.randomBytes(16);
119
- var key = nodeCrypto.pbkdf2Sync(pwBytes, salt, iterations, keyBits / 8, prfNode);
120
+ var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : guard.crypto.randomBytes(16);
121
+ var iv = opts.iv != null ? opts.iv : guard.crypto.randomBytes(16);
122
+ var key = guard.crypto.pbkdf2(pwBytes, salt, iterations, keyBits / 8, prfNode);
120
123
  try {
121
124
  return { algId: pbes2AlgId(salt, iterations, prf, cipherName, iv), ct: cbcEncrypt(key, iv, plaintext, keyBits, E, prefix + "/bad-input") };
122
125
  } finally {
@@ -148,7 +151,7 @@ function pbes2Decrypt(pwBytes, params, ciphertext, opts, E, prefix, budget) {
148
151
  budget.rounds -= pb.iterations;
149
152
  if (budget.rounds < 0) throw E(prefix + "/iteration-limit", "the aggregate PBKDF2 key-derivation work exceeds the budget (a hostile many-element input)");
150
153
  }
151
- var dk = nodeCrypto.pbkdf2Sync(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
154
+ var dk = guard.crypto.pbkdf2(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
152
155
  try { return cbcDecrypt(dk, iv, ciphertext, keyBits, E, prefix + "/decrypt-failed"); }
153
156
  catch (_e) { throw E(prefix + "/decrypt-failed", "decryption failed"); }
154
157
  finally { guard.secret.zeroize(dk, E, prefix + "/bad-input", "the password-derived decryption key"); }
@@ -158,7 +161,7 @@ function _hmacAlgId(name) { return b.sequence([b.oid(O(name)), b.nullValue()]);
158
161
 
159
162
  function pbmac1AlgId(desc) {
160
163
  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));
164
+ if (desc.prfName !== "hmacWithSHA1") _push(pbkdf2Params,_hmacAlgId(desc.prfName));
162
165
  var pbkdf2AlgId = b.sequence([b.oid(O("pbkdf2")), b.sequence(pbkdf2Params)]);
163
166
  return b.sequence([b.oid(O("pbmac1")), b.sequence([pbkdf2AlgId, _hmacAlgId(desc.macName)])]);
164
167
  }
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);
@@ -17,7 +17,6 @@
17
17
  * @card Build a password-integrity PKCS#12 store (RFC 7292 / RFC 9579) and verify its MAC.
18
18
  */
19
19
 
20
- var nodeCrypto = require("crypto");
21
20
  var asn1 = require("./asn1-der");
22
21
  var rc2 = require("./rc2");
23
22
  var oid = require("./oid");
@@ -34,6 +33,9 @@ var pkix = require("./schema-pkix");
34
33
  var pkiBuild = require("./pki-build");
35
34
  var guard = require("./guard-all");
36
35
  var intrinsic = require("./guard-intrinsic");
36
+ /** @internal The append every list here is built with: `push` stores at the index and a store
37
+ * consults a setter inherited there, and these lists become the bags a PFX carries under its MAC. */
38
+ var _push = intrinsic.append;
37
39
  var _toLower = intrinsic.uncurry(String.prototype.toLowerCase);
38
40
  var frameworkError = require("./framework-error");
39
41
  var C = require("./constants");
@@ -147,7 +149,7 @@ function _p12Kdf(hashName, id, pwBytes, salt, iterations, nBytes) {
147
149
  var A = Buffer.concat([D, I]);
148
150
  for (var r = 0; r < iterations; r++) {
149
151
  var prev = A;
150
- A = nodeCrypto.createHash(hashName).update(A).digest();
152
+ A = guard.crypto.digest(hashName, A);
151
153
  guard.secret.zeroize(prev, Pkcs12Error, "pkcs12/bad-input", "a key-derivation intermediate");
152
154
  }
153
155
  A.copy(out, i * u);
@@ -197,11 +199,11 @@ function _bagAttributes(bag) {
197
199
  if (typeof bag.friendlyName !== "string") {
198
200
  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
201
  }
200
- attrs.push(b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
202
+ _push(attrs,b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
201
203
  }
202
204
  if (bag.localKeyId != null) {
203
205
  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"))])]));
206
+ _push(attrs,b.sequence([b.oid(O("localKeyId")), b.set([b.octetString(_bytes(bag.localKeyId, "localKeyId"))])]));
205
207
  }
206
208
  return attrs.length ? b.set(attrs) : null;
207
209
  }
@@ -214,7 +216,7 @@ function _secretTypeOid(id) {
214
216
  function _safeBag(bagName, bagValueDer, bag) {
215
217
  var children = [b.oid(O(bagName)), b.explicit(0, bagValueDer)];
216
218
  var attrs = _bagAttributes(bag);
217
- if (attrs) children.push(attrs);
219
+ if (attrs) _push(children,attrs);
218
220
  return b.sequence(children);
219
221
  }
220
222
 
@@ -348,7 +350,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
348
350
  var password = macOpts.password != null ? macOpts.password : sharedPassword;
349
351
  var algorithm = macOpts.algorithm || "hmac";
350
352
  var hash = macOpts.hash || "sha256";
351
- var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") : nodeCrypto.randomBytes(MAC_SALT_BYTES);
353
+ var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") : guard.crypto.randomBytes(MAC_SALT_BYTES);
352
354
  if (salt.length === 0) throw _err("pkcs12/bad-input", "the MAC salt must be non-empty (RFC 9579 sec. 4c)");
353
355
  if (salt.length > C.LIMITS.PBKDF2_MAX_SALT) throw _err("pkcs12/bad-input", "the MAC salt exceeds the " + C.LIMITS.PBKDF2_MAX_SALT + "-octet cap");
354
356
 
@@ -360,7 +362,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
360
362
  var macKey = _p12Kdf(node, 3, macPw.bytes, salt, iter, P12_KDF_UV[node].u);
361
363
  if (macPw.owned) guard.secret.zeroize(macPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
362
364
  try {
363
- var digest = nodeCrypto.createHmac(node, macKey).update(authSafeDer).digest();
365
+ var digest = guard.crypto.hmac(node, macKey, authSafeDer);
364
366
  var digestInfo = b.sequence([b.sequence([b.oid(O(node)), b.nullValue()]), b.octetString(digest)]);
365
367
  return b.sequence([digestInfo, b.octetString(salt), b.integer(BigInt(iter))]);
366
368
  } finally {
@@ -485,18 +487,18 @@ function _normalizeSpec(spec, opts, form) {
485
487
  var enveloped = recipientCerts != null;
486
488
  if (enveloped && (!intrinsic.isArray(recipientCerts) || !recipientCerts.length)) throw _err("pkcs12/bad-input", "opts.recipientCerts must be a non-empty array of recipient certificates");
487
489
  var certBags = [];
488
- if (spec.cert != null) certBags.push({ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
490
+ if (spec.cert != null) _push(certBags,{ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
489
491
  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 }); });
492
+ (spec.ca || []).forEach(function (ca) { _push(certBags,{ type: "cert", cert: ca }); });
491
493
  var sc = [];
492
494
  if (enveloped) {
493
495
  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 });
496
+ if (spec.key != null) _push(bags,{ type: "key", key: spec.key, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
497
+ _push(sc,{ recipients: recipientCerts.map(function (c) { return { cert: c }; }), bags: bags });
496
498
  return sc;
497
499
  }
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 }] });
500
+ if (certBags.length) _push(sc,{ encrypt: { password: opts.password }, bags: certBags });
501
+ if (spec.key != null) _push(sc,{ bags: [{ type: "shroudedKey", key: spec.key, encrypt: { password: opts.password }, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId }] });
500
502
  return sc;
501
503
  }
502
504
  throw _err("pkcs12/bad-input", "spec must be { safeContents: [...] } or { key, cert, ca? }");
@@ -584,7 +586,7 @@ async function _build(spec, opts) {
584
586
  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
587
  await _assertKeyPairs(spec, form, safeContentsSpecs);
586
588
  var elements = [];
587
- for (var i = 0; i < safeContentsSpecs.length; i++) elements.push(await _buildAuthSafeElement(safeContentsSpecs[i], opts));
589
+ for (var i = 0; i < safeContentsSpecs.length; i++) _push(elements,await _buildAuthSafeElement(safeContentsSpecs[i], opts));
588
590
  var authSafeDer = b.sequence(elements);
589
591
 
590
592
  var pfx;
@@ -619,7 +621,7 @@ async function _build(spec, opts) {
619
621
  : "");
620
622
  });
621
623
  }
622
- if (opts.mac !== false) pfxChildren.push(await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
624
+ if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
623
625
  pfx = b.sequence(pfxChildren);
624
626
  }
625
627
 
@@ -685,7 +687,7 @@ async function _verifyMacOfStore(m, password, opts) {
685
687
  var vMacPw = _p12PasswordOwned(password);
686
688
  var macKey = _p12Kdf(node, 3, vMacPw.bytes, m.mac.macSalt, m.mac.iterations, P12_KDF_UV[node].u);
687
689
  if (vMacPw.owned) guard.secret.zeroize(vMacPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
688
- try { computed = nodeCrypto.createHmac(node, macKey).update(m.macedBytes).digest(); }
690
+ try { computed = guard.crypto.hmac(node, macKey, m.macedBytes); }
689
691
  finally { guard.secret.zeroize(macKey, Pkcs12Error, "pkcs12/bad-input", "the password-derived MAC key"); }
690
692
  } else {
691
693
  var kdf = m.mac.pbmac1.kdf;
@@ -865,7 +867,7 @@ function _decryptLegacyPbe(ea, ct, password, opts, budget) {
865
867
  if (p12pw.owned) guard.secret.zeroize(p12pw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
866
868
  try {
867
869
  if (scheme.rc2) return rc2.cbcDecrypt(keyM, scheme.rc2, iv, ct, _err, "pkcs12/decrypt-failed");
868
- var d = nodeCrypto.createDecipheriv(scheme.cipher, keyM, iv);
870
+ var d = guard.crypto.decipher(scheme.cipher, keyM, iv);
869
871
  return guard.secret.cipherFinish(d, ct, Pkcs12Error, "pkcs12/bad-input", "the recovered safe contents");
870
872
  } catch (_e) { throw _err("pkcs12/decrypt-failed", "decryption failed"); }
871
873
  finally { guard.secret.zeroize(keyM, Pkcs12Error, "pkcs12/bad-input", "the password-derived decryption key"); }
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;
@@ -414,7 +418,7 @@ var DP_KEYS = intrinsic.assign(intrinsic.create(null), { fullName: 1, reasons: 1
414
418
  * others, so the loop keeps the leading octet uniform over 1 to 127. */
415
419
  function randomSerial() {
416
420
  for (;;) {
417
- var rnd = nodeCrypto.randomBytes(20);
421
+ var rnd = guard.crypto.randomBytes(20);
418
422
  rnd[0] &= 0x7f;
419
423
  if (rnd[0] !== 0) return BigInt("0x" + rnd.toString("hex"));
420
424
  }
@@ -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,14 +1242,14 @@ 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
 
1246
1250
  function spkiKeyId(spkiDer) {
1247
1251
  var keyBytes = asn1.read.bitString(asn1.decode(spkiDer).children[1]).bytes;
1248
- return nodeCrypto.createHash("sha1").update(keyBytes).digest();
1252
+ return guard.crypto.digest("sha1", keyBytes);
1249
1253
  }
1250
1254
  function skiKeyId(val, spkiDer) {
1251
1255
  if (guard.bytes.isByteSource(val)) return guard.bytes.snapshotSource(val, ErrorClass, ctx.prefix + "/bad-input", "subjectKeyIdentifier");
@@ -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)));
@@ -1513,7 +1517,7 @@ function samePublicKey(spkiA, spkiB) {
1513
1517
  /** @internal Two keys of different types are never the same key, and comparing them through
1514
1518
  * the runtime's equality leaves a fault queued in the crypto library that surfaces on the
1515
1519
  * next unrelated key import in the process, so the type decides that case first. */
1516
- if (ka.asymmetricKeyType !== kb.asymmetricKeyType) return false;
1520
+ if (guard.crypto.keyType(ka) !== guard.crypto.keyType(kb)) return false;
1517
1521
  return _keyEquals(ka, kb) === true;
1518
1522
  }
1519
1523
 
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;