@blamejs/pki 0.8.61 → 0.9.1
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 +35 -0
- package/MIGRATING.md +46 -0
- package/README.md +8 -1
- package/index.js +55 -26
- package/lib/acme.js +5 -5
- package/lib/asn1-der.js +1 -1
- package/lib/attrcert-sign.js +2 -2
- package/lib/cbor-det.js +4 -1
- package/lib/cmc-build.js +1 -1
- package/lib/cmp-build.js +5 -5
- package/lib/cmp-session.js +6 -3
- package/lib/cmp-verify.js +1 -1
- package/lib/cms-compress.js +5 -2
- package/lib/cms-decrypt.js +2 -2
- package/lib/cms-encrypt.js +2 -2
- package/lib/cms-sign.js +2 -2
- package/lib/constants.js +3 -0
- package/lib/crl-sign.js +3 -3
- package/lib/crmf-sign.js +1 -1
- package/lib/csr-sign.js +1 -1
- package/lib/ct.js +14 -13
- package/lib/est.js +101 -29
- package/lib/framework-error.js +1 -1
- package/lib/guard-bytes.js +1 -1
- package/lib/guard-limits.js +3 -2
- package/lib/hpke.js +2 -2
- package/lib/http-retry-after.js +4 -1
- package/lib/http-transport.js +6 -6
- package/lib/inspect.js +9 -4
- package/lib/jose.js +3 -3
- package/lib/merkle.js +4 -4
- package/lib/mime.js +124 -17
- package/lib/ocsp.js +2 -2
- package/lib/path-validate.js +3 -3
- package/lib/pbes2.js +8 -4
- package/lib/pkcs12-build.js +5 -5
- package/lib/scep.js +1 -1
- package/lib/schema-engine.js +12 -12
- package/lib/schema-pkix.js +12 -12
- package/lib/sign-scheme.js +2 -2
- package/lib/sigstore.js +1 -1
- package/lib/smime.js +11 -12
- package/lib/tlog.js +2 -2
- package/lib/tls-cert-compress.js +3 -3
- package/lib/tsp-sign.js +6 -6
- package/lib/tuf.js +3 -3
- package/lib/webauthn-mds.js +1 -1
- package/lib/webauthn.js +1 -1
- package/lib/x509-sign.js +3 -3
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/constants.js
CHANGED
|
@@ -189,6 +189,9 @@ var LIMITS = Object.assign(Object.create(null), {
|
|
|
189
189
|
PBKDF2_MAX_SALT: 1024,
|
|
190
190
|
MIME_MAX_BYTES: BYTES.mib(16),
|
|
191
191
|
HEADER_LINE_MAX_OCTETS: 998,
|
|
192
|
+
MIME_MAX_PARTS: 1024,
|
|
193
|
+
MIME_MAX_HEADERS: 1024,
|
|
194
|
+
MIME_MAX_PARAMS: 256,
|
|
192
195
|
COMPRESS_MAX_BYTES: BYTES.mib(16),
|
|
193
196
|
TLS_CERT_MSG_MAX_BYTES: BYTES.mib(16) - 1,
|
|
194
197
|
TLS_CERT_MAX_ENTRIES: 100,
|
package/lib/crl-sign.js
CHANGED
|
@@ -240,7 +240,7 @@ function _buildCrlExtensions(spec, ctx) {
|
|
|
240
240
|
var crlNumberVal = null;
|
|
241
241
|
if (spec.crlNumber != null) { var cn = _boundedInteger(spec.crlNumber, "cRLNumber"); crlNumberVal = cn.value; push("cRLNumber", false, cn.tlv); }
|
|
242
242
|
var ext = spec.extensions;
|
|
243
|
-
if (ext == null) ext =
|
|
243
|
+
if (ext == null) ext = intrinsic.create(null);
|
|
244
244
|
if (Array.isArray(ext)) {
|
|
245
245
|
var arrBase = null, arrCrlNum = null;
|
|
246
246
|
/** @internal The walk goes through `guard.list.copyMap`, never the caller's own `forEach`. Reached
|
|
@@ -391,9 +391,9 @@ function _assertIssuerCanSignCrl(issuerCert) {
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
function _sign(spec, issuer, opts) {
|
|
394
|
-
opts = opts ||
|
|
394
|
+
opts = opts || intrinsic.create(null);
|
|
395
395
|
if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("crl/bad-input", "the CRL spec must be an object");
|
|
396
|
-
issuer = issuer ||
|
|
396
|
+
issuer = issuer || intrinsic.create(null);
|
|
397
397
|
var byCert = issuer.cert != null, byName = issuer.name != null;
|
|
398
398
|
guard.identifier.assertKnownKeys(spec, byCert || byName ? KNOWN_SPEC_KEYS_ISSUER_NAMED : KNOWN_SPEC_KEYS,
|
|
399
399
|
_err, "crl/bad-input", function (k) {
|
package/lib/crmf-sign.js
CHANGED
|
@@ -1215,7 +1215,7 @@ function _buildCertReqMsg(spec, key, opts) {
|
|
|
1215
1215
|
}
|
|
1216
1216
|
|
|
1217
1217
|
function _build(spec, key, opts) {
|
|
1218
|
-
opts = opts ||
|
|
1218
|
+
opts = opts || intrinsic.create(null);
|
|
1219
1219
|
if (!spec || typeof spec !== "object" || _isBuffer(spec)) throw _err("crmf/bad-input", "the certificate-request-message spec must be an object");
|
|
1220
1220
|
var specs;
|
|
1221
1221
|
if (spec.messages != null) {
|
package/lib/csr-sign.js
CHANGED
|
@@ -209,7 +209,7 @@ function sign(spec, key, opts) {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
function _sign(spec, key, opts) {
|
|
212
|
-
opts = opts ||
|
|
212
|
+
opts = opts || intrinsic.create(null);
|
|
213
213
|
if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("csr/bad-input", "the certification-request spec must be an object");
|
|
214
214
|
guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "csr/bad-input", "unknown spec field ");
|
|
215
215
|
guard.identifier.assertKnownKeys(opts, KNOWN_SIGN_OPTS, _err, "csr/bad-input", "pki.csr.sign has an unknown option ");
|
package/lib/ct.js
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
var asn1 = require("./asn1-der.js");
|
|
43
|
+
var _create = require("./guard-intrinsic").create;
|
|
43
44
|
var constants = require("./constants.js");
|
|
44
45
|
var frameworkError = require("./framework-error.js");
|
|
45
46
|
var guard = require("./guard-all.js");
|
|
@@ -357,7 +358,7 @@ function _u24Bytes(n) {
|
|
|
357
358
|
var _X509_ENTRY_KEYS = intrinsic.assign(intrinsic.create(null), { entryType: 1, leafCert: 1 });
|
|
358
359
|
var _PRECERT_ENTRY_KEYS = intrinsic.assign(intrinsic.create(null), { entryType: 1, tbsCertificate: 1, issuerKeyHash: 1 });
|
|
359
360
|
function reconstructSignedData(entry, sct) {
|
|
360
|
-
entry = entry ||
|
|
361
|
+
entry = entry || _create(null);
|
|
361
362
|
if (typeof entry !== "object") throw new CtError("ct/bad-input", "the log entry must be an object { entryType, ... } (RFC 6962 sec. 3.1)");
|
|
362
363
|
var entryType = entry.entryType;
|
|
363
364
|
if (entryType !== 0 && entryType !== 1) {
|
|
@@ -493,7 +494,7 @@ async function verifySct(entry, sct, logPublicKey) {
|
|
|
493
494
|
throw new CtError("ct/log-id-mismatch", "the SCT logId does not match SHA-256 of the provided log key (RFC 6962 sec. 3.2)");
|
|
494
495
|
}
|
|
495
496
|
}
|
|
496
|
-
var sigInfo = rec.signatureAlgorithm ||
|
|
497
|
+
var sigInfo = rec.signatureAlgorithm || _create(null);
|
|
497
498
|
var hashName = CT_HASH[sigInfo.hashName];
|
|
498
499
|
if (!hashName) throw new CtError("ct/unsupported-algorithm", "unsupported SCT hash algorithm " + JSON.stringify(sigInfo.hashName) + " (RFC 6962 sec. 2.1.4 mandates sha256)");
|
|
499
500
|
var alg = _spkiAlg(spki);
|
|
@@ -899,7 +900,7 @@ function _classifyLog(sct, logList, entry, opts) {
|
|
|
899
900
|
}
|
|
900
901
|
|
|
901
902
|
async function verifySctWithLogList(entry, sct, logList, opts) {
|
|
902
|
-
opts = opts ||
|
|
903
|
+
opts = opts || _create(null);
|
|
903
904
|
var c = _classifyLog(sct, logList, entry, opts);
|
|
904
905
|
if (c.status !== "ok") throw _ctErr(c.code, c.message);
|
|
905
906
|
/** @internal Read before the verify, so the timestamp the verdict states is the one the signature covered.
|
|
@@ -1249,7 +1250,7 @@ function _assertTransport(opts) {
|
|
|
1249
1250
|
* `Symbol.split` is part of that operation. The token decides which parser a log's response body is
|
|
1250
1251
|
* handed to. */
|
|
1251
1252
|
function _fetchCtypeToken(headers) {
|
|
1252
|
-
var raw = intrinsic.String((headers ||
|
|
1253
|
+
var raw = intrinsic.String((headers || _create(null))["content-type"] || "");
|
|
1253
1254
|
var parts = intrinsic.splitChar(raw, 59);
|
|
1254
1255
|
return _toLowerCase(_ctTrim(parts.length ? parts[0] : ""));
|
|
1255
1256
|
}
|
|
@@ -1279,7 +1280,7 @@ function _fetchBody(transport, url, req, label) {
|
|
|
1279
1280
|
if (req.body !== undefined) request.body = req.body;
|
|
1280
1281
|
return transport(request);
|
|
1281
1282
|
}).then(function (res) {
|
|
1282
|
-
res = res ||
|
|
1283
|
+
res = res || _create(null);
|
|
1283
1284
|
var h = intrinsic.create(null);
|
|
1284
1285
|
guard.identifier.optionNames(res.headers).forEach(function (k) { h[k.toLowerCase()] = res.headers[k]; });
|
|
1285
1286
|
var body = guard.bytes.isByteSource(res.body)
|
|
@@ -1581,7 +1582,7 @@ function _uintField(obj, name, code, label) {
|
|
|
1581
1582
|
var _STH_KEYS = intrinsic.assign(intrinsic.create(null),
|
|
1582
1583
|
{ timestamp: 1, treeSize: 1, rootHash: 1, signature: 1, raw: 1, then: 1 });
|
|
1583
1584
|
function sthSignedData(sth) {
|
|
1584
|
-
sth = sth ||
|
|
1585
|
+
sth = sth || _create(null);
|
|
1585
1586
|
guard.identifier.assertKnownKeys(sth, _STH_KEYS, _ctErr, "ct/bad-input", "unknown sth field ");
|
|
1586
1587
|
var ts = guard.range.uint64(sth.timestamp, _ctErr, "ct/bad-input", "sth.timestamp");
|
|
1587
1588
|
var size = guard.range.uint64(sth.treeSize, _ctErr, "ct/bad-input", "sth.treeSize");
|
|
@@ -1627,7 +1628,7 @@ function sthSignedData(sth) {
|
|
|
1627
1628
|
* // -> true
|
|
1628
1629
|
*/
|
|
1629
1630
|
async function verifySth(sth, logKey) {
|
|
1630
|
-
sth = sth ||
|
|
1631
|
+
sth = sth || _create(null);
|
|
1631
1632
|
var signature = _toBuffer(sth.signature, "sth.signature");
|
|
1632
1633
|
var signedData = sthSignedData({ timestamp: sth.timestamp, treeSize: sth.treeSize, rootHash: sth.rootHash });
|
|
1633
1634
|
return await _verifyDigitallySigned(signedData, signature, logKey, "the signed tree head");
|
|
@@ -1668,7 +1669,7 @@ async function verifySth(sth, logKey) {
|
|
|
1668
1669
|
* sth.treeSize; // -> 3n
|
|
1669
1670
|
*/
|
|
1670
1671
|
async function getSth(opts) {
|
|
1671
|
-
var door = _clientDoor(opts ||
|
|
1672
|
+
var door = _clientDoor(opts || _create(null), "logKey");
|
|
1672
1673
|
opts = door.o;
|
|
1673
1674
|
/** @internal ONE read of the option, and the presence check and the copy both decide from it. Reading
|
|
1674
1675
|
* it twice let an accessor answer the two separately: a non-null value for the check and an
|
|
@@ -1727,7 +1728,7 @@ async function getSth(opts) {
|
|
|
1727
1728
|
* p.verified; // -> true
|
|
1728
1729
|
*/
|
|
1729
1730
|
async function getProofByHash(opts) {
|
|
1730
|
-
var door = _clientDoor(opts ||
|
|
1731
|
+
var door = _clientDoor(opts || _create(null), null);
|
|
1731
1732
|
opts = door.o;
|
|
1732
1733
|
var sth = _assertSth(opts.sth, "opts.sth");
|
|
1733
1734
|
/** @internal Copied for the reason the tree head is: it is sent on the wire and then folded against the
|
|
@@ -1783,7 +1784,7 @@ async function getProofByHash(opts) {
|
|
|
1783
1784
|
* c.verified; // -> true
|
|
1784
1785
|
*/
|
|
1785
1786
|
async function getSthConsistency(opts) {
|
|
1786
|
-
var door = _clientDoor(opts ||
|
|
1787
|
+
var door = _clientDoor(opts || _create(null), null);
|
|
1787
1788
|
opts = door.o;
|
|
1788
1789
|
var oldSth = _assertSth(opts.oldSth, "opts.oldSth");
|
|
1789
1790
|
var newSth = _assertSth(opts.newSth, "opts.newSth");
|
|
@@ -1841,7 +1842,7 @@ async function getSthConsistency(opts) {
|
|
|
1841
1842
|
* e.entries[0].leafInput; // -> <Buffer ...>
|
|
1842
1843
|
*/
|
|
1843
1844
|
async function getEntries(opts) {
|
|
1844
|
-
var door = _clientDoor(opts ||
|
|
1845
|
+
var door = _clientDoor(opts || _create(null), null);
|
|
1845
1846
|
opts = door.o;
|
|
1846
1847
|
var start = guard.range.uint64(opts.start, _ctErr, "ct/bad-input", "opts.start");
|
|
1847
1848
|
var end = guard.range.uint64(opts.end, _ctErr, "ct/bad-input", "opts.end");
|
|
@@ -1899,7 +1900,7 @@ async function getEntries(opts) {
|
|
|
1899
1900
|
*/
|
|
1900
1901
|
async function getRoots(opts) {
|
|
1901
1902
|
/** @internal This message carries no options of its own, so the door's record is all that is used. */
|
|
1902
|
-
var door = _clientDoor(opts ||
|
|
1903
|
+
var door = _clientDoor(opts || _create(null), null);
|
|
1903
1904
|
var doc = await _clientJson(door, "get-roots", "roots");
|
|
1904
1905
|
return guard.verdict.of({ certificates: _b64Array(doc, "certificates", "ct/bad-roots", "roots", undefined, C.LIMITS.CT_MAX_ROOTS) });
|
|
1905
1906
|
}
|
|
@@ -1982,7 +1983,7 @@ async function addPreChain(opts) {
|
|
|
1982
1983
|
* The chain encoding, the response shape, and the refusal when the receipt does not verify are one
|
|
1983
1984
|
* rule stated once. */
|
|
1984
1985
|
async function _addChain(opts, message, entryType) {
|
|
1985
|
-
var door = _clientDoor(opts ||
|
|
1986
|
+
var door = _clientDoor(opts || _create(null), "logKey");
|
|
1986
1987
|
opts = door.o;
|
|
1987
1988
|
/** @internal ONE read of the option, used by the presence check here and by the copy below. Reading it
|
|
1988
1989
|
* twice let an accessor answer the two separately, presenting a non-null value to the check and an
|
package/lib/est.js
CHANGED
|
@@ -281,8 +281,14 @@ function _matchDelimAt(text, ls, boundary) {
|
|
|
281
281
|
if (_charCodeAt(text, q) === 0x0d && q + 1 < n && _charCodeAt(text, q + 1) === 0x0a) return { end: q + 2, close: close };
|
|
282
282
|
return null;
|
|
283
283
|
}
|
|
284
|
+
/** @internal The delimiter count is bounded before the list is built, since one mark is appended per
|
|
285
|
+
* delimiter found anywhere in the body and the scan does not stop at the terminal one. The bound is
|
|
286
|
+
* the part cap plus that terminal delimiter, and it is the same `C.LIMITS` row the MIME reader
|
|
287
|
+
* counts parts against, so the two doors hold a multipart body to one number. */
|
|
284
288
|
function _findMultipartMarks(text, boundary) {
|
|
285
289
|
var marks = [], n = text.length, searchStart = 0, p;
|
|
290
|
+
var counted = guard.limits.counter(constants.LIMITS.MIME_MAX_PARTS, E, "est/bad-multipart",
|
|
291
|
+
"the multipart body part");
|
|
286
292
|
while (searchStart <= n) {
|
|
287
293
|
var found = null, foundAt = -1;
|
|
288
294
|
for (p = searchStart; p <= n; p++) {
|
|
@@ -293,7 +299,15 @@ function _findMultipartMarks(text, boundary) {
|
|
|
293
299
|
if (lsN !== -1) { var r1 = _matchDelimAt(text, lsN, boundary); if (r1) { found = r1; foundAt = p; break; } }
|
|
294
300
|
}
|
|
295
301
|
if (!found) break;
|
|
302
|
+
/** @internal The closing delimiter opens no part, so it is not charged and the cap counts the
|
|
303
|
+
* parts an operator is told it counts. */
|
|
304
|
+
if (!found.close) counted.tick();
|
|
296
305
|
guard.list.append(marks, { at: foundAt, bodyStart: found.end, close: found.close });
|
|
306
|
+
/** @internal RFC 2046 sec. 5.1.1 discards everything after the closing delimiter, and the caller
|
|
307
|
+
* reads no mark past the first one that closes, so the scan stops there. Running on charged the
|
|
308
|
+
* epilogue against the part budget: a body at the cap was refused for text it never reads, while
|
|
309
|
+
* the same body without that epilogue was accepted. */
|
|
310
|
+
if (found.close) break;
|
|
297
311
|
searchStart = found.end === foundAt ? found.end + 1 : found.end;
|
|
298
312
|
}
|
|
299
313
|
return marks;
|
|
@@ -314,18 +328,29 @@ function _stripOneTrailingEol(seg, end) {
|
|
|
314
328
|
}
|
|
315
329
|
return end;
|
|
316
330
|
}
|
|
317
|
-
|
|
318
|
-
|
|
331
|
+
/** @internal Every line break in the part's header area is charged as the scan passes it, before the
|
|
332
|
+
* unfolded text is split, so the refusal costs the cap rather than the input. Counting the split
|
|
333
|
+
* lines afterwards instead read 2,000,000 one-line headers in 425 ms and 172 MiB of resident memory
|
|
334
|
+
* before refusing, and never reached two on 1,500,000 continuation lines, which fold into one line. */
|
|
335
|
+
function _unfoldHeaders(raw, counted) {
|
|
336
|
+
var out = "", last = 0, i = 0, n = raw.length, afterLastBreak = 0;
|
|
319
337
|
while (i < n) {
|
|
320
338
|
var nlLen = 0;
|
|
321
339
|
if (_charCodeAt(raw, i) === 0x0d && i + 1 < n && _charCodeAt(raw, i + 1) === 0x0a) nlLen = 2;
|
|
322
340
|
else if (_charCodeAt(raw, i) === 0x0a) nlLen = 1;
|
|
323
|
-
if (nlLen
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
341
|
+
if (nlLen === 0) { i += 1; continue; }
|
|
342
|
+
/** @internal The scan steps PAST the whole break rather than one byte into it, so a CRLF is one
|
|
343
|
+
* line and not two: stepping one byte left the LF to be read as a second break on the next pass,
|
|
344
|
+
* which charged every CRLF twice and halved the cap a part was actually held to. */
|
|
345
|
+
counted.tick();
|
|
346
|
+
var after = i + nlLen;
|
|
347
|
+
afterLastBreak = after;
|
|
348
|
+
if (after < n && (_charCodeAt(raw, after) === 0x20 || _charCodeAt(raw, after) === 0x09)) { out += _strSlice(raw, last, i); last = after; i = after; continue; }
|
|
349
|
+
i = after;
|
|
328
350
|
}
|
|
351
|
+
/** @internal The run after the last break is a line as well, and a header area that ends at a break
|
|
352
|
+
* has no run after it, so the charge is the LINE count the cap is stated in and not one less. */
|
|
353
|
+
if (afterLastBreak < n) counted.tick();
|
|
329
354
|
return out + _strSlice(raw, last, n);
|
|
330
355
|
}
|
|
331
356
|
function _splitCrlf(s) {
|
|
@@ -359,7 +384,9 @@ function splitMultipartMixed(body, contentType) {
|
|
|
359
384
|
var rawHeaders = _strSlice(seg, 0, sep);
|
|
360
385
|
var partBody = _strSlice(seg, _stripTwoLeadingEol(seg, sep), _stripOneTrailingEol(seg, seg.length));
|
|
361
386
|
var headers = intrinsic.create(null);
|
|
362
|
-
var
|
|
387
|
+
var countedHeaders = guard.limits.counter(constants.LIMITS.MIME_MAX_HEADERS, E, "est/bad-multipart",
|
|
388
|
+
"the multipart part header line");
|
|
389
|
+
var lines = _splitCrlf(_unfoldHeaders(rawHeaders, countedHeaders));
|
|
363
390
|
for (var li = 0; li < lines.length; li++) {
|
|
364
391
|
var line = lines[li];
|
|
365
392
|
/** @internal A part's header name and value are cut, trimmed and folded through the captured
|
|
@@ -367,7 +394,20 @@ function splitMultipartMixed(body, contentType) {
|
|
|
367
394
|
* its body goes to: measured, a part stating `application/pkcs8` was read as
|
|
368
395
|
* `application/pkcs7-mime` with a `smime-type` of `certs-only`. */
|
|
369
396
|
var col = _estIndexOf(line, ":");
|
|
370
|
-
if (col
|
|
397
|
+
if (col <= 0) continue;
|
|
398
|
+
var fname = _toLowerCase(_estTrim(_strSlice(line, 0, col)));
|
|
399
|
+
/** @internal A repeat is refused rather than overwritten. Storing each value in turn left the
|
|
400
|
+
* LAST line deciding the field, and the field this decides is the part's own content type,
|
|
401
|
+
* which selects the reader its body goes to: measured, the same two Content-Type lines swapped
|
|
402
|
+
* reported `application/pkcs7-mime; smime-type=certs-only` one way and `application/pkcs8` the
|
|
403
|
+
* other, which is which part is the private key and which is the certificate. RFC 5322 sec. 3.6
|
|
404
|
+
* gives a singleton field one occurrence, and taking the first is as conforming as taking the
|
|
405
|
+
* last, so there is no value here to resolve to. */
|
|
406
|
+
if (intrinsic.hasOwn(headers, fname)) {
|
|
407
|
+
throw E("est/bad-multipart", "a multipart part declares the " + guard.text.showValue(fname) +
|
|
408
|
+
" header field more than once, so the value it resolves to is ambiguous (RFC 5322 sec. 3.6)");
|
|
409
|
+
}
|
|
410
|
+
headers[fname] = _estTrim(_strSlice(line, col + 1));
|
|
371
411
|
}
|
|
372
412
|
var partCt = headers["content-type"] || "";
|
|
373
413
|
if (_ciStartsWith(partCt, "MULTIPART/")) throw E("est/bad-multipart", "a nested multipart part is not permitted");
|
|
@@ -471,36 +511,58 @@ function _recipientMatches(recipientInfos, opts) {
|
|
|
471
511
|
* replacement decides which segments a parameter is then looked for in, and one of those parameters
|
|
472
512
|
* is the multipart boundary a response body is divided on: measured, a `boundary=wire` header
|
|
473
513
|
* yielded `forged`. */
|
|
514
|
+
/** @internal The first segment is the media type rather than a parameter, so it is not charged, and
|
|
515
|
+
* the charge comes BEFORE the segment is stored, so a refusal costs the cap and not the input: with
|
|
516
|
+
* no cap here a 3.8 MiB Content-Type carrying 1,000,000 parameters was accepted in 194 ms and 100 MiB
|
|
517
|
+
* of resident memory, and a part's media type splits the same value a second time. The bound is the
|
|
518
|
+
* `C.LIMITS` row the MIME reader counts parameters against, so both doors hold one media type to one
|
|
519
|
+
* number. */
|
|
520
|
+
function _pushCtSegment(segs, seg, counted) {
|
|
521
|
+
if (segs.length > 0) counted.tick();
|
|
522
|
+
intrinsic.append(segs, seg);
|
|
523
|
+
}
|
|
524
|
+
|
|
474
525
|
function _splitContentTypeParams(s) {
|
|
475
526
|
var segs = [], cur = "", inQuote = false;
|
|
527
|
+
var counted = guard.limits.counter(constants.LIMITS.MIME_MAX_PARAMS, E, "est/bad-multipart",
|
|
528
|
+
"the Content-Type parameter");
|
|
476
529
|
for (var i = 0; i < s.length; i++) {
|
|
477
530
|
var ch = _estCharAt(s, i);
|
|
478
531
|
if (ch === '"') { inQuote = !inQuote; cur += ch; }
|
|
479
|
-
else if (ch === ";" && !inQuote) {
|
|
532
|
+
else if (ch === ";" && !inQuote) { _pushCtSegment(segs, cur, counted); cur = ""; }
|
|
480
533
|
else cur += ch;
|
|
481
534
|
}
|
|
482
|
-
|
|
535
|
+
_pushCtSegment(segs, cur, counted);
|
|
483
536
|
return segs;
|
|
484
537
|
}
|
|
485
538
|
|
|
486
539
|
function _ctParam(contentType, name) {
|
|
487
540
|
var segs = _splitContentTypeParams(_stringOf(contentType || ""));
|
|
488
|
-
var value = null,
|
|
541
|
+
var value = null, plain = 0, starred = 0;
|
|
489
542
|
/** @internal Each parameter is read through the captured operations. The name decides which
|
|
490
543
|
* parameter this is, and the value it returns is the one a caller acts on: for the RFC 7030
|
|
491
544
|
* multipart boundary, it is where a response body is split. */
|
|
492
545
|
for (var i = 1; i < segs.length; i++) {
|
|
493
546
|
var seg = segs[i];
|
|
494
547
|
var eq = _estIndexOf(seg, "=");
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
548
|
+
/** @internal An occurrence counts whether or not it carries a value, which is why a bare
|
|
549
|
+
* attribute is counted: skipping it let `boundary; boundary="b"` through while
|
|
550
|
+
* `boundary="a"; boundary="b"` was refused. The plain and the starred RFC 2231 spellings are
|
|
551
|
+
* counted apart, because what has to be refused is two readings carrying DIFFERENT values.
|
|
552
|
+
* `boundary*=us-ascii''DECOY; boundary=REAL` is read here as REAL and by an RFC 2231 reader as
|
|
553
|
+
* DECOY, while continuation segments alone leave this reader no boundary at all, which the
|
|
554
|
+
* caller already refuses (RFC 2231 sec. 3, sec. 4, sec. 7). */
|
|
555
|
+
var attr = _toLowerCase(_estTrim(eq === -1 ? seg : _strSlice(seg, 0, eq)));
|
|
556
|
+
var star = _estIndexOf(attr, "*");
|
|
557
|
+
if ((star > 0 ? _strSlice(attr, 0, star) : attr) !== name) continue;
|
|
558
|
+
if (star > 0) { starred++; continue; }
|
|
559
|
+
plain++;
|
|
560
|
+
if (eq === -1 || plain > 1) continue;
|
|
499
561
|
var val = _estTrim(_strSlice(seg, eq + 1));
|
|
500
562
|
if (val.length >= 2 && _estCharAt(val, 0) === '"' && _estCharAt(val, val.length - 1) === '"') val = _strSlice(val, 1, -1);
|
|
501
563
|
value = val;
|
|
502
564
|
}
|
|
503
|
-
return { value: value, duplicated:
|
|
565
|
+
return { value: value, duplicated: plain > 1 || (plain > 0 && starred > 0) };
|
|
504
566
|
}
|
|
505
567
|
|
|
506
568
|
var _MT_FIRST = pkix.charTable("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
|
@@ -533,7 +595,7 @@ function _partMediaType(contentType) {
|
|
|
533
595
|
}
|
|
534
596
|
|
|
535
597
|
function parseServerKeygenResponse(body, contentType, opts) {
|
|
536
|
-
opts = opts ||
|
|
598
|
+
opts = opts || intrinsic.create(null);
|
|
537
599
|
opts = _knownOpts(opts, PARSE_SERVERKEYGEN_OPTS, "parseServerKeygenResponse");
|
|
538
600
|
var parts = splitMultipartMixed(body, contentType);
|
|
539
601
|
if (parts.length !== 2) throw E("est/bad-multipart", "a serverkeygen response must have exactly two parts (RFC 7030 sec. 4.4.2)");
|
|
@@ -617,7 +679,7 @@ function classifyResponse(status, headers, body, opts) {
|
|
|
617
679
|
}
|
|
618
680
|
|
|
619
681
|
function _classifyResponse(status, headers, body, opts) {
|
|
620
|
-
opts = opts ||
|
|
682
|
+
opts = opts || intrinsic.create(null);
|
|
621
683
|
opts = _knownOpts(opts, CLASSIFY_OPTS, "classifyResponse");
|
|
622
684
|
var op = opts.op;
|
|
623
685
|
if (op !== undefined && op !== null && CLASSIFIABLE_OPS.indexOf(op) === -1) throw E("est/unsupported-operation", "unrecognized EST operation " + guard.text.showValue(op));
|
|
@@ -689,7 +751,7 @@ function _classifyResponse(status, headers, body, opts) {
|
|
|
689
751
|
* // -> "https://ca.example/.well-known/est/cacerts"
|
|
690
752
|
*/
|
|
691
753
|
function paths(baseUrl, opts) {
|
|
692
|
-
opts = opts ||
|
|
754
|
+
opts = opts || intrinsic.create(null);
|
|
693
755
|
opts = _knownOpts(opts, PATHS_OPTS, "paths");
|
|
694
756
|
var base = String(baseUrl);
|
|
695
757
|
var prefix = base.slice(0, _stripTrailingSlashEnd(base)) + "/.well-known/est";
|
|
@@ -957,7 +1019,7 @@ function _drive(method, url, body, headers, opts, transport, budgets) {
|
|
|
957
1019
|
function step() {
|
|
958
1020
|
var hopBody = (typeof body === "function" && budgets.onAttempt) ? budgets.onAttempt() : body;
|
|
959
1021
|
return guard.async.invoked(transport, [{ method: method, url: _urlHref(url), headers: _headersFor(url), body: hopBody, tls: _tlsFor(url), proxy: budgets.proxy, timeout: budgets.timeout, maxResponseBytes: budgets.maxResponseBytes }], E, "est/bad-input", "opts.transport").then(function (res) {
|
|
960
|
-
res = res ||
|
|
1022
|
+
res = res || intrinsic.create(null);
|
|
961
1023
|
var blen = _bodyLen(res);
|
|
962
1024
|
if (blen > budgets.maxResponseBytes) throw E("est/response-too-large", "the response body (" + blen + " bytes) exceeds the " + budgets.maxResponseBytes + "-byte cap (RFC 7030 sec. 6)");
|
|
963
1025
|
var h = intrinsic.assign(intrinsic.create(null), {
|
|
@@ -1159,7 +1221,7 @@ function _certsResult(op, res, opts, csrSpki) {
|
|
|
1159
1221
|
* r.retry && r.retryAfterSeconds; // 60
|
|
1160
1222
|
*/
|
|
1161
1223
|
function fullcmc(baseUrl, request, opts) {
|
|
1162
|
-
opts = opts ||
|
|
1224
|
+
opts = opts || intrinsic.create(null);
|
|
1163
1225
|
var der, wanted, sent;
|
|
1164
1226
|
try {
|
|
1165
1227
|
if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw E("est/bad-input", "pki.est.fullcmc options must be an object");
|
|
@@ -1588,7 +1650,7 @@ function _enroll(op, baseUrl, csrInput, opts, proxySnap) {
|
|
|
1588
1650
|
* r.certificates; // -> [Buffer, ...] raw, unordered
|
|
1589
1651
|
*/
|
|
1590
1652
|
function cacerts(baseUrl, opts) {
|
|
1591
|
-
opts = opts ||
|
|
1653
|
+
opts = opts || intrinsic.create(null);
|
|
1592
1654
|
var proxySnap; try { proxySnap = _snapProxy(opts); } catch (_pe) { return _rej(E("est/bad-input", "the options object could not be read", _pe)); }
|
|
1593
1655
|
return _promiseResolve(_Promise, undefined).then(function () {
|
|
1594
1656
|
opts = _knownOpts(opts, CACERTS_OPTS, "cacerts");
|
|
@@ -1654,7 +1716,7 @@ function cacerts(baseUrl, opts) {
|
|
|
1654
1716
|
* bound.retry; // true
|
|
1655
1717
|
*/
|
|
1656
1718
|
function simpleenroll(baseUrl, csrInput, opts) {
|
|
1657
|
-
opts = opts ||
|
|
1719
|
+
opts = opts || intrinsic.create(null);
|
|
1658
1720
|
var proxySnap; try { proxySnap = _snapProxy(opts); } catch (_pe) { return _rej(E("est/bad-input", "the options object could not be read", _pe)); }
|
|
1659
1721
|
return _promiseResolve(_Promise, undefined).then(function () {
|
|
1660
1722
|
opts = _knownOpts(opts, SIMPLEENROLL_OPTS, "simpleenroll");
|
|
@@ -1694,7 +1756,7 @@ function simpleenroll(baseUrl, csrInput, opts) {
|
|
|
1694
1756
|
* r.retry; // true
|
|
1695
1757
|
*/
|
|
1696
1758
|
function simplereenroll(baseUrl, csrInput, opts) {
|
|
1697
|
-
opts = opts ||
|
|
1759
|
+
opts = opts || intrinsic.create(null);
|
|
1698
1760
|
var proxySnap; try { proxySnap = _snapProxy(opts); } catch (_pe) { return _rej(E("est/bad-input", "the options object could not be read", _pe)); }
|
|
1699
1761
|
return _promiseResolve(_Promise, undefined).then(function () {
|
|
1700
1762
|
opts = _knownOpts(opts, SIMPLEREENROLL_OPTS, "simplereenroll");
|
|
@@ -1751,7 +1813,7 @@ function _assertConfidentialCipher(res) {
|
|
|
1751
1813
|
}
|
|
1752
1814
|
|
|
1753
1815
|
function _ciHeaderList(headers, name) {
|
|
1754
|
-
headers = headers ||
|
|
1816
|
+
headers = headers || intrinsic.create(null);
|
|
1755
1817
|
/** @internal The header NAME a value is selected under is folded through the captured conversion on
|
|
1756
1818
|
* both sides of the comparison: the match decides which header this response is read from. */
|
|
1757
1819
|
var lname = _toLowerCase(name), keys = guard.identifier.optionNames(headers), parts = [];
|
|
@@ -1765,7 +1827,7 @@ function _ciHeaderList(headers, name) {
|
|
|
1765
1827
|
}
|
|
1766
1828
|
|
|
1767
1829
|
function _ciHeader(headers, name) {
|
|
1768
|
-
headers = headers ||
|
|
1830
|
+
headers = headers || intrinsic.create(null);
|
|
1769
1831
|
var lname = _toLowerCase(name), keys = guard.identifier.optionNames(headers), found = null, n = 0;
|
|
1770
1832
|
for (var i = 0; i < keys.length; i++) {
|
|
1771
1833
|
if (_toLowerCase(keys[i]) !== lname) continue;
|
|
@@ -1777,6 +1839,16 @@ function _ciHeader(headers, name) {
|
|
|
1777
1839
|
"the response carries more than one " + lname + " header field, so what the body is cannot be told " +
|
|
1778
1840
|
"from it (RFC 9110 sec. 5.1: field names are case-insensitive)");
|
|
1779
1841
|
}
|
|
1842
|
+
/** @internal One key can still hold SEVERAL values, which is how `node:http` reports a field that
|
|
1843
|
+
* arrived more than once, and these three fields each carry one value. Counting keys alone left a
|
|
1844
|
+
* two-element array to be read as one string: measured, the two orders of the same pair gave
|
|
1845
|
+
* `est/bad-content-type` one way and an accepted classification the other, because the joined text
|
|
1846
|
+
* parsed as a media type in one order and not in the other. */
|
|
1847
|
+
if (intrinsic.isArray(found) && found.length > 1) {
|
|
1848
|
+
throw E("est/bad-content-type",
|
|
1849
|
+
"the response carries " + found.length + " values for " + lname + ", so what the body is cannot be " +
|
|
1850
|
+
"told from it (RFC 9110 sec. 5.1)");
|
|
1851
|
+
}
|
|
1780
1852
|
return n === 0 ? null : found;
|
|
1781
1853
|
}
|
|
1782
1854
|
|
|
@@ -1854,7 +1926,7 @@ async function _serverkeygenResult(res, opts, derived) {
|
|
|
1854
1926
|
* r.retry; // true -- a 202 is surfaced, never slept
|
|
1855
1927
|
*/
|
|
1856
1928
|
function serverkeygen(baseUrl, csrInput, opts) {
|
|
1857
|
-
opts = opts ||
|
|
1929
|
+
opts = opts || intrinsic.create(null);
|
|
1858
1930
|
var proxySnap; try { proxySnap = _snapProxy(opts); } catch (_pe) { return _rej(E("est/bad-input", "the options object could not be read", _pe)); }
|
|
1859
1931
|
return _promiseResolve(_Promise, undefined).then(function () {
|
|
1860
1932
|
opts = _knownOpts(opts, SERVERKEYGEN_OPTS, "serverkeygen");
|
|
@@ -1916,7 +1988,7 @@ function _csrattrsResult(res, opts) {
|
|
|
1916
1988
|
* r.available; // false -- a 404 is "no CSR-attributes policy available"
|
|
1917
1989
|
*/
|
|
1918
1990
|
function csrattrs(baseUrl, opts) {
|
|
1919
|
-
opts = opts ||
|
|
1991
|
+
opts = opts || intrinsic.create(null);
|
|
1920
1992
|
var proxySnap; try { proxySnap = _snapProxy(opts); } catch (_pe) { return _rej(E("est/bad-input", "the options object could not be read", _pe)); }
|
|
1921
1993
|
return _promiseResolve(_Promise, undefined).then(function () {
|
|
1922
1994
|
opts = _knownOpts(opts, CSRATTRS_OPTS, "csrattrs");
|
package/lib/framework-error.js
CHANGED
|
@@ -122,7 +122,7 @@ function defineClass(name, opts) {
|
|
|
122
122
|
if (typeof name !== "string" || name.length === 0) {
|
|
123
123
|
throw new TypeError("defineClass: name must be a non-empty string");
|
|
124
124
|
}
|
|
125
|
-
opts = opts ||
|
|
125
|
+
opts = opts || intrinsic.create(null);
|
|
126
126
|
var withCause = !!opts.withCause;
|
|
127
127
|
var flagKey = "is" + name;
|
|
128
128
|
|
package/lib/guard-bytes.js
CHANGED
|
@@ -281,7 +281,7 @@ function snapshotSource(input, ErrorClass, code, label) {
|
|
|
281
281
|
* the budget rather than the shape of the input. The figure is far above any real caller value: an
|
|
282
282
|
* options bag or a JWK is tens of nodes, and a certificate chain passed as an anchor list is thousands. */
|
|
283
283
|
function snapshotDeep(value, ErrorClass, code, label, opts) {
|
|
284
|
-
var o = opts ||
|
|
284
|
+
var o = opts || _create(null);
|
|
285
285
|
var cap = o.maxDepth == null ? 64 : o.maxDepth;
|
|
286
286
|
var maxNodes = o.maxNodes == null ? constants.LIMITS.DEEP_COPY_MAX_NODES : o.maxNodes;
|
|
287
287
|
return _deep(value, ErrorClass, code, label, cap, 0, o.collect || null, { n: 0, max: maxNodes });
|
package/lib/guard-limits.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// @internal
|
|
5
5
|
|
|
6
6
|
var constants = require("./constants");
|
|
7
|
+
var _create = require("./guard-intrinsic").create;
|
|
7
8
|
var _isInteger = require("./guard-intrinsic").isInteger;
|
|
8
9
|
var _freeze = require("./guard-intrinsic").freeze;
|
|
9
10
|
var _sizeOf = require("./guard-intrinsic").sizeOf;
|
|
@@ -15,7 +16,7 @@ function _monotonicNow() { return _Number(_hrtimeBigint() / 1000000n); }
|
|
|
15
16
|
// @enforced-by behavioral -- a config-time cap validator has no rename-proof code
|
|
16
17
|
function cap(value, key, dflt, opts) {
|
|
17
18
|
if (value === undefined) return dflt;
|
|
18
|
-
opts = opts ||
|
|
19
|
+
opts = opts || _create(null);
|
|
19
20
|
/** @internal Each bound is read ONCE, into the value the integer check and the comparison share.
|
|
20
21
|
* Read twice, the check saw one bound and the comparison another, so an `opts` answering a valid
|
|
21
22
|
* small integer to the check and a large one to the comparison configured a cap that admitted a
|
|
@@ -141,7 +142,7 @@ function budget(limits) {
|
|
|
141
142
|
*/
|
|
142
143
|
// @enforced-by behavioral -- an elapsed-time comparison has no rename-proof shape that separates a deadline from any other subtraction; the vectors driving a checker to its bound are the guard
|
|
143
144
|
function deadline(totalMs, opts) {
|
|
144
|
-
opts = opts ||
|
|
145
|
+
opts = opts || _create(null);
|
|
145
146
|
var rawNow = opts.now;
|
|
146
147
|
var now = typeof rawNow === "function" ? rawNow : _monotonicNow;
|
|
147
148
|
if (!_isInteger(totalMs) || totalMs < 0) {
|
package/lib/hpke.js
CHANGED
|
@@ -923,7 +923,7 @@ function _setupS(ids, pkR, opts) {
|
|
|
923
923
|
* the subject being the key rather than the ciphertext. `_suite(ids)` stays above both, by necessity:
|
|
924
924
|
* which KEM this is decides the width the key is held to. */
|
|
925
925
|
var r = _recipPublic(suite, pkR);
|
|
926
|
-
opts = _options(opts ||
|
|
926
|
+
opts = _options(opts || intrinsic.create(null), _SETUP_S_KEYS, "sender setup");
|
|
927
927
|
var mode = opts.mode;
|
|
928
928
|
var kem = suite.kem, k;
|
|
929
929
|
if (mode === MODE_AUTH || mode === MODE_AUTH_PSK) {
|
|
@@ -978,7 +978,7 @@ function _setupR(ids, enc, skR, opts) {
|
|
|
978
978
|
* size of whatever was supplied: a 64 MiB value handed where a 32-byte encapsulation belongs was
|
|
979
979
|
* copied in full and only then refused. */
|
|
980
980
|
var sealed = _rawKey(enc, _encWidth(suite.kem));
|
|
981
|
-
opts = _options(opts ||
|
|
981
|
+
opts = _options(opts || intrinsic.create(null), _SETUP_R_KEYS, "recipient setup");
|
|
982
982
|
var mode = opts.mode;
|
|
983
983
|
var r = _recipPrivate(suite, skR);
|
|
984
984
|
var kem = suite.kem, ss;
|
package/lib/http-retry-after.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
// @internal
|
|
5
5
|
|
|
6
|
+
/** @internal The record constructor, captured at load, for the reason the same capture in
|
|
7
|
+
* `lib/inspect.js` gives: arming this module counts 48 live runtime reads. */
|
|
8
|
+
var _create = Object.create;
|
|
6
9
|
var constants = require("./constants");
|
|
7
10
|
var guard = require("./guard-all");
|
|
8
11
|
|
|
@@ -100,7 +103,7 @@ function httpDateMs(s, refMs) {
|
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
function parse(value, opts) {
|
|
103
|
-
opts = opts ||
|
|
106
|
+
opts = opts || _create(null);
|
|
104
107
|
var raStr = String(value).trim();
|
|
105
108
|
var out = { retryAfterSeconds: null, retryAfterDate: null };
|
|
106
109
|
if (_isAllDigits(raStr)) {
|
package/lib/http-transport.js
CHANGED
|
@@ -339,7 +339,7 @@ function _blockedAddrErr(hostname, address) {
|
|
|
339
339
|
}
|
|
340
340
|
function _makeGuardedLookup(lookupFn) {
|
|
341
341
|
return function guardedLookup(hostname, options, callback) {
|
|
342
|
-
lookupFn(hostname, options ||
|
|
342
|
+
lookupFn(hostname, options || intrinsic.create(null), function (err, address, family) {
|
|
343
343
|
if (err) return callback(err);
|
|
344
344
|
/** @internal Each address is read ONCE, the read is what gets classified, and the SNAPSHOT is
|
|
345
345
|
* what the socket layer is handed. Forwarding the list the resolver returned let the entry be
|
|
@@ -633,7 +633,7 @@ function _proxyErrorClass(e, C) {
|
|
|
633
633
|
* res.status; // 200
|
|
634
634
|
*/
|
|
635
635
|
function httpsTransport(defaults) {
|
|
636
|
-
defaults = defaults ||
|
|
636
|
+
defaults = defaults || intrinsic.create(null);
|
|
637
637
|
/** @internal Each of these is read ONCE, into the value both the test and the use see, and the
|
|
638
638
|
* error factory a refusal is built from is one of them. */
|
|
639
639
|
var rawE = defaults.E;
|
|
@@ -789,7 +789,7 @@ function httpsTransport(defaults) {
|
|
|
789
789
|
}
|
|
790
790
|
|
|
791
791
|
var _transportFn = function transport(request) {
|
|
792
|
-
request = request ||
|
|
792
|
+
request = request || intrinsic.create(null);
|
|
793
793
|
var prep;
|
|
794
794
|
try { prep = _prepare(request); }
|
|
795
795
|
catch (e) { return _promiseReject(_Promise, e); }
|
|
@@ -848,7 +848,7 @@ function httpsTransport(defaults) {
|
|
|
848
848
|
/** @internal Captured for consistency with the rest of the file, not because this gates
|
|
849
849
|
* anything: an understated `content-length` only skips this EARLY refusal, and the cap is
|
|
850
850
|
* enforced below on the bytes actually counted as they arrive. */
|
|
851
|
-
var declared = intrinsic.parseInt((res.headers ||
|
|
851
|
+
var declared = intrinsic.parseInt((res.headers || intrinsic.create(null))["content-length"], 10);
|
|
852
852
|
if (intrinsic.numberIsFinite(declared) && declared > prep.maxBytes) { fail(C("response-too-large"), "the declared content-length " + declared + " exceeds the " + prep.maxBytes + "-byte cap (RFC 7030 sec. 6)"); return; }
|
|
853
853
|
var buf = _bufferAllocUnsafe(0);
|
|
854
854
|
var len = 0;
|
|
@@ -1039,7 +1039,7 @@ function httpsTransport(defaults) {
|
|
|
1039
1039
|
* connecting directly while a proxy is configured would reach an origin the caller asked not to
|
|
1040
1040
|
* reach directly. */
|
|
1041
1041
|
_transportFn.peerChain = function peerChain(request) {
|
|
1042
|
-
request = request ||
|
|
1042
|
+
request = request || intrinsic.create(null);
|
|
1043
1043
|
var prep;
|
|
1044
1044
|
try { prep = _prepare({
|
|
1045
1045
|
url: request.url,
|
|
@@ -1149,6 +1149,6 @@ function httpsTransport(defaults) {
|
|
|
1149
1149
|
* pki.schema.x509.parse(channel.peerChain[0]).subject.dn; // the leaf's subject
|
|
1150
1150
|
* channel.peerCertificate; // the one certificate the endpoint sent
|
|
1151
1151
|
*/
|
|
1152
|
-
function peerChain(request, defaults) { return httpsTransport(defaults ||
|
|
1152
|
+
function peerChain(request, defaults) { return httpsTransport(defaults || intrinsic.create(null)).peerChain(request); }
|
|
1153
1153
|
|
|
1154
1154
|
module.exports = { https: httpsTransport, peerChain: peerChain, isBlockedIp: _isBlockedIp, _makeGuardedLookup: _makeGuardedLookup, MAX_TIMEOUT: MAX_TIMEOUT, snapshotProxy: snapshotProxy };
|
package/lib/inspect.js
CHANGED
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
* @card Read a certificate like `openssl x509 -text`, in pure JS.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
/** @internal The record constructor, captured at load. A default record written as `{}` has
|
|
27
|
+
* `Object.prototype`, so every field the caller omitted is read off the prototype chain. This module
|
|
28
|
+
* does not take the guard-intrinsic captures, and requiring them arms it whole: measured, that counts
|
|
29
|
+
* 662 live runtime reads here, which is a migration of its own rather than a line in this change. */
|
|
30
|
+
var _create = Object.create;
|
|
26
31
|
var frameworkError = require("./framework-error");
|
|
27
32
|
var constants = require("./constants");
|
|
28
33
|
var asn1 = require("./asn1-der");
|
|
@@ -56,7 +61,7 @@ var OID_UNOTICE = oid.byName("unotice");
|
|
|
56
61
|
|
|
57
62
|
var HEX = "0123456789abcdef";
|
|
58
63
|
function _hexColon(buf, opts) {
|
|
59
|
-
opts = opts ||
|
|
64
|
+
opts = opts || _create(null);
|
|
60
65
|
var hex = [];
|
|
61
66
|
for (var i = 0; i < buf.length; i++) {
|
|
62
67
|
var b = buf[i], s = HEX[(b >> 4) & 0xf] + HEX[b & 0xf];
|
|
@@ -346,7 +351,7 @@ var EXT_RENDERERS = Object.assign(Object.create(null), {
|
|
|
346
351
|
return (decoded || []).map(function (ad) {
|
|
347
352
|
var m = null;
|
|
348
353
|
try { m = oid.name(ad.accessMethod); } catch (_e) { /* allow:swallow-unverified display best-effort: an unregistered accessMethod OID falls back to the raw dotted OID below (inspection is best-effort, never a verdict) */ }
|
|
349
|
-
var loc = ad.accessLocation ||
|
|
354
|
+
var loc = ad.accessLocation || _create(null), lv;
|
|
350
355
|
if (loc.tag === 6) lv = "URI:" + loc.value;
|
|
351
356
|
else if (loc.tag === 2) lv = "DNS:" + loc.value;
|
|
352
357
|
else if (loc.tag === 1) lv = "email:" + loc.value;
|
|
@@ -1368,7 +1373,7 @@ function pkcs12Report(input) {
|
|
|
1368
1373
|
* structure, and the outer MacData fields then describe nothing: read from there, a store with 2048
|
|
1369
1374
|
* PBKDF2 iterations reported one iteration, an empty salt, and "pbmac1" as its digest. */
|
|
1370
1375
|
if (p.mac.pbmac1) {
|
|
1371
|
-
var kdf = p.mac.pbmac1.kdf ||
|
|
1376
|
+
var kdf = p.mac.pbmac1.kdf || _create(null);
|
|
1372
1377
|
_optLine(L, " ", "Digest", p.mac.pbmac1.schemeName || p.mac.pbmac1.schemeOid);
|
|
1373
1378
|
_optLine(L, " ", "Key Derivation", kdf.prfName || kdf.prfOid);
|
|
1374
1379
|
_optLine(L, " ", "Iterations", kdf.iterationCount);
|
|
@@ -2363,7 +2368,7 @@ var KNOWN_DUMP_OPTS = Object.assign(Object.create(null),
|
|
|
2363
2368
|
* // Incomplete: the walk could not read the value at offset 5: content length 3 overruns the 0 bytes that remain.
|
|
2364
2369
|
*/
|
|
2365
2370
|
function asn1Dump(input, opts) {
|
|
2366
|
-
if (opts === undefined || opts === null) opts =
|
|
2371
|
+
if (opts === undefined || opts === null) opts = _create(null);
|
|
2367
2372
|
if (typeof opts !== "object" || Array.isArray(opts)) {
|
|
2368
2373
|
throw _err("inspect/bad-input", "pki.inspect.asn1 options must be an object");
|
|
2369
2374
|
}
|