@blamejs/pki 0.6.14 → 0.6.16

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 (112) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/lib/acme.js +59 -815
  3. package/lib/asn1-der.js +7 -245
  4. package/lib/attrcert-sign.js +12 -260
  5. package/lib/attrcert-verify.js +1 -7
  6. package/lib/byte-reader.js +0 -8
  7. package/lib/byte-writer.js +0 -11
  8. package/lib/cbor-det.js +0 -54
  9. package/lib/cmc-build.js +15 -357
  10. package/lib/cmc-verify.js +6 -239
  11. package/lib/cmp-build.js +41 -317
  12. package/lib/cmp-session.js +73 -760
  13. package/lib/cmp-verify.js +32 -488
  14. package/lib/cms-compress.js +3 -32
  15. package/lib/cms-decrypt.js +29 -294
  16. package/lib/cms-encrypt.js +14 -234
  17. package/lib/cms-sign.js +29 -324
  18. package/lib/cms-verify.js +9 -500
  19. package/lib/composite-kem.js +2 -102
  20. package/lib/composite-sig.js +1 -77
  21. package/lib/constants.js +0 -249
  22. package/lib/crl-sign.js +9 -237
  23. package/lib/crl-verify.js +1 -10
  24. package/lib/crmf-sign.js +19 -198
  25. package/lib/crmf-verify.js +1 -12
  26. package/lib/csr-sign.js +3 -34
  27. package/lib/csr-verify.js +1 -12
  28. package/lib/ct.js +28 -253
  29. package/lib/edwards-point.js +10 -44
  30. package/lib/est.js +28 -764
  31. package/lib/framework-error.js +4 -182
  32. package/lib/guard-all.js +1 -58
  33. package/lib/guard-async.js +1 -36
  34. package/lib/guard-bytes.js +6 -650
  35. package/lib/guard-compress.js +5 -102
  36. package/lib/guard-crypto.js +1 -40
  37. package/lib/guard-der.js +2 -93
  38. package/lib/guard-encoding.js +2 -60
  39. package/lib/guard-header.js +1 -36
  40. package/lib/guard-identifier.js +7 -531
  41. package/lib/guard-intrinsic.js +1 -150
  42. package/lib/guard-json.js +10 -73
  43. package/lib/guard-limits.js +1 -77
  44. package/lib/guard-list.js +1 -49
  45. package/lib/guard-name.js +3 -209
  46. package/lib/guard-parsed.js +7 -335
  47. package/lib/guard-range.js +1 -71
  48. package/lib/guard-secret.js +1 -102
  49. package/lib/guard-text.js +1 -64
  50. package/lib/guard-time.js +1 -97
  51. package/lib/hpke.js +3 -105
  52. package/lib/http-digest.js +14 -142
  53. package/lib/http-retry-after.js +1 -47
  54. package/lib/http-transport.js +21 -131
  55. package/lib/inspect.js +30 -284
  56. package/lib/ip-utils.js +6 -47
  57. package/lib/jose.js +7 -142
  58. package/lib/key.js +2 -67
  59. package/lib/lint.js +9 -194
  60. package/lib/merkle.js +1 -27
  61. package/lib/mime.js +9 -82
  62. package/lib/ocsp-request-verify.js +1 -14
  63. package/lib/ocsp-verify.js +1 -82
  64. package/lib/ocsp.js +11 -169
  65. package/lib/oid.js +5 -337
  66. package/lib/path-validate.js +103 -1492
  67. package/lib/pbes2.js +2 -89
  68. package/lib/pkcs12-build.js +31 -379
  69. package/lib/pki-build.js +64 -290
  70. package/lib/rc2.js +2 -18
  71. package/lib/rfc3339.js +4 -27
  72. package/lib/scep.js +140 -286
  73. package/lib/schema-all.js +0 -122
  74. package/lib/schema-attrcert.js +4 -146
  75. package/lib/schema-c509.js +153 -802
  76. package/lib/schema-cmc.js +5 -220
  77. package/lib/schema-cmp.js +2 -223
  78. package/lib/schema-cms.js +13 -427
  79. package/lib/schema-crl.js +5 -68
  80. package/lib/schema-crmf.js +6 -167
  81. package/lib/schema-csr.js +1 -54
  82. package/lib/schema-csrattrs.js +2 -87
  83. package/lib/schema-engine.js +0 -152
  84. package/lib/schema-ocsp.js +0 -117
  85. package/lib/schema-pkcs12.js +2 -93
  86. package/lib/schema-pkcs8.js +3 -35
  87. package/lib/schema-pkix.js +24 -655
  88. package/lib/schema-smime.js +0 -54
  89. package/lib/schema-tsp.js +3 -99
  90. package/lib/schema-x509.js +4 -63
  91. package/lib/shbs.js +11 -95
  92. package/lib/sign-scheme.js +2 -97
  93. package/lib/sigstore.js +9 -169
  94. package/lib/sleep.js +2 -8
  95. package/lib/smime.js +15 -408
  96. package/lib/tls-cert-compress.js +0 -62
  97. package/lib/trust.js +19 -185
  98. package/lib/tsp-sign.js +16 -270
  99. package/lib/validator-all.js +1 -30
  100. package/lib/validator-attcert.js +2 -46
  101. package/lib/validator-cose.js +2 -153
  102. package/lib/validator-keydesc.js +1 -37
  103. package/lib/validator-sig.js +1 -46
  104. package/lib/validator-tls.js +1 -88
  105. package/lib/validator-tpm.js +19 -122
  106. package/lib/verify-seam.js +1 -24
  107. package/lib/webauthn-mds.js +3 -400
  108. package/lib/webauthn.js +12 -833
  109. package/lib/webcrypto.js +5 -485
  110. package/lib/x509-sign.js +4 -108
  111. package/package.json +1 -1
  112. package/sbom.cdx.json +6 -6
@@ -1,30 +1,14 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // Copyright (c) blamejs contributors
3
3
  "use strict";
4
- //
5
- // @internal -- no operator-facing namespace. The documented surface is the
6
- // primitives whose input boundaries compose these guards (pki.asn1.decode,
7
- // pki.cbor.decode, pki.ct.parseSctList, pki.webcrypto.*).
8
- //
4
+ // @internal
9
5
  var async = require("./guard-async");
10
6
  var identifier = require("./guard-identifier");
11
7
  var time = require("./guard-time");
12
8
  var intrinsic = require("./guard-intrinsic");
13
- // The slot predicates, snapshotted at load. `util.types` is an ordinary object, so reading a
14
- // predicate off it at call time would let a caller decide what this guard calls a typed array, a
15
- // DataView, an ArrayBuffer or a Proxy -- which is every question this module asks about a value it
16
- // was handed.
17
9
  var util = { types: intrinsic.types };
18
10
  var _isArray = intrinsic.isArray;
19
- // The Buffer constructor, taken at load. It is how this module turns a backing store into
20
- // something the toolkit can read or clear, so one returning a buffer over DIFFERENT memory hands
21
- // every later step a decoy: a wipe then zeroes the decoy while the plaintext it was aimed at stays
22
- // readable, and every check in between still passes.
23
11
  var _bufferFrom = intrinsic.bufferFrom;
24
- // The rest of what this module reads from the runtime while it is deciding something. `isView` is
25
- // how it recognizes the shape whose backing store must be refused when shared, and the reflective
26
- // operations are how it inspects a value honestly; a replacement for any of them answers the
27
- // question this guard asked on the caller's behalf. See guard-intrinsic for the whole set.
28
12
  var _isView = intrinsic.isView;
29
13
  var _isBuffer = intrinsic.isBuffer;
30
14
  var _asyncIterator = intrinsic.asyncIterator;
@@ -37,9 +21,6 @@ var _objectKeys = intrinsic.keys;
37
21
  var _isExtensible = intrinsic.isExtensible;
38
22
  var _ownKeys = intrinsic.ownKeys;
39
23
  var _stringify = intrinsic.stringify;
40
- // The array operations, uncurried. They run on arrays this module owns, so `Array.prototype` is
41
- // what a caller can still reach; a `forEach` replaced with a no-op makes a walk over real elements
42
- // report nothing, and whatever is keyed on that walk then passes vacuously.
43
24
  var _forEach = intrinsic.forEach;
44
25
  var _map = intrinsic.map;
45
26
  var _filter = intrinsic.filter;
@@ -47,9 +28,6 @@ var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
47
28
  var _setForEach = intrinsic.uncurry(Set.prototype.forEach);
48
29
  var _mapForEach = intrinsic.uncurry(Map.prototype.forEach);
49
30
  var _String = intrinsic.String;
50
- // The constructor the private copy of a caller's Date is built with. A replacement returns an
51
- // object of its own choosing, and the snapshot that is supposed to be ours carries the caller's
52
- // instant only if they let it.
53
31
  var _Date = intrinsic.Date;
54
32
  var _apply = intrinsic.apply;
55
33
  var _promiseFinally = intrinsic.promiseFinally;
@@ -57,24 +35,14 @@ var _ArrayBuffer = intrinsic.ArrayBuffer;
57
35
  var _Uint8Array = intrinsic.Uint8Array;
58
36
  var _DataView = intrinsic.DataView;
59
37
  var _ObjectProto = intrinsic.ObjectProto;
60
- // The collection operations. The cycle-safe chain walks are a `Set` this module owns, and the copy
61
- // writes bytes through the typed-array `set`; a replacement for either decides what the walk sees
62
- // or what the copy contains.
63
38
  var _setAdd = intrinsic.setAdd;
64
39
  var _setHas = intrinsic.setHas;
65
40
  var _mapSet = intrinsic.mapSet;
66
41
  var _taSet = intrinsic.typedArraySet;
67
42
  var _Set = intrinsic.Set;
68
43
  var _Map = intrinsic.Map;
