@blamejs/pki 0.8.55 → 0.8.56

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 (50) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/lib/acme.js +2 -2
  3. package/lib/asn1-der.js +17 -5
  4. package/lib/attrcert-verify.js +1 -1
  5. package/lib/cmc-verify.js +1 -1
  6. package/lib/cmp-session.js +2 -2
  7. package/lib/cmp-verify.js +2 -2
  8. package/lib/cms-decrypt.js +4 -1
  9. package/lib/cms-encrypt.js +4 -1
  10. package/lib/cms-sign.js +26 -12
  11. package/lib/cms-verify.js +1 -1
  12. package/lib/composite-kem.js +30 -12
  13. package/lib/composite-sig.js +42 -23
  14. package/lib/constants.js +7 -2
  15. package/lib/crl-verify.js +1 -1
  16. package/lib/crmf-sign.js +72 -43
  17. package/lib/crmf-verify.js +1 -1
  18. package/lib/csr-verify.js +1 -1
  19. package/lib/ct.js +2 -2
  20. package/lib/edwards-point.js +1 -1
  21. package/lib/est.js +3 -3
  22. package/lib/guard-async.js +22 -1
  23. package/lib/guard-bytes.js +6 -3
  24. package/lib/guard-identifier.js +1 -1
  25. package/lib/guard-intrinsic.js +474 -0
  26. package/lib/http-digest.js +146 -62
  27. package/lib/http-transport.js +82 -17
  28. package/lib/identity-match.js +2 -2
  29. package/lib/merkle.js +2 -2
  30. package/lib/ocsp-request-verify.js +1 -1
  31. package/lib/ocsp.js +46 -22
  32. package/lib/path-validate.js +169 -76
  33. package/lib/pbes2.js +14 -7
  34. package/lib/schema-attrcert.js +2 -2
  35. package/lib/schema-cmc.js +2 -2
  36. package/lib/schema-cmp.js +2 -2
  37. package/lib/schema-cms.js +2 -2
  38. package/lib/schema-crmf.js +2 -2
  39. package/lib/schema-csr.js +2 -2
  40. package/lib/schema-pkix.js +3 -3
  41. package/lib/schema-x509.js +2 -2
  42. package/lib/sigstore.js +1 -1
  43. package/lib/tlog.js +7 -4
  44. package/lib/trust.js +187 -104
  45. package/lib/tsp-sign.js +1 -1
  46. package/lib/webauthn-mds.js +257 -121
  47. package/lib/webauthn.js +327 -164
  48. package/lib/webcrypto.js +10 -3
  49. package/package.json +1 -1
  50. package/sbom.cdx.json +6 -6
@@ -20,6 +20,15 @@ var _bufferByteLength = Buffer.byteLength;
20
20
  var _bufferCompare = Buffer.compare;
21
21
  var _bufferEquals = uncurry(Buffer.prototype.equals);
22
22
  var _bufferToString = uncurry(Buffer.prototype.toString);
23
+ /** @internal The big-endian integer readers, captured at load. A length or a counter read out of a
24
+ * wire structure is what the bounds check and the slice after it are computed from, so a replaced
25
+ * reader decides which bytes a check runs over and which value a monotonicity rule compares. */
26
+ var _readUInt8 = uncurry(Buffer.prototype.readUInt8);
27
+ var _readUInt16BE = uncurry(Buffer.prototype.readUInt16BE);
28
+ var _readUInt32BE = uncurry(Buffer.prototype.readUInt32BE);
29
+ var _readUIntBE = uncurry(Buffer.prototype.readUIntBE);
30
+ var _writeUInt16BE = uncurry(Buffer.prototype.writeUInt16BE);
31
+ var _writeUInt32BE = uncurry(Buffer.prototype.writeUInt32BE);
23
32
  /** @internal Key identity, taken off the KeyObject prototype at load. A caller that replaced this
24
33
  * method could make two different keys answer as one, which is the question a proof of possession
25
34
  * turns on. */
@@ -40,6 +49,7 @@ var _objectKeys = Object.keys;
40
49
  var _objectAssign = Object.assign;
41
50
  var _objectFreeze = Object.freeze;
42
51
  var _isExtensible = Object.isExtensible;
52
+ var _isFrozen = Object.isFrozen;
43
53
  var _ownKeys = Reflect.ownKeys;
44
54
  var _jsonStringify = JSON.stringify;
45
55
  var _mathFloor = Math.floor;
@@ -68,6 +78,142 @@ var _promiseAny = Promise.any;
68
78
  * present on the supported runtime floor. */
69
79
  var _promiseTry = Promise["try"];
70
80
  var _promiseWithResolvers = Promise.withResolvers;
