@blamejs/pki 0.8.59 → 0.8.60
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 +33 -0
- package/lib/acme.js +15 -7
- package/lib/alt-sig.js +3 -1
- package/lib/asn1-der.js +82 -34
- package/lib/attrcert-sign.js +19 -16
- package/lib/byte-writer.js +63 -13
- package/lib/cbor-det.js +9 -3
- package/lib/cmc-build.js +12 -9
- package/lib/cmp-build.js +35 -33
- package/lib/cmp-session.js +19 -9
- package/lib/cms-decrypt.js +22 -8
- package/lib/cms-encrypt.js +23 -17
- package/lib/cms-sign.js +65 -43
- package/lib/cms-verify.js +8 -4
- package/lib/crl-sign.js +24 -17
- package/lib/csr-sign.js +5 -2
- package/lib/ct.js +27 -16
- package/lib/est.js +12 -9
- package/lib/guard-bytes.js +5 -1
- package/lib/guard-der.js +6 -1
- package/lib/guard-intrinsic.js +12 -4
- package/lib/guard-list.js +64 -0
- package/lib/guard-name.js +1 -1
- package/lib/hpke.js +10 -3
- package/lib/http-transport.js +12 -3
- package/lib/inspect.js +10 -2
- package/lib/jose.js +3 -1
- package/lib/lint.js +236 -152
- package/lib/mime.js +9 -5
- package/lib/ocsp.js +25 -22
- package/lib/path-validate.js +43 -13
- package/lib/pbes2.js +6 -2
- package/lib/pkcs11-uri.js +3 -1
- package/lib/pkcs12-build.js +14 -11
- package/lib/pki-build.js +14 -10
- package/lib/possession.js +3 -1
- package/lib/rc2.js +6 -2
- package/lib/revocation-fetch.js +78 -19
- package/lib/scep.js +14 -6
- package/lib/schema-attrcert.js +4 -2
- package/lib/schema-c509.js +94 -78
- package/lib/schema-cmc.js +5 -2
- package/lib/schema-cmp.js +6 -3
- package/lib/schema-cms.js +7 -4
- package/lib/schema-crl.js +1 -1
- package/lib/schema-crmf.js +1 -1
- package/lib/schema-csr.js +3 -3
- package/lib/schema-engine.js +36 -18
- package/lib/schema-pkcs1.js +7 -3
- package/lib/schema-pkcs12.js +9 -6
- package/lib/schema-pkix.js +19 -3
- package/lib/schema-sec1.js +4 -1
- package/lib/schema-tsp.js +4 -1
- package/lib/shbs.js +7 -3
- package/lib/smime.js +18 -14
- package/lib/tlog.js +17 -11
- package/lib/tuf.js +3 -1
- package/lib/validator-keydesc.js +4 -1
- package/lib/validator-tls.js +7 -2
- package/lib/webcrypto.js +9 -3
- package/lib/x509-sign.js +20 -15
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/mime.js
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
var C = require("./constants.js");
|
|
20
20
|
var guard = require("./guard-all.js");
|
|
21
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
22
|
+
* consults a setter inherited there, and these lists become the headers and parts of a message
|
|
23
|
+
* body a signature is computed over. */
|
|
24
|
+
var _push = guard.list.append;
|
|
21
25
|
|
|
22
26
|
var CRLF = Buffer.from("\r\n");
|
|
23
27
|
|
|
@@ -60,7 +64,7 @@ function _unfoldHeaders(headerText) {
|
|
|
60
64
|
var ln = lines[i];
|
|
61
65
|
if (ln === "") continue;
|
|
62
66
|
if ((ln[0] === " " || ln[0] === "\t") && out.length) out[out.length - 1] += " " + _stripLeadingHtab(ln);
|
|
63
|
-
else out
|
|
67
|
+
else _push(out,ln);
|
|
64
68
|
}
|
|
65
69
|
return out;
|
|
66
70
|
}
|
|
@@ -103,10 +107,10 @@ function _splitSemicolons(s) {
|
|
|
103
107
|
else if (ch === '"' && depth === 0) { inQ = !inQ; cur += ch; }
|
|
104
108
|
else if (ch === "(" && !inQ) { depth++; cur += ch; }
|
|
105
109
|
else if (ch === ")" && !inQ && depth > 0) { depth--; cur += ch; }
|
|
106
|
-
else if (ch === ";" && !inQ && depth === 0) { out
|
|
110
|
+
else if (ch === ";" && !inQ && depth === 0) { _push(out,cur); cur = ""; }
|
|
107
111
|
else cur += ch;
|
|
108
112
|
}
|
|
109
|
-
out
|
|
113
|
+
_push(out,cur);
|
|
110
114
|
return out;
|
|
111
115
|
}
|
|
112
116
|
|
|
@@ -124,7 +128,7 @@ function parse(input, E, code) {
|
|
|
124
128
|
if (colon < 0) throw new E(code, "a MIME header line has no colon: " + JSON.stringify(rawHeaders[i].slice(0, 40)));
|
|
125
129
|
var nm = rawHeaders[i].slice(0, colon).trim();
|
|
126
130
|
var body = rawHeaders[i].slice(colon + 1);
|
|
127
|
-
headers
|
|
131
|
+
_push(headers,{ name: nm, lname: nm.toLowerCase(), value: body.trim(), rawValue: body.charAt(0) === " " ? body.slice(1) : body });
|
|
128
132
|
}
|
|
129
133
|
function header(name) { var l = name.toLowerCase(); for (var j = 0; j < headers.length; j++) if (headers[j].lname === l) return headers[j].value; return null; }
|
|
130
134
|
var ctv = header("content-type");
|
|
@@ -160,7 +164,7 @@ function splitMultipart(bodyBytes, boundary, E, code) {
|
|
|
160
164
|
var partEnd = next;
|
|
161
165
|
if (partEnd >= 2 && body[partEnd - 2] === 0x0d && body[partEnd - 1] === 0x0a) partEnd -= 2;
|
|
162
166
|
else if (partEnd >= 1 && body[partEnd - 1] === 0x0a) partEnd -= 1;
|
|
163
|
-
parts
|
|
167
|
+
_push(parts,body.subarray(pos, partEnd));
|
|
164
168
|
var afterDelim = next + delim.length;
|
|
165
169
|
if (body[afterDelim] === 0x2d && body[afterDelim + 1] === 0x2d) break;
|
|
166
170
|
pos = _afterLine(body, afterDelim, E, code);
|
package/lib/ocsp.js
CHANGED
|
@@ -51,6 +51,9 @@ var ocspRequestVerify = require("./ocsp-request-verify");
|
|
|
51
51
|
var webcrypto = require("./webcrypto");
|
|
52
52
|
var subtle = webcrypto.webcrypto.subtle;
|
|
53
53
|
var guard = require("./guard-all");
|
|
54
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
55
|
+
* consults a setter inherited there, and these lists become a signed request or response. */
|
|
56
|
+
var _push = guard.list.append;
|
|
54
57
|
var constants = require("./constants");
|
|
55
58
|
var frameworkError = require("./framework-error");
|
|
56
59
|
var E = _err;
|
|
@@ -230,7 +233,7 @@ function _buildRequest(query, opts) {
|
|
|
230
233
|
var singles = pkiBuild.reqDenseArray(q.singleRequestExtensions, "singleRequestExtensions", _err, "ocsp/bad-input");
|
|
231
234
|
if (singles.length) {
|
|
232
235
|
if (lightweight) throw _err("ocsp/bad-input", "the lightweight profile permits no singleRequestExtensions (RFC 5019 sec. 2.1.1)");
|
|
233
|
-
reqChildren
|
|
236
|
+
_push(reqChildren,b.explicit(0, b.sequence(singles)));
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
return b.sequence(reqChildren);
|
|
@@ -238,15 +241,15 @@ function _buildRequest(query, opts) {
|
|
|
238
241
|
}));
|
|
239
242
|
return _ocspIntrinsic.chain(builtRequests, function (requests) {
|
|
240
243
|
var tbsChildren = [];
|
|
241
|
-
if (requestorNameDer !== null) tbsChildren
|
|
242
|
-
tbsChildren
|
|
244
|
+
if (requestorNameDer !== null) _push(tbsChildren,b.explicit(1, b.contextConstructed(4, requestorNameDer)));
|
|
245
|
+
_push(tbsChildren,b.sequence(requests));
|
|
243
246
|
var reqExts = [];
|
|
244
247
|
if (opts.nonce) {
|
|
245
248
|
var nonceBytes = opts.nonce === true ? nodeCrypto.randomBytes(32) : opts.nonce;
|
|
246
249
|
_assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
|
|
247
|
-
reqExts
|
|
250
|
+
_push(reqExts,_nonceExt(nonceBytes));
|
|
248
251
|
}
|
|
249
|
-
if (reqExts.length) tbsChildren
|
|
252
|
+
if (reqExts.length) _push(tbsChildren,b.explicit(2, b.sequence(reqExts)));
|
|
250
253
|
var tbsRequest = b.sequence(tbsChildren);
|
|
251
254
|
if (signerCert === null) return _emitReq(b.sequence([tbsRequest]), opts);
|
|
252
255
|
var scheme = signScheme.resolveSignScheme(signerCert, { combinedRsaSig: true }, true, _signE);
|
|
@@ -389,9 +392,9 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
389
392
|
}
|
|
390
393
|
var rdChildren = [ridNode, b.generalizedTime(_asEncodableDate(responseData.producedAt, "producedAt") || new Date()), b.sequence(srNodes)];
|
|
391
394
|
var respExts = [];
|
|
392
|
-
if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); respExts
|
|
393
|
-
if (opts.extendedRevoke || anyNonIssued) respExts
|
|
394
|
-
if (respExts.length) rdChildren
|
|
395
|
+
if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); _push(respExts,_nonceExt(opts.nonce)); }
|
|
396
|
+
if (opts.extendedRevoke || anyNonIssued) _push(respExts,b.sequence([b.oid(OID_EXTENDED_REVOKE), b.octetString(b.nullValue())]));
|
|
397
|
+
if (respExts.length) _push(rdChildren,b.explicit(1, b.sequence(respExts)));
|
|
395
398
|
var responseDataDer = b.sequence(rdChildren);
|
|
396
399
|
var scheme = signScheme.resolveSignScheme(respCert, { combinedRsaSig: true }, true, _signE);
|
|
397
400
|
return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE), function (sig) {
|
|
@@ -401,7 +404,7 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
401
404
|
var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(responseDataDer, sig, respCert.subjectPublicKeyInfo.bytes, scheme));
|
|
402
405
|
return _ocspIntrinsic.chain(selfChecked, function () {
|
|
403
406
|
var basicChildren = [responseDataDer, scheme.sigAlgId, b.bitString(sig, 0)];
|
|
404
|
-
if (opts.embedCert !== false) basicChildren
|
|
407
|
+
if (opts.embedCert !== false) _push(basicChildren,b.explicit(0, b.sequence([b.raw(respCertDer)])));
|
|
405
408
|
var responseBytes = b.sequence([b.oid(OID_OCSP_BASIC), b.octetString(b.sequence(basicChildren))]);
|
|
406
409
|
var der = b.sequence([b.enumerated(0n), b.explicit(0, responseBytes)]);
|
|
407
410
|
return opts.pem ? ocspSchema.pemEncode(der, "OCSP RESPONSE") : der;
|
|
@@ -426,7 +429,7 @@ function _asEncodableDate(d, which) {
|
|
|
426
429
|
function _snapshotSignerKey(key, owned) {
|
|
427
430
|
if (Buffer.isBuffer(key) || key instanceof Uint8Array) { // allow:byte-source-narrow -- responder private key on the key-ownership contract (Buffer / Uint8Array / PEM / CryptoKey); widening keys is a separate root decision
|
|
428
431
|
var copy = guard.bytes.snapshot(key, OcspError, "ocsp/bad-input", "the responder key");
|
|
429
|
-
owned
|
|
432
|
+
_push(owned,copy);
|
|
430
433
|
return copy;
|
|
431
434
|
}
|
|
432
435
|
if (key && typeof key === "object" && (key.mldsa != null || key.trad != null)) {
|
|
@@ -482,10 +485,10 @@ function _buildSingleResponse(r, opts) {
|
|
|
482
485
|
var statusNode = _certStatusNode(r.status, opts);
|
|
483
486
|
var nonIssued = _isNonIssuedStatus(r.status);
|
|
484
487
|
var srChildren = [certID, statusNode, b.generalizedTime(thisUpdate)];
|
|
485
|
-
if (nextUpdate !== null) srChildren
|
|
488
|
+
if (nextUpdate !== null) _push(srChildren,b.explicit(0, b.generalizedTime(nextUpdate)));
|
|
486
489
|
if (r.singleExtensions != null) {
|
|
487
490
|
var singleDer = _singleExtensionsDer(r.singleExtensions, nonIssued);
|
|
488
|
-
if (singleDer.length) srChildren
|
|
491
|
+
if (singleDer.length) _push(srChildren,b.explicit(1, b.sequence(singleDer)));
|
|
489
492
|
}
|
|
490
493
|
return { node: b.sequence(srChildren), nonIssued: nonIssued };
|
|
491
494
|
});
|
|
@@ -558,7 +561,7 @@ function _singleExtensionsDer(spec, nonIssued) {
|
|
|
558
561
|
var out = [];
|
|
559
562
|
if (spec.archiveCutoff != null) {
|
|
560
563
|
guard.time.assertEncodable(spec.archiveCutoff, _err, "ocsp/bad-input", "singleExtensions archiveCutoff");
|
|
561
|
-
out
|
|
564
|
+
_push(out,b.sequence([b.oid(oid.byName("ocspArchiveCutoff")), b.octetString(b.generalizedTime(spec.archiveCutoff))]));
|
|
562
565
|
}
|
|
563
566
|
if (spec.crlReferences != null) {
|
|
564
567
|
if (nonIssued) throw _err("ocsp/bad-input", NON_ISSUED_FORBIDDEN);
|
|
@@ -575,18 +578,18 @@ function _singleExtensionsDer(spec, nonIssued) {
|
|
|
575
578
|
for (var j = 0; j < c.crlUrl.length; j++) {
|
|
576
579
|
if (c.crlUrl.charCodeAt(j) > 0x7f) throw _err("ocsp/bad-input", "crlReferences crlUrl must be 7-bit ASCII (an IA5String, RFC 6960 sec. 4.4.2)");
|
|
577
580
|
}
|
|
578
|
-
fields
|
|
581
|
+
_push(fields,b.explicit(0, b.ia5(c.crlUrl)));
|
|
579
582
|
}
|
|
580
583
|
if (c.crlNum != null) {
|
|
581
584
|
var num = guard.range.authoredInteger(c.crlNum, _err, "ocsp/bad-input", "crlReferences crlNum");
|
|
582
585
|
if (num < 0n) throw _err("ocsp/bad-input", "crlReferences crlNum must be non-negative (it is a cRLNumber, RFC 5280 sec. 5.2.3)");
|
|
583
|
-
fields
|
|
586
|
+
_push(fields,b.explicit(1, b.integer(num)));
|
|
584
587
|
}
|
|
585
588
|
if (c.crlTime != null) {
|
|
586
589
|
guard.time.assertEncodable(c.crlTime, _err, "ocsp/bad-input", "crlReferences crlTime");
|
|
587
|
-
fields
|
|
590
|
+
_push(fields,b.explicit(2, b.generalizedTime(c.crlTime)));
|
|
588
591
|
}
|
|
589
|
-
out
|
|
592
|
+
_push(out,b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
|
|
590
593
|
}
|
|
591
594
|
return out;
|
|
592
595
|
}
|
|
@@ -600,7 +603,7 @@ function _certStatusNode(status, opts) {
|
|
|
600
603
|
if (status.revocationReason != null) {
|
|
601
604
|
var code = typeof status.revocationReason === "number" ? status.revocationReason : REASON_CODE[guard.text.keyOf(status.revocationReason)];
|
|
602
605
|
if (code == null) throw _err("ocsp/bad-input", "unknown revocationReason " + guard.text.showValue(status.revocationReason));
|
|
603
|
-
ri
|
|
606
|
+
_push(ri,b.explicit(0, b.enumerated(BigInt(code))));
|
|
604
607
|
}
|
|
605
608
|
return b.contextConstructed(1, Buffer.concat(ri));
|
|
606
609
|
}
|
|
@@ -744,14 +747,14 @@ function _reqVerdict(parsed, extra) {
|
|
|
744
747
|
async function _findRequestSigners(candidates, strict, parsed, sig, sigBits) {
|
|
745
748
|
var parsedList = [];
|
|
746
749
|
for (var i = 0; i < candidates.length; i++) {
|
|
747
|
-
try { parsedList
|
|
750
|
+
try { _push(parsedList,{ der: candidates[i], cert: x509.parse(candidates[i]) }); }
|
|
748
751
|
catch (e) { if (strict) throw _err("ocsp/bad-signer-cert", "an opts.certs entry does not parse as an X.509 certificate", e); }
|
|
749
752
|
}
|
|
750
753
|
var parseable = parsedList.map(function (p) { return p.der; });
|
|
751
754
|
var matches = [];
|
|
752
755
|
for (var j = 0; j < parsedList.length; j++) {
|
|
753
756
|
if (await ocspRequestVerify.verifyRequestSignature(sig.signatureAlgorithm, sigBits, parsedList[j].cert.subjectPublicKeyInfo.bytes, parsed.tbsRequestBytes)) {
|
|
754
|
-
matches
|
|
757
|
+
_push(matches,{ der: parsedList[j].der, subject: parsedList[j].cert.subject });
|
|
755
758
|
}
|
|
756
759
|
}
|
|
757
760
|
return { matches: matches, parseable: parseable };
|
|
@@ -770,7 +773,7 @@ function _requestorNamed(parsed, matches) {
|
|
|
770
773
|
if (!rn.value.rdns.length) return { named: [], reason: "the signed OCSP request's requestorName is an empty distinguished name, which names nobody (RFC 6960 sec. 4.1.2)" };
|
|
771
774
|
var named = [];
|
|
772
775
|
for (var i = 0; i < matches.length; i++) {
|
|
773
|
-
if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) named
|
|
776
|
+
if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) _push(named,matches[i]);
|
|
774
777
|
}
|
|
775
778
|
if (named.length) return { named: named, reason: null };
|
|
776
779
|
return { named: [], reason: "the requestorName " + guard.text.showValue(rn.value.dn) + " is not the subject of a certificate that signed the request (RFC 6960 sec. 4.1.2)" };
|
|
@@ -866,7 +869,7 @@ async function verifyRequest(request, opts) {
|
|
|
866
869
|
var suppliedCerts = [];
|
|
867
870
|
if (opts.certs != null) {
|
|
868
871
|
var list = pkiBuild.reqDenseArray(opts.certs, "opts.certs", _err, "ocsp/bad-input");
|
|
869
|
-
for (var i = 0; i < list.length; i++) suppliedCerts
|
|
872
|
+
for (var i = 0; i < list.length; i++) _push(suppliedCerts,_normCertDer(list[i], "an opts.certs entry"));
|
|
870
873
|
}
|
|
871
874
|
if (!suppliedCerts.length) {
|
|
872
875
|
return _reqVerdict(parsed, { signed: true, signatureValid: false,
|
package/lib/path-validate.js
CHANGED
|
@@ -57,7 +57,6 @@ var guard = require("./guard-all");
|
|
|
57
57
|
var intrinsic = require("./guard-intrinsic");
|
|
58
58
|
var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
|
|
59
59
|
var _pop = intrinsic.pop;
|
|
60
|
-
var _splice = intrinsic.splice;
|
|
61
60
|
var _strSlice = intrinsic.uncurry(String.prototype.slice);
|
|
62
61
|
var _strIndexOf = intrinsic.uncurry(String.prototype.indexOf);
|
|
63
62
|
/** @internal The case fold a name constraint is compared under. Read off the live prototype, it is
|
|
@@ -761,9 +760,17 @@ function absorbNameConstraints(state, decoded) {
|
|
|
761
760
|
* `state.policyIndex[depth]` maps a policy identifier to the one node at that depth, so the "is there
|
|
762
761
|
* already a node here for this policy" question every step asks is a lookup rather than a walk.
|
|
763
762
|
*/
|
|
763
|
+
/** @internal The predicate for "the first element this list holds", so a selection reads one slot
|
|
764
|
+
* once rather than testing it and then reading it. */
|
|
765
|
+
function _anyElement() { return true; }
|
|
764
766
|
function graphRoot() {
|
|
765
767
|
return { depth: 0, validPolicy: OID.anyPolicy, qualifierSet: [], expectedPolicySet: [OID.anyPolicy], children: [], parents: [] };
|
|
766
768
|
}
|
|
769
|
+
/** @internal `policyIndex` has NO PROTOTYPE, because it is keyed by depth and holds nothing at a
|
|
770
|
+
* depth no node has been placed at yet. Held in an array, every such depth was a hole: reading one
|
|
771
|
+
* answered from the array prototype, so a value installed at an index was taken for the layer at
|
|
772
|
+
* that depth and the lookups below read their nodes, and the expected policy sets those nodes carry,
|
|
773
|
+
* out of it. Creating the layer was a store at the same index, which runs an inherited setter. */
|
|
767
774
|
function policyLayer(state, depth) {
|
|
768
775
|
var layer = state.policyIndex[depth];
|
|
769
776
|
if (layer === undefined) { layer = intrinsic.create(null); state.policyIndex[depth] = layer; }
|
|
@@ -805,13 +812,20 @@ function removePolicyNode(state, node) {
|
|
|
805
812
|
/** @internal The unlinking walks come from the captures. Removing a node is how a policy stops
|
|
806
813
|
* being valid for the chain, so a walk that skips an edge leaves the node reachable and the policy
|
|
807
814
|
* still counted after the step that disqualified it. */
|
|
815
|
+
/** @internal The removal goes through `guard.list.removeAt`, not `splice`. `splice` RETURNS what it
|
|
816
|
+
* removed, so it builds that result through `ArraySpeciesCreate`, which reads the receiver's
|
|
817
|
+
* `constructor` and then its `Symbol.species`: a getter installed on `Array.prototype.constructor`
|
|
818
|
+
* is handed the real `children` array as its `this`, which gives caller code a reference to the
|
|
819
|
+
* policy-node records mid-edit and a window to change a surviving node's expected-policy set
|
|
820
|
+
* before the walk reads it. Capturing `splice` closes which function runs, not the protocol it
|
|
821
|
+
* consults. `removeAt` returns nothing and constructs nothing. */
|
|
808
822
|
intrinsic.forEach(node.parents, function (p) {
|
|
809
|
-
var idx = intrinsic.
|
|
810
|
-
if (idx !== -1)
|
|
823
|
+
var idx = intrinsic.ownIndexOf(p.children, node);
|
|
824
|
+
if (idx !== -1) guard.list.removeAt(p.children, idx);
|
|
811
825
|
});
|
|
812
826
|
intrinsic.forEach(node.children, function (c) {
|
|
813
|
-
var idx = intrinsic.
|
|
814
|
-
if (idx !== -1)
|
|
827
|
+
var idx = intrinsic.ownIndexOf(c.parents, node);
|
|
828
|
+
if (idx !== -1) guard.list.removeAt(c.parents, idx);
|
|
815
829
|
});
|
|
816
830
|
node.parents = [];
|
|
817
831
|
var layer = state.policyIndex[node.depth];
|
|
@@ -1007,7 +1021,7 @@ function _initialState(certs, params, seeds, anchor, n, ta, policySwitches) {
|
|
|
1007
1021
|
var anchorPathLen = ta.pathLenConstraint;
|
|
1008
1022
|
return {
|
|
1009
1023
|
validPolicyGraph: graphRoot(),
|
|
1010
|
-
policyIndex:
|
|
1024
|
+
policyIndex: intrinsic.create(null),
|
|
1011
1025
|
policyNodeCount: 1,
|
|
1012
1026
|
maxPolicyNodes: params.maxPolicyNodes !== undefined ? params.maxPolicyNodes : constants.LIMITS.PATH_MAX_POLICY_NODES,
|
|
1013
1027
|
minRsaModulusBits: params.minRsaModulusBits !== undefined ? params.minRsaModulusBits : constants.LIMITS.RSA_MIN_MODULUS_BITS,
|
|
@@ -1250,7 +1264,12 @@ function applyPolicyMappings(state, mappings, i) {
|
|
|
1250
1264
|
if (anyHere === null) return;
|
|
1251
1265
|
var anyPrev = nodeAt(state, i - 1, OID.anyPolicy);
|
|
1252
1266
|
if (anyPrev === null) return;
|
|
1253
|
-
|
|
1267
|
+
/** @internal The qualifier is the first element the list HOLDS, in one read. `qualifierSet[0]`
|
|
1268
|
+
* on an empty list answers from the array prototype, so a value installed there would become
|
|
1269
|
+
* the qualifier of a node this step generates; an own-slot test followed by a read is two
|
|
1270
|
+
* reads of one slot, which an accessor answers twice. */
|
|
1271
|
+
var anyQual = guard.list.firstMatch(anyHere.qualifierSet, _anyElement);
|
|
1272
|
+
addPolicyNode(state, i, idp, anyQual, intrinsic.copyList(mappedFrom[idp]), [anyPrev]);
|
|
1254
1273
|
});
|
|
1255
1274
|
return;
|
|
1256
1275
|
}
|
|
@@ -1575,7 +1594,10 @@ async function _validate(path, opts, run, scope) {
|
|
|
1575
1594
|
var preNc = _precaptureAnchorNameConstraints(anchorEntries, "validate");
|
|
1576
1595
|
var tuples = [];
|
|
1577
1596
|
for (var ti = 0; ti < anchorEntries.length; ti++) {
|
|
1578
|
-
|
|
1597
|
+
/** @internal Appended by defining the index. A store at an index this list has no own property
|
|
1598
|
+
* at consults a setter inherited from the array prototype, and these are the trust anchors each
|
|
1599
|
+
* attempt below is run against. */
|
|
1600
|
+
guard.list.append(tuples, toAnchor(anchorEntries[ti], "validate"));
|
|
1579
1601
|
if (preNc[ti] !== undefined) intrinsic.defineProperty(tuples[ti], "nameConstraints", { value: preNc[ti], enumerable: true, configurable: true, writable: true });
|
|
1580
1602
|
}
|
|
1581
1603
|
/** @internal Each anchor is a separate attempt and the later ones run after an await, so the
|
|
@@ -2953,19 +2975,27 @@ function _copyAtv(atv) {
|
|
|
2953
2975
|
return out;
|
|
2954
2976
|
}
|
|
2955
2977
|
|
|
2978
|
+
/** @internal Each count is read ONCE and each element is read once. `isArray` is satisfied by a
|
|
2979
|
+
* Proxy over an array, so a `length` trap answers afresh on every read: the length the result was
|
|
2980
|
+
* sized to and the length the walk ran to could differ, and an element read three times for a type
|
|
2981
|
+
* test, a copy and a fallback could be three different values, which is a copy of something the test
|
|
2982
|
+
* never saw. This is the door a caller's own distinguished name comes through. */
|
|
2956
2983
|
function _copyRdnsDeep(rdns) {
|
|
2957
2984
|
if (!intrinsic.isArray(rdns)) return rdns;
|
|
2958
2985
|
var out = [];
|
|
2959
|
-
|
|
2960
|
-
|
|
2986
|
+
var n = guard.list.count(rdns, "name rdns");
|
|
2987
|
+
out.length = n;
|
|
2988
|
+
for (var i = 0; i < n; i++) {
|
|
2961
2989
|
if (!intrinsic.hasOwn(rdns, i)) continue;
|
|
2962
2990
|
var rdn = rdns[i], val;
|
|
2963
2991
|
if (intrinsic.isArray(rdn)) {
|
|
2964
2992
|
var rdnOut = [];
|
|
2965
|
-
|
|
2966
|
-
|
|
2993
|
+
var m = guard.list.count(rdn, "a name rdn");
|
|
2994
|
+
rdnOut.length = m;
|
|
2995
|
+
for (var j = 0; j < m; j++) {
|
|
2967
2996
|
if (!intrinsic.hasOwn(rdn, j)) continue;
|
|
2968
|
-
var
|
|
2997
|
+
var raw = rdn[j];
|
|
2998
|
+
var atv = (raw !== null && typeof raw === "object") ? _copyAtv(raw) : raw;
|
|
2969
2999
|
intrinsic.defineProperty(rdnOut, j, { value: atv, enumerable: true, configurable: true, writable: true });
|
|
2970
3000
|
}
|
|
2971
3001
|
val = rdnOut;
|
package/lib/pbes2.js
CHANGED
|
@@ -8,6 +8,10 @@ var asn1 = require("./asn1-der");
|
|
|
8
8
|
var oid = require("./oid");
|
|
9
9
|
var webcrypto = require("./webcrypto");
|
|
10
10
|
var guard = require("./guard-all");
|
|
11
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
12
|
+
* consults a setter inherited there, and these lists become the key-derivation parameters an
|
|
13
|
+
* encrypted structure declares. */
|
|
14
|
+
var _push = guard.list.append;
|
|
11
15
|
var C = require("./constants");
|
|
12
16
|
|
|
13
17
|
var b = asn1.build;
|
|
@@ -48,7 +52,7 @@ function prfNodeByOid(oidStr, E, prefix) { if (!PRF_NODE_BY_OID[oidStr]) throw E
|
|
|
48
52
|
|
|
49
53
|
function pbkdf2ParamsSeq(salt, iterations, prf) {
|
|
50
54
|
var kids = [b.octetString(salt), b.integer(BigInt(iterations))];
|
|
51
|
-
if (prf !== "hmacWithSHA1") kids
|
|
55
|
+
if (prf !== "hmacWithSHA1") _push(kids,b.sequence([b.oid(O(prf)), b.nullValue()]));
|
|
52
56
|
return b.sequence(kids);
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -158,7 +162,7 @@ function _hmacAlgId(name) { return b.sequence([b.oid(O(name)), b.nullValue()]);
|
|
|
158
162
|
|
|
159
163
|
function pbmac1AlgId(desc) {
|
|
160
164
|
var pbkdf2Params = [b.octetString(desc.salt), b.integer(BigInt(desc.iterationCount)), b.integer(BigInt(desc.keyLength))];
|
|
161
|
-
if (desc.prfName !== "hmacWithSHA1") pbkdf2Params
|
|
165
|
+
if (desc.prfName !== "hmacWithSHA1") _push(pbkdf2Params,_hmacAlgId(desc.prfName));
|
|
162
166
|
var pbkdf2AlgId = b.sequence([b.oid(O("pbkdf2")), b.sequence(pbkdf2Params)]);
|
|
163
167
|
return b.sequence([b.oid(O("pbmac1")), b.sequence([pbkdf2AlgId, _hmacAlgId(desc.macName)])]);
|
|
164
168
|
}
|
package/lib/pkcs11-uri.js
CHANGED
|
@@ -57,7 +57,9 @@ var _assign = intrinsic.assign;
|
|
|
57
57
|
var _hasOwn = intrinsic.hasOwn;
|
|
58
58
|
var _keys = intrinsic.keys;
|
|
59
59
|
var _forEach = intrinsic.forEach;
|
|
60
|
-
|
|
60
|
+
/** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
|
|
61
|
+
* setter, so an accessor there takes the element being appended. `append` defines it. */
|
|
62
|
+
var _push = intrinsic.append;
|
|
61
63
|
var _join = intrinsic.join;
|
|
62
64
|
var _String = intrinsic.String;
|
|
63
65
|
var _charCodeAt = intrinsic.uncurry(String.prototype.charCodeAt);
|
package/lib/pkcs12-build.js
CHANGED
|
@@ -34,6 +34,9 @@ var pkix = require("./schema-pkix");
|
|
|
34
34
|
var pkiBuild = require("./pki-build");
|
|
35
35
|
var guard = require("./guard-all");
|
|
36
36
|
var intrinsic = require("./guard-intrinsic");
|
|
37
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
38
|
+
* consults a setter inherited there, and these lists become the bags a PFX carries under its MAC. */
|
|
39
|
+
var _push = intrinsic.append;
|
|
37
40
|
var _toLower = intrinsic.uncurry(String.prototype.toLowerCase);
|
|
38
41
|
var frameworkError = require("./framework-error");
|
|
39
42
|
var C = require("./constants");
|
|
@@ -197,11 +200,11 @@ function _bagAttributes(bag) {
|
|
|
197
200
|
if (typeof bag.friendlyName !== "string") {
|
|
198
201
|
throw _err("pkcs12/bad-input", "a bag's friendlyName must be a string, since it is the text a key store lists the bag under");
|
|
199
202
|
}
|
|
200
|
-
attrs
|
|
203
|
+
_push(attrs,b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
|
|
201
204
|
}
|
|
202
205
|
if (bag.localKeyId != null) {
|
|
203
206
|
if (bag.localKeyId === "ski") throw _err("pkcs12/bad-input", "localKeyId 'ski' auto-derivation is not yet supported -- supply an explicit Buffer");
|
|
204
|
-
attrs
|
|
207
|
+
_push(attrs,b.sequence([b.oid(O("localKeyId")), b.set([b.octetString(_bytes(bag.localKeyId, "localKeyId"))])]));
|
|
205
208
|
}
|
|
206
209
|
return attrs.length ? b.set(attrs) : null;
|
|
207
210
|
}
|
|
@@ -214,7 +217,7 @@ function _secretTypeOid(id) {
|
|
|
214
217
|
function _safeBag(bagName, bagValueDer, bag) {
|
|
215
218
|
var children = [b.oid(O(bagName)), b.explicit(0, bagValueDer)];
|
|
216
219
|
var attrs = _bagAttributes(bag);
|
|
217
|
-
if (attrs) children
|
|
220
|
+
if (attrs) _push(children,attrs);
|
|
218
221
|
return b.sequence(children);
|
|
219
222
|
}
|
|
220
223
|
|
|
@@ -485,18 +488,18 @@ function _normalizeSpec(spec, opts, form) {
|
|
|
485
488
|
var enveloped = recipientCerts != null;
|
|
486
489
|
if (enveloped && (!intrinsic.isArray(recipientCerts) || !recipientCerts.length)) throw _err("pkcs12/bad-input", "opts.recipientCerts must be a non-empty array of recipient certificates");
|
|
487
490
|
var certBags = [];
|
|
488
|
-
if (spec.cert != null) certBags
|
|
491
|
+
if (spec.cert != null) _push(certBags,{ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
|
|
489
492
|
if (spec.ca != null && !Array.isArray(spec.ca)) throw _err("pkcs12/bad-input", "spec.ca must be an array of certificates");
|
|
490
|
-
(spec.ca || []).forEach(function (ca) { certBags
|
|
493
|
+
(spec.ca || []).forEach(function (ca) { _push(certBags,{ type: "cert", cert: ca }); });
|
|
491
494
|
var sc = [];
|
|
492
495
|
if (enveloped) {
|
|
493
496
|
var bags = certBags.slice();
|
|
494
|
-
if (spec.key != null) bags
|
|
495
|
-
sc
|
|
497
|
+
if (spec.key != null) _push(bags,{ type: "key", key: spec.key, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
|
|
498
|
+
_push(sc,{ recipients: recipientCerts.map(function (c) { return { cert: c }; }), bags: bags });
|
|
496
499
|
return sc;
|
|
497
500
|
}
|
|
498
|
-
if (certBags.length) sc
|
|
499
|
-
if (spec.key != null) sc
|
|
501
|
+
if (certBags.length) _push(sc,{ encrypt: { password: opts.password }, bags: certBags });
|
|
502
|
+
if (spec.key != null) _push(sc,{ bags: [{ type: "shroudedKey", key: spec.key, encrypt: { password: opts.password }, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId }] });
|
|
500
503
|
return sc;
|
|
501
504
|
}
|
|
502
505
|
throw _err("pkcs12/bad-input", "spec must be { safeContents: [...] } or { key, cert, ca? }");
|
|
@@ -584,7 +587,7 @@ async function _build(spec, opts) {
|
|
|
584
587
|
if (safeContentsSpecs.length > C.LIMITS.PKCS12_MAX_ELEMENTS) throw _err("pkcs12/bad-input", "the AuthenticatedSafe exceeds the element cap " + C.LIMITS.PKCS12_MAX_ELEMENTS + " (safeContents entries)");
|
|
585
588
|
await _assertKeyPairs(spec, form, safeContentsSpecs);
|
|
586
589
|
var elements = [];
|
|
587
|
-
for (var i = 0; i < safeContentsSpecs.length; i++) elements
|
|
590
|
+
for (var i = 0; i < safeContentsSpecs.length; i++) _push(elements,await _buildAuthSafeElement(safeContentsSpecs[i], opts));
|
|
588
591
|
var authSafeDer = b.sequence(elements);
|
|
589
592
|
|
|
590
593
|
var pfx;
|
|
@@ -619,7 +622,7 @@ async function _build(spec, opts) {
|
|
|
619
622
|
: "");
|
|
620
623
|
});
|
|
621
624
|
}
|
|
622
|
-
if (opts.mac !== false) pfxChildren
|
|
625
|
+
if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
|
|
623
626
|
pfx = b.sequence(pfxChildren);
|
|
624
627
|
}
|
|
625
628
|
|
package/lib/pki-build.js
CHANGED
|
@@ -8,6 +8,10 @@ var schema = require("./schema-engine");
|
|
|
8
8
|
var compositeSig = require("./composite-sig");
|
|
9
9
|
var guard = require("./guard-all");
|
|
10
10
|
var intrinsic = require("./guard-intrinsic");
|
|
11
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
12
|
+
* consults a setter inherited there, and these lists become the extension and name structures
|
|
13
|
+
* every signing verb embeds. */
|
|
14
|
+
var _push = intrinsic.append;
|
|
11
15
|
var _isArray = intrinsic.isArray;
|
|
12
16
|
var _bufferFrom = intrinsic.bufferFrom;
|
|
13
17
|
var _bufferEquals = intrinsic.bufferEquals;
|
|
@@ -632,8 +636,8 @@ function makeBuilder(ctx) {
|
|
|
632
636
|
}
|
|
633
637
|
function extBasicConstraints(spec) {
|
|
634
638
|
var children = [];
|
|
635
|
-
if (spec.cA === true) children
|
|
636
|
-
if (spec.pathLen != null) children
|
|
639
|
+
if (spec.cA === true) _push(children,b.boolean(true));
|
|
640
|
+
if (spec.pathLen != null) _push(children,b.integer(pathLen(spec.pathLen)));
|
|
637
641
|
return b.sequence(children);
|
|
638
642
|
}
|
|
639
643
|
function pathLen(v) {
|
|
@@ -1238,8 +1242,8 @@ function makeBuilder(ctx) {
|
|
|
1238
1242
|
}
|
|
1239
1243
|
function ext(oidStr, critical, valueDer) {
|
|
1240
1244
|
var children = [b.oid(oidStr)];
|
|
1241
|
-
if (critical) children
|
|
1242
|
-
children
|
|
1245
|
+
if (critical) _push(children,b.boolean(true));
|
|
1246
|
+
_push(children,b.octetString(valueDer));
|
|
1243
1247
|
return b.sequence(children);
|
|
1244
1248
|
}
|
|
1245
1249
|
|
|
@@ -1353,13 +1357,13 @@ function makeBuilder(ctx) {
|
|
|
1353
1357
|
var out = [];
|
|
1354
1358
|
if (extSpec.subjectKeyIdentifier != null) {
|
|
1355
1359
|
if (extSpec.subjectKeyIdentifier === true && spki == null) throw E("bad-input", "subjectKeyIdentifier auto-derive (true) requires the public key -- supply a Buffer key id, or include the public key");
|
|
1356
|
-
out
|
|
1360
|
+
_push(out,ext(O("subjectKeyIdentifier"), false, extSki(skiKeyId(extSpec.subjectKeyIdentifier, spki))));
|
|
1357
1361
|
}
|
|
1358
|
-
if (extSpec.keyUsage != null) out
|
|
1359
|
-
if (extSpec.extendedKeyUsage != null) out
|
|
1360
|
-
if (extSpec.basicConstraints != null) { validateBcSpec(extSpec.basicConstraints); out
|
|
1361
|
-
if (extSpec.subjectAltName != null) out
|
|
1362
|
-
if (extSpec.certificatePolicies != null) out
|
|
1362
|
+
if (extSpec.keyUsage != null) _push(out,ext(O("keyUsage"), extSpec.keyUsageCritical !== false, extKeyUsage(extSpec.keyUsage)));
|
|
1363
|
+
if (extSpec.extendedKeyUsage != null) _push(out,ext(O("extKeyUsage"), !!extSpec.extendedKeyUsageCritical, extExtKeyUsage(extSpec.extendedKeyUsage)));
|
|
1364
|
+
if (extSpec.basicConstraints != null) { validateBcSpec(extSpec.basicConstraints); _push(out,ext(O("basicConstraints"), extSpec.basicConstraints.critical !== false, extBasicConstraints(extSpec.basicConstraints))); }
|
|
1365
|
+
if (extSpec.subjectAltName != null) _push(out,ext(O("subjectAltName"), false, extSan(extSpec.subjectAltName)));
|
|
1366
|
+
if (extSpec.certificatePolicies != null) _push(out,ext(O("certificatePolicies"), !!extSpec.certificatePoliciesCritical, extCertPolicies(extSpec.certificatePolicies)));
|
|
1363
1367
|
/** @internal RFC 5280 sec. 4.2.1.10 fixes this extension critical, in a request as in the certificate. */
|
|
1364
1368
|
if (extSpec.nameConstraints != null) guard.list.append(out, ext(O("nameConstraints"), true, extNameConstraints(extSpec.nameConstraints)));
|
|
1365
1369
|
if (extSpec.authorityInfoAccess != null) guard.list.append(out, ext(O("authorityInfoAccess"), false, extAuthorityInfoAccess(extSpec.authorityInfoAccess)));
|
package/lib/possession.js
CHANGED
|
@@ -78,7 +78,9 @@ var _promiseResolve = intrinsic.uncurry(intrinsic.promiseResolve);
|
|
|
78
78
|
* while its signature certificate chained to an untrusted CA, which is the RFC 9883 sec. 4 MUST this
|
|
79
79
|
* verb exists to apply. */
|
|
80
80
|
var _Promise = intrinsic.Promise;
|
|
81
|
-
|
|
81
|
+
/** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
|
|
82
|
+
* setter, so an accessor there takes the element being appended. `append` defines it. */
|
|
83
|
+
var _push = intrinsic.append;
|
|
82
84
|
var _join = intrinsic.join;
|
|
83
85
|
var _every = intrinsic.every;
|
|
84
86
|
var _filter = intrinsic.filter;
|
package/lib/rc2.js
CHANGED
|
@@ -22,15 +22,19 @@ var PITABLE = [
|
|
|
22
22
|
0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad,
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
+
/** @internal Both schedules are TYPED arrays. `new Array(n)` has no own property at any index, so
|
|
26
|
+
* every write below was a store the prototype chain is walked for, and an accessor at one of those
|
|
27
|
+
* indexes would take a byte of the expanded key and answer with its own in its place. A typed array
|
|
28
|
+
* handles its own integer-indexed writes, holds the widths these values need, and starts zeroed. */
|
|
25
29
|
function _expandKey(key, effectiveBits) {
|
|
26
|
-
var T = key.length, L = new
|
|
30
|
+
var T = key.length, L = new Uint8Array(128);
|
|
27
31
|
for (var i = 0; i < T; i++) L[i] = key[i];
|
|
28
32
|
for (i = T; i < 128; i++) L[i] = PITABLE[(L[i - 1] + L[i - T]) & 0xff];
|
|
29
33
|
var T8 = (effectiveBits + 7) >>> 3;
|
|
30
34
|
var TM = 0xff >>> ((8 - (effectiveBits & 7)) & 7);
|
|
31
35
|
L[128 - T8] = PITABLE[L[128 - T8] & TM];
|
|
32
36
|
for (i = 127 - T8; i >= 0; i--) L[i] = PITABLE[L[i + 1] ^ L[i + T8]];
|
|
33
|
-
var K = new
|
|
37
|
+
var K = new Uint16Array(64);
|
|
34
38
|
for (i = 0; i < 64; i++) K[i] = L[2 * i] + (L[2 * i + 1] << 8);
|
|
35
39
|
return K;
|
|
36
40
|
}
|