@blamejs/pki 0.8.60 → 0.9.0
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 +48 -0
- package/README.md +7 -0
- 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 +15 -10
- 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 +17 -17
- package/lib/cms-digest.js +2 -3
- package/lib/cms-encrypt.js +17 -18
- package/lib/cms-sign.js +2 -2
- package/lib/composite-kem.js +28 -29
- package/lib/crl-sign.js +3 -3
- package/lib/crmf-sign.js +12 -18
- package/lib/csr-sign.js +1 -1
- package/lib/ct.js +25 -22
- package/lib/est.js +12 -12
- package/lib/framework-error.js +1 -1
- package/lib/guard-bytes.js +1 -1
- package/lib/guard-crypto.js +506 -14
- package/lib/guard-limits.js +3 -2
- package/lib/guard-secret.js +3 -2
- package/lib/hpke.js +26 -26
- package/lib/http-digest.js +5 -7
- 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/key.js +41 -29
- package/lib/merkle.js +4 -4
- package/lib/ocsp.js +3 -4
- package/lib/path-validate.js +3 -3
- package/lib/pbes2.js +14 -11
- package/lib/pkcs12-build.js +10 -11
- package/lib/pki-build.js +3 -3
- package/lib/scep.js +8 -9
- package/lib/schema-engine.js +12 -12
- package/lib/schema-pkix.js +12 -12
- package/lib/schema-tsp.js +3 -3
- package/lib/shbs.js +3 -6
- package/lib/sign-scheme.js +4 -4
- package/lib/sigstore.js +10 -10
- package/lib/smime.js +12 -9
- package/lib/tlog.js +5 -4
- package/lib/tls-cert-compress.js +3 -3
- package/lib/tsp-sign.js +6 -6
- package/lib/tuf.js +6 -5
- package/lib/validator-cose.js +2 -2
- package/lib/webauthn-mds.js +4 -8
- package/lib/webauthn.js +5 -12
- package/lib/webcrypto.js +61 -46
- package/lib/x509-sign.js +3 -3
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/hpke.js
CHANGED
|
@@ -250,10 +250,10 @@ function _importPublic(kem, raw) {
|
|
|
250
250
|
if (raw[0] !== 0x04) throw _err("hpke/bad-key", "EC public key must be an uncompressed 0x04 point (RFC 9180 sec. 7.1.4)");
|
|
251
251
|
var half = (raw.length - 1) / 2;
|
|
252
252
|
var jwk = { kty: "EC", crv: kem.curve, x: raw.subarray(1, 1 + half).toString("base64url"), y: raw.subarray(1 + half).toString("base64url") };
|
|
253
|
-
return
|
|
253
|
+
return guard.crypto.publicKey({ key: jwk, format: "jwk" });
|
|
254
254
|
}
|
|
255
255
|
var prefix = kem.kind === "mlkem" ? ML_KEM_SPKI[kem.name] : OKP_SPKI[kem.curve];
|
|
256
|
-
return
|
|
256
|
+
return guard.crypto.publicKey({ key: _bufferConcat([_hex(prefix), raw]), format: "der", type: "spki" });
|
|
257
257
|
} catch (e) {
|
|
258
258
|
if (e instanceof HpkeError) throw e;
|
|
259
259
|
throw _err("hpke/bad-key", "invalid " + kem.name + " public key" +
|
|
@@ -261,15 +261,15 @@ function _importPublic(kem, raw) {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
function _exportPublic(kem, keyObject) {
|
|
264
|
-
var pub = keyObject.type === "public" ? keyObject :
|
|
264
|
+
var pub = keyObject.type === "public" ? keyObject : guard.crypto.publicKey(keyObject);
|
|
265
265
|
if (kem.kind === "mlkem") {
|
|
266
|
-
var der =
|
|
266
|
+
var der = guard.crypto.exportKey(pub, { format: "der", type: "spki" }), prefix = _hex(ML_KEM_SPKI[kem.name]);
|
|
267
267
|
if (der.length !== prefix.length + kem.Npub || !_bufferEquals(_subarray(der, 0, prefix.length), prefix)) {
|
|
268
268
|
throw _err("hpke/bad-key", "the KeyObject is not an " + kem.name + " key");
|
|
269
269
|
}
|
|
270
270
|
return _subarray(der, prefix.length);
|
|
271
271
|
}
|
|
272
|
-
var jwk =
|
|
272
|
+
var jwk = guard.crypto.exportKey(pub, { format: "jwk" });
|
|
273
273
|
if (jwk.crv !== kem.curve) throw _err("hpke/bad-key", "the KeyObject is not a " + kem.name + " key");
|
|
274
274
|
if (kem.kind === "ec") return concat([Buffer.from([0x04]), _b64u(jwk.x), _b64u(jwk.y)]);
|
|
275
275
|
return _b64u(jwk.x);
|
|
@@ -293,7 +293,7 @@ function _importPrivate(kem, rawSk) {
|
|
|
293
293
|
der = _bufferConcat([_hex(kem.kind === "mlkem" ? ML_KEM_PKCS8[kem.name] : OKP_PKCS8[kem.curve]), rawSk]);
|
|
294
294
|
}
|
|
295
295
|
try {
|
|
296
|
-
return
|
|
296
|
+
return guard.crypto.privateKey({ key: der, format: "der", type: kem.kind === "ec" ? "sec1" : "pkcs8" });
|
|
297
297
|
} catch (e) {
|
|
298
298
|
throw _err("hpke/bad-key", "invalid " + kem.name + " private key", e);
|
|
299
299
|
} finally {
|
|
@@ -301,7 +301,7 @@ function _importPrivate(kem, rawSk) {
|
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
function _boundPublic(kem, privateKey, pkm) {
|
|
304
|
-
var derived = _exportPublic(kem,
|
|
304
|
+
var derived = _exportPublic(kem, guard.crypto.publicKey(privateKey));
|
|
305
305
|
if (pkm === undefined) return derived;
|
|
306
306
|
if (!_isBuffer(pkm) || !_bufferEquals(derived, pkm)) {
|
|
307
307
|
throw _err("hpke/bad-key", "pkm is not the " + kem.name + " public key derived from skm");
|
|
@@ -310,7 +310,7 @@ function _boundPublic(kem, privateKey, pkm) {
|
|
|
310
310
|
}
|
|
311
311
|
function _dh(privateKey, publicKey) {
|
|
312
312
|
try {
|
|
313
|
-
return
|
|
313
|
+
return guard.crypto.diffieHellman({ privateKey: privateKey, publicKey: publicKey });
|
|
314
314
|
} catch (e) {
|
|
315
315
|
throw _err("hpke/bad-key", "KEM Diffie-Hellman failed: invalid or low-order public key", e);
|
|
316
316
|
}
|
|
@@ -319,8 +319,8 @@ function _dh(privateKey, publicKey) {
|
|
|
319
319
|
* drawn and expanded by generateKeyPair, and an ML-KEM encapsulation takes its randomness from the
|
|
320
320
|
* runtime rather than from an ephemeral key pair. */
|
|
321
321
|
function _generate(kem) {
|
|
322
|
-
if (kem.kind === "ec") return
|
|
323
|
-
return
|
|
322
|
+
if (kem.kind === "ec") return guard.crypto.generateKeyPair("ec", { namedCurve: kem.nodeCurve });
|
|
323
|
+
return guard.crypto.generateKeyPair(intrinsic.toLowerCase(kem.curve));
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
|
|
@@ -385,8 +385,8 @@ function _hybridExpand(kem, seed) {
|
|
|
385
385
|
var skT = _importPrivate(_groupRow(kem), _randomScalar(kem, _subarray(full, kem.pq.Nsk)));
|
|
386
386
|
return {
|
|
387
387
|
skPQ: skPQ, skT: skT,
|
|
388
|
-
ekPQ: _exportPublic(kem.pq,
|
|
389
|
-
ekT: _exportPublic(_groupRow(kem),
|
|
388
|
+
ekPQ: _exportPublic(kem.pq, guard.crypto.publicKey(skPQ)),
|
|
389
|
+
ekT: _exportPublic(_groupRow(kem), guard.crypto.publicKey(skT)),
|
|
390
390
|
};
|
|
391
391
|
} finally {
|
|
392
392
|
guard.secret.zeroize(full, HpkeError, "hpke/bad-input", "the hybrid seed expansion");
|
|
@@ -491,7 +491,7 @@ function _refuseEph(kem, eph) {
|
|
|
491
491
|
function _mlKemEncap(kem, pkR, eph) {
|
|
492
492
|
_refuseEph(kem, eph);
|
|
493
493
|
var r;
|
|
494
|
-
try { r =
|
|
494
|
+
try { r = guard.crypto.encapsulate(pkR); }
|
|
495
495
|
catch (e) { throw _err("hpke/bad-key", kem.name + " encapsulation failed", e); }
|
|
496
496
|
return { sharedSecret: r.sharedKey, enc: r.ciphertext };
|
|
497
497
|
}
|
|
@@ -499,7 +499,7 @@ function _mlKemDecap(kem, enc, skR) {
|
|
|
499
499
|
if (enc.length !== kem.Nenc) {
|
|
500
500
|
throw _err("hpke/bad-key", kem.name + " encapsulated key must be " + kem.Nenc + " bytes (FIPS 203 sec. 7.3 ciphertext check)");
|
|
501
501
|
}
|
|
502
|
-
try { return
|
|
502
|
+
try { return guard.crypto.decapsulate(skR, enc); }
|
|
503
503
|
catch (e) { throw _err("hpke/bad-key", kem.name + " decapsulation failed", e); }
|
|
504
504
|
}
|
|
505
505
|
function _encap(kem, pkR, pkRm, eph) {
|
|
@@ -648,10 +648,10 @@ Context.prototype.seal = function (aad, pt) {
|
|
|
648
648
|
* which is what RFC 9180 sec. 5.2 uses. */
|
|
649
649
|
var aadBytes = _buf(aad);
|
|
650
650
|
var nonce = this._nonce();
|
|
651
|
-
var c =
|
|
652
|
-
if (aadBytes.length)
|
|
651
|
+
var c = guard.crypto.cipher(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
|
|
652
|
+
if (aadBytes.length) guard.crypto.transformSetAAD(c, aadBytes);
|
|
653
653
|
var body = guard.secret.cipherFinish(c, _buf(pt), HpkeError, "hpke/bad-input", "a seal intermediate");
|
|
654
|
-
var ct = concat([body,
|
|
654
|
+
var ct = concat([body, guard.crypto.cipherAuthTag(c)]);
|
|
655
655
|
this._inc();
|
|
656
656
|
return ct;
|
|
657
657
|
};
|
|
@@ -665,9 +665,9 @@ Context.prototype.open = function (aad, ct) {
|
|
|
665
665
|
* so the AAD was dropped on this side too and the pair round-tripped with nothing bound. */
|
|
666
666
|
var aadBytes = _buf(aad);
|
|
667
667
|
var nonce = this._nonce();
|
|
668
|
-
var d =
|
|
669
|
-
if (aadBytes.length)
|
|
670
|
-
|
|
668
|
+
var d = guard.crypto.decipher(aead.cipher, this._key, nonce, { authTagLength: aead.Nt });
|
|
669
|
+
if (aadBytes.length) guard.crypto.transformSetAAD(d, aadBytes);
|
|
670
|
+
guard.crypto.decipherSetAuthTag(d, ct.subarray(ct.length - aead.Nt));
|
|
671
671
|
var pt;
|
|
672
672
|
try { pt = guard.secret.cipherFinish(d, ct.subarray(0, ct.length - aead.Nt), HpkeError, "hpke/bad-input", "the recovered plaintext"); }
|
|
673
673
|
catch (e) { throw _err("hpke/open-failed", "AEAD authentication failed (RFC 9180 sec. 5.2)", e); }
|
|
@@ -814,7 +814,7 @@ function _recipPrivate(suite, sk) {
|
|
|
814
814
|
}
|
|
815
815
|
try {
|
|
816
816
|
if (sk.type !== "private") throw _err("hpke/bad-key", "the private key must be a private KeyObject or { skm, pkm }, got a " + guard.text.showValue(sk.type) + " KeyObject");
|
|
817
|
-
var pkm = _exportPublic(kem,
|
|
817
|
+
var pkm = _exportPublic(kem, guard.crypto.publicKey(sk));
|
|
818
818
|
return { key: sk, pkm: pkm };
|
|
819
819
|
} catch (e) {
|
|
820
820
|
if (e instanceof HpkeError) throw e;
|
|
@@ -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;
|
|
@@ -1118,11 +1118,11 @@ function deriveKeyPair(kemId, ikm) {
|
|
|
1118
1118
|
* and the decapsulation key returned is that 64-byte value. */
|
|
1119
1119
|
var dk = _labeledDerive("shake256", _kemSuiteId(_kemId(kem)), input, "DeriveKeyPair", _EMPTY, kem.Nsk);
|
|
1120
1120
|
var mlSk = _importPrivate(kem, dk);
|
|
1121
|
-
return { publicKey: _exportPublic(kem,
|
|
1121
|
+
return { publicKey: _exportPublic(kem, guard.crypto.publicKey(mlSk)), privateKey: dk };
|
|
1122
1122
|
}
|
|
1123
1123
|
var raw = _deriveKeyPairDhkem(kem, input);
|
|
1124
1124
|
var sk = _importPrivate(kem, raw);
|
|
1125
|
-
return { publicKey: _exportPublic(kem,
|
|
1125
|
+
return { publicKey: _exportPublic(kem, guard.crypto.publicKey(sk)), privateKey: raw };
|
|
1126
1126
|
}
|
|
1127
1127
|
|
|
1128
1128
|
/** @internal DeriveKeyPair for a DHKEM (RFC 9180 sec. 7.1.3). X25519 and X448 expand the extract output
|
|
@@ -1258,7 +1258,7 @@ function decap(kemId, enc, recipientPrivateKey) {
|
|
|
1258
1258
|
* Nsk rather than trusted. An ML-KEM or hybrid key never reaches here, its private half being a seed
|
|
1259
1259
|
* that generateKeyPair draws. */
|
|
1260
1260
|
function _exportPrivateRaw(kem, privateKey) {
|
|
1261
|
-
var raw = _b64u(
|
|
1261
|
+
var raw = _b64u(guard.crypto.exportKey(privateKey, { format: "jwk" }).d);
|
|
1262
1262
|
if (!_isBuffer(raw) || raw.length !== kem.Nsk) {
|
|
1263
1263
|
throw _err("hpke/bad-key", "the generated " + kem.name + " private key is not the " +
|
|
1264
1264
|
kem.Nsk + "-byte scalar this verb returns");
|
package/lib/http-digest.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
var crypto = require("crypto");
|
|
7
7
|
var constants = require("./constants");
|
|
8
8
|
var intrinsic = require("./guard-intrinsic");
|
|
9
|
+
var guard = require("./guard-all");
|
|
9
10
|
var guardIdentifier = require("./guard-identifier");
|
|
10
11
|
var _hasOwn = intrinsic.hasOwn;
|
|
11
12
|
/** @internal The URL parser, taken at load: the origin it reports is what a challenge is bound to.
|
|
@@ -46,14 +47,11 @@ var DEFAULT_CODES = intrinsic.assign(intrinsic.create(null), {
|
|
|
46
47
|
noQop: "digest/no-qop", badChallenge: "digest/bad-challenge",
|
|
47
48
|
});
|
|
48
49
|
|
|
49
|
-
/** @internal
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
var _createHash = crypto.createHash;
|
|
50
|
+
/** @internal Every Digest response value is this function's output, so whatever computes it chooses
|
|
51
|
+
* what is sent in place of the password-derived proof. RFC 7616 sec. 3 computes over the octets of
|
|
52
|
+
* the latin1 encoding, which is why the input encoding is named rather than defaulted. */
|
|
53
53
|
var _randomBytes = crypto.randomBytes;
|
|
54
|
-
|
|
55
|
-
var _hashDigest = intrinsic.uncurry(crypto.createHash("sha256").digest);
|
|
56
|
-
function H(hash, s) { return _hashDigest(_hashUpdate(_createHash(hash), s, "latin1"), "hex"); }
|
|
54
|
+
function H(hash, s) { return guard.crypto.digest(hash, s, { input: "latin1", output: "hex" }); }
|
|
57
55
|
function KD(hash, secret, data) { return H(hash, secret + ":" + data); }
|
|
58
56
|
function _qstr(v) {
|
|
59
57
|
var s = intrinsic.String(v), out = "";
|
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
|
}
|
package/lib/jose.js
CHANGED
|
@@ -325,7 +325,7 @@ function assertPublicJwk(jwk) {
|
|
|
325
325
|
*/
|
|
326
326
|
var _VERIFY_KEYS = intrinsic.assign(intrinsic.create(null), { key: 1, profile: 1 });
|
|
327
327
|
async function verify(jws, opts) {
|
|
328
|
-
opts = opts ||
|
|
328
|
+
opts = opts || intrinsic.create(null);
|
|
329
329
|
guard.identifier.assertKnownKeys(opts, _VERIFY_KEYS, E, "jose/bad-input", "unknown pki.jose.verify option ");
|
|
330
330
|
/** @internal opts.key is examined several times: the type gate, the RFC 7638 thumbprint comparison
|
|
331
331
|
* against the embedded jwk, and the key the signature is verified under. An option reached through
|
|
@@ -456,7 +456,7 @@ function _fixedPayload(supplied) {
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
async function sign(opts) {
|
|
459
|
-
opts = opts ||
|
|
459
|
+
opts = opts || intrinsic.create(null);
|
|
460
460
|
guard.identifier.assertKnownKeys(opts, _SIGN_KEYS, E, "jose/bad-input", "unknown pki.jose.sign option ");
|
|
461
461
|
var fixedPayload = _fixedPayload(opts.payload);
|
|
462
462
|
var headerJson;
|
|
@@ -496,7 +496,7 @@ async function sign(opts) {
|
|
|
496
496
|
var protectedB64 = b64uEncode(headerBytes);
|
|
497
497
|
var payloadB64 = payload.length === 0 ? "" : b64uEncode(payload);
|
|
498
498
|
var signingInput = _bufferFrom(protectedB64 + "." + payloadB64, "ascii");
|
|
499
|
-
var jwk = header.jwk || opts.jwk ||
|
|
499
|
+
var jwk = header.jwk || opts.jwk || intrinsic.create(null);
|
|
500
500
|
/** @internal `suppliedKey` is the reading taken at the top, so the key adopted for signing, the key the
|
|
501
501
|
* hash-to-algorithm check approved and the key the expected signature width is computed from are all
|
|
502
502
|
* one key. */
|
package/lib/key.js
CHANGED
|
@@ -183,11 +183,11 @@ async function encrypt(privateKey, password, opts) {
|
|
|
183
183
|
var prf = opts.prf || "hmacWithSHA256";
|
|
184
184
|
var prfNode = pbes2.prfNodeByName(prf, _err, "key");
|
|
185
185
|
var iterations = pbes2.assertIterations(opts.iterations == null ? 600000 : opts.iterations, _err, "key");
|
|
186
|
-
var salt = opts.salt != null ? pbes2.assertSalt(guard.bytes.view(opts.salt, KeyError, "key/bad-input", "salt"), _err, "key") :
|
|
187
|
-
var iv =
|
|
186
|
+
var salt = opts.salt != null ? pbes2.assertSalt(guard.bytes.view(opts.salt, KeyError, "key/bad-input", "salt"), _err, "key") : guard.crypto.randomBytes(16);
|
|
187
|
+
var iv = guard.crypto.randomBytes(16);
|
|
188
188
|
var pwK = pbes2.passwordBytesOwned(password, _err, "key");
|
|
189
189
|
var dk;
|
|
190
|
-
try { dk =
|
|
190
|
+
try { dk = guard.crypto.pbkdf2(pwK.bytes, salt, iterations, keyBits / 8, prfNode); }
|
|
191
191
|
finally { if (pwK.owned) guard.secret.zeroize(pwK.bytes, KeyError, "key/bad-input", "the password encoding"); }
|
|
192
192
|
try {
|
|
193
193
|
var ciphertext = pbes2.cbcEncrypt(dk, iv, der, keyBits, KeyError, "key/bad-input");
|
|
@@ -290,6 +290,10 @@ function _decryptPbes2(encAlg, ciphertext, password, opts) {
|
|
|
290
290
|
* var spkiPem = await pki.key.export(pair.publicKey, { format: "pem" });
|
|
291
291
|
*/
|
|
292
292
|
var _EXPORT_OPTS = _assign(_create(null), { format: 1, label: 1 });
|
|
293
|
+
/** @internal The WebCrypto export format each key type calls for, named here so the ONE read of the
|
|
294
|
+
* key's type below settles the encoding as well as the PEM label. Passing the format explicitly is
|
|
295
|
+
* what keeps the engine from reading the type a second time. */
|
|
296
|
+
var _EXPORT_WANT_BY_TYPE = _assign(_create(null), { "private": "pkcs8", "public": "spki", "secret": "raw" });
|
|
293
297
|
|
|
294
298
|
async function export_(key, opts) {
|
|
295
299
|
opts = guard.identifier.optionsObject(opts, _err, "key/bad-input", "pki.key.export options");
|
|
@@ -297,9 +301,14 @@ async function export_(key, opts) {
|
|
|
297
301
|
"pki.key.export has an unknown option. It serializes only. To protect a private key, call " +
|
|
298
302
|
"pki.key.encrypt(key, password) first and export its result. The unknown option was: ");
|
|
299
303
|
if (!_isCryptoKey(key)) throw _err("key/bad-input", "export expects a WebCrypto CryptoKey");
|
|
304
|
+
/** @internal ONE read of the key's type, which both the PEM label and every encoding decision
|
|
305
|
+
* below come from. On node's own CryptoKey it is a getter, so reading it per question let a
|
|
306
|
+
* replacement answer "private" where the label was chosen and "public" where the bytes were, and
|
|
307
|
+
* a public key came back inside a `PRIVATE KEY` block. */
|
|
308
|
+
var keyType = key.type;
|
|
300
309
|
var defaultLabel;
|
|
301
|
-
if (
|
|
302
|
-
else if (
|
|
310
|
+
if (keyType === "private") defaultLabel = "PRIVATE KEY";
|
|
311
|
+
else if (keyType === "public") defaultLabel = "PUBLIC KEY";
|
|
303
312
|
else throw _err("key/bad-input", "export supports asymmetric (private / public) CryptoKeys only");
|
|
304
313
|
var fmt = opts.format || "der";
|
|
305
314
|
if (fmt === "jwk") {
|
|
@@ -310,11 +319,11 @@ async function export_(key, opts) {
|
|
|
310
319
|
throw _err("key/bad-input", "exporting the key as a JWK failed", e);
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
|
-
var der = await _exportAnyKey(key, _err, "key/bad-input");
|
|
322
|
+
var der = await _exportAnyKey(key, _err, "key/bad-input", _EXPORT_WANT_BY_TYPE[keyType]);
|
|
314
323
|
if (fmt === "der") return der;
|
|
315
324
|
if (fmt === "pem") return pkix.pemEncode(der, opts.label || defaultLabel, PemError);
|
|
316
|
-
if (fmt === "pkcs1") return _toPkcs1(der, key);
|
|
317
|
-
if (fmt === "sec1") return _toSec1(der, key);
|
|
325
|
+
if (fmt === "pkcs1") return _toPkcs1(der, key, keyType);
|
|
326
|
+
if (fmt === "sec1") return _toSec1(der, key, keyType);
|
|
318
327
|
throw _err("key/bad-input", "unsupported format " + guard.text.showValue(opts.format) + " (der / pem / pkcs1 / sec1 / jwk)");
|
|
319
328
|
}
|
|
320
329
|
|
|
@@ -923,18 +932,19 @@ var _PAIR_RSA = _assign(_create(null), { rsa: 1, "rsa-pss": 1 });
|
|
|
923
932
|
var _PAIR_PROBE = _bufferFrom("pki.js key pair correspondence", "utf8");
|
|
924
933
|
|
|
925
934
|
function _sameKeyFamily(priv, pub) {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
935
|
+
var privType = guard.crypto.keyType(priv), pubType = guard.crypto.keyType(pub);
|
|
936
|
+
if (privType === pubType) return true;
|
|
937
|
+
return !!(_PAIR_RSA[guard.text.keyOf(privType)] && _PAIR_RSA[guard.text.keyOf(pubType)]);
|
|
929
938
|
}
|
|
930
939
|
|
|
931
940
|
/** @internal How to exercise a signing pair: the digest, and any padding the encoding requires. An
|
|
932
941
|
* `id-RSASSA-PSS` key may pin the hash and salt length it is usable with, and the engine refuses any
|
|
933
942
|
* other, so a pinned value from either half is what proves the pair. */
|
|
934
943
|
function _pairSignOptions(priv, pub) {
|
|
935
|
-
var
|
|
944
|
+
var privType = guard.crypto.keyType(priv);
|
|
945
|
+
var privPss = privType === "rsa-pss", pubPss = guard.crypto.keyType(pub) === "rsa-pss";
|
|
936
946
|
if (!privPss && !pubPss) {
|
|
937
|
-
return { digest: _PAIR_DIGEST[guard.text.keyOf(
|
|
947
|
+
return { digest: _PAIR_DIGEST[guard.text.keyOf(privType)] || null, options: null };
|
|
938
948
|
}
|
|
939
949
|
var privDetails = _pssRestrictionOf(priv, privPss);
|
|
940
950
|
var pubDetails = _pssRestrictionOf(pub, pubPss);
|
|
@@ -969,7 +979,7 @@ var _PSS_PINS = ["hashAlgorithm", "mgf1HashAlgorithm", "saltLength"];
|
|
|
969
979
|
* carried, and refuse a genuine pair. */
|
|
970
980
|
function _pssRestrictionOf(key, isPss) {
|
|
971
981
|
var out = _create(null);
|
|
972
|
-
var details = isPss ? key
|
|
982
|
+
var details = isPss ? guard.crypto.keyDetails(key) : null;
|
|
973
983
|
if (details == null) return out;
|
|
974
984
|
for (var i = 0; i < _PSS_PINS.length; i++) {
|
|
975
985
|
var name = _PSS_PINS[i];
|
|
@@ -1026,7 +1036,7 @@ async function correspondsTo(privateKey, spkiDer) {
|
|
|
1026
1036
|
try { pub = guard.crypto.publicKey({ key: pubAsPkcs3, format: "der", type: "spki" }); }
|
|
1027
1037
|
catch (e) { throw _err("key/bad-input", "the public key could not be read", e); }
|
|
1028
1038
|
if (!_sameKeyFamily(priv, pub)) return false;
|
|
1029
|
-
var kind = guard.text.keyOf(priv
|
|
1039
|
+
var kind = guard.text.keyOf(guard.crypto.keyType(priv));
|
|
1030
1040
|
/** @internal Every secret a probe makes, wiped once the verdict is decided, on every way out. */
|
|
1031
1041
|
var secrets = [];
|
|
1032
1042
|
try {
|
|
@@ -1041,17 +1051,17 @@ async function correspondsTo(privateKey, spkiDer) {
|
|
|
1041
1051
|
return _keyEquals(guard.crypto.publicKey(priv), pub) === true;
|
|
1042
1052
|
}
|
|
1043
1053
|
if (_PAIR_KEM[kind]) {
|
|
1044
|
-
var sealed =
|
|
1054
|
+
var sealed = guard.crypto.encapsulate(pub);
|
|
1045
1055
|
guard.list.append(secrets, sealed.sharedKey);
|
|
1046
|
-
var opened =
|
|
1056
|
+
var opened = guard.crypto.decapsulate(priv, sealed.ciphertext);
|
|
1047
1057
|
guard.list.append(secrets, opened);
|
|
1048
1058
|
return guard.crypto.constantTimeEqual(opened, sealed.sharedKey);
|
|
1049
1059
|
}
|
|
1050
1060
|
if (_PAIR_AGREE[kind]) {
|
|
1051
|
-
var ephemeral =
|
|
1052
|
-
var ours =
|
|
1061
|
+
var ephemeral = guard.crypto.generateKeyPair(guard.crypto.keyType(priv));
|
|
1062
|
+
var ours = guard.crypto.diffieHellman({ privateKey: priv, publicKey: ephemeral.publicKey });
|
|
1053
1063
|
guard.list.append(secrets, ours);
|
|
1054
|
-
var theirs =
|
|
1064
|
+
var theirs = guard.crypto.diffieHellman({ privateKey: ephemeral.privateKey, publicKey: pub });
|
|
1055
1065
|
guard.list.append(secrets, theirs);
|
|
1056
1066
|
if (!guard.crypto.constantTimeEqual(ours, theirs)) return false;
|
|
1057
1067
|
/** @internal The agreement proves the SCALAR, not the encoding it was handed. RFC 7748 masks the
|
|
@@ -1194,13 +1204,13 @@ async function _importNamedFormat(input, opts) {
|
|
|
1194
1204
|
/** @internal The inverse of the wrap: pull the inner key out of the PKCS#8 or SPKI the engine
|
|
1195
1205
|
* wrote. The bytes come back as they went in, since the engine carries the inner structure
|
|
1196
1206
|
* unchanged and this reads it rather than re-encoding it. */
|
|
1197
|
-
function _toPkcs1(der, key) {
|
|
1198
|
-
var algOid = _wrappedAlgorithmOid(der,
|
|
1207
|
+
function _toPkcs1(der, key, keyType) {
|
|
1208
|
+
var algOid = _wrappedAlgorithmOid(der, keyType);
|
|
1199
1209
|
if (algOid !== O("rsaEncryption")) {
|
|
1200
1210
|
throw _err("key/bad-input", "PKCS#1 is an RSA encoding (RFC 8017 App. A.1) and this key is " + _algName(key.algorithm));
|
|
1201
1211
|
}
|
|
1202
1212
|
var node = asn1.decode(der);
|
|
1203
|
-
if (
|
|
1213
|
+
if (keyType === "public") {
|
|
1204
1214
|
var bits = asn1.read.bitString(node.children[1]);
|
|
1205
1215
|
if (bits.unusedBits !== 0) throw _err("key/bad-input", "the exported public key does not hold whole octets");
|
|
1206
1216
|
schemaPkcs1.parsePublic(bits.bytes);
|
|
@@ -1210,12 +1220,12 @@ function _toPkcs1(der, key) {
|
|
|
1210
1220
|
schemaPkcs1.parse(inner);
|
|
1211
1221
|
return inner;
|
|
1212
1222
|
}
|
|
1213
|
-
function _toSec1(der, key) {
|
|
1214
|
-
var algOid = _wrappedAlgorithmOid(der,
|
|
1223
|
+
function _toSec1(der, key, keyType) {
|
|
1224
|
+
var algOid = _wrappedAlgorithmOid(der, keyType);
|
|
1215
1225
|
if (algOid !== O("ecPublicKey")) {
|
|
1216
1226
|
throw _err("key/bad-input", "SEC1 is an elliptic-curve private-key encoding (RFC 5915 sec. 3) and this key is " + _algName(key.algorithm));
|
|
1217
1227
|
}
|
|
1218
|
-
if (
|
|
1228
|
+
if (keyType !== "private") {
|
|
1219
1229
|
throw _err("key/bad-input", "SEC1 encodes a private key; export the public half as SubjectPublicKeyInfo");
|
|
1220
1230
|
}
|
|
1221
1231
|
var node = asn1.decode(der);
|
|
@@ -1248,11 +1258,13 @@ function _toSec1(der, key) {
|
|
|
1248
1258
|
}
|
|
1249
1259
|
|
|
1250
1260
|
/** @internal The algorithm the wrapper names, read from whichever wrapper the key type produced:
|
|
1251
|
-
* a PrivateKeyInfo names it second, a SubjectPublicKeyInfo first.
|
|
1252
|
-
|
|
1261
|
+
* a PrivateKeyInfo names it second, a SubjectPublicKeyInfo first. `keyType` is the one read the
|
|
1262
|
+
* caller took, rather than a fresh one off the key, so every decision in an export comes from the
|
|
1263
|
+
* same answer. */
|
|
1264
|
+
function _wrappedAlgorithmOid(der, keyType) {
|
|
1253
1265
|
var node;
|
|
1254
1266
|
try { node = asn1.decode(der); } catch (e) { throw _err("key/bad-input", "the exported key is not DER", e); }
|
|
1255
|
-
var algSeq =
|
|
1267
|
+
var algSeq = keyType === "public" ? node.children[0] : node.children[1];
|
|
1256
1268
|
if (!algSeq || !algSeq.children || algSeq.children.length === 0) {
|
|
1257
1269
|
throw _err("key/bad-input", "the exported key names no algorithm");
|
|
1258
1270
|
}
|
package/lib/merkle.js
CHANGED
|
@@ -274,7 +274,7 @@ function emptyRootHash() {
|
|
|
274
274
|
*/
|
|
275
275
|
var _INCLUSION_KEYS = _assign(_create(null), { leafIndex: 1, treeSize: 1, leafHash: 1, rootHash: 1, proof: 1 });
|
|
276
276
|
function verifyInclusion(opts) {
|
|
277
|
-
opts = opts ||
|
|
277
|
+
opts = opts || _create(null);
|
|
278
278
|
guard.identifier.assertKnownKeys(opts, _INCLUSION_KEYS, function (c, m) { return new MerkleError(c, m); },
|
|
279
279
|
"merkle/bad-input", "unknown verifyInclusion option ");
|
|
280
280
|
var leafIndex = _coerceCoord(opts.leafIndex, "leafIndex");
|
|
@@ -346,7 +346,7 @@ function verifyInclusion(opts) {
|
|
|
346
346
|
*/
|
|
347
347
|
var _CONSISTENCY_KEYS = _assign(_create(null), { oldSize: 1, newSize: 1, oldRoot: 1, newRoot: 1, proof: 1 });
|
|
348
348
|
function verifyConsistency(opts) {
|
|
349
|
-
opts = opts ||
|
|
349
|
+
opts = opts || _create(null);
|
|
350
350
|
guard.identifier.assertKnownKeys(opts, _CONSISTENCY_KEYS, function (c, m) { return new MerkleError(c, m); },
|
|
351
351
|
"merkle/bad-input", "unknown verifyConsistency option ");
|
|
352
352
|
var oldSize = _coerceCoord(opts.oldSize, "oldSize");
|
|
@@ -456,7 +456,7 @@ function root(leafHashes) {
|
|
|
456
456
|
*/
|
|
457
457
|
var _INCLUSION_PROOF_KEYS = _assign(_create(null), { leafHashes: 1, leafIndex: 1 });
|
|
458
458
|
function inclusionProof(opts) {
|
|
459
|
-
opts = opts ||
|
|
459
|
+
opts = opts || _create(null);
|
|
460
460
|
guard.identifier.assertKnownKeys(opts, _INCLUSION_PROOF_KEYS, _merkleErr,
|
|
461
461
|
"merkle/bad-input", "unknown inclusionProof option ");
|
|
462
462
|
var leaves = _leafArray(opts.leafHashes, "leafHashes");
|
|
@@ -498,7 +498,7 @@ function inclusionProof(opts) {
|
|
|
498
498
|
*/
|
|
499
499
|
var _CONSISTENCY_PROOF_KEYS = _assign(_create(null), { leafHashes: 1, oldSize: 1 });
|
|
500
500
|
function consistencyProof(opts) {
|
|
501
|
-
opts = opts ||
|
|
501
|
+
opts = opts || _create(null);
|
|
502
502
|
guard.identifier.assertKnownKeys(opts, _CONSISTENCY_PROOF_KEYS, _merkleErr,
|
|
503
503
|
"merkle/bad-input", "unknown consistencyProof option ");
|
|
504
504
|
var leaves = _leafArray(opts.leafHashes, "leafHashes");
|
package/lib/ocsp.js
CHANGED
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
* @card Build, sign, and verify RFC 6960 OCSP requests + responses (a responder + a relying party).
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
var nodeCrypto = require("crypto");
|
|
27
26
|
var asn1 = require("./asn1-der");
|
|
28
27
|
var pkiBuild = require("./pki-build");
|
|
29
28
|
var _ocspIntrinsic = require("./guard-intrinsic");
|
|
@@ -245,7 +244,7 @@ function _buildRequest(query, opts) {
|
|
|
245
244
|
_push(tbsChildren,b.sequence(requests));
|
|
246
245
|
var reqExts = [];
|
|
247
246
|
if (opts.nonce) {
|
|
248
|
-
var nonceBytes = opts.nonce === true ?
|
|
247
|
+
var nonceBytes = opts.nonce === true ? guard.crypto.randomBytes(32) : opts.nonce;
|
|
249
248
|
_assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
|
|
250
249
|
_push(reqExts,_nonceExt(nonceBytes));
|
|
251
250
|
}
|
|
@@ -351,7 +350,7 @@ function _sign(responseData, responder, opts) {
|
|
|
351
350
|
opts = guard.identifier.optionsObject(opts, _err, "ocsp/bad-input", "pki.ocsp.sign options");
|
|
352
351
|
guard.identifier.assertKnownKeys(opts, _SIGN_OPTS, _err, "ocsp/bad-input",
|
|
353
352
|
"pki.ocsp.sign has an unknown option (the nonce to echo back is `nonce`): ");
|
|
354
|
-
responseData = responseData ||
|
|
353
|
+
responseData = responseData || _ocspIntrinsic.create(null);
|
|
355
354
|
if (typeof responseData !== "object") throw _err("ocsp/bad-input", "the responseData must be an object { responderID, responses, producedAt? }");
|
|
356
355
|
guard.identifier.assertKnownKeys(responseData, _RESPONSE_DATA_KEYS, _err, "ocsp/bad-input", "unknown responseData field (accepted: responderID, responses, producedAt): ");
|
|
357
356
|
if (!responder || typeof responder !== "object") throw _err("ocsp/bad-input", "a responder must be { cert, key }");
|
|
@@ -450,7 +449,7 @@ function _responderID(rid, respCert) {
|
|
|
450
449
|
throw _err("ocsp/bad-input", "responderID must be \"byName\" or \"byKey\"");
|
|
451
450
|
}
|
|
452
451
|
function _buildSingleResponse(r, opts) {
|
|
453
|
-
r = r ||
|
|
452
|
+
r = r || _ocspIntrinsic.create(null);
|
|
454
453
|
var certIdP;
|
|
455
454
|
if (typeof r !== "object") return _promiseReject(_Promise, _err("ocsp/bad-input", "each response entry must be an object"));
|
|
456
455
|
try { guard.identifier.assertKnownKeys(r, _SINGLE_RESPONSE_KEYS, _err, "ocsp/bad-input", "unknown response entry field (accepted: cert, issuer, certID, hashAlgorithm, status, thisUpdate, nextUpdate, singleExtensions): "); }
|
package/lib/path-validate.js
CHANGED
|
@@ -1867,7 +1867,7 @@ async function _validate(path, opts, run, scope) {
|
|
|
1867
1867
|
}
|
|
1868
1868
|
|
|
1869
1869
|
if (opts.ctLogList != null) {
|
|
1870
|
-
var ctCheck = await ctGateCheck(certs[n - 1], certs, anchor, opts.ctLogList, opts.ctPolicy ||
|
|
1870
|
+
var ctCheck = await ctGateCheck(certs[n - 1], certs, anchor, opts.ctLogList, opts.ctPolicy || intrinsic.create(null), n, opts.time);
|
|
1871
1871
|
var target = null;
|
|
1872
1872
|
for (var tr = 0; tr < state.results.length; tr++) { if (state.results[tr].index === n - 1) { target = state.results[tr]; break; } }
|
|
1873
1873
|
if (target) guard.list.append(target.checks, ctCheck);
|
|
@@ -2599,7 +2599,7 @@ function _ocspFromBytes(response) {
|
|
|
2599
2599
|
}
|
|
2600
2600
|
|
|
2601
2601
|
function _verifyOcspParsed(parsedResponse, cert, issuerCert, time, opts) {
|
|
2602
|
-
opts = opts ||
|
|
2602
|
+
opts = opts || intrinsic.create(null);
|
|
2603
2603
|
/** @internal The captured finite test rather than a live `isNaN`: a valid Date's instant is always
|
|
2604
2604
|
* finite and an invalid one's is not, so the two answer the same question, and the instant is read
|
|
2605
2605
|
* ONCE into the value the test decides on. */
|
|
@@ -3356,7 +3356,7 @@ async function _aiaFetchOne(uri, aia) {
|
|
|
3356
3356
|
var res = await guard.async.invoked(aia.transport,
|
|
3357
3357
|
[{ method: "GET", url: uri, tls: aia.tls, timeout: aia.timeout, maxResponseBytes: aia.maxResponseBytes, blockPrivateAddresses: true }],
|
|
3358
3358
|
E, "path/bad-input", "opts.transport");
|
|
3359
|
-
res = res ||
|
|
3359
|
+
res = res || intrinsic.create(null);
|
|
3360
3360
|
if (res.status !== 200) throw E("path/aia-status", "an AIA fetch returned HTTP " + res.status + " (only 200 is a cert source; no redirect following)");
|
|
3361
3361
|
var body = guard.bytes.isByteSource(res.body)
|
|
3362
3362
|
? guard.bytes.source(res.body, PathError, "path/aia-bad-body", "the AIA response body")
|