@blamejs/pki 0.6.13 → 0.6.15
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.
- package/CHANGELOG.md +22 -1
- package/README.md +1 -1
- package/index.js +1 -1
- package/lib/acme.js +59 -815
- package/lib/asn1-der.js +7 -245
- package/lib/attrcert-sign.js +12 -260
- package/lib/attrcert-verify.js +1 -7
- package/lib/byte-reader.js +0 -8
- package/lib/byte-writer.js +0 -11
- package/lib/cbor-det.js +0 -54
- package/lib/cmc-build.js +15 -357
- package/lib/cmc-verify.js +6 -239
- package/lib/cmp-build.js +41 -317
- package/lib/cmp-session.js +73 -760
- package/lib/cmp-verify.js +32 -488
- package/lib/cms-compress.js +3 -32
- package/lib/cms-decrypt.js +29 -294
- package/lib/cms-encrypt.js +14 -234
- package/lib/cms-sign.js +29 -324
- package/lib/cms-verify.js +9 -500
- package/lib/composite-kem.js +2 -102
- package/lib/composite-sig.js +1 -77
- package/lib/constants.js +0 -249
- package/lib/crl-sign.js +9 -237
- package/lib/crl-verify.js +1 -10
- package/lib/crmf-sign.js +19 -198
- package/lib/crmf-verify.js +1 -12
- package/lib/csr-sign.js +3 -34
- package/lib/csr-verify.js +1 -12
- package/lib/ct.js +28 -253
- package/lib/edwards-point.js +10 -44
- package/lib/est.js +28 -764
- package/lib/framework-error.js +4 -182
- package/lib/guard-all.js +1 -58
- package/lib/guard-async.js +1 -36
- package/lib/guard-bytes.js +6 -650
- package/lib/guard-compress.js +5 -102
- package/lib/guard-crypto.js +1 -40
- package/lib/guard-der.js +2 -93
- package/lib/guard-encoding.js +2 -60
- package/lib/guard-header.js +1 -36
- package/lib/guard-identifier.js +7 -531
- package/lib/guard-intrinsic.js +1 -150
- package/lib/guard-json.js +10 -73
- package/lib/guard-limits.js +1 -77
- package/lib/guard-list.js +1 -49
- package/lib/guard-name.js +3 -209
- package/lib/guard-parsed.js +7 -335
- package/lib/guard-range.js +1 -71
- package/lib/guard-secret.js +1 -102
- package/lib/guard-text.js +1 -64
- package/lib/guard-time.js +1 -97
- package/lib/hpke.js +3 -105
- package/lib/http-digest.js +14 -142
- package/lib/http-retry-after.js +1 -47
- package/lib/http-transport.js +21 -131
- package/lib/inspect.js +30 -284
- package/lib/ip-utils.js +6 -47
- package/lib/jose.js +7 -142
- package/lib/key.js +2 -67
- package/lib/lint.js +9 -194
- package/lib/merkle.js +1 -27
- package/lib/mime.js +9 -82
- package/lib/ocsp-request-verify.js +1 -14
- package/lib/ocsp-verify.js +1 -82
- package/lib/ocsp.js +11 -169
- package/lib/oid.js +5 -337
- package/lib/path-validate.js +103 -1492
- package/lib/pbes2.js +2 -89
- package/lib/pkcs12-build.js +31 -379
- package/lib/pki-build.js +64 -290
- package/lib/rc2.js +2 -18
- package/lib/rfc3339.js +4 -27
- package/lib/scep.js +59 -233
- package/lib/schema-all.js +0 -122
- package/lib/schema-attrcert.js +4 -146
- package/lib/schema-c509.js +153 -802
- package/lib/schema-cmc.js +5 -220
- package/lib/schema-cmp.js +2 -223
- package/lib/schema-cms.js +13 -427
- package/lib/schema-crl.js +5 -68
- package/lib/schema-crmf.js +6 -167
- package/lib/schema-csr.js +1 -54
- package/lib/schema-csrattrs.js +2 -87
- package/lib/schema-engine.js +0 -152
- package/lib/schema-ocsp.js +0 -117
- package/lib/schema-pkcs12.js +2 -93
- package/lib/schema-pkcs8.js +3 -35
- package/lib/schema-pkix.js +24 -655
- package/lib/schema-smime.js +0 -54
- package/lib/schema-tsp.js +3 -99
- package/lib/schema-x509.js +4 -63
- package/lib/shbs.js +11 -95
- package/lib/sign-scheme.js +2 -97
- package/lib/sigstore.js +9 -169
- package/lib/sleep.js +2 -8
- package/lib/smime.js +15 -408
- package/lib/tls-cert-compress.js +0 -62
- package/lib/trust.js +19 -185
- package/lib/tsp-sign.js +16 -270
- package/lib/validator-all.js +1 -30
- package/lib/validator-attcert.js +2 -46
- package/lib/validator-cose.js +2 -153
- package/lib/validator-keydesc.js +1 -37
- package/lib/validator-sig.js +1 -46
- package/lib/validator-tls.js +1 -88
- package/lib/validator-tpm.js +19 -122
- package/lib/verify-seam.js +1 -24
- package/lib/webauthn-mds.js +3 -400
- package/lib/webauthn.js +12 -833
- package/lib/webcrypto.js +5 -485
- package/lib/x509-sign.js +4 -108
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/guard-bytes.js
CHANGED
|
@@ -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;
|
|
223
|
-
if (_charCodeAt(name, 0) !== 105 || _charCodeAt(name, 1) !== 115) return false;
|
|
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;
|
|
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;
|
|
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);
|
|
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,
|