69
- // Appended by index rather than through `push`, so the growth reads no prototype method at all.
70
44
  function _append(arr, v) { _defineProperty(arr, arr.length, { value: v, writable: true, enumerable: true, configurable: true }); }
71
45
 
72
- // The array's OWN element indices below `length`, the positions it actually holds rather than the ones
73
- // a read resolves. A hole reads through the prototype chain, so enumerating what reads resolve would
74
- // materialize an inherited index -- a polluted `Array.prototype[i]` among them -- as an own element on
75
- // the copy, importing a value the array never held. Copying own indices alone leaves the hole a hole,
76
- // so the caller-array density check the verbs apply sees the original sparsity and refuses it, rather
77
- // than the copy silently answering with a prototype-supplied element.
78
46
  function _ownArrayIndices(v, n) {
79
47
  var keys = _ownKeys(v);
80
48
  var out = [];
@@ -87,39 +55,12 @@ function _ownArrayIndices(v, n) {
87
55
  return out;
88
56
  }
89
57
 
90
- // isByteSource(x) -> boolean: is this one of the four forms the toolkit calls bytes?
91
- //
92
- // A Buffer, any typed-array view, a DataView, or a bare ArrayBuffer. Exported so a door deciding
93
- // whether an argument is bytes asks the module that finally reads them, instead of restating the
94
- // list. A restatement narrows without anyone noticing. An `x instanceof ArrayBuffer` at such a
95
- // door turns away a real buffer from another realm, and the caller's container is then accepted
96
- // at one door and refused at the next.
97
58
  // @enforced-by behavioral -- a narrowed restatement of a list has no rename-proof code shape;
98
- // the RED vector (a byte form accepted by one door and refused by the other) is the guard.
99
59
  function isByteSource(x) {
100
60
  return _isBuffer(x) || _isView(x) || _isArrayBuffer(x);
101
61
  }
102
62
 
103
- // asyncStreamOf(x) -> a LAZY single-use async iterable of x's byte chunks, or null when x is not a
104
- // byte stream.
105
- //
106
- // A door offering both a byte source and a streamed content (an async iterable of byte chunks) asks
107
- // this ONE module which it has, instead of re-inlining the `for await` protocol test and drifting on
108
- // what counts. It reads x's Symbol.asyncIterator EXACTLY ONCE, captures that method, and returns a
109
- // thin iterable that CALLS it only when the consumer drives the stream. Deferring the call matters
110
- // twice: the underlying iterator is acquired once, in the digest engine, so reading the protocol
111
- // property a second time downstream cannot fire a one-shot or stateful accessor and refuse a stream a
112
- // direct `for await` accepts; AND a caller whose iterator factory opens a file or socket has that
113
- // resource opened only on a path that will actually consume it, never on a pre-hash rejection (a
114
- // missing detached option, an empty signer list, a message needing no streamed digest) that would
115
- // otherwise acquire and leak it. A byte source is bytes, never a stream, EVEN when a caller attached a
116
- // Symbol.asyncIterator to it: the byte-source classification wins and is checked FIRST, so a Buffer /
117
- // typed array / DataView goes down the byte path every time and its own accessors are never invoked
118
- // here. A callable carrying the method is a valid async iterable that `for await` consumes, so it too
119
- // yields a stream.
120
63
  // @enforced-by behavioral -- a lazy stream wrapper has no rename-proof code shape; the RED vectors (a
121
- // stream produced where a byte source is not, a one-shot-accessor stream still consumed, and the
122
- // factory NOT invoked until the stream is driven) are the guard.
123
64
  function asyncStreamOf(x) {
124
65
  if (isByteSource(x) || x == null || (typeof x !== "object" && typeof x !== "function")) return null;
125
66
  var acquire = x[_asyncIterator];
@@ -129,98 +70,36 @@ function asyncStreamOf(x) {
129
70
  return stream;
130
71
  }
131
72
 
132
- // A streamed content driven through the engine's digestStream / encryptStream reports a malformed chunk
133
- // or iterator in the ENGINE's domain: a non-byte chunk is webcrypto/data, and a malformed async-iterator
134
- // protocol (a non-callable next, or a factory returning a non-iterator) is webcrypto/syntax. Rethrow both
135
- // in the CALLER's domain through its typed factory E, so the public verb keeps its own <ns>/bad-input
136
- // contract for malformed streamed content rather than leaking the engine code; a caller's own next()
137
- // fault (any other error) is rethrown unchanged. E(code, msg, cause) is the caller's error factory. Always
138
- // throws. The digest / cipher algorithm names each verb passes are its own, so webcrypto/syntax here is
139
- // never an algorithm fault.
140
73
  function translateStreamError(e, E, code) {
141
74
  if (e && e.code === "webcrypto/data") throw E(code, "a streamed content chunk is not a byte source", e);
142
75
  if (e && e.code === "webcrypto/syntax") throw E(code, "the streamed content is not a valid async iterable of byte chunks", e);
143
76
  throw e;
144
77
  }
145
78
 
146
- // Is this value a byte store, asked of the internal slot rather than the prototype?
147
- //
148
- // `v instanceof ArrayBuffer` answers what a value inherits from, which is a different question
149
- // from what it holds. `_create(ArrayBuffer.prototype)` inherits everything and holds no
150
- // bytes, so it passes and the read that follows throws a raw TypeError out of a boundary whose
151
- // contract is a typed error. The same test also misses a real buffer from another realm, whose
152
- // prototype is that realm's. `util.types` reads the slot, so both answers come out right.
153
79
  function _isArrayBuffer(v) {
154
80
  return util.types.isArrayBuffer(v);
155
81
  }
156
82
 
157
- // Where a view's bytes actually are, asked of the language rather than of the view.
158
- //
159
- // `v.buffer`, `v.byteOffset` and `v.byteLength` are accessors on the shared typed-array prototype,
160
- // so `class Opts extends Uint8Array { get buffer() { return elsewhere; } }` answers all three
161
- // questions itself. Two things followed from reading them off the value. A getter that throws left
162
- // this module through the caller's own exception, from a boundary whose contract is a typed error.
163
- // And a getter that lied substituted the memory: an array holding AA AA AA AA whose `buffer`
164
- // returned another store had `view` and `snapshot` hand back that other store's bytes, so the
165
- // bytes a verb went on to hash, sign or parse were not the bytes in the array it was given.
166
- //
167
- // The getters are taken off the prototypes the language installs them on and called against the
168
- // view, which reaches the internal slot whatever the value's own class says. A subclass override
169
- // is then what it is -- a property of the caller's object -- and answers no question asked here.
170
83
  var _TYPED_ARRAY_PROTO = _getPrototypeOf(Uint8Array.prototype);
171
84
 
172
- // Uncurried as they are captured, so the reads below invoke them directly. A getter taken off a
173
- // prototype is still reachable there, and an own `call` assigned to it would shadow
174
- // `Function.prototype.call` and hand back whatever store, offset and length a caller chose. The
175
- // capture and the refusal for a runtime that lacks the accessor both live in guard-intrinsic, so
176
- // every guard measuring a view measures it the same way.
177
85
  var _uncurriedGetter = intrinsic.getter;
178
86
  var _taBuffer = _uncurriedGetter(_TYPED_ARRAY_PROTO, "buffer", "%TypedArray%.prototype");
179
87
  var _taByteOffset = _uncurriedGetter(_TYPED_ARRAY_PROTO, "byteOffset", "%TypedArray%.prototype");
180
88
  var _dvBuffer = _uncurriedGetter(DataView.prototype, "buffer", "DataView.prototype");
181
89
  var _dvByteOffset = _uncurriedGetter(DataView.prototype, "byteOffset", "DataView.prototype");
182
90
 
183
- // A DataView carries its own accessors rather than the typed-array ones, so the pair is chosen by
184
- // the value's slot. Either getter refuses a receiver with no slot behind it, which is the same
185
- // refusal a detached store gets, and every caller here already types that.
186
91
  function _storeOf(v) { return util.types.isDataView(v) ? _dvBuffer(v) : _taBuffer(v); }
187
92
  function _offsetOf(v) { return util.types.isDataView(v) ? _dvByteOffset(v) : _taByteOffset(v); }
188
93
  function _lengthOf(v) { return intrinsic.sizeOf(v); }
189
94
 
190
- // The Buffer over a view's own bytes. The single place this module turns a view into a Buffer, so
191
- // the intrinsic reads above cannot be skipped at one of the two call sites and kept at the other.
192
95
  function _reView(v) {
193
96
  return _bufferFrom(_storeOf(v), _offsetOf(v), _lengthOf(v));
194
97
  }
195
98
 
196
- // Which concrete typed-array kind a value is, decided by its slot and answered with this realm's
197
- // own constructor. `v.constructor` is an ordinary inherited property, so a subclass answers it and
198
- // a copy built through it is whatever the caller said.
199
- //
200
- // The pairs are DERIVED from what this runtime offers, never written out. A hand-written list is
201
- // complete on the day it is written and silently short afterwards: `Float16Array` landed on Node 24
202
- // and a list drafted before it refused the kind outright, since the fallback that used to catch it
203
- // was `v.constructor` -- which is the read this table exists to replace. Deriving covers the next
204
- // kind on the day the runtime exposes its predicate, and covers nothing the runtime does not.
205
- //
206
- // `util.types` names each concrete kind's predicate `is<Constructor>`, so the global of that name
207
- // is the constructor for it. `BYTES_PER_ELEMENT` on the CONSTRUCTOR is what separates a concrete
208
- // kind from the umbrella predicates: `isTypedArray` has no `TypedArray` global to pair with, and
209
- // `isArrayBufferView` would pair with none either.
210
- // The predicate FUNCTION is held, never its name. A name is looked up afresh on every call, and
211
- // `util.types` is an ordinary object: replacing a predicate on it after this module loads would
212
- // hand the kind decision, and with it the constructor the copy is built from, to whoever did.
213
- // Reading it once at load leaves nothing to replace.
214
- // The two string operations in this table run AT LOAD, in the same statement that reads
215
- // `util.types` once and for the same reason. Nothing a caller can replace has run yet, so there is
216
- // no live read to remove; capturing them would only move the question one line earlier.
217
- // A util.types predicate that names a concrete typed-array kind: "is" + one-or-more alphanumerics +
218
- // "Array" (e.g. "isUint8Array"), decided character by character so no regex match protocol -- which
219
- // re-dispatches through a replaceable `exec` -- stands between this table and the runtime it reads.
220
99
  function _isTypedArrayPredName(name) {
221
100
  var n = name.length;
222
- if (n < 8) return false; // "is" + >=1 middle char + "Array"
223
- if (_charCodeAt(name, 0) !== 105 || _charCodeAt(name, 1) !== 115) return false; // "is"
101
+ if (n < 8) return false;
102
+ if (_charCodeAt(name, 0) !== 105 || _charCodeAt(name, 1) !== 115) return false;
224
103
  var tail = "Array";
225
104
  for (var k = 0; k < 5; k++) { if (_charCodeAt(name, n - 5 + k) !== _charCodeAt(tail, k)) return false; }
226
105
  for (var i = 2; i < n - 5; i++) {
@@ -250,10 +129,6 @@ function _concreteKindOf(v) {
250
129
  return null;
251
130
  }
252
131
 
253
- // A name for a refused value, for the message alone. Taken from what the value IS, since
254
- // `v.constructor.name` is two ordinary property reads a caller answers: a getter under either one
255
- // took the refusal below out through the caller's exception, in place of the typed error whose
256
- // whole purpose here is to say why the value was refused.
257
132
  var _NAMED_KINDS = _filter([
258
133
  ["isNativeError", "Error"], ["isRegExp", "RegExp"], ["isPromise", "Promise"],
259
134
  ["isWeakMap", "WeakMap"], ["isWeakSet", "WeakSet"], ["isMap", "Map"], ["isSet", "Set"],
@@ -270,23 +145,11 @@ function _kindName(v) {
270
145
  function _article(name) {
271
146
  var c = name.length > 0 ? _charCodeAt(name, 0) : 0;
272
147
  var vowel = c === 65 || c === 69 || c === 73 || c === 79 || c === 85 ||
273
- c === 97 || c === 101 || c === 105 || c === 111 || c === 117; // A E I O U, either case
148
+ c === 97 || c === 101 || c === 105 || c === 111 || c === 117;
274
149
  return vowel ? "an" : "a";
275
150
  }
276
151
 
277
- // outputView(input, ErrorClass, code, label) -> a Buffer aliasing a caller's view, for WRITING.
278
- //
279
- // The same slot-based re-view as `view`, without the shared-memory refusal. That refusal answers a
280
- // question about INPUT: bytes another thread can rewrite after they have been checked cannot be
281
- // checked at all. A write target is the other direction. The caller is asking to be handed random
282
- // bytes in memory they chose, and choosing shared memory is a decision they are entitled to make;
283
- // `crypto.getRandomValues` on a `SharedArrayBuffer`-backed view is ordinary, and both the platform
284
- // and this runtime fill it. Refusing it here turned a supported W3C call into an error.
285
- //
286
- // The bytes still come back through the intrinsic accessors, so a subclass cannot redirect the
287
- // write to memory the caller does not own, and a detached store is still refused.
288
152
  // @enforced-by behavioral -- an input door reaching for this instead of `view` has no rename-proof
289
- // code shape; the RED vectors (a shared view filled here, and a detached one refused) are the guard.
290
153
  function outputView(input, ErrorClass, code, label) {
291
154
  if (!util.types.isUint8Array(input) && !_isView(input)) {
292
155
  throw _raise(ErrorClass, code, label + ": expected a Buffer / TypedArray to write into");
@@ -298,27 +161,11 @@ function outputView(input, ErrorClass, code, label) {
298
161
  }
299
162
  }
300
163
 
301
- // lengthOf(view) -> how many bytes a view holds, read the same way.
302
- //
303
- // For the boundaries that size a value rather than read it: a response-body cap, an emptiness
304
- // test. `length` is an accessor on the shared typed-array prototype AND shadowable by an own
305
- // property on any instance, so `_defineProperty(buf, "length", { get: () => 0 })` answers
306
- // for a Buffer holding megabytes. A cap measured that way is a cap its caller sets.
307
164
  // @enforced-by behavioral -- `x.length` is the ordinary spelling wherever the value is this
308
- // toolkit's own, so the misuse has no rename-proof code shape; the RED vector (a planted `length`
309
- // getting a body past a documented size cap) is the guard.
310
165
  function lengthOf(view) {
311
166
  return _lengthOf(view);
312
167
  }
313
168
 
314
- // Shared memory is refused rather than accepted as bytes.
315
- //
316
- // This module exists to hand a verb bytes its caller can no longer change once they have been
317
- // checked, and a SharedArrayBuffer is writable from another thread for as long as it lives, so
318
- // no copy taken here can hold that promise for the value the caller passed. Copying it into a
319
- // private ArrayBuffer would keep the bytes and change the kind, which is the same-kind contract
320
- // broken quietly; refusing says so instead. The message names the shape, since "not a byte
321
- // container" about a container that plainly holds bytes reads as the toolkit being wrong.
322
169
  function _refuseShared(v, ErrorClass, code, label) {
323
170
  if (util.types.isSharedArrayBuffer(v) ||
324
171
  (_isView(v) && util.types.isSharedArrayBuffer(_storeOf(v)))) {
@@ -328,43 +175,8 @@ function _refuseShared(v, ErrorClass, code, label) {
328
175
  }
329
176
  }
330
177
 
331
- // guard-bytes -- fail-closed coercion of an untrusted byte-source input to a
332
- // Buffer view. One of the enforced choke points of the guard family: a
333
- // codebase-patterns detector requires every byte-input boundary to route
334
- // through here, so the defense below cannot be forgotten at a new boundary.
335
- //
336
- // Defends the detached-buffer fail-OPEN: a transferred / structuredClone'd
337
- // Buffer or view has a detached backing ArrayBuffer and reads as ZERO-LENGTH.
338
- // An identity fast-path (`_isBuffer(x) return x`) that skips the re-view
339
- // hands the caller an empty buffer, so a downstream digest / signature / parse
340
- // silently processes EMPTY input instead of failing (CWE-20 improper input
341
- // validation feeding a CWE-347-style verification-of-nothing). Always re-viewing
342
- // through Buffer.from(x.buffer, x.byteOffset, x.byteLength) turns the detached
343
- // read into a typed reject at the boundary. Size / length-field allocation
344
- // bounds (CWE-770 / CWE-400, the parser-DoS class) are not enforced here. They
345
- // are per-format (a multi-MB CRL is legitimate, a Merkle proof is tiny), so they
346
- // live in guard-params and each decoder's own cap.
347
178
 
348
- // Choosing between `view` and `snapshot` at a boundary: a byte argument that is read only
349
- // during the synchronous pass that received it can be re-viewed, because nothing can run
350
- // between the check and the use. One that survives that pass (stored in state, compared
351
- // after an await, embedded into output the verb assembles later) must be snapshotted, or the
352
- // caller can still rewrite the bytes after they were validated. The exceptions are the two
353
- // places holding a caller's SECRET, where a copy is the worse defect: a password or a private
354
- // key is re-viewed and left borrowed only when this module also clears the copy it made, so
355
- // no plaintext duplicate outlives the derivation.
356
179
 
357
- // The guard family threads a caller's typed error under two conventions: most guards take a
358
- // FACTORY (`E(code, message, cause)`, no `new`) because the engines that call them (sign-scheme,
359
- // composite-sig, pki-build) carry a bound factory that prefixes the caller's domain onto the
360
- // code; guard-bytes and guard-header take the error CLASS. A boundary that has only one of the two
361
- // would otherwise have to hand-roll the re-view to reach this guard at all, which is precisely what
362
- // the re-inline detector forbids, so accept either: a class (its prototype is an Error) is
363
- // constructed, anything else is called.
364
- // Whether E's instances would be Errors, decided by walking the prototype chain with the captured
365
- // `getPrototypeOf` rather than by `instanceof`, which asks `Error[Symbol.hasInstance]` at call time.
366
- // The walk carries the same visited set _protoChainIsCyclic uses, because a Proxy can report a
367
- // cyclic chain and an unbounded walk would hang here rather than at the boundary that refuses one.
368
180
  var _ErrorProto = Error.prototype;
369
181
  function _isErrorClass(E) {
370
182
  if (typeof E !== "function") return false;
@@ -381,20 +193,7 @@ function _raise(E, code, message, cause) {
381
193
  return _isErrorClass(E) ? new E(code, message, cause) : E(code, message, cause);
382
194
  }
383
195
 
384
- // view(input, ErrorClass, code, label) -> Buffer view | throws ErrorClass(code, msg, cause)
385
- // Accepts a Buffer / Uint8Array -- the DER / CBOR / CT / Merkle input contract.
386
- // ErrorClass MUST be a withCause PkiError subclass (the raw detach failure is
387
- // threaded as the cause).
388
- // The kind is read from the slot. A prototype test turns away a real Uint8Array built in another
389
- // realm, whose prototype is that realm's, and tells the caller their bytes are not bytes. It
390
- // admits the mirror shape, `_create(Uint8Array.prototype)`, which holds none; that one comes
391
- // back as this guard's own code either way, since the read below is wrapped, so reading the slot
392
- // only moves the refusal to the door from the failing read.
393
196
  // @enforced-by guard-shape-reinlined
394
- // The shape covers the re-view however the view is constructed. It was anchored on `Buffer.from(`
395
- // alone, and `Buffer.from(new Uint8Array(v.buffer, v.byteOffset, v.byteLength))` slipped past it
396
- // into two format modules, where a caller's subclass could answer all three accessors and hand the
397
- // copy a different store than the array held.
398
197
  // @guard-shape (?:Buffer\.from|new\s+[A-Za-z_$][\w$]*Array)\(\s*(?:new\s+[A-Za-z_$][\w$]*Array\(\s*)?([A-Za-z_$][\w$]*)\.buffer\s*,\s*\1\.byteOffset
399
198
  function view(input, ErrorClass, code, label) {
400
199
  _refuseShared(input, ErrorClass, code, label);
@@ -408,14 +207,6 @@ function view(input, ErrorClass, code, label) {
408
207
  throw _raise(ErrorClass, code, label + ": expected a Buffer / Uint8Array");
409
208
  }
410
209
 
411
- // source(input, ErrorClass, code, label) -> Buffer | throws ErrorClass
412
- // Accepts the full W3C BufferSource (Buffer / TypedArray view / raw ArrayBuffer)
413
- // -- the WebCrypto input contract. Re-views in every case, sharing the caller's
414
- // memory instead of taking a copy: `Buffer.from(arrayBuffer)` wraps the backing
415
- // store, it does not duplicate it. That is what makes this safe to call before a
416
- // size ceiling has been applied (nothing is materialized), and it is also why a
417
- // caller that must hold the bytes across an await wants `snapshotSource`, which
418
- // copies. Throws on a detached backing store.
419
210
  // @enforced-by guard-shape-reinlined (the re-view shape is declared on view above)
420
211
  function source(input, ErrorClass, code, label) {
421
212
  _refuseShared(input, ErrorClass, code, label);
@@ -430,156 +221,43 @@ function source(input, ErrorClass, code, label) {
430
221
  throw _raise(ErrorClass, code, label + ": expected a BufferSource (ArrayBuffer / TypedArray / Buffer)");
431
222
  }
432
223
 
433
- // snapshot(input, ErrorClass, code, label) -> private Buffer copy | throws ErrorClass
434
- //
435
- // The parse-then-verify time-of-check/time-of-use defense. A verification entry
436
- // point that PARSES its input synchronously and then VERIFIES a signature over
437
- // the same bytes in a later promise turn is reading the caller's memory twice
438
- // with an await in between. Every byte range the parse surfaced (the signed
439
- // content, the signer set, the values the verdict is built from) is a view into
440
- // that memory, so anything that rewrites the buffer in the gap makes the verdict
441
- // describe bytes other than the ones the signature was checked against
442
- // (CWE-367 TOCTOU reaching a CWE-347 wrong-verdict). The window is real without
443
- // an attacker in the process: a caller recycling a pooled read buffer across
444
- // concurrent verifies hits it by accident.
445
- //
446
- // So take one private copy at the boundary and read everything from it. `view`
447
- // re-views and is the right guard where the input is consumed in one synchronous
448
- // pass; this is its sibling for the boundary that spans an await.
449
224
  // @enforced-by behavioral -- a copy has no rename-proof code shape to detect (any
450
- // `Buffer.from(x)` is one, and most are legitimate). The guard is the RED vector
451
- // that mutates the caller's buffer between parse and verify and asserts the
452
- // verdict still describes the bytes that were verified.
453
225
  function snapshot(input, ErrorClass, code, label) {
454
226
  return _bufferFrom(view(input, ErrorClass, code, label));
455
227
  }
456
228
 
457
- // snapshotSource(input, ErrorClass, code, label) -> private Buffer copy | throws
458
- // The same parse-then-verify defense as `snapshot`, over the whole W3C BufferSource
459
- // (raw ArrayBuffer / DataView / any typed-array view) and not only the
460
- // Buffer / Uint8Array contract. A parser that accepts a BufferSource must snapshot
461
- // the same set: leaving an ArrayBuffer or a DataView aliased reopens the window for
462
- // exactly the inputs that took the wider path in.
463
229
  // @enforced-by behavioral -- a copy has no rename-proof shape to detect; the guard
464
- // is the RED vector that mutates the caller's backing buffer across the await.
465
230
  function snapshotSource(input, ErrorClass, code, label) {
466
231
  return _bufferFrom(source(input, ErrorClass, code, label));
467
232
  }
468
233
 
469
- // snapshotDeep(value, ErrorClass, code, label) -> a private copy of every byte leaf | throws
470
- //
471
- // `snapshot` closes the parse-then-verify window for one buffer. This closes it for a whole
472
- // caller-supplied spec: the object a producing verb is handed and then reads across several
473
- // promise turns while it resolves a key, hashes, and signs. Every byte the verb ends up
474
- // encoding reaches it through some field of that object, and the caller still owns all of them,
475
- // so a spec validated at entry and read again after the first turn need not describe the same
476
- // certificate, CRL, or request. It is the same defect as an aliased buffer, one level up: the
477
- // value that passed the checks and the value that gets signed are two different reads.
478
- //
479
- // Copies byte views (through `snapshotSource`, so a detached backing store is refused instead
480
- // of copied as empty), arrays, dates, and plain objects. Everything else (a string, number,
481
- // bigint, boolean, a CryptoKey, any class instance) is passed through by reference, because a
482
- // non-plain object is a platform or library handle whose identity is what makes it work; cloning
483
- // one would break it. `opts.maxDepth` bounds a cyclic or hostile structure; the cap is set far
484
- // above any real spec (the deepest is a certificate policy's UserNotice noticeRef, around 12).
485
- //
486
- // A spec that carries secret material must pass `opts.collect`, an array this fills with every
487
- // buffer it copied. Copying a password or a private key produces a plaintext duplicate, and a
488
- // module whose ownership rules say "a caller's Buffer is borrowed, so leave it alone" will not
489
- // clear it: the copy outlives the operation with no one accountable for it. Collect the copies
490
- // and zeroize them in a `finally`, so the fix for one defect does not open another.
491
234
  // @enforced-by behavioral -- a copy has no rename-proof code shape to detect (any `Buffer.from(x)`
492
- // is one). The guards are the RED vector that rewrites a field of the caller's spec after the
493
- // verb has returned its promise and asserts the emitted artifact carries the entry value, and
494
- // the vector that holds a reference to every copy and asserts it reads all-zero after the call.
495
235
  function snapshotDeep(value, ErrorClass, code, label, opts) {
496
236
  var o = opts || {};
497
237
  var cap = o.maxDepth == null ? 64 : o.maxDepth;
498
238
  return _deep(value, ErrorClass, code, label, cap, 0, o.collect || null);
499
239
  }
500
240
 
501
- // Is this object a handle, meaning something a copy would break instead of duplicate?
502
- //
503
- // The line is not "does it have Object.prototype". A caller's own class instance used as an
504
- // options bag is data, and passing it through by reference on the strength of its prototype left
505
- // exactly the window this exists to close: `cms.sign` accepts any non-Buffer object as options, so
506
- // an instance whose `signedAttributes` flipped to false after the call still reached the signing
507
- // turn. What a copy genuinely breaks is an object whose meaning lives somewhere other than its own
508
- // properties: a key handle, a live collection, a pending result. Those are named here, never
509
- // inferred, because inference gets it wrong in both directions: this engine's own CryptoKey carries
510
- // its Node key handle as an own property, so "has no own keys" would have copied it into a shell
511
- // that cannot sign, while a URL has none and would have copied into one that cannot be read.
512
- // isCryptoKeyLike is the toolkit's own answer to "is this a key handle", the same one key.js and
513
- // jose.js ask, so a foreign implementation's CryptoKey is recognized here too.
514
- // The WebCrypto surface a CryptoKey presents, and nothing else. A real one (this engine's, the
515
- // platform's, or another implementation's) carries exactly these (its key material lives in an
516
- // internal slot or a non-enumerable own property). A caller's options bag that happens to satisfy
517
- // the structural predicate carries its own fields alongside, and those are what give it away.
518
- // `Symbol.toStringTag` is the language's own name for what a value is, and a key handle carries it
519
- // as a non-enumerable own property. It answers no named option, so it is surface rather than data,
520
- // and naming it here is what lets the pass-through test below judge every key by the same rule it
521
- // judges every other property by.
522
- // A surface is a table of names, so it is built WITHOUT a prototype. An ordinary object literal
523
- // answers `surface["toString"]` with a function it inherited, and every table is then read as
524
- // though it listed `toString`, `constructor`, `valueOf`, `hasOwnProperty` and `__proto__` -- names
525
- // a caller can write, on an object that is passed on by reference. Membership has to be a fact
526
- // about the table rather than about what any object answers to a lookup.
527
- //
528
- // `Symbol.toStringTag` is on every surface: it is the language's own name for what a value is, a
529
- // key handle carries it as a non-enumerable own property, and it answers no named option.
530
241
  function _surface(names) {
531
242
  var t = _create(null);
532
243
  _forEach(names, function (n) { t[n] = 1; });
533
244
  t[Symbol.toStringTag] = 1;
534
245
  return t;
535
246
  }
536
- // `_handle` is this engine's own state on its own key object, the counterpart of the
537
- // `asymmetricKeyType` and `asymmetricKeyDetails` that Node puts on a KeyObject. What it holds
538
- // varies by algorithm -- a KeyObject for a signing key, the raw bytes for an HMAC one -- and it is
539
- // reachable only on a value already recognized as a key, whose material the caller holds anyway.
540
247
  var _CRYPTO_KEY_SURFACE = _surface(["type", "extractable", "algorithm", "usages",
541
248
  "asymmetricKeyType", "asymmetricKeyDetails", "_handle"]);
542
- // The same, for the other kinds whose state cannot be copied: what belongs to the kind, so that
543
- // anything else on the object is recognizably the caller's own and gets the refusal below.
544
249
  var _ERROR_SURFACE = _surface(["message", "stack", "name", "cause"]);
545
250
  var _REGEXP_SURFACE = _surface(["lastIndex", "source", "flags", "global", "ignoreCase", "multiline",
546
251
  "sticky", "unicode", "unicodeSets", "hasIndices", "dotAll"]);
547
252
  var _THENABLE_SURFACE = _surface(["then", "catch", "finally"]);
548
253
 
549
- // Is this an object whose state this module cannot read, and therefore cannot copy?
550
- //
551
- // Everything else is copied. Enumerating "handle shapes" to pass through was the wrong shape of
552
- // answer and lost repeatedly: every kind named as a handle turned out to be usable as an options
553
- // bag with fields glued on, and each new shape reopened the window for exactly the fields that
554
- // were glued on. There are only two honest outcomes for a caller's argument: copy it, or refuse
555
- // it. This names the small set where copying is impossible, so the refusal below can be the
556
- // rule for all of them at once, never a shape to be found later.
557
- // The surface an opaque kind is defined by, or null when the value is not one of them. A plain
558
- // object literal is never opaque whatever it looks like: it is data this module can read and copy,
559
- // and isCryptoKeyLike is structural by design so a literal can wear the key shape.
560
254
  function _opaqueSurface(v, ErrorClass, code, label) {
561
255
  var proto = _getPrototypeOf(v);
562
256
  if (proto === _ObjectProto || proto === null) return null;
563
- // Deliberately empty, and null-prototype so it stays empty: this surface is the allowed-field set
564
- // for a value with no enumerable contents, and on a `{}` a planted `Object.prototype[name]` reads
565
- // back as an allowed field, so a mutable one the caller added would pass the refusal.
566
257
  if (util.types.isWeakMap(v) || util.types.isWeakSet(v)) return _create(null);
567
- // The slot, not the prototype. This picks which surface an opaque object is copied through, and
568
- // `instanceof` asks `Error[Symbol.hasInstance]`, which a caller can answer. It also admits a real
569
- // Error from another realm, whose prototype is that realm's and which the prototype test refuses.
570
258
  if (util.types.isNativeError(v)) return _ERROR_SURFACE;
571
259
  if (util.types.isRegExp(v)) return _REGEXP_SURFACE;
572
- // A node:crypto KeyObject, read off its internal slot. `pki.hpke` documents one as a key input
573
- // and `pki.ct` names it too, and a copy of a key handle is not a key: its material lives behind
574
- // the slot, so what the copy holds is the shape of a key and none of the key. Recognized here so
575
- // it reaches the verb as itself, which is the same treatment a WebCrypto CryptoKey gets.
576
- // `util.types.isKeyObject` reads the slot, so it answers for a handle from any realm and says no
577
- // to `_create(KeyObject.prototype)`.
578
260
  if (util.types.isKeyObject(v)) return _CRYPTO_KEY_SURFACE;
579
- // Asking whether it is key-shaped reads its properties, and a value wearing a key's prototype
580
- // without a key behind it answers with a getter that throws: `_create(KeyObject.prototype)`
581
- // raises a raw TypeError from inside `type`. Typed here, like the `then` read below, so a
582
- // question this module asked on its own behalf cannot escape as somebody else's error.
583
261
  var keyLike;
584
262
  try {
585
263
  keyLike = require("./webcrypto").isCryptoKeyLike(v); // allow:inline-require -- circular load: webcrypto requires this module
@@ -587,34 +265,13 @@ function _opaqueSurface(v, ErrorClass, code, label) {
587
265
  throw _raise(ErrorClass, code, label + ": reading the key surface threw", e);
588
266
  }
589
267
  if (keyLike) return _CRYPTO_KEY_SURFACE;
590
- // Asking whether it is a thenable reads a property, and a caller's accessor can throw: the
591
- // same fault the copy itself types, so it is typed here too and never escapes raw from a
592
- // question this module asked on its own behalf.
593
268
  var then;
594
269
  try { then = v.then; }
595
270
  catch (e) { throw _raise(ErrorClass, code, label + ": reading \"then\" threw", e); }
596
- if (typeof then === "function") return _THENABLE_SURFACE; // a pending result, not a value
271
+ if (typeof then === "function") return _THENABLE_SURFACE;
597
272
  return null;
598
273
  }
599
274
 
600
- // Is this opaque object safe to pass through, carrying nothing beyond the surface its kind is
601
- // defined by? Anything more is the case with no safe answer: the object cannot be copied, and
602
- // passing it through would leave that data the caller's to change after the checks have read it.
603
- // Every reachable name is examined, not only the own ones; a verb reads a field by name and does
604
- // not care where on the chain it sits.
605
- // Can this name answer differently after the checks have read it? That is the whole question for a
606
- // value handed on BY REFERENCE, and it is a fact about the property rather than a guess about who
607
- // wrote it. An accessor answers afresh every read. A writable or configurable data property can be
608
- // assigned or redefined. A data property that is neither is settled: whatever the checks saw is
609
- // what the verb gets.
610
- //
611
- // Judged where the property is found, walking up as a read does. A `getPrototypeOf` trap can hand
612
- // back a fresh object forever, so the walk stops at one it has already visited, the same bound the
613
- // name walk uses.
614
- //
615
- // One limit, stated rather than papered over: a caller can still swap the whole prototype after the
616
- // call and change what an inherited name answers. That is true of every value passed by reference,
617
- // and a platform object's prototype is the platform's.
618
275
  function _canChangeAfterTheCheck(v, name) {
619
276
  var visited = new _Set();
620
277
  for (var o = v; o && !_setHas(visited, o); o = _getPrototypeOf(o)) {
@@ -622,30 +279,15 @@ function _canChangeAfterTheCheck(v, name) {
622
279
  var d = _getOwnPropertyDescriptor(o, name);
623
280
  if (!d) continue;
624
281
  if (d.get || d.set || d.writable || d.configurable) return true;
625
- // Settled where it sits. Reached through the chain it is settled only while nothing can be put
626
- // in front of it: an extensible receiver takes an own property of the same name at any time,
627
- // and the read then answers with that one. Own on the value itself, or a value nothing can be
628
- // added to, is the case where what was read is what stays.
629
282
  return o !== v && _isExtensible(v);
630
283
  }
631
284
  return false;
632
285
  }
633
286
 
634
- // Is what a settled binding POINTS AT settled too? A property that cannot be reassigned still
635
- // answers with whatever its value has become: a frozen `signingTime` holding a Date is a binding
636
- // nobody can move and an instant anybody can move, and `pki.cms.sign` signed 2030 while the
637
- // operator read 2040 off the same object afterwards. A primitive cannot change. Another handle is
638
- // settled exactly when the same question about it comes back clean, which is this function one
639
- // level down. Everything else is state the caller keeps, and this module would have copied it.
640
- //
641
- // Bounded, because the chain is the caller's to make as long as they like.
642
287
  var _SETTLED_DEPTH = 4;
643
288
  function _settledValueIsFixed(value, ErrorClass, code, label, depth) {
644
289
  if (value === null || (typeof value !== "object" && typeof value !== "function")) return true;
645
290
  if (depth >= _SETTLED_DEPTH) return false;
646
- // A Proxy answers every question through a handler, so it is never settled and asking is the
647
- // harm: reading its prototype runs a trap, and a trap that throws would leave this module over
648
- // a question it asked on its own behalf. `util.types.isProxy` reads the slot and runs nothing.
649
291
  if (util.types.isProxy(value)) return false;
650
292
  var surface = _opaqueSurface(value, ErrorClass, code, label);
651
293
  if (!surface) return false;
@@ -655,42 +297,8 @@ function _settledValueIsFixed(value, ErrorClass, code, label, depth) {
655
297
  function _opaqueFieldOutsideSurface(v, surface, ErrorClass, code, label, depth) {
656
298
  var keys = _namesToCopy(v, ErrorClass, code, label);
657
299
  for (var i = 0; i < keys.length; i++) {
658
- // The kind's own surface, and nothing else. Enumerability says how a property was written,
659
- // never who wrote it: `Object.defineProperty` is available to a caller as much as to a
660
- // platform, so skipping the non-enumerable ones let a field ride in on a handle that is
661
- // passed through BY REFERENCE and stays the caller's to change afterwards. A foreign RegExp
662
- // carrying a non-enumerable `detached` reached pki.cms.sign that way, and flipping it after
663
- // the call moved the content out of the message the call had already been asked to sign.
664
- //
665
- // The surfaces are what makes this affordable rather than a blanket refusal: each names what
666
- // the real platform object of that kind carries, so the ordinary value passes and anything
667
- // beyond it is the caller's. A callable value is no exemption either -- an option is read for
668
- // what it is, and `signedAttributes` holding a function is neither false nor a method of
669
- // anything.
670
300
  if (surface[keys[i]]) continue;
671
- // A symbol is not an option. Every verb reads its options by name, so nothing under a symbol
672
- // key reaches one, and refusing a handle for carrying one buys nothing. What it costs is real:
673
- // a CryptoKey from another WebCrypto implementation is a documented input, and an
674
- // implementation that keeps its internals under a symbol -- written the ordinary way, by
675
- // assignment -- would have its keys refused at every verb.
676
- //
677
- // The options door is unaffected and still refuses one. `assertKnownKeys` walks the bag a
678
- // caller passed as options and reports a symbol there, because a caller who wrote one meant it
679
- // as an option and no verb will ever read it. That is a different question from whether a key
680
- // handle may be handed on.
681
301
  if (typeof keys[i] === "symbol") continue;
682
- // A name outside the surface is refused only if it can still move. Enumerability was the old
683
- // test and it decided the wrong question: it describes how a property was written, and
684
- // `Object.defineProperty` belongs to a caller as much as to a platform, so a hidden `detached`
685
- // on a foreign RegExp rode into pki.cms.sign and moved the content out of the signed message
686
- // after the call. Position was no better -- a key is an argument in its own right at
687
- // `pki.csr.sign(spec, key)`, so refusing everything at the argument refused the key.
688
- //
689
- // Settled data is what an implementation's internals are: this engine writes `_handle` on a key
690
- // with neither `writable` nor `configurable`, so it cannot be reassigned or redefined, and
691
- // nothing the checks read about that key can change afterwards. A field a caller can still
692
- // assign to, redefine, or answer with a getter is the case this refusal is for -- whatever
693
- // kind of object it rides on, and wherever in the arguments that object sits.
694
302
  if (!_canChangeAfterTheCheck(v, keys[i]) &&
695
303
  _settledValueIsFixed(v[keys[i]], ErrorClass, code, label, depth || 0)) continue;
696
304
  return keys[i];
@@ -698,30 +306,15 @@ function _opaqueFieldOutsideSurface(v, surface, ErrorClass, code, label, depth)
698
306
  return null;
699
307
  }
700
308
 
701
- // A private copy of a byte value of the same kind the caller passed. The kind is
702
- // load-bearing: each verb's own field validators decide which byte forms that field accepts, and
703
- // most accept only Buffer / Uint8Array. Handing them a Buffer made from a DataView or a
704
- // Uint16Array would have those inputs quietly accepted, reinterpreted through a platform's own
705
- // element layout, where they were rejected before. Copying is not the place to decide what a
706
- // field takes, so the copy preserves the type and the validator still sees what it was given.
707
309
  function _copyBytesSameKind(v, ErrorClass, code, label, collect) {
708
- var src = source(v, ErrorClass, code, label); // re-views; a detached backing store is refused
709
- // Sized once, from the slot. `src.length` is a replaceable accessor, and it decides three things
710
- // here at once: how large the private store is, how much of it the returned view covers, and how
711
- // much of it goes on the wipe list. A number smaller than the truth puts a short Buffer on that
712
- // list, so `release` clears the front of a copy that still holds the rest of the secret.
310
+ var src = source(v, ErrorClass, code, label);
713
311
  var srcLen = _lengthOf(src);
714
312
  var owned = new _ArrayBuffer(srcLen);
715
313
  _taSet(new _Uint8Array(owned), src);
716
- // What `release` clears: a Buffer over the whole private store, whatever kind is handed back.
717
314
  if (collect) _append(collect, _bufferFrom(owned, 0, srcLen));
718
315
  if (_isBuffer(v)) return _bufferFrom(owned, 0, srcLen);
719
316
  if (_isArrayBuffer(v)) return owned;
720
317
  if (util.types.isDataView(v)) return new _DataView(owned);
721
- // The kind comes from the value's slot, never from `v.constructor` or `v.BYTES_PER_ELEMENT`.
722
- // Both are ordinary properties a subclass answers: a `constructor` that threw took this module
723
- // out through the caller's own exception, and a `BYTES_PER_ELEMENT` that lied built the copy
724
- // with a different element count and a different kind than the value it was copying.
725
318
  var Ctor = _concreteKindOf(v);
726
319
  if (!Ctor) {
727
320
  throw _raise(ErrorClass, code, label + ": a " +
@@ -731,16 +324,6 @@ function _copyBytesSameKind(v, ErrorClass, code, label, collect) {
731
324
  return new Ctor(owned, 0, srcLen / Ctor.BYTES_PER_ELEMENT);
732
325
  }
733
326
 
734
- // Is this value's prototype chain cyclic? A Proxy whose `getPrototypeOf` trap returns the proxy
735
- // itself makes one, and the engine permits it while the target stays extensible.
736
- //
737
- // It has to be asked before anything else this module does with the value. Almost every question
738
- // about a kind is an `instanceof`, and `instanceof` walks the prototype chain. On a cyclic chain
739
- // it exhausts the stack, and a raw RangeError escapes from a guard whose whole contract is a
740
- // typed error.
741
- //
742
- // Naming the shape is the fail-closed answer. An options bag cannot need a prototype chain that
743
- // loops, and copying one has no meaning to fall back to.
744
327
  function _protoChainIsCyclic(v) {
745
328
  var visited = new _Set();
746
329
  for (var o = v; o; o = _getPrototypeOf(o)) {
@@ -750,9 +333,6 @@ function _protoChainIsCyclic(v) {
750
333
  return false;
751
334
  }
752
335
 
753
- // Is a Proxy anywhere on this chain? The copy reads names from the whole chain, so one sitting
754
- // above a plain object decides what the copy takes while the original answers reads from its
755
- // `get` trap. Testing only the value handed in leaves that one line of indirection open.
756
336
  function _protoChainHasProxy(v) {
757
337
  var visited = new _Set();
758
338
  for (var o = v; o && !_setHas(visited, o); o = _getPrototypeOf(o)) {
@@ -762,153 +342,51 @@ function _protoChainHasProxy(v) {
762
342
  return false;
763
343
  }
764
344
 
765
- // Give the copy of a collection the same prototype the original carries.
766
- //
767
- // The object branch does this with `_create(_getPrototypeOf(v))`, so an instance of a
768
- // caller's class keeps its methods. A collection branch builds a plain `[]`, `Map` or `Set`, and
769
- // a subclass of one holds its additions on a prototype above that. Copying the chain down onto a
770
- // plain array turns `class Opts extends Array { describe() {} }` into an array with `describe` as
771
- // an own function that nothing above supplies, which the check reads as a typed option and
772
- // refuses, though the same bag passed that check before the copy.
773
- //
774
- // A subclass of a built-in is the caller's own class, so this is the same trade the object branch
775
- // makes. The prototype is theirs and stays theirs, while every readable name is copied down so no
776
- // value is re-read through it after the checks have run.
777
- // The copy's class is this module's, never the caller's.
778
- //
779
- // A copy used to be given the original's prototype back, so that the walk which reports option
780
- // names read the copy the way it read the original. It does that anyway: a method the caller's
781
- // class defines is not a name that walk reports, so it is never copied across as one, and the two
782
- // sides agree without the prototype. Measured, not assumed -- the vectors compare both.
783
- //
784
- // What restoring it cost was the whole point of copying. The prototype is part of the argument, so
785
- // the copy went on dispatching into the caller's code: `list.map(...)` inside a signing verb
786
- // reached an override on an Array subclass, `getUTCFullYear()` reached one on a Date subclass, and
787
- // an override that threw surfaced the caller's own exception from inside a verb whose contract is
788
- // a typed error. Worse, a prototype can be rewritten after the call has begun, so a copy taken to
789
- // stop the argument changing under the verb changed with it.
790
345
  function _plainCopy(copy) { return copy; }
791
346
 
792
347
  function _deep(v, ErrorClass, code, label, cap, depth, collect) {
793
348
  if (depth > cap) throw _raise(ErrorClass, code, label + " is nested too deeply to copy");
794
349
  if (v == null || typeof v !== "object") return v;
795
350
  _refuseShared(v, ErrorClass, code, label);
796
- // The Proxy test comes FIRST, ahead of the cycle walk and every `instanceof` below, because
797
- // both of those read the prototype chain and a `getPrototypeOf` trap runs the caller's code.
798
- // A trap that throws then escapes as its own raw Error from a guard whose whole contract is a
799
- // typed one. This test reaches `Object.getPrototypeOf` only on links it has already cleared,
800
- // so no trap runs before the refusal that makes running it unnecessary.
801
- //
802
- // A Proxy answers `ownKeys` and `get` from two independent traps, so the copy takes the names
803
- // one trap reports while the original answers reads from the other. One reporting no keys and
804
- // returning "pw" for `password` copies to an object holding nothing, and the field the caller
805
- // supplied is gone with no fault raised. Copying it is therefore not copying it, which is the
806
- // case this refusal is for: an argument is copied or refused, never half-taken.
807
351
  if (_protoChainHasProxy(v)) {
808
352
  throw _raise(ErrorClass, code, label + ": a Proxy cannot be copied faithfully, because the " +
809
353
  "keys it reports need not be the ones it answers; pass a plain object");
810
354
  }
811
- // A second line under the Proxy rule, and unreachable while that one holds: `setPrototypeOf`
812
- // refuses to build a cycle out of ordinary objects, so a Proxy is the only way to have one and
813
- // the refusal above already covers every such value. It stays because the cost is one walk and
814
- // the failure it prevents is an unbounded loop rather than a wrong answer.
815
355
  if (_protoChainIsCyclic(v)) {
816
356
  throw _raise(ErrorClass, code, label + ": its prototype chain is a cycle, so it cannot be " +
817
357
  "read or copied; pass a plain object");
818
358
  }
819
359
  if (_isBuffer(v) || _isView(v) || _isArrayBuffer(v)) {
820
360
  var bytesCopy = _copyBytesSameKind(v, ErrorClass, code, label, collect);
821
- // A byte value can carry named properties too, and a verb reads an option by name whatever the
822
- // argument's type: `opts = new Uint8Array(0); opts.pem = true` is an options object as far as
823
- // `opts.pem` is concerned. An ArrayBuffer is extensible and takes them the same way.
824
361
  _copyNamed(v, bytesCopy, ErrorClass, code, label, cap, depth, collect);
825
362
  return bytesCopy;
826
363
  }
827
- // A parsed structure carrying guard-parsed's provenance record is a handle: the record is keyed
828
- // on the object's identity, so a copy of it carries none and every door that decides integrity
829
- // refuses the copy. It is also safe to leave alone, since that door re-derives from the bytes the
830
- // record names, so nothing done to the object since matters. That holds for it as a parse
831
- // result; a caller who adds an option to one and passes it where options are read by name has
832
- // added a field no door re-derives, so `AsProduced` is what is asked, not `isRecorded`.
833
- // Required inline because guard-parsed requires this module; at call time it is fully loaded.
834
364
  if (require("./guard-parsed").isRecordedAsProduced(v)) return v; // allow:inline-require -- circular load: guard-parsed requires this module
835
365
  if (util.types.isDate(v)) {
836
- // A Date can carry named properties too, and a verb reads an option by name whatever the
837
- // argument's type. Returning the instant alone dropped anything the caller had added, so the
838
- // copy held nothing while the original still answered, and the check read the copy.
839
- //
840
- // The instant comes through the time guard's intrinsic read. `getTime` is an ordinary method
841
- // a subclass answers, so reading it off the value put a different instant in the copy than the
842
- // original holds, and the value validated and the value used were two different reads.
843
- //
844
- // What the copy carries is the caller's DATA. A name the language already supplies on a Date
845
- // is that Date's behavior, and copying an own one down put a caller's function on an object
846
- // whose whole purpose is to answer as a plain Date holding that instant: an own
847
- // `getUTCFullYear` that throws rode onto the copy and threw out of pki.cms.sign when the
848
- // signing time was encoded. Normalizing the prototype does not reach an own shadow, so the
849
- // shadow is left behind here. The excluded set is read off `Date.prototype` rather than
850
- // written out, so it cannot fall behind the language.
851
366
  var dateCopy = new _Date(time.instantOf(v));
852
367
  _copyNamed(v, dateCopy, ErrorClass, code, label, cap, depth, collect, _DATE_BEHAVIOR);
853
368
  return _plainCopy(dateCopy);
854
369
  }
855
370
  if (_isArray(v)) {
856
371
  var arr = [];
857
- // The indices a read on the array resolves, rather than a count from zero to `length`. An array is
858
- // sparse whenever a caller sets a high index or assigns `length`, and `[].length = 4e9` is one
859
- // statement: walking to `length` then does four billion iterations for an array holding nothing,
860
- // inside a guard whose job includes keeping a caller's argument from costing unbounded work. Copying
861
- // the indices it actually holds costs what it holds; `length` is carried across afterwards so trailing
862
- // holes survive and the copy measures the same.
863
- //
864
- // OWN indices only, and refuse an index a read resolves through the PROTOTYPE. An array reads its
865
- // holes through the prototype chain, so an inherited in-range index -- a polluted `Array.prototype[i]`,
866
- // or one a hostile prototype supplies -- is a value the caller never placed on the array. Materializing
867
- // it would import it; leaving it a hole would let a verb's map silently skip an element the array
868
- // appears to hold. Neither is safe, so the copy refuses it, once, for every argument the module copies,
869
- // rather than each verb having to. A GENUINE hole -- own-absent AND prototype-absent -- is preserved,
870
- // so an ordinary sparse array round-trips unchanged and the per-verb density check on a list that must
871
- // be dense still refuses that. `readableIndices` walks own + inherited in-range indices; when it holds
872
- // one the array does not own, an in-range index came from the prototype.
873
372
  var indexE = function (c, m) { return _raise(ErrorClass, c, m); };
874
373
  var indices = _ownArrayIndices(v, v.length);
875
374
  if (identifier.readableIndices(v, indexE, code, label).length !== indices.length) {
876
375
  throw _raise(ErrorClass, code, label + " has an in-range index supplied by its prototype rather than the array itself; a list resolved through the prototype chain is refused");
877
376
  }
878
- // An accessor is refused among the elements for the reason it is refused among the names:
879
- // reading it once and writing what it returned as plain data leaves the later check nothing
880
- // to find, since it sees a value and cannot tell an accessor was ever there. The refusal
881
- // covered names only, so the same trick under an index passed -- and a list is exactly where
882
- // it pays, an element answering as a trusted signer to the check and as another afterwards.
883
- // The argument itself, not everything under it, matching the rule for names.
884
377
  if (depth === 0) identifier.refuseAccessorFields(v, indices, indexE, code, label);
885
378
  _forEach(indices, function (k) {
886
- // Reading an element can run a caller's accessor, the same as reading a named field: an
887
- // index can carry a getter too, and one that threw escaped as itself from a boundary whose
888
- // contract is a typed error. Typed here with the raw fault as its cause, as the named walk
889
- // below does, so an element and a field fail the same way.
890
379
  var element;
891
380
  try { element = v[k]; }
892
381
  catch (e) { throw _raise(ErrorClass, code, label + ": reading element " + k + " threw", e); }
893
382
  arr[k] = _deep(element, ErrorClass, code, label, cap, depth + 1, collect);
894
383
  });
895
384
  arr.length = v.length;
896
- // An array can carry named properties too, and a verb reads an option by name whatever the
897
- // argument's type: `opts = []; opts.pem = true` is an options object as far as `opts.pem` is
898
- // concerned. Copying only the indexed elements dropped those fields, which silently changed
899
- // what the verb was asked to do instead of failing.
900
385
  _copyNamed(v, arr, ErrorClass, code, label, cap, depth, collect);
901
386
  return _plainCopy(arr);
902
387
  }
903
- // The only kinds this module cannot read the state of. One carrying nothing of its own is passed
904
- // through: there is no data on it to fix, and a copy would break it. One carrying its own
905
- // fields has no safe handling at all: it cannot be copied, and passing it through would leave
906
- // those fields the caller's to rewrite after the checks read them. That case is refused outright,
907
- // never half-handled, which is what keeps this from being another shape to be found later.
908
388
  var surface = _opaqueSurface(v, ErrorClass, code, label);
909
389
  if (surface) {
910
- // The name that decided it, so the message says which field to move rather than leaving the
911
- // caller to find it on an object whose whole problem is that its state cannot be read.
912
390
  var carried = _opaqueFieldOutsideSurface(v, surface, ErrorClass, code, label);
913
391
  if (carried === null) return v;
914
392
  throw _raise(ErrorClass, code, label + ": " + _article(_kindName(v)) + " " + _kindName(v) +
@@ -922,74 +400,20 @@ function _deep(v, ErrorClass, code, label, cap, depth, collect) {
922
400
  if (util.types.isSet(v)) {
923
401
  return _plainCopy(_copyEntries(v, new _Set(), ErrorClass, code, label, cap, depth, collect));
924
402
  }
925
- // A plain object, or a dictionary with no prototype at all -- never the caller's class.
926
- //
927
- // Carrying the class across was for its methods, and it cost what copying is for: the copy went
928
- // on dispatching into the caller's code, and their class could be rewritten after the call had
929
- // begun. The names the copy reports do not depend on it, which the vectors measure rather than
930
- // assume, and no verb calls a method on an options bag.
931
- //
932
- // Having NO prototype is different and is kept. `_create(null)` and what `JSON.parse`
933
- // produces inherit nothing, and a copy that gained `Object.prototype` would inherit whatever a
934
- // runtime has planted there -- names the original never answered, reported against a caller who
935
- // never wrote them.
936
403
  var out = _create(_getPrototypeOf(v) === null ? null : _ObjectProto);
937
404
  _copyNamed(v, out, ErrorClass, code, label, cap, depth, collect);
938
405
  return out;
939
406
  }
940
407
 
941
- // Which names to carry across, given what the copy is.
942
- //
943
- // For a plain object or a class instance (the shapes an options bag actually takes) it is every
944
- // name a lookup could resolve, inherited included, because that is what the verb reads.
945
- //
946
- // For an array, a byte view, a Map or a Set, it is the caller's own added names only. Their
947
- // prototypes are full of accessors that describe the kind, not the caller (`length`,
948
- // `buffer`, `size`, and Node's `parent`, which hands back the 64 KiB arena a small Buffer was
949
- // allocated from). Every one of those is already correct on the copy, and reading them would
950
- // copy things the caller never passed. Enumerating the accessors to skip is the wrong way round;
951
- // what the caller added is exactly what is own and not an index.
952
- //
953
- // Which strings are indices is guard-identifier's to answer, for names and for elements alike. A
954
- // second copy of that test here could drift from it, and the set of names that module passes over
955
- // would then stop matching the set this one carries across as structure.
956
408
 
957
- // The names to carry across, asked of the module that decides which names a caller supplied.
958
- //
959
- // One walk answers for both questions, because a second walk here drifts from it and the two then
960
- // disagree about one value. A walk that stops at whatever object is identical to `Object.prototype`
961
- // reads a foreign realm's root as caller data and copies `__proto__` down as a field. One that
962
- // reads every level outside a collection gives `_create(Array.prototype)` an own `length`
963
- // and `Symbol.unscopables`. Either way the copy holds a different set than the check accepted, and
964
- // a bag that passes the check is refused once it has been copied.
965
- //
966
- // The prototype is kept on every branch, so a name skipped here still resolves through it, and the
967
- // indices of an array are carried by that branch as the structure they are. What the check reads
968
- // is therefore what the copy answers to.
969
409
  function _namesToCopy(src, ErrorClass, code, label, atArgument) {
970
410
  var E = function (c, m) { return _raise(ErrorClass, c, m); };
971
411
  var names = identifier.readableNames(src, E, code, label);
972
- // Refused here as well as at the options door, because this copy runs FIRST for the verbs that
973
- // take a spec. Reading an accessor and writing what it returned as plain data leaves the later
974
- // check nothing to find: it sees a value and cannot tell an accessor was ever there, so a field
975
- // that answers differently on the next read passes as a settled one.
976
- //
977
- // The argument itself, not everything under it. A platform object nested in a spec carries its
978
- // own accessors, and a Node KeyObject inside a signer holds `asymmetricKeyType` among others;
979
- // those belong to the platform and refusing them turns an ordinary signer into a bad input.
980
412
  if (atArgument) identifier.refuseAccessorFields(src, names, E, code, label);
981
413
  return names;
982
414
  }
983
415
 
984
- // A Map or a Set is data the caller can still change, entry by entry, so it is copied like any
985
- // other: entries first, then the named properties one can carry alongside them.
986
416
  function _copyEntries(src, dst, ErrorClass, code, label, cap, depth, collect) {
987
- // The walk uses the intrinsic `forEach`, called against the collection. `forEach` is an ordinary
988
- // method on `Map.prototype` and `Set.prototype`, so an own one or a subclass's answers instead:
989
- // one that threw took this module out through the caller's own exception, and one that yielded
990
- // different entries filled the copy with something other than what the collection holds. Both are
991
- // taken at load and invoked uncurried, so neither the method nor the `call` that reaches it is
992
- // read off a prototype while a caller is in a position to have replaced it.
993
417
  var walk = util.types.isSet(src) ? _setForEach : _mapForEach;
994
418
  walk(src, function (value, key) {
995
419
  var copiedValue = _deep(value, ErrorClass, code, label, cap, depth + 1, collect);
@@ -1000,45 +424,19 @@ function _copyEntries(src, dst, ErrorClass, code, label, cap, depth, collect) {
1000
424
  return dst;
1001
425
  }
1002
426
 
1003
- // Copy every value a name lookup on `src` could reach onto `dst`, as an own data property.
1004
- //
1005
- // Own matters: a key literally named `__proto__` would otherwise re-point `dst`, so the field the
1006
- // caller passed disappears from Object.keys and an unknown-option check walks a different object
1007
- // than the verb goes on to read. Shadowing matters for the same reason it is done at all: an own
1008
- // copy is what makes an inherited value stop tracking the caller's prototype. A method is left
1009
- // where it is, since copying a function would only move it, and it is the prototype's behavior,
1010
- // not the caller's data.
1011
- // The names `Date.prototype` supplies, read off the language rather than written out, so a method
1012
- // the language gains later is behavior here on the day it lands.
1013
427
  var _DATE_BEHAVIOR = (function () {
1014
428
  var t = _create(null);
1015
429
  _forEach(_ownKeys(Date.prototype), function (n) { t[n] = 1; });
1016
430
  return t;
1017
431
  })();
1018
432
 
1019
- // `behavior`, when given, names what belongs to the destination's KIND rather than to the caller.
1020
- // An own property under one of those names is a shadow of the kind's own method, and copying it
1021
- // down would make the copy answer with the caller's function where the original answered with the
1022
- // language's. The copy is meant to be that kind holding the caller's data.
1023
433
  function _copyNamed(src, dst, ErrorClass, code, label, cap, depth, collect, behavior) {
1024
434
  var keys = _namesToCopy(src, ErrorClass, code, label, depth === 0);
1025
435
  for (var k = 0; k < keys.length; k++) {
1026
436
  var value;
1027
- // Reading a caller's property can run a caller's accessor, and one that throws is a bad input
1028
- // like any other: the fault gets this boundary's typed code with the raw error as its cause,
1029
- // and never escapes as itself from inside a verb the caller called for something else.
1030
437
  try { value = src[keys[k]]; }
1031
438
  catch (e) { throw _raise(ErrorClass, code, label + ": reading " + _stringify(keys[k]) + " threw", e); }
1032
- // A name the destination's KIND already defines, holding a FUNCTION, is a shadow of that
1033
- // kind's own method: copying it down would make the copy answer with the caller's code where
1034
- // the original answered with the language's. The value decides, not the name -- a plain
1035
- // `date.getTime = "unused"` is a field, and dropping it took the caller's typo out of reach of
1036
- // the unknown-option check, which is the silence this release exists to end.
1037
439
  if (behavior && behavior[keys[k]] && typeof value === "function") continue;
1038
- // A function is carried across by reference, since there is nothing in it to copy, but it is
1039
- // still carried. Dropping it changed what the caller passed: an unknown spec
1040
- // field whose value happened to be a function stopped reaching the verb's own key check, so a
1041
- // typo that used to be refused was silently accepted.
1042
440
  _defineProperty(dst, keys[k], {
1043
441
  value: typeof value === "function" ? value
1044
442
  : _deep(value, ErrorClass, code, label, cap, depth + 1, collect),
@@ -1047,8 +445,6 @@ function _copyNamed(src, dst, ErrorClass, code, label, cap, depth, collect, beha
1047
445
  }
1048
446
  }
1049
447
 
1050
- // Whether a name lookup on `v` would have found this property as an enumerable one, anywhere on
1051
- // the chain -- so the copy's own keys enumerate the way the original's did.
1052
448
  function _wasEnumerable(v, name) {
1053
449
  for (var o = v; o && o !== _ObjectProto; o = _getPrototypeOf(o)) {
1054
450
  var d = _getOwnPropertyDescriptor(o, name);
@@ -1057,30 +453,10 @@ function _wasEnumerable(v, name) {
1057
453
  return false;
1058
454
  }
1059
455
 
1060
- // fixArguments(ErrorClass, code, args) -> { values, release }
1061
- //
1062
- // The whole rule for a verb that spans a promise turn, in one call. `args` is a list of
1063
- // `[value, label]` pairs, one per argument the verb was handed. Each is deep-copied, so no field
1064
- // of any of them, at any depth, is still the caller's to change once the verb has begun; `release`
1065
- // clears every copy that was made and belongs in a `finally`, so a copied password or private key
1066
- // does not outlive the call.
1067
- //
1068
- // Both halves are needed and neither is optional. Copying only the argument that looks like data
1069
- // leaves a secret nested inside the one that looks like a handle (`opts.mac.secret` sitting a
1070
- // level below a shallow copy) readable and rewritable across the turn. Copying without releasing
1071
- // answers that by duplicating the secret instead. Deciding per field which is which is the judgment
1072
- // that keeps going wrong, so there is no per-field decision here: everything is copied, everything
1073
- // copied is cleared, and the only things left alone are the ones a copy would break: a CryptoKey
1074
- // or any class instance (its identity is what makes it work) and a recorded parse result (its
1075
- // provenance is keyed to the object).
1076
456
  // @enforced-by behavioral -- there is no rename-proof code shape for "copied every argument". The
1077
- // guard is the per-verb RED vector that mutates each argument after the verb returns its promise
1078
- // and asserts the artifact carries the entry value.
1079
457
  function fixArguments(ErrorClass, code, args) {
1080
458
  var copies = [];
1081
459
  var values = [];
1082
- // Through guard.secret, which owns what clearing a secret means. Required inline because
1083
- // guard-secret requires this module; at call time it is fully loaded.
1084
460
  function release() {
1085
461
  require("./guard-secret").zeroizeAll(copies, ErrorClass, code, // allow:inline-require -- circular load: guard-secret requires this module
1086
462
  "a copy of a caller-supplied argument");
@@ -1090,41 +466,21 @@ function fixArguments(ErrorClass, code, args) {
1090
466
  _append(values, snapshotDeep(args[i][0], ErrorClass, code, args[i][1], { collect: copies }));
1091
467
  }
1092
468
  } catch (e) {
1093
- // The copying itself can fail partway (a detached leaf, a structure past the depth cap, a
1094
- // getter that throws), and the arguments already copied by then are just as much ours as if
1095
- // the call had gone on to succeed. Returning nothing would leave the caller with no handle to
1096
- // release them, so a signer key or a password copied before the fault would stay readable for
1097
- // as long as the heap held it. Clear what was made, then let the fault out unchanged.
1098
469
  release();
1099
470
  throw e;
1100
471
  }
1101
472
  return { values: values, release: release };
1102
473
  }
1103
474
 
1104
- // fixedCall(ErrorClass, code, args, body) -> Promise
1105
- //
1106
- // The form every Promise-returning producing verb uses, because the halves have to be arranged in
1107
- // exactly one way and this is it. The copy runs inside guard-async's boundary, so a fault in the
1108
- // copy itself (a detached view, a structure nested past the cap, a getter that throws) leaves
1109
- // as a rejection like every other fault of a verb documented `-> Promise<...>`, never as a
1110
- // synchronous throw past the caller's `.catch`. It still runs at the call, before any turn passes,
1111
- // which is what fixes the arguments. And the release runs whether the body resolved, rejected, or
1112
- // never ran, so a copied secret is cleared on every path out.
1113
475
  // @enforced-by behavioral -- an arrangement of two calls has no rename-proof shape to detect. The
1114
- // guards are promise-contract.test.js (every documented Promise verb refuses by rejecting, now
1115
- // including a fault raised by the copy itself) and the per-verb entry-value vectors.
1116
476
  function fixedCall(ErrorClass, code, args, body) {
1117
477
  var handle = null;
1118
- // Both halves through captures. `body.apply` and `.finally` are prototype reads, and between them
1119
- // they decide whether the verb runs and whether the copies it was handed are ever cleared.
1120
478
  return _promiseFinally(async.deferred(function () {
1121
479
  handle = fixArguments(ErrorClass, code, args);
1122
480
  return _apply(body, null, handle.values);
1123
481
  }), function () { if (handle) handle.release(); });
1124
482
  }
1125
483
 
1126
- // Frozen for the reason the family header gives: a boundary reads its guard off this object at the
1127
- // call, so a writable export would let a caller replace the check rather than pass it.
1128
484
  module.exports = intrinsic.freeze({
1129
485
  view: view, source: source, snapshot: snapshot, snapshotSource: snapshotSource,
1130
486
  isByteSource: isByteSource, asyncStreamOf: asyncStreamOf, translateStreamError: translateStreamError, lengthOf: lengthOf, outputView: outputView,