@blamejs/pki 0.8.59 → 0.8.61
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 +57 -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 +26 -18
- package/lib/cmp-build.js +35 -33
- package/lib/cmp-session.js +19 -9
- package/lib/cms-decrypt.js +37 -23
- package/lib/cms-digest.js +2 -3
- package/lib/cms-encrypt.js +38 -33
- package/lib/cms-sign.js +65 -43
- package/lib/cms-verify.js +8 -4
- package/lib/composite-kem.js +28 -29
- package/lib/crl-sign.js +24 -17
- package/lib/crmf-sign.js +11 -17
- package/lib/csr-sign.js +5 -2
- package/lib/ct.js +38 -25
- package/lib/est.js +12 -9
- package/lib/guard-bytes.js +5 -1
- package/lib/guard-crypto.js +506 -14
- 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/guard-secret.js +3 -2
- package/lib/hpke.js +34 -27
- package/lib/http-digest.js +5 -7
- package/lib/http-transport.js +12 -3
- package/lib/inspect.js +10 -2
- package/lib/jose.js +3 -1
- package/lib/key.js +41 -29
- package/lib/lint.js +236 -152
- package/lib/mime.js +9 -5
- package/lib/ocsp.js +26 -24
- package/lib/path-validate.js +43 -13
- package/lib/pbes2.js +12 -9
- package/lib/pkcs11-uri.js +3 -1
- package/lib/pkcs12-build.js +19 -17
- package/lib/pki-build.js +17 -13
- package/lib/possession.js +3 -1
- package/lib/rc2.js +6 -2
- package/lib/revocation-fetch.js +78 -19
- package/lib/scep.js +21 -14
- 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 +7 -4
- package/lib/shbs.js +10 -9
- package/lib/sign-scheme.js +2 -2
- package/lib/sigstore.js +9 -9
- package/lib/smime.js +19 -16
- package/lib/tlog.js +20 -13
- package/lib/tuf.js +7 -4
- package/lib/validator-cose.js +2 -2
- package/lib/validator-keydesc.js +4 -1
- package/lib/validator-tls.js +7 -2
- package/lib/webauthn-mds.js +3 -7
- package/lib/webauthn.js +4 -11
- package/lib/webcrypto.js +70 -49
- 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
|
@@ -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");
|
|
@@ -51,6 +50,9 @@ var ocspRequestVerify = require("./ocsp-request-verify");
|
|
|
51
50
|
var webcrypto = require("./webcrypto");
|
|
52
51
|
var subtle = webcrypto.webcrypto.subtle;
|
|
53
52
|
var guard = require("./guard-all");
|
|
53
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
54
|
+
* consults a setter inherited there, and these lists become a signed request or response. */
|
|
55
|
+
var _push = guard.list.append;
|
|
54
56
|
var constants = require("./constants");
|
|
55
57
|
var frameworkError = require("./framework-error");
|
|
56
58
|
var E = _err;
|
|
@@ -230,7 +232,7 @@ function _buildRequest(query, opts) {
|
|
|
230
232
|
var singles = pkiBuild.reqDenseArray(q.singleRequestExtensions, "singleRequestExtensions", _err, "ocsp/bad-input");
|
|
231
233
|
if (singles.length) {
|
|
232
234
|
if (lightweight) throw _err("ocsp/bad-input", "the lightweight profile permits no singleRequestExtensions (RFC 5019 sec. 2.1.1)");
|
|
233
|
-
reqChildren
|
|
235
|
+
_push(reqChildren,b.explicit(0, b.sequence(singles)));
|
|
234
236
|
}
|
|
235
237
|
}
|
|
236
238
|
return b.sequence(reqChildren);
|
|
@@ -238,15 +240,15 @@ function _buildRequest(query, opts) {
|
|
|
238
240
|
}));
|
|
239
241
|
return _ocspIntrinsic.chain(builtRequests, function (requests) {
|
|
240
242
|
var tbsChildren = [];
|
|
241
|
-
if (requestorNameDer !== null) tbsChildren
|
|
242
|
-
tbsChildren
|
|
243
|
+
if (requestorNameDer !== null) _push(tbsChildren,b.explicit(1, b.contextConstructed(4, requestorNameDer)));
|
|
244
|
+
_push(tbsChildren,b.sequence(requests));
|
|
243
245
|
var reqExts = [];
|
|
244
246
|
if (opts.nonce) {
|
|
245
|
-
var nonceBytes = opts.nonce === true ?
|
|
247
|
+
var nonceBytes = opts.nonce === true ? guard.crypto.randomBytes(32) : opts.nonce;
|
|
246
248
|
_assertNonce(nonceBytes, REQUESTER_NONCE_FLOOR);
|
|
247
|
-
reqExts
|
|
249
|
+
_push(reqExts,_nonceExt(nonceBytes));
|
|
248
250
|
}
|
|
249
|
-
if (reqExts.length) tbsChildren
|
|
251
|
+
if (reqExts.length) _push(tbsChildren,b.explicit(2, b.sequence(reqExts)));
|
|
250
252
|
var tbsRequest = b.sequence(tbsChildren);
|
|
251
253
|
if (signerCert === null) return _emitReq(b.sequence([tbsRequest]), opts);
|
|
252
254
|
var scheme = signScheme.resolveSignScheme(signerCert, { combinedRsaSig: true }, true, _signE);
|
|
@@ -389,9 +391,9 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
389
391
|
}
|
|
390
392
|
var rdChildren = [ridNode, b.generalizedTime(_asEncodableDate(responseData.producedAt, "producedAt") || new Date()), b.sequence(srNodes)];
|
|
391
393
|
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
|
|
394
|
+
if (opts.nonce != null) { _assertNonce(opts.nonce, RESPONDER_NONCE_FLOOR); _push(respExts,_nonceExt(opts.nonce)); }
|
|
395
|
+
if (opts.extendedRevoke || anyNonIssued) _push(respExts,b.sequence([b.oid(OID_EXTENDED_REVOKE), b.octetString(b.nullValue())]));
|
|
396
|
+
if (respExts.length) _push(rdChildren,b.explicit(1, b.sequence(respExts)));
|
|
395
397
|
var responseDataDer = b.sequence(rdChildren);
|
|
396
398
|
var scheme = signScheme.resolveSignScheme(respCert, { combinedRsaSig: true }, true, _signE);
|
|
397
399
|
return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE), function (sig) {
|
|
@@ -401,7 +403,7 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
401
403
|
var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(responseDataDer, sig, respCert.subjectPublicKeyInfo.bytes, scheme));
|
|
402
404
|
return _ocspIntrinsic.chain(selfChecked, function () {
|
|
403
405
|
var basicChildren = [responseDataDer, scheme.sigAlgId, b.bitString(sig, 0)];
|
|
404
|
-
if (opts.embedCert !== false) basicChildren
|
|
406
|
+
if (opts.embedCert !== false) _push(basicChildren,b.explicit(0, b.sequence([b.raw(respCertDer)])));
|
|
405
407
|
var responseBytes = b.sequence([b.oid(OID_OCSP_BASIC), b.octetString(b.sequence(basicChildren))]);
|
|
406
408
|
var der = b.sequence([b.enumerated(0n), b.explicit(0, responseBytes)]);
|
|
407
409
|
return opts.pem ? ocspSchema.pemEncode(der, "OCSP RESPONSE") : der;
|
|
@@ -426,7 +428,7 @@ function _asEncodableDate(d, which) {
|
|
|
426
428
|
function _snapshotSignerKey(key, owned) {
|
|
427
429
|
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
430
|
var copy = guard.bytes.snapshot(key, OcspError, "ocsp/bad-input", "the responder key");
|
|
429
|
-
owned
|
|
431
|
+
_push(owned,copy);
|
|
430
432
|
return copy;
|
|
431
433
|
}
|
|
432
434
|
if (key && typeof key === "object" && (key.mldsa != null || key.trad != null)) {
|
|
@@ -482,10 +484,10 @@ function _buildSingleResponse(r, opts) {
|
|
|
482
484
|
var statusNode = _certStatusNode(r.status, opts);
|
|
483
485
|
var nonIssued = _isNonIssuedStatus(r.status);
|
|
484
486
|
var srChildren = [certID, statusNode, b.generalizedTime(thisUpdate)];
|
|
485
|
-
if (nextUpdate !== null) srChildren
|
|
487
|
+
if (nextUpdate !== null) _push(srChildren,b.explicit(0, b.generalizedTime(nextUpdate)));
|
|
486
488
|
if (r.singleExtensions != null) {
|
|
487
489
|
var singleDer = _singleExtensionsDer(r.singleExtensions, nonIssued);
|
|
488
|
-
if (singleDer.length) srChildren
|
|
490
|
+
if (singleDer.length) _push(srChildren,b.explicit(1, b.sequence(singleDer)));
|
|
489
491
|
}
|
|
490
492
|
return { node: b.sequence(srChildren), nonIssued: nonIssued };
|
|
491
493
|
});
|
|
@@ -558,7 +560,7 @@ function _singleExtensionsDer(spec, nonIssued) {
|
|
|
558
560
|
var out = [];
|
|
559
561
|
if (spec.archiveCutoff != null) {
|
|
560
562
|
guard.time.assertEncodable(spec.archiveCutoff, _err, "ocsp/bad-input", "singleExtensions archiveCutoff");
|
|
561
|
-
out
|
|
563
|
+
_push(out,b.sequence([b.oid(oid.byName("ocspArchiveCutoff")), b.octetString(b.generalizedTime(spec.archiveCutoff))]));
|
|
562
564
|
}
|
|
563
565
|
if (spec.crlReferences != null) {
|
|
564
566
|
if (nonIssued) throw _err("ocsp/bad-input", NON_ISSUED_FORBIDDEN);
|
|
@@ -575,18 +577,18 @@ function _singleExtensionsDer(spec, nonIssued) {
|
|
|
575
577
|
for (var j = 0; j < c.crlUrl.length; j++) {
|
|
576
578
|
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
579
|
}
|
|
578
|
-
fields
|
|
580
|
+
_push(fields,b.explicit(0, b.ia5(c.crlUrl)));
|
|
579
581
|
}
|
|
580
582
|
if (c.crlNum != null) {
|
|
581
583
|
var num = guard.range.authoredInteger(c.crlNum, _err, "ocsp/bad-input", "crlReferences crlNum");
|
|
582
584
|
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
|
|
585
|
+
_push(fields,b.explicit(1, b.integer(num)));
|
|
584
586
|
}
|
|
585
587
|
if (c.crlTime != null) {
|
|
586
588
|
guard.time.assertEncodable(c.crlTime, _err, "ocsp/bad-input", "crlReferences crlTime");
|
|
587
|
-
fields
|
|
589
|
+
_push(fields,b.explicit(2, b.generalizedTime(c.crlTime)));
|
|
588
590
|
}
|
|
589
|
-
out
|
|
591
|
+
_push(out,b.sequence([b.oid(oid.byName("ocspCrl")), b.octetString(b.sequence(fields))]));
|
|
590
592
|
}
|
|
591
593
|
return out;
|
|
592
594
|
}
|
|
@@ -600,7 +602,7 @@ function _certStatusNode(status, opts) {
|
|
|
600
602
|
if (status.revocationReason != null) {
|
|
601
603
|
var code = typeof status.revocationReason === "number" ? status.revocationReason : REASON_CODE[guard.text.keyOf(status.revocationReason)];
|
|
602
604
|
if (code == null) throw _err("ocsp/bad-input", "unknown revocationReason " + guard.text.showValue(status.revocationReason));
|
|
603
|
-
ri
|
|
605
|
+
_push(ri,b.explicit(0, b.enumerated(BigInt(code))));
|
|
604
606
|
}
|
|
605
607
|
return b.contextConstructed(1, Buffer.concat(ri));
|
|
606
608
|
}
|
|
@@ -744,14 +746,14 @@ function _reqVerdict(parsed, extra) {
|
|
|
744
746
|
async function _findRequestSigners(candidates, strict, parsed, sig, sigBits) {
|
|
745
747
|
var parsedList = [];
|
|
746
748
|
for (var i = 0; i < candidates.length; i++) {
|
|
747
|
-
try { parsedList
|
|
749
|
+
try { _push(parsedList,{ der: candidates[i], cert: x509.parse(candidates[i]) }); }
|
|
748
750
|
catch (e) { if (strict) throw _err("ocsp/bad-signer-cert", "an opts.certs entry does not parse as an X.509 certificate", e); }
|
|
749
751
|
}
|
|
750
752
|
var parseable = parsedList.map(function (p) { return p.der; });
|
|
751
753
|
var matches = [];
|
|
752
754
|
for (var j = 0; j < parsedList.length; j++) {
|
|
753
755
|
if (await ocspRequestVerify.verifyRequestSignature(sig.signatureAlgorithm, sigBits, parsedList[j].cert.subjectPublicKeyInfo.bytes, parsed.tbsRequestBytes)) {
|
|
754
|
-
matches
|
|
756
|
+
_push(matches,{ der: parsedList[j].der, subject: parsedList[j].cert.subject });
|
|
755
757
|
}
|
|
756
758
|
}
|
|
757
759
|
return { matches: matches, parseable: parseable };
|
|
@@ -770,7 +772,7 @@ function _requestorNamed(parsed, matches) {
|
|
|
770
772
|
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
773
|
var named = [];
|
|
772
774
|
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
|
|
775
|
+
if (guard.name.dnEqual(matches[i].subject.rdns, rn.value.rdns, _err, "ocsp/bad-input", "the requestorName")) _push(named,matches[i]);
|
|
774
776
|
}
|
|
775
777
|
if (named.length) return { named: named, reason: null };
|
|
776
778
|
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 +868,7 @@ async function verifyRequest(request, opts) {
|
|
|
866
868
|
var suppliedCerts = [];
|
|
867
869
|
if (opts.certs != null) {
|
|
868
870
|
var list = pkiBuild.reqDenseArray(opts.certs, "opts.certs", _err, "ocsp/bad-input");
|
|
869
|
-
for (var i = 0; i < list.length; i++) suppliedCerts
|
|
871
|
+
for (var i = 0; i < list.length; i++) _push(suppliedCerts,_normCertDer(list[i], "an opts.certs entry"));
|
|
870
872
|
}
|
|
871
873
|
if (!suppliedCerts.length) {
|
|
872
874
|
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
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
// @internal
|
|
5
5
|
|
|
6
|
-
var nodeCrypto = require("crypto");
|
|
7
6
|
var asn1 = require("./asn1-der");
|
|
8
7
|
var oid = require("./oid");
|
|
9
8
|
var webcrypto = require("./webcrypto");
|
|
10
9
|
var guard = require("./guard-all");
|
|
10
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
11
|
+
* consults a setter inherited there, and these lists become the key-derivation parameters an
|
|
12
|
+
* encrypted structure declares. */
|
|
13
|
+
var _push = guard.list.append;
|
|
11
14
|
var C = require("./constants");
|
|
12
15
|
|
|
13
16
|
var b = asn1.build;
|
|
@@ -48,7 +51,7 @@ function prfNodeByOid(oidStr, E, prefix) { if (!PRF_NODE_BY_OID[oidStr]) throw E
|
|
|
48
51
|
|
|
49
52
|
function pbkdf2ParamsSeq(salt, iterations, prf) {
|
|
50
53
|
var kids = [b.octetString(salt), b.integer(BigInt(iterations))];
|
|
51
|
-
if (prf !== "hmacWithSHA1") kids
|
|
54
|
+
if (prf !== "hmacWithSHA1") _push(kids,b.sequence([b.oid(O(prf)), b.nullValue()]));
|
|
52
55
|
return b.sequence(kids);
|
|
53
56
|
}
|
|
54
57
|
|
|
@@ -98,11 +101,11 @@ function parsePbkdf2Params(paramsDer, opts, E, prefix, strictPrf) {
|
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
function cbcEncrypt(key, iv, plaintext, keyBits, E, code) {
|
|
101
|
-
var c =
|
|
104
|
+
var c = guard.crypto.cipher("aes-" + keyBits + "-cbc", key, iv);
|
|
102
105
|
return guard.secret.cipherFinish(c, plaintext, E, code, "a content-encryption intermediate");
|
|
103
106
|
}
|
|
104
107
|
function cbcDecrypt(key, iv, ct, keyBits, E, code) {
|
|
105
|
-
var d =
|
|
108
|
+
var d = guard.crypto.decipher("aes-" + keyBits + "-cbc", key, iv);
|
|
106
109
|
return guard.secret.cipherFinish(d, ct, E, code, "the partially recovered plaintext");
|
|
107
110
|
}
|
|
108
111
|
|
|
@@ -114,9 +117,9 @@ function pbes2Encrypt(pwBytes, plaintext, opts, E, prefix) {
|
|
|
114
117
|
var prf = opts.prf || "hmacWithSHA256";
|
|
115
118
|
var prfNode = prfNodeByName(prf, E, prefix);
|
|
116
119
|
var iterations = assertIterations(opts.iterations == null ? 2048 : opts.iterations, E, prefix);
|
|
117
|
-
var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) :
|
|
118
|
-
var iv = opts.iv != null ? opts.iv :
|
|
119
|
-
var key =
|
|
120
|
+
var salt = opts.salt != null ? assertSalt(opts.salt, E, prefix) : guard.crypto.randomBytes(16);
|
|
121
|
+
var iv = opts.iv != null ? opts.iv : guard.crypto.randomBytes(16);
|
|
122
|
+
var key = guard.crypto.pbkdf2(pwBytes, salt, iterations, keyBits / 8, prfNode);
|
|
120
123
|
try {
|
|
121
124
|
return { algId: pbes2AlgId(salt, iterations, prf, cipherName, iv), ct: cbcEncrypt(key, iv, plaintext, keyBits, E, prefix + "/bad-input") };
|
|
122
125
|
} finally {
|
|
@@ -148,7 +151,7 @@ function pbes2Decrypt(pwBytes, params, ciphertext, opts, E, prefix, budget) {
|
|
|
148
151
|
budget.rounds -= pb.iterations;
|
|
149
152
|
if (budget.rounds < 0) throw E(prefix + "/iteration-limit", "the aggregate PBKDF2 key-derivation work exceeds the budget (a hostile many-element input)");
|
|
150
153
|
}
|
|
151
|
-
var dk =
|
|
154
|
+
var dk = guard.crypto.pbkdf2(pwBytes, pb.salt, pb.iterations, keyBits / 8, pb.prfNode);
|
|
152
155
|
try { return cbcDecrypt(dk, iv, ciphertext, keyBits, E, prefix + "/decrypt-failed"); }
|
|
153
156
|
catch (_e) { throw E(prefix + "/decrypt-failed", "decryption failed"); }
|
|
154
157
|
finally { guard.secret.zeroize(dk, E, prefix + "/bad-input", "the password-derived decryption key"); }
|
|
@@ -158,7 +161,7 @@ function _hmacAlgId(name) { return b.sequence([b.oid(O(name)), b.nullValue()]);
|
|
|
158
161
|
|
|
159
162
|
function pbmac1AlgId(desc) {
|
|
160
163
|
var pbkdf2Params = [b.octetString(desc.salt), b.integer(BigInt(desc.iterationCount)), b.integer(BigInt(desc.keyLength))];
|
|
161
|
-
if (desc.prfName !== "hmacWithSHA1") pbkdf2Params
|
|
164
|
+
if (desc.prfName !== "hmacWithSHA1") _push(pbkdf2Params,_hmacAlgId(desc.prfName));
|
|
162
165
|
var pbkdf2AlgId = b.sequence([b.oid(O("pbkdf2")), b.sequence(pbkdf2Params)]);
|
|
163
166
|
return b.sequence([b.oid(O("pbmac1")), b.sequence([pbkdf2AlgId, _hmacAlgId(desc.macName)])]);
|
|
164
167
|
}
|
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
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
* @card Build a password-integrity PKCS#12 store (RFC 7292 / RFC 9579) and verify its MAC.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
var nodeCrypto = require("crypto");
|
|
21
20
|
var asn1 = require("./asn1-der");
|
|
22
21
|
var rc2 = require("./rc2");
|
|
23
22
|
var oid = require("./oid");
|
|
@@ -34,6 +33,9 @@ var pkix = require("./schema-pkix");
|
|
|
34
33
|
var pkiBuild = require("./pki-build");
|
|
35
34
|
var guard = require("./guard-all");
|
|
36
35
|
var intrinsic = require("./guard-intrinsic");
|
|
36
|
+
/** @internal The append every list here is built with: `push` stores at the index and a store
|
|
37
|
+
* consults a setter inherited there, and these lists become the bags a PFX carries under its MAC. */
|
|
38
|
+
var _push = intrinsic.append;
|
|
37
39
|
var _toLower = intrinsic.uncurry(String.prototype.toLowerCase);
|
|
38
40
|
var frameworkError = require("./framework-error");
|
|
39
41
|
var C = require("./constants");
|
|
@@ -147,7 +149,7 @@ function _p12Kdf(hashName, id, pwBytes, salt, iterations, nBytes) {
|
|
|
147
149
|
var A = Buffer.concat([D, I]);
|
|
148
150
|
for (var r = 0; r < iterations; r++) {
|
|
149
151
|
var prev = A;
|
|
150
|
-
A =
|
|
152
|
+
A = guard.crypto.digest(hashName, A);
|
|
151
153
|
guard.secret.zeroize(prev, Pkcs12Error, "pkcs12/bad-input", "a key-derivation intermediate");
|
|
152
154
|
}
|
|
153
155
|
A.copy(out, i * u);
|
|
@@ -197,11 +199,11 @@ function _bagAttributes(bag) {
|
|
|
197
199
|
if (typeof bag.friendlyName !== "string") {
|
|
198
200
|
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
201
|
}
|
|
200
|
-
attrs
|
|
202
|
+
_push(attrs,b.sequence([b.oid(O("friendlyName")), b.set([b.bmpString(bag.friendlyName)])]));
|
|
201
203
|
}
|
|
202
204
|
if (bag.localKeyId != null) {
|
|
203
205
|
if (bag.localKeyId === "ski") throw _err("pkcs12/bad-input", "localKeyId 'ski' auto-derivation is not yet supported -- supply an explicit Buffer");
|
|
204
|
-
attrs
|
|
206
|
+
_push(attrs,b.sequence([b.oid(O("localKeyId")), b.set([b.octetString(_bytes(bag.localKeyId, "localKeyId"))])]));
|
|
205
207
|
}
|
|
206
208
|
return attrs.length ? b.set(attrs) : null;
|
|
207
209
|
}
|
|
@@ -214,7 +216,7 @@ function _secretTypeOid(id) {
|
|
|
214
216
|
function _safeBag(bagName, bagValueDer, bag) {
|
|
215
217
|
var children = [b.oid(O(bagName)), b.explicit(0, bagValueDer)];
|
|
216
218
|
var attrs = _bagAttributes(bag);
|
|
217
|
-
if (attrs) children
|
|
219
|
+
if (attrs) _push(children,attrs);
|
|
218
220
|
return b.sequence(children);
|
|
219
221
|
}
|
|
220
222
|
|
|
@@ -348,7 +350,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
|
|
|
348
350
|
var password = macOpts.password != null ? macOpts.password : sharedPassword;
|
|
349
351
|
var algorithm = macOpts.algorithm || "hmac";
|
|
350
352
|
var hash = macOpts.hash || "sha256";
|
|
351
|
-
var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") :
|
|
353
|
+
var salt = macOpts.salt != null ? _bytes(macOpts.salt, "mac salt") : guard.crypto.randomBytes(MAC_SALT_BYTES);
|
|
352
354
|
if (salt.length === 0) throw _err("pkcs12/bad-input", "the MAC salt must be non-empty (RFC 9579 sec. 4c)");
|
|
353
355
|
if (salt.length > C.LIMITS.PBKDF2_MAX_SALT) throw _err("pkcs12/bad-input", "the MAC salt exceeds the " + C.LIMITS.PBKDF2_MAX_SALT + "-octet cap");
|
|
354
356
|
|
|
@@ -360,7 +362,7 @@ async function _buildMacData(macOpts, sharedPassword, authSafeDer) {
|
|
|
360
362
|
var macKey = _p12Kdf(node, 3, macPw.bytes, salt, iter, P12_KDF_UV[node].u);
|
|
361
363
|
if (macPw.owned) guard.secret.zeroize(macPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
|
|
362
364
|
try {
|
|
363
|
-
var digest =
|
|
365
|
+
var digest = guard.crypto.hmac(node, macKey, authSafeDer);
|
|
364
366
|
var digestInfo = b.sequence([b.sequence([b.oid(O(node)), b.nullValue()]), b.octetString(digest)]);
|
|
365
367
|
return b.sequence([digestInfo, b.octetString(salt), b.integer(BigInt(iter))]);
|
|
366
368
|
} finally {
|
|
@@ -485,18 +487,18 @@ function _normalizeSpec(spec, opts, form) {
|
|
|
485
487
|
var enveloped = recipientCerts != null;
|
|
486
488
|
if (enveloped && (!intrinsic.isArray(recipientCerts) || !recipientCerts.length)) throw _err("pkcs12/bad-input", "opts.recipientCerts must be a non-empty array of recipient certificates");
|
|
487
489
|
var certBags = [];
|
|
488
|
-
if (spec.cert != null) certBags
|
|
490
|
+
if (spec.cert != null) _push(certBags,{ type: "cert", cert: spec.cert, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
|
|
489
491
|
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
|
|
492
|
+
(spec.ca || []).forEach(function (ca) { _push(certBags,{ type: "cert", cert: ca }); });
|
|
491
493
|
var sc = [];
|
|
492
494
|
if (enveloped) {
|
|
493
495
|
var bags = certBags.slice();
|
|
494
|
-
if (spec.key != null) bags
|
|
495
|
-
sc
|
|
496
|
+
if (spec.key != null) _push(bags,{ type: "key", key: spec.key, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId });
|
|
497
|
+
_push(sc,{ recipients: recipientCerts.map(function (c) { return { cert: c }; }), bags: bags });
|
|
496
498
|
return sc;
|
|
497
499
|
}
|
|
498
|
-
if (certBags.length) sc
|
|
499
|
-
if (spec.key != null) sc
|
|
500
|
+
if (certBags.length) _push(sc,{ encrypt: { password: opts.password }, bags: certBags });
|
|
501
|
+
if (spec.key != null) _push(sc,{ bags: [{ type: "shroudedKey", key: spec.key, encrypt: { password: opts.password }, friendlyName: spec.friendlyName, localKeyId: spec.localKeyId }] });
|
|
500
502
|
return sc;
|
|
501
503
|
}
|
|
502
504
|
throw _err("pkcs12/bad-input", "spec must be { safeContents: [...] } or { key, cert, ca? }");
|
|
@@ -584,7 +586,7 @@ async function _build(spec, opts) {
|
|
|
584
586
|
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
587
|
await _assertKeyPairs(spec, form, safeContentsSpecs);
|
|
586
588
|
var elements = [];
|
|
587
|
-
for (var i = 0; i < safeContentsSpecs.length; i++) elements
|
|
589
|
+
for (var i = 0; i < safeContentsSpecs.length; i++) _push(elements,await _buildAuthSafeElement(safeContentsSpecs[i], opts));
|
|
588
590
|
var authSafeDer = b.sequence(elements);
|
|
589
591
|
|
|
590
592
|
var pfx;
|
|
@@ -619,7 +621,7 @@ async function _build(spec, opts) {
|
|
|
619
621
|
: "");
|
|
620
622
|
});
|
|
621
623
|
}
|
|
622
|
-
if (opts.mac !== false) pfxChildren
|
|
624
|
+
if (opts.mac !== false) _push(pfxChildren,await _buildMacData(opts.mac || {}, opts.password, authSafeDer));
|
|
623
625
|
pfx = b.sequence(pfxChildren);
|
|
624
626
|
}
|
|
625
627
|
|
|
@@ -685,7 +687,7 @@ async function _verifyMacOfStore(m, password, opts) {
|
|
|
685
687
|
var vMacPw = _p12PasswordOwned(password);
|
|
686
688
|
var macKey = _p12Kdf(node, 3, vMacPw.bytes, m.mac.macSalt, m.mac.iterations, P12_KDF_UV[node].u);
|
|
687
689
|
if (vMacPw.owned) guard.secret.zeroize(vMacPw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
|
|
688
|
-
try { computed =
|
|
690
|
+
try { computed = guard.crypto.hmac(node, macKey, m.macedBytes); }
|
|
689
691
|
finally { guard.secret.zeroize(macKey, Pkcs12Error, "pkcs12/bad-input", "the password-derived MAC key"); }
|
|
690
692
|
} else {
|
|
691
693
|
var kdf = m.mac.pbmac1.kdf;
|
|
@@ -865,7 +867,7 @@ function _decryptLegacyPbe(ea, ct, password, opts, budget) {
|
|
|
865
867
|
if (p12pw.owned) guard.secret.zeroize(p12pw.bytes, Pkcs12Error, "pkcs12/bad-input", "the password encoding");
|
|
866
868
|
try {
|
|
867
869
|
if (scheme.rc2) return rc2.cbcDecrypt(keyM, scheme.rc2, iv, ct, _err, "pkcs12/decrypt-failed");
|
|
868
|
-
var d =
|
|
870
|
+
var d = guard.crypto.decipher(scheme.cipher, keyM, iv);
|
|
869
871
|
return guard.secret.cipherFinish(d, ct, Pkcs12Error, "pkcs12/bad-input", "the recovered safe contents");
|
|
870
872
|
} catch (_e) { throw _err("pkcs12/decrypt-failed", "decryption failed"); }
|
|
871
873
|
finally { guard.secret.zeroize(keyM, Pkcs12Error, "pkcs12/bad-input", "the password-derived decryption key"); }
|
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;
|
|
@@ -414,7 +418,7 @@ var DP_KEYS = intrinsic.assign(intrinsic.create(null), { fullName: 1, reasons: 1
|
|
|
414
418
|
* others, so the loop keeps the leading octet uniform over 1 to 127. */
|
|
415
419
|
function randomSerial() {
|
|
416
420
|
for (;;) {
|
|
417
|
-
var rnd =
|
|
421
|
+
var rnd = guard.crypto.randomBytes(20);
|
|
418
422
|
rnd[0] &= 0x7f;
|
|
419
423
|
if (rnd[0] !== 0) return BigInt("0x" + rnd.toString("hex"));
|
|
420
424
|
}
|
|
@@ -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,14 +1242,14 @@ 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
|
|
|
1246
1250
|
function spkiKeyId(spkiDer) {
|
|
1247
1251
|
var keyBytes = asn1.read.bitString(asn1.decode(spkiDer).children[1]).bytes;
|
|
1248
|
-
return
|
|
1252
|
+
return guard.crypto.digest("sha1", keyBytes);
|
|
1249
1253
|
}
|
|
1250
1254
|
function skiKeyId(val, spkiDer) {
|
|
1251
1255
|
if (guard.bytes.isByteSource(val)) return guard.bytes.snapshotSource(val, ErrorClass, ctx.prefix + "/bad-input", "subjectKeyIdentifier");
|
|
@@ -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)));
|
|
@@ -1513,7 +1517,7 @@ function samePublicKey(spkiA, spkiB) {
|
|
|
1513
1517
|
/** @internal Two keys of different types are never the same key, and comparing them through
|
|
1514
1518
|
* the runtime's equality leaves a fault queued in the crypto library that surfaces on the
|
|
1515
1519
|
* next unrelated key import in the process, so the type decides that case first. */
|
|
1516
|
-
if (ka
|
|
1520
|
+
if (guard.crypto.keyType(ka) !== guard.crypto.keyType(kb)) return false;
|
|
1517
1521
|
return _keyEquals(ka, kb) === true;
|
|
1518
1522
|
}
|
|
1519
1523
|
|
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;
|