81
+ /** @internal The continuation itself, which the static methods above do not cover: every `p.then(f)`
82
+ * reads `then` off the promise at the call, and the value a continuation RESOLVES is the verdict its
83
+ * caller goes on to report. A replacement that settles `true` without running `f` skips whatever `f`
84
+ * was going to check: in the fold that walks a metadata BLOB's candidate anchors, that feeds `true`
85
+ * into the seed and the chain validation is never called, so a chain unrelated to every supplied
86
+ * root reports trusted. `chain(p, onOk, onFail)` calls the captured method on `p`. */
87
+ var _promiseProto = Promise.prototype;
88
+ var _promiseThen = uncurry(Promise.prototype.then);
89
+ /** @internal Three replaceable mechanisms stand between a captured `then` and the value a caller
90
+ * reads, and closing only the first leaves the verdict steerable:
91
+ *
92
+ * THE METHOD. `p.then(f)` reads `then` off the promise at the call. Measured: a replacement that
93
+ * settled without running `f` made `pki.webauthn.verify` return a packed self-attestation whose
94
+ * signature does not verify, and made `verifyMetadataBlob` hand back a verified catalogue for a
95
+ * chain reaching none of the supplied roots.
96
+ *
97
+ * THE CONSTRUCTION. Native `then` builds the promise it RETURNS through `SpeciesConstructor`, which
98
+ * reads `constructor` off the promise and `Symbol.species` off that, and the species descriptor is
99
+ * configurable. Measured: a species whose executor dropped its resolve function and answered with
100
+ * `Promise.resolve({ valid: true })` made `verifyAssertion` FULFILL with that object where it
101
+ * rejects with `webauthn/bad-input`. So the promise handed back is built here, from the captured
102
+ * constructor, and whatever `then` returns is discarded.
103
+ *
104
+ * THE ADOPTION. Resolving a promise with a thenable is specified to read `then` off that thenable
105
+ * and call it, which is the live method again: a callback returning the verify promise was adopted
106
+ * that way, and a replacement answered the outer chain with a fabricated verdict. A returned real
107
+ * promise is adopted here through the capture instead. A value that is not a promise still goes to
108
+ * the resolve function, because a caller's own thenable IS the thing to call.
109
+ *
110
+ * What remains is the caller's own `await` of the returned promise, which the language resolves by
111
+ * reading `then`. By then every check has run and any refusal has already thrown. */
112
+ // @enforced-by behavioral -- RED vectors replace the method, the species and the adoption in turn
113
+ function chain(p, onOk, onFail) {
114
+ var resolveFn, rejectFn;
115
+ var out = new _Promise(function (res, rej) { resolveFn = res; rejectFn = rej; });
116
+ _chainAttach(p, function (value) {
117
+ if (typeof onOk !== "function") { _chainResolve(out, resolveFn, rejectFn, value); return; }
118
+ var r;
119
+ try { r = onOk(value); }
120
+ catch (e) { rejectFn(e); return; }
121
+ _chainResolve(out, resolveFn, rejectFn, r);
122
+ }, function (reason) {
123
+ if (typeof onFail !== "function") { rejectFn(reason); return; }
124
+ var r;
125
+ try { r = onFail(reason); }
126
+ catch (e) { rejectFn(e); return; }
127
+ _chainResolve(out, resolveFn, rejectFn, r);
128
+ }, rejectFn);
129
+ return out;
130
+ }
131
+ /** @internal Is this a promise, decided against the prototype captured at load rather than through
132
+ * `instanceof`, whose `Promise.prototype` read is replaceable, or a brand string, which is
133
+ * configurable per object. A subclass instance has the captured prototype in its chain and is
134
+ * recognized; anything else is a caller's own thenable or a plain value. */
135
+ function _isPromiseBrand(value) {
136
+ var proto = value;
137
+ for (var depth = 0; depth < 64; depth++) {
138
+ proto = _getPrototypeOf(proto);
139
+ if (proto === null) return false;
140
+ if (proto === _promiseProto) return true;
141
+ }
142
+ return false;
143
+ }
144
+ /** @internal Register the two handlers on whatever the caller supplied. A promise is subscribed to
145
+ * through the capture; a thenable has its own `then` called, which is what a caller supplying one
146
+ * means; anything else is the TypeError `p.then(...)` raises for the same input. A throw from the
147
+ * capture is a REFUSAL rather than a reason to fall back: native `then` reads `constructor` off the
148
+ * promise for its species, so a throwing `constructor` getter is the one way a real promise makes
149
+ * the captured call fail, and falling back to the resolve function there would adopt the promise's
150
+ * own `then` instead, which is the substitution this exists to prevent. */
151
+ function _chainAttach(p, onFulfilled, onRejected, rejectFn) {
152
+ if (p !== null && (typeof p === "object" || typeof p === "function")) {
153
+ if (_isPromiseBrand(p)) {
154
+ try { _promiseThen(p, onFulfilled, onRejected); }
155
+ catch (e) { rejectFn(e); }
156
+ return;
157
+ }
158
+ var thenFn;
159
+ try { thenFn = p.then; }
160
+ catch (e) { rejectFn(e); return; }
161
+ if (typeof thenFn === "function") { _chainThenable(p, thenFn, onFulfilled, onRejected); return; }
162
+ }
163
+ throw new TypeError("intrinsic.chain: the first argument must be a promise or a thenable");
164
+ }
165
+ /** @internal The thenable job for a RECEIVER that is not a promise, which is what `p.then(f)` does
166
+ * for the same argument: it calls the object's own `then`. First settlement wins and a throw after
167
+ * one is dropped, as the specified job does. */
168
+ function _chainThenable(value, thenFn, onFulfilled, onRejected) {
169
+ var settled = false;
170
+ try {
171
+ _reflectApply(thenFn, value, [
172
+ function (v) { if (!settled) { settled = true; onFulfilled(v); } },
173
+ function (e) { if (!settled) { settled = true; onRejected(e); } },
174
+ ]);
175
+ } catch (e) {
176
+ if (!settled) { settled = true; onRejected(e); }
177
+ }
178
+ }
179
+ function _chainResolve(out, resolveFn, rejectFn, value) {
180
+ /** @internal A handler returning the promise this call hands back is the cycle the native
181
+ * resolution procedure rejects rather than waiting on. Subscribing to it would wait forever, and
182
+ * a verify that never settles is a verify that never refuses. */
183
+ if (value === out) {
184
+ rejectFn(new TypeError("intrinsic.chain: a handler returned the promise it settles"));
185
+ return;
186
+ }
187
+ /** @internal A promise is adopted through the capture, and its own value goes through this step
188
+ * again. Anything else is handed to the resolve function, which reads `then` ONCE and calls it if
189
+ * it is callable: that is the specified procedure, and testing `then` here first would read it
190
+ * twice, so a getter answering a non-function and then a function would be settled by the second
191
+ * read after the first had decided. No route in this toolkit returns a thenable that is not a
192
+ * promise, and the resolve function calling a caller's own `then` is what a caller supplying one
193
+ * means. */
194
+ if (value !== null && (typeof value === "object" || typeof value === "function")) {
195
+ /** @internal The brand test runs inside the refusal too. This function is called from inside a
196
+ * continuation, so a throw escaping it settles nothing and the chain waits forever: a proxy
197
+ * whose `getPrototypeOf` trap throws left the verb pending with an unhandled rejection beside
198
+ * it. Anything that cannot be classified is refused instead. */
199
+ var isPromise;
200
+ try { isPromise = _isPromiseBrand(value); }
201
+ catch (e) { rejectFn(e); return; }
202
+ if (!isPromise) { resolveFn(value); return; }
203
+ try {
204
+ _promiseThen(value, function (v) { _chainResolve(out, resolveFn, rejectFn, v); }, rejectFn);
205
+ } catch (e) {
206
+ /** @internal A refusal, not a fallback. Two kinds of value reach here: one carrying the promise
207
+ * prototype without a promise's state, and a real promise whose species cannot be used, which
208
+ * is a `constructor` getter that throws or one answering something that is not a constructor.
209
+ * Settling through the resolve function instead would adopt the value's own `then`, which is
210
+ * the substitution the capture exists to prevent, so neither is passed along. */
211
+ rejectFn(e);
212
+ }
213
+ return;
214
+ }
215
+ resolveFn(value);
216
+ }
71
217
  /** @internal The URL parser, captured for the reason the promise constructor is: what it returns names
72
218
  * the host a request is sent to. A replacement installed while a call is in flight answers with a
73
219
  * genuine URL of its own, and an endpoint built from that answer reaches a host the caller never
@@ -102,6 +248,279 @@ var _arrFilter = uncurry(Array.prototype.filter);
102
248
  var _arrEvery = uncurry(Array.prototype.every);
103
249
  var _arrSome = uncurry(Array.prototype.some);
104
250
  var _arrIndexOf = uncurry(Array.prototype.indexOf);
251
+ /** @internal The fold, captured at load. A fold is how a sequence of checks is chained into one verdict,
252
+ * so a replacement that returns its seed without visiting an element answers for a sequence it never
253
+ * walked. */
254
+ var _arrReduce = uncurry(Array.prototype.reduce);
255
+ /** @internal The append these three build with. `push` is not usable for it: it writes through Set,
256
+ * which WALKS THE PROTOTYPE for a numeric setter, so an accessor installed at `Array.prototype[0]`
257
+ * takes the value and leaves no own property on the array at all, and the index then reads back as
258
+ * whatever its getter answers. MEASURED: a fresh literal appended to with `push` held no own index
259
+ * `0` and read as the getter's value. `defineProperty` consults no setter, which is the same reason
260
+ * `guard.list.append` is written this way. */
261
+ function _appendOwn(out, i, value) {
262
+ _defineProperty(out, i, { value: value, writable: true, enumerable: true, configurable: true });
263
+ }
264
+ var _strCharCodeAt = uncurry(String.prototype.charCodeAt);
265
+ var _strSliceOwn = uncurry(String.prototype.slice);
266
+ /** @internal A split on ONE delimiter character, scanned rather than dispatched.
267
+ * `String.prototype.split` is specified to look the separator's `Symbol.split` method up and call
268
+ * it (ES2015 21.1.3.19 step 2), so the separator's prototype chain is part of the operation and a
269
+ * capture of `split` does not close it. Hard rule 11 bans `split` in `lib/` for exactly that
270
+ * reason. MEASURED on Node 24.21, the supported runtime: a captured split with a string separator
271
+ * DOES dispatch to an installed `String.prototype[Symbol.split]`, and that made
272
+ * `isBlockedIp("127.0.0.1")` answer false, so a request to loopback proceeded under
273
+ * `blockPrivateAddresses`. Node 26.9 fast-paths a primitive-string separator past the lookup, which
274
+ * is why a local run cannot see it: whether the dispatch happens is a property of the engine.
275
+ * `charCodeAt` and `slice` carry no such protocol, and the delimiter here is a CHARACTER CODE
276
+ * rather than a string, so there is no separator object to consult on any engine. */
277
+ // @enforced-by behavioral -- a RED vector on Node 24 pins isBlockedIp against an installed @@split
278
+ function splitChar(s, code) {
279
+ /** @internal The receiver has to BE a string. `charCodeAt` and `slice` each convert their receiver,
280
+ * so an object answering `toString` differently per call is scanned as one value and sliced as
281
+ * another: measured, a receiver reporting length 3 returned the fields of a string the delimiter
282
+ * scan never saw. The delimiter has to be a number for the same reason in reverse. `===` against
283
+ * a character code never coerces, so an object delimiter matches nothing and the whole input comes
284
+ * back as a single field, which reads as "this value carries no delimiter" at every caller. */
285
+ if (typeof s !== "string") {
286
+ throw new TypeError("intrinsic.splitChar: the receiver must be a string");
287
+ }
288
+ if (typeof code !== "number" || !_isSafeInteger(code)) {
289
+ throw new TypeError("intrinsic.splitChar: the delimiter must be a character code");
290
+ }
291
+ var out = [];
292
+ var n = s.length, start = 0, k = 0;
293
+ for (var i = 0; i < n; i++) {
294
+ if (_strCharCodeAt(s, i) === code) { _appendOwn(out, k++, _strSliceOwn(s, start, i)); start = i + 1; }
295
+ }
296
+ _appendOwn(out, k, _strSliceOwn(s, start, n));
297
+ return out;
298
+ }
299
+ /** @internal The element count, refusing anything but a real array. An array's `length` is an OWN
300
+ * data property, so reading it consults nothing; an array-LIKE answers from wherever its own
301
+ * descriptor says, and a typed array answers from an accessor on `%TypedArray%.prototype` that a
302
+ * caller can redefine, which would report zero and empty every result below. The four verbs are for
303
+ * lists, so the narrow argument is the honest contract rather than a length read taken on trust;
304
+ * `guard.list.append` refuses a non-array for the same reason. */
305
+ function _ownLength(list, who) {
306
+ if (!_isArray(list)) throw new TypeError("intrinsic." + who + ": the receiver must be an array");
307
+ var n = list.length;
308
+ /** @internal The count is read ONCE and type-checked, because `isArray` is satisfied by a Proxy
309
+ * over an array whose `length` trap returns an OBJECT. Coerced afresh on each comparison, such a
310
+ * length answers 2 and then 1, so a loop reading it per iteration visits fewer elements than the
311
+ * first read promised. MEASURED through `pki.path.validate`: a proxied two-certificate path whose
312
+ * length shrank that way reported `valid: true` with the second certificate silently dropped.
313
+ * `guard.list` validates its count the same way, and for the same reason. */
314
+ if (typeof n !== "number" || !_isSafeInteger(n) || n < 0) {
315
+ throw new TypeError("intrinsic." + who + ": the receiver's length is not a non-negative integer");
316
+ }
317
+ return n;
318
+ }
319
+ /** @internal A caller-supplied index bound, coerced ONCE and held to a whole number. The clamping
320
+ * arithmetic below reads each bound two or three times, and every relational comparison coerces an
321
+ * object afresh: measured, a `start` whose `valueOf` answered 1 three times and then 0 was compared
322
+ * as 1 and sliced from 0, so the window returned was not the window any single read describes. A
323
+ * fractional bound is refused rather than truncated, because reading `list[0.5]` finds no slot and
324
+ * returns a result of the right length filled with nothing, which a caller reads as a window of
325
+ * absent values rather than as the bad argument it is. */
326
+ function _ownBound(value, fallback, who) {
327
+ if (value === undefined) return fallback;
328
+ var n = _Number(value);
329
+ if (!_isSafeInteger(n)) {
330
+ throw new TypeError("intrinsic." + who + ": a bound must be a safe integer");
331
+ }
332
+ return n;
333
+ }
334
+ // @enforced-by behavioral -- a RED vector installs an Array.prototype numeric setter and pins that
335
+ /** @internal The same append, for a module that holds a list and adds to its end. `guard.list.append`
336
+ * is the orchestrated form of this and is preferred where `guard` is in scope; this exists for the
337
+ * modules that take only the intrinsic captures. */
338
+ function append(list, value) {
339
+ _appendOwn(list, _ownLength(list, "append"), value);
340
+ return list;
341
+ }
342
+ /** @internal Membership and a universal test over the OWN elements. `indexOf` and `every` are
343
+ * specified in terms of HasProperty, so both consult the prototype at an index the list has a hole
344
+ * at: `indexOf` finds a value the list does not hold, and `every` SKIPS the hole and so answers
345
+ * true for a list with no elements of its own at all. Together that is an allow-list a caller left
346
+ * empty admitting a value installed on the prototype, which is why these read own indexes and count
347
+ * a hole as a member that fails any test. */
348
+ // @enforced-by behavioral -- a RED vector installs Array.prototype[0] and drives the origin door
349
+ function ownIndexOf(list, value) {
350
+ var n = _ownLength(list, "ownIndexOf");
351
+ for (var i = 0; i < n; i++) {
352
+ if (_getOwnPropertyDescriptor(list, i) !== undefined && _ownAt(list, i) === value) return i;
353
+ }
354
+ return -1;
355
+ }
356
+ /** @internal Every element of a list of promises, awaited together, without consulting an operation
357
+ * a caller can replace. Capturing `Promise.all` is not sufficient: it performs GetPromiseResolve on
358
+ * the constructor at EACH call, so a replaced `Promise.resolve` answering a fulfilled `true` for
359
+ * every input hands the aggregate its own values and never awaits a component. Measured on the
360
+ * composite signature verifier, whose verdict is the conjunction of two component results: a
361
+ * certificate whose classical half is corrupted reported `valid: true`. This subscribes to each
362
+ * member through `chain` and settles its own promise when the last one arrives. */
363
+ // @enforced-by behavioral -- a RED vector replaces Promise.resolve and pins the composite verdict
364
+ function allOf(list) {
365
+ var n = _ownLength(list, "allOf");
366
+ var resolveFn, rejectFn;
367
+ var out = new _Promise(function (res, rej) { resolveFn = res; rejectFn = rej; });
368
+ var results = [];
369
+ var pending = n;
370
+ var settled = false;
371
+ if (n === 0) { resolveFn(_detached(results)); return out; }
372
+ for (var i = 0; i < n; i++) {
373
+ (function (index) {
374
+ chain(_ownAt(list, index), function (value) {
375
+ if (settled) return;
376
+ _appendOwn(results, index, value);
377
+ pending -= 1;
378
+ if (pending === 0) { settled = true; resolveFn(_detached(results)); }
379
+ }, function (reason) {
380
+ if (settled) return;
381
+ settled = true;
382
+ rejectFn(reason);
383
+ });
384
+ })(i);
385
+ }
386
+ return out;
387
+ }
388
+ /** @internal A list with no prototype, which is how an aggregate's result list is handed back.
389
+ * Settling a promise with a value is specified to read `then` off that value and call it when it is
390
+ * callable, so a `then` installed on `Array.prototype` makes every ordinary array a thenable:
391
+ * measured, both aggregates below settled with the string that replacement answered instead of
392
+ * their result list. A list that inherits nothing has no `then` to find. Every consumer reads these
393
+ * through the captured verbs, which take the receiver rather than calling a method on it. */
394
+ function _detached(list) {
395
+ _setPrototypeOf(list, null);
396
+ return list;
397
+ }
398
+ /** @internal The settled outcome of every member, in the shape `Promise.allSettled` reports, built
399
+ * the same way and for the same reason: the static form reads `resolve` off the constructor at each
400
+ * call, so a replacement answers for every member and the outcomes a caller reads are its own. The
401
+ * composite KEM combiner reads both halves of a shared secret out of these records. */
402
+ // @enforced-by behavioral -- a RED vector replaces Promise.resolve and pins the combined secret
403
+ function settledOf(list) {
404
+ var n = _ownLength(list, "settledOf");
405
+ var resolveFn;
406
+ var out = new _Promise(function (res) { resolveFn = res; });
407
+ var records = [];
408
+ var pending = n;
409
+ if (n === 0) { resolveFn(_detached(records)); return out; }
410
+ for (var i = 0; i < n; i++) {
411
+ (function (index) {
412
+ chain(_ownAt(list, index), function (value) {
413
+ _appendOwn(records, index, { status: "fulfilled", value: value });
414
+ pending -= 1;
415
+ if (pending === 0) resolveFn(_detached(records));
416
+ }, function (reason) {
417
+ _appendOwn(records, index, { status: "rejected", reason: reason });
418
+ pending -= 1;
419
+ if (pending === 0) resolveFn(_detached(records));
420
+ });
421
+ })(i);
422
+ }
423
+ return out;
424
+ }
425
+ // @enforced-by behavioral -- the same RED vector pins the universal form
426
+ function everyOwn(list, pred) {
427
+ var n = _ownLength(list, "everyOwn");
428
+ for (var i = 0; i < n; i++) {
429
+ var d = _getOwnPropertyDescriptor(list, i);
430
+ if (d === undefined) return false;
431
+ if (!pred(_hasOwn(d, "value") ? d.value : (typeof d.get === "function" ? _reflectApply(d.get, list, []) : undefined), i, list)) return false;
432
+ }
433
+ return true;
434
+ }
435
+ /** @internal A selection and a projection that consult NO construction protocol. Capturing
436
+ * `Array.prototype.filter` and `map` is not sufficient on its own: both build their result through
437
+ * ArraySpeciesCreate, which reads `constructor` off the receiver and `Symbol.species` off that, and
438
+ * the species descriptor is configurable. A species returning `{ length: 0 }` takes every match as
439
+ * an indexed property while the length stays zero, so the result reads as EMPTY, and empty is rarely
440
+ * inert: an empty subject-alternative-name selection sends a hostname check to its common-name
441
+ * fallback, an empty permitted-subtree list reads as "this issuer constrains no name of that form"
442
+ * and skips the check, and an empty quality-of-protection list reads as a challenge offering none.
443
+ * A species returning a longer object substitutes the elements instead, which is how a fabricated
444
+ * certificate chain or anchor set reaches a verify. These append into an array literal, which is
445
+ * created through no protocol. Use them wherever the result feeds a refusal.
446
+ *
447
+ * There is no rename-proof code shape to detect, because `intrinsic.map` stays the right spelling
448
+ * wherever the result only feeds a report and is wrong only where it feeds a refusal, so a lexical
449
+ * detector on the call would fire across most of the tree. The guard is the conformance vector in
450
+ * `guard-intrinsic.test.js`, which installs a hostile `Array[Symbol.species]` and asserts in the
451
+ * same run that the captured operation IS steered and these are not. */
452
+ /** @internal The element at one index, read as an OWN property. A list with a HOLE answers from its
453
+ * prototype at that index, so a numeric cell installed on `Array.prototype` is read as if the list
454
+ * held it: measured, a caller's one-element sparse allow-list carrying no origin of its own admitted
455
+ * a response whose origin sat on the prototype, and the check reported the origin as verified. A
456
+ * hole is the absence of an element, so it reads as `undefined` here. Every verb below reads its
457
+ * elements this way. */
458
+ function _ownAt(list, i) {
459
+ /** @internal Existence and value come from ONE operation. Asking `hasOwn` and then indexing is two,
460
+ * and a proxy whose `getOwnPropertyDescriptor` trap reports the element and then deletes it
461
+ * answers the first with yes and the second from the prototype, which is the inherited read this
462
+ * exists to prevent. A descriptor carries the value for a data property; an accessor's getter is
463
+ * the caller's own and is called once. */
464
+ var d = _getOwnPropertyDescriptor(list, i);
465
+ if (d === undefined) return undefined;
466
+ if (_hasOwn(d, "value")) return d.value;
467
+ return typeof d.get === "function" ? _reflectApply(d.get, list, []) : undefined;
468
+ }
469
+ // @enforced-by behavioral -- a RED vector installs a hostile Array species and pins both outcomes
470
+ function mapList(list, fn) {
471
+ var out = [];
472
+ var n = _ownLength(list, "mapList");
473
+ for (var i = 0; i < n; i++) _appendOwn(out, i, fn(_ownAt(list, i), i, list));
474
+ return out;
475
+ }
476
+ // @enforced-by behavioral -- the same RED vector pins the selection form
477
+ function selectList(list, pred) {
478
+ var out = [];
479
+ var n = _ownLength(list, "selectList"), k = 0;
480
+ /** @internal Each element is read ONCE: the value the predicate decides on is the value that goes
481
+ * into the result. Written as `pred(list[i]) && append(list[i])` it reads the slot twice, so an
482
+ * element with a getter answers the test with one value and supplies another, which is the shape
483
+ * where a selection that gates a refusal admits what the refusal examined. */
484
+ for (var i = 0; i < n; i++) {
485
+ var v = _ownAt(list, i);
486
+ if (pred(v, i, list)) _appendOwn(out, k++, v);
487
+ }
488
+ return out;
489
+ }
490
+ /** @internal A copy that consults no construction protocol. `Array.prototype.slice` runs
491
+ * ArraySpeciesCreate like the selections above, so a species answering with an object of its own
492
+ * receives the elements and the length write: a copy of a certificate chain that discards them left
493
+ * an empty path, and an empty path reads as "nothing left to validate" where a self-presented anchor
494
+ * had just been stripped, so the chain reported trusted with no path validated at all. */
495
+ /** @internal A join that consults no construction protocol. `concat` reads
496
+ * `Symbol.isConcatSpreadable` off each operand and builds its result through ArraySpeciesCreate, so
497
+ * a `false` there leaves an operand NESTED inside the result where a per-element field test finds
498
+ * nothing to recognize, and a hostile species discards the elements outright. A join that drops an
499
+ * excluded-subtree list loses the exclusion, and one that drops a chain element shortens the path
500
+ * that gets validated. */
501
+ // @enforced-by behavioral -- the same RED vector pins the join form
502
+ function concatList(a, b) {
503
+ var out = copyList(a);
504
+ /** @internal The offset the second operand lands at comes from the COPY, not from re-reading the
505
+ * first operand's length. Re-read, an element getter that ran during the copy could have changed
506
+ * that length in between, so the second operand would overwrite copied entries or leave holes. */
507
+ var k = _ownLength(out, "concatList");
508
+ var n = _ownLength(b, "concatList");
509
+ for (var i = 0; i < n; i++) _appendOwn(out, k + i, _ownAt(b, i));
510
+ return out;
511
+ }
512
+ // @enforced-by behavioral -- the same RED vector pins the copy form
513
+ function copyList(list, start, end) {
514
+ var n = _ownLength(list, "copyList");
515
+ var s0 = _ownBound(start, 0, "copyList");
516
+ var e0 = _ownBound(end, n, "copyList");
517
+ var s = s0 < 0 ? (n + s0 < 0 ? 0 : n + s0) : (s0 > n ? n : s0);
518
+ var e = e0 < 0 ? (n + e0 < 0 ? 0 : n + e0) : (e0 > n ? n : e0);
519
+ var out = [];
520
+ var k = 0;
521
+ for (var i = s; i < e; i++) _appendOwn(out, k++, _ownAt(list, i));
522
+ return out;
523
+ }
105
524
  /** @internal The in-place sort, captured at load. A DER SET OF is ordered by its encoded bytes, so the
106
525
  * sort decides the bytes emitted: MEASURED, a replaced `slice` or `sort` made an attribute set encode a
107
526
  * member other than the one that was validated, on a path whose output is then signed. */
