@blamejs/pki 0.8.58 → 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 (66) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/lib/acme.js +53 -30
  3. package/lib/alt-sig.js +3 -1
  4. package/lib/asn1-der.js +98 -39
  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 +16 -10
  9. package/lib/cmp-build.js +45 -34
  10. package/lib/cmp-session.js +19 -9
  11. package/lib/cms-decrypt.js +28 -10
  12. package/lib/cms-encrypt.js +23 -17
  13. package/lib/cms-sign.js +65 -43
  14. package/lib/cms-verify.js +11 -7
  15. package/lib/crl-sign.js +27 -20
  16. package/lib/csr-sign.js +5 -2
  17. package/lib/ct.js +37 -17
  18. package/lib/est.js +55 -32
  19. package/lib/guard-bytes.js +5 -1
  20. package/lib/guard-der.js +6 -1
  21. package/lib/guard-identifier.js +1 -1
  22. package/lib/guard-intrinsic.js +12 -4
  23. package/lib/guard-list.js +64 -0
  24. package/lib/guard-name.js +1 -1
  25. package/lib/hpke.js +10 -3
  26. package/lib/http-transport.js +12 -3
  27. package/lib/inspect.js +10 -2
  28. package/lib/jose.js +3 -1
  29. package/lib/key.js +11 -7
  30. package/lib/lint.js +236 -152
  31. package/lib/mime.js +9 -5
  32. package/lib/ocsp.js +25 -22
  33. package/lib/path-validate.js +48 -18
  34. package/lib/pbes2.js +6 -2
  35. package/lib/pkcs11-uri.js +3 -1
  36. package/lib/pkcs12-build.js +14 -11
  37. package/lib/pki-build.js +18 -14
  38. package/lib/possession.js +3 -1
  39. package/lib/rc2.js +6 -2
  40. package/lib/revocation-fetch.js +78 -19
  41. package/lib/scep.js +14 -6
  42. package/lib/schema-attrcert.js +4 -2
  43. package/lib/schema-c509.js +94 -78
  44. package/lib/schema-cmc.js +5 -2
  45. package/lib/schema-cmp.js +6 -3
  46. package/lib/schema-cms.js +7 -4
  47. package/lib/schema-crl.js +1 -1
  48. package/lib/schema-crmf.js +1 -1
  49. package/lib/schema-csr.js +3 -3
  50. package/lib/schema-engine.js +36 -18
  51. package/lib/schema-pkcs1.js +7 -3
  52. package/lib/schema-pkcs12.js +9 -6
  53. package/lib/schema-pkix.js +19 -3
  54. package/lib/schema-sec1.js +4 -1
  55. package/lib/schema-tsp.js +4 -1
  56. package/lib/shbs.js +7 -3
  57. package/lib/sign-scheme.js +4 -4
  58. package/lib/smime.js +18 -14
  59. package/lib/tlog.js +17 -11
  60. package/lib/tuf.js +3 -1
  61. package/lib/validator-keydesc.js +4 -1
  62. package/lib/validator-tls.js +7 -2
  63. package/lib/webcrypto.js +14 -8
  64. package/lib/x509-sign.js +20 -15
  65. package/package.json +1 -1
  66. package/sbom.cdx.json +6 -6
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);
package/lib/key.js CHANGED
@@ -48,6 +48,10 @@ var _floor = intrinsic.floor;
48
48
  var _isFinite = intrinsic.isFinite;
49
49
  var _String = intrinsic.String;
50
50
  var _toUpperCase = intrinsic.toUpperCase;
51
+ /** @internal The walk over an array LITERAL is captured too. The receiver is the literal rather than
52
+ * a caller's value, but the method is still read off the live prototype at the moment it runs, and a
53
+ * replacement decides which rows of a registry this module builds. */
54
+ var _forEach = intrinsic.forEach;
51
55
  var _strIndexOf = intrinsic.stringIndexOf;
52
56
 
53
57
  var b = asn1.build;
@@ -60,13 +64,13 @@ function _err(code, msg, cause) { return new KeyError(code, msg, cause); }
60
64
  var CIPHER_NAME = _assign(_create(null), { "aes-128-cbc": "aes128-CBC", "aes-192-cbc": "aes192-CBC", "aes-256-cbc": "aes256-CBC" });
61
65
 
62
66
  var INFER_ALG = _create(null);
63
- ["Ed25519", "Ed448", "X25519", "X448"].forEach(function (n) { INFER_ALG[O(n)] = { name: n }; });
64
- [["id-ml-dsa-44", "ML-DSA-44"], ["id-ml-dsa-65", "ML-DSA-65"], ["id-ml-dsa-87", "ML-DSA-87"],
65
- ["id-ml-kem-512", "ML-KEM-512"], ["id-ml-kem-768", "ML-KEM-768"], ["id-ml-kem-1024", "ML-KEM-1024"]
66
- ].forEach(function (r) { INFER_ALG[O(r[0])] = { name: r[1] }; });
67
- ["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
68
- "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
69
- ].forEach(function (s) { INFER_ALG[O("id-slh-dsa-" + s)] = { name: _toUpperCase("SLH-DSA-" + s) }; });
67
+ _forEach(["Ed25519", "Ed448", "X25519", "X448"], function (n) { INFER_ALG[O(n)] = { name: n }; });
68
+ _forEach([["id-ml-dsa-44", "ML-DSA-44"], ["id-ml-dsa-65", "ML-DSA-65"], ["id-ml-dsa-87", "ML-DSA-87"],
69
+ ["id-ml-kem-512", "ML-KEM-512"], ["id-ml-kem-768", "ML-KEM-768"], ["id-ml-kem-1024", "ML-KEM-1024"]
70
+ ], function (r) { INFER_ALG[O(r[0])] = { name: r[1] }; });
71
+ _forEach(["sha2-128s", "sha2-128f", "sha2-192s", "sha2-192f", "sha2-256s", "sha2-256f",
72
+ "shake-128s", "shake-128f", "shake-192s", "shake-192f", "shake-256s", "shake-256f"
73
+ ], function (s) { INFER_ALG[O("id-slh-dsa-" + s)] = { name: _toUpperCase("SLH-DSA-" + s) }; });
70
74
 
71
75
  function _isCryptoKey(x) { return webcrypto.isCryptoKeyLike(x); }
72
76
  function _algName(a) { return typeof a === "string" ? a : (a && a.name); }