@@ -136,7 +555,40 @@ var _mapHas = uncurry(Map.prototype.has);
136
555
  var _weakGet = uncurry(WeakMap.prototype.get);
137
556
  var _weakSet = uncurry(WeakMap.prototype.set);
138
557
  var _weakHas = uncurry(WeakMap.prototype.has);
558
+ /** @internal A WeakSet's own pair. `WeakMap.prototype.has` throws on a WeakSet receiver, so a module
559
+ * marking objects in a WeakSet needs these rather than the WeakMap captures above. A marker read
560
+ * this way is what says an object came from a verifying producer rather than from a caller. */
561
+ var _weakSetAdd = uncurry(WeakSet.prototype.add);
562
+ var _weakSetHas = uncurry(WeakSet.prototype.has);
139
563
  var _taSet = uncurry(Uint8Array.prototype.set);
564
+ /** @internal The three accessors a byte view is described by, taken off `%TypedArray%.prototype`
565
+ * itself so none of them is read through a replaceable property at the call. */
566
+ var _taProto = _getPrototypeOf(Uint8Array.prototype);
567
+ var _taBuffer = getter(_taProto, "buffer", "%TypedArray%.prototype");
568
+ var _taByteOffset = getter(_taProto, "byteOffset", "%TypedArray%.prototype");
569
+ var _taLength = getter(_taProto, "length", "%TypedArray%.prototype");
570
+ /** @internal A byte slice that consults NO construction protocol. `subarray` runs
571
+ * TypedArraySpeciesCreate, which reads `constructor` off the receiver and then `Symbol.species` off
572
+ * that, so a hostile species returns a fabricated object in place of the slice: answering with the
573
+ * expected RP ID hash for a 32-byte slice made an assertion produced for another relying party
574
+ * satisfy `expectedRpId`, while the signature was still verified over the original bytes. This
575
+ * builds the view from the buffer and offset directly, which is what `subarray` would have produced
576
+ * and shares the same memory, so it is a drop-in for it.
577
+ *
578
+ * `intrinsic.subarray` stays correct wherever the slice only feeds a length or a copy, so no
579
+ * rename-proof shape separates the two uses. The guard is the conformance vector in
580
+ * `guard-intrinsic.test.js`, which poisons a buffer's own `constructor` with a hostile species and
581
+ * asserts in the same run that `subarray` IS steered and this one is not. */
582
+ // @enforced-by behavioral -- a RED vector poisons a buffer's constructor and pins both outcomes
583
+ function byteSlice(buf, start, end) {
584
+ var len = _taLength(buf);
585
+ var s0 = _ownBound(start, 0, "byteSlice");
586
+ var e0 = _ownBound(end, len, "byteSlice");
587
+ var s = s0 < 0 ? 0 : (s0 > len ? len : s0);
588
+ var e = e0 > len ? len : e0;
589
+ if (e < s) e = s;
590
+ return _bufferFrom(_taBuffer(buf), _taByteOffset(buf) + s, e - s);
591
+ }
140
592
  var _hasOwn = uncurry(Object.prototype.hasOwnProperty);
141
593
  var _String = String;
142
594
  var _Number = Number;
@@ -224,6 +676,12 @@ module.exports = Object.freeze({
224
676
  byteLength: _bufferByteLength,
225
677
  compare: _bufferCompare,
226
678
  bufferEquals: _bufferEquals,
679
+ readUInt8: _readUInt8,
680
+ readUInt16BE: _readUInt16BE,
681
+ readUInt32BE: _readUInt32BE,
682
+ readUIntBE: _readUIntBE,
683
+ writeUInt16BE: _writeUInt16BE,
684
+ writeUInt32BE: _writeUInt32BE,
227
685
  keyEquals: _keyEquals,
228
686
  isView: _isView,
229
687
  isInteger: _isInteger,
@@ -240,6 +698,7 @@ module.exports = Object.freeze({
240
698
  assign: _objectAssign,
241
699
  freeze: _objectFreeze,
242
700
  isExtensible: _isExtensible,
701
+ isFrozen: _isFrozen,
243
702
  ownKeys: _ownKeys,
244
703
  stringify: _jsonStringify,
245
704
  floor: _mathFloor,
@@ -269,6 +728,7 @@ module.exports = Object.freeze({
269
728
  promiseAny: _promiseAny,
270
729
  promiseTry: _promiseTry,
271
730
  promiseWithResolvers: _promiseWithResolvers,
731
+ chain: chain,
272
732
  setter: setter,
273
733
  URL: _URL,
274
734
  urlCanParse: _urlCanParse,
@@ -293,6 +753,17 @@ module.exports = Object.freeze({
293
753
  every: _arrEvery,
294
754
  some: _arrSome,
295
755
  indexOf: _arrIndexOf,
756
+ reduce: _arrReduce,
757
+ mapList: mapList,
758
+ selectList: selectList,
759
+ ownIndexOf: ownIndexOf,
760
+ everyOwn: everyOwn,
761
+ allOf: allOf,
762
+ settledOf: settledOf,
763
+ copyList: copyList,
764
+ concatList: concatList,
765
+ splitChar: splitChar,
766
+ append: append,
296
767
  sort: _arrSort,
297
768
  concat: _arrConcat,
298
769
  arraySlice: _arrSlice,
@@ -324,7 +795,10 @@ module.exports = Object.freeze({
324
795
  weakGet: _weakGet,
325
796
  weakSet: _weakSet,
326
797
  weakHas: _weakHas,
798
+ weakSetAdd: _weakSetAdd,
799
+ weakSetHas: _weakSetHas,
327
800
  typedArraySet: _taSet,
801
+ byteSlice: byteSlice,
328
802
  Set: _Set,
329
803
  Map: _Map,
330
804
  WeakMap: _WeakMap,