@blamejs/pki 0.8.11 → 0.8.14
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 +47 -0
- package/README.md +3 -2
- package/index.js +6 -0
- package/lib/acme.js +13 -5
- package/lib/attrcert-sign.js +3 -3
- package/lib/cmc-build.js +9 -9
- package/lib/cmc-verify.js +5 -5
- package/lib/cmp-build.js +3 -4
- package/lib/cmp-session.js +6 -6
- package/lib/cms-verify.js +4 -4
- package/lib/crl-sign.js +1 -1
- package/lib/crmf-sign.js +1 -1
- package/lib/ct.js +2 -2
- package/lib/est.js +12 -13
- package/lib/framework-error.js +3 -0
- package/lib/guard-header.js +15 -1
- package/lib/guard-identifier.js +34 -0
- package/lib/hpke.js +7 -2
- package/lib/http-transport.js +5 -6
- package/lib/identity-match.js +4 -3
- package/lib/ocsp.js +5 -3
- package/lib/oid.js +1 -1
- package/lib/path-validate.js +380 -111
- package/lib/pki-build.js +1 -1
- package/lib/revocation-fetch.js +1 -1
- package/lib/scep.js +21 -9
- package/lib/schema-all.js +10 -1
- package/lib/schema-engine.js +7 -2
- package/lib/schema-pkix.js +40 -0
- package/lib/schema-trustanchor.js +469 -0
- package/lib/schema-x509.js +66 -33
- package/lib/smime.js +5 -1
- package/lib/trust.js +192 -11
- package/lib/trustanchor-build.js +278 -0
- package/lib/validator-tpm.js +1 -1
- package/lib/webauthn-mds.js +1 -1
- package/lib/webauthn.js +9 -10
- package/lib/webcrypto.js +3 -3
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/pki-build.js
CHANGED
|
@@ -436,7 +436,7 @@ function makeBuilder(ctx) {
|
|
|
436
436
|
}
|
|
437
437
|
function encodeRdn(rdnSpec) {
|
|
438
438
|
if (!rdnSpec || typeof rdnSpec !== "object" || Buffer.isBuffer(rdnSpec)) throw E("bad-name", "each RDN must be an object of { attributeName: value }");
|
|
439
|
-
var keys =
|
|
439
|
+
var keys = guard.identifier.optionNames(rdnSpec);
|
|
440
440
|
if (!keys.length) throw E("bad-name", "an RDN must carry at least one attribute");
|
|
441
441
|
return b.set(keys.map(function (k) { return encodeAtv(k, rdnSpec[k]); }));
|
|
442
442
|
}
|
package/lib/revocation-fetch.js
CHANGED
|
@@ -294,7 +294,7 @@ async function _fetchOne(state, req, what) {
|
|
|
294
294
|
|
|
295
295
|
function _contentType(headers) {
|
|
296
296
|
var h = headers || {};
|
|
297
|
-
var keys =
|
|
297
|
+
var keys = guard.identifier.optionNames(h);
|
|
298
298
|
for (var i = 0; i < keys.length; i++) {
|
|
299
299
|
if (keys[i].toLowerCase() !== "content-type") continue;
|
|
300
300
|
try { return mime.parse(String(h[keys[i]])).type; }
|
package/lib/scep.js
CHANGED
|
@@ -68,7 +68,12 @@ var MESSAGE_TYPE = Object.assign(Object.create(null), { CertRep: "3", RenewalReq
|
|
|
68
68
|
var PKI_STATUS = Object.assign(Object.create(null), { SUCCESS: "0", FAILURE: "2", PENDING: "3" });
|
|
69
69
|
var FAIL_INFO = Object.assign(Object.create(null), { badAlg: "0", badMessageCheck: "1", badRequest: "2", badTime: "3", badCertId: "4" });
|
|
70
70
|
|
|
71
|
-
function _invert(table) {
|
|
71
|
+
function _invert(table) {
|
|
72
|
+
var o = Object.create(null);
|
|
73
|
+
var names = guard.identifier.optionNames(table);
|
|
74
|
+
for (var i = 0; i < names.length; i++) o[table[names[i]]] = names[i];
|
|
75
|
+
return o;
|
|
76
|
+
}
|
|
72
77
|
var MESSAGE_TYPE_BY_CODE = _invert(MESSAGE_TYPE), PKI_STATUS_BY_CODE = _invert(PKI_STATUS), FAIL_INFO_BY_CODE = _invert(FAIL_INFO);
|
|
73
78
|
|
|
74
79
|
var _PARSE_SUPPORTED = Object.assign(Object.create(null), { PKCSReq: 1, RenewalReq: 1, CertRep: 1, CertPoll: 1, GetCert: 1, GetCRL: 1 });
|
|
@@ -621,10 +626,10 @@ function _trim(s) { var a = 0, e = s.length; while (a < e && _isWs(s.charCodeAt(
|
|
|
621
626
|
|
|
622
627
|
function _header(headers, name) {
|
|
623
628
|
if (!headers || typeof headers !== "object") return null;
|
|
624
|
-
var found = null, seen = 0
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
if (_foldLower(String(
|
|
629
|
+
var found = null, seen = 0;
|
|
630
|
+
var hNames = guard.identifier.optionNames(headers);
|
|
631
|
+
for (var hi = 0; hi < hNames.length; hi++) {
|
|
632
|
+
if (_foldLower(String(hNames[hi])) === name) { found = headers[hNames[hi]]; seen += 1; }
|
|
628
633
|
}
|
|
629
634
|
if (seen > 1) throw _err("scep/bad-response", "the response carried more than one " + name + " header");
|
|
630
635
|
return found == null ? null : String(found);
|
|
@@ -739,7 +744,7 @@ function _client(method, url, body, headers, opts, checked) {
|
|
|
739
744
|
maxResponseBytes: guard.limits.cap(opts.maxResponseBytes, "maxResponseBytes", C.LIMITS.HTTP_MAX_RESPONSE_BYTES, { E: _err, code: "scep/bad-input", min: 1, max: C.LIMITS.HTTP_MAX_RESPONSE_BYTES }),
|
|
740
745
|
maxRedirects: guard.limits.cap(opts.maxRedirects, "maxRedirects", 5, { E: _err, code: "scep/bad-input", min: 0, max: 32 }),
|
|
741
746
|
};
|
|
742
|
-
return _drive(method, url, body,
|
|
747
|
+
return _drive(method, url, body, guard.identifier.ownOptions(headers), opts, transport, budgets);
|
|
743
748
|
}
|
|
744
749
|
function _requireOk(res, expected, what) {
|
|
745
750
|
var status = res.status;
|
|
@@ -1056,7 +1061,7 @@ async function _pkiOperation(messageType, baseUrl, opts, verbName) {
|
|
|
1056
1061
|
var recipientKey = _captureRecipientKey(opts.recipientKey);
|
|
1057
1062
|
var signer = { cert: guard.bytes.snapshotSource(opts.signer.cert, ScepError, "scep/bad-input", "signer.cert"), key: opts.signer.key };
|
|
1058
1063
|
var clientOpts = {
|
|
1059
|
-
tls: opts.tls != null ?
|
|
1064
|
+
tls: opts.tls != null ? guard.identifier.ownOptions(opts.tls) : opts.tls,
|
|
1060
1065
|
maxRedirects: opts.maxRedirects,
|
|
1061
1066
|
allowCrossOriginRedirect: opts.allowCrossOriginRedirect,
|
|
1062
1067
|
timeout: opts.timeout,
|
|
@@ -1207,7 +1212,7 @@ async function _queryOperation(messageType, baseUrl, opts, verbName) {
|
|
|
1207
1212
|
var recipientKey = _captureRecipientKey(opts.recipientKey);
|
|
1208
1213
|
var signer = { cert: guard.bytes.snapshotSource(opts.signer.cert, ScepError, "scep/bad-input", "signer.cert"), key: opts.signer.key };
|
|
1209
1214
|
var want = _resolveQueryTarget(opts);
|
|
1210
|
-
var clientOpts = { tls: opts.tls != null ?
|
|
1215
|
+
var clientOpts = { tls: opts.tls != null ? guard.identifier.ownOptions(opts.tls) : opts.tls, maxRedirects: opts.maxRedirects, allowCrossOriginRedirect: opts.allowCrossOriginRedirect, timeout: opts.timeout, maxResponseBytes: opts.maxResponseBytes, proxy: _snapshotProxy(opts.proxy) };
|
|
1211
1216
|
if (checkedTransport !== undefined) clientOpts.transport = checkedTransport;
|
|
1212
1217
|
var senderNonce = nodeCrypto.randomBytes(16);
|
|
1213
1218
|
var transactionId = opts.transactionId != null ? opts.transactionId : _defaultTransactionId();
|
|
@@ -1320,7 +1325,14 @@ async function getCrl(baseUrl, opts) {
|
|
|
1320
1325
|
}
|
|
1321
1326
|
|
|
1322
1327
|
var _TRANSPORT_KEYS = Object.assign(Object.create(null), { transport: 1, timeout: 1, maxResponseBytes: 1, maxRedirects: 1, tls: 1, allowCrossOriginRedirect: 1, proxy: 1 });
|
|
1323
|
-
function _withKeys(extra) {
|
|
1328
|
+
function _withKeys(extra) {
|
|
1329
|
+
var o = Object.create(null);
|
|
1330
|
+
var base = guard.identifier.optionNames(_TRANSPORT_KEYS);
|
|
1331
|
+
for (var bi = 0; bi < base.length; bi++) o[base[bi]] = 1;
|
|
1332
|
+
var more = guard.identifier.optionNames(extra);
|
|
1333
|
+
for (var mi = 0; mi < more.length; mi++) o[more[mi]] = 1;
|
|
1334
|
+
return o;
|
|
1335
|
+
}
|
|
1324
1336
|
var _CACAPS_KEYS = _withKeys({ expectSCEPStandard: 1, requireStrongProfile: 1 });
|
|
1325
1337
|
var _CACERT_KEYS = _withKeys({ expectedFingerprint: 1, fingerprintAlgorithm: 1 });
|
|
1326
1338
|
var _NEXTCACERT_KEYS = _withKeys({ caCertificate: 1 });
|
package/lib/schema-all.js
CHANGED
|
@@ -47,6 +47,7 @@ var tsp = require("./schema-tsp");
|
|
|
47
47
|
var crmf = require("./schema-crmf");
|
|
48
48
|
var cmp = require("./schema-cmp");
|
|
49
49
|
var csrattrs = require("./schema-csrattrs");
|
|
50
|
+
var trustanchor = require("./schema-trustanchor");
|
|
50
51
|
var attrcert = require("./schema-attrcert");
|
|
51
52
|
var smime = require("./schema-smime");
|
|
52
53
|
var cmc = require("./schema-cmc");
|
|
@@ -88,6 +89,12 @@ var FORMATS = [
|
|
|
88
89
|
detect: csrattrs.matches,
|
|
89
90
|
parse: function (input, caps) { return csrattrs.parse(input, caps); },
|
|
90
91
|
},
|
|
92
|
+
{
|
|
93
|
+
name: "trustanchor",
|
|
94
|
+
module: trustanchor,
|
|
95
|
+
detect: trustanchor.matches,
|
|
96
|
+
parse: function (input, caps) { return trustanchor.parse(input, caps); },
|
|
97
|
+
},
|
|
91
98
|
{
|
|
92
99
|
name: "ocsp-request",
|
|
93
100
|
module: ocsp,
|
|
@@ -155,7 +162,7 @@ var FORMATS = [
|
|
|
155
162
|
* The names of every registered format, in detection order.
|
|
156
163
|
*
|
|
157
164
|
* @example
|
|
158
|
-
* pki.schema.all(); // -> ["cms", "tsp", "crmf", "cmp", "csrattrs", "ocsp-request", "ocsp-response", "pkcs12", "pkcs8", "csr", "attrcert", "attrcert-v1", "crl", "x509"]
|
|
165
|
+
* pki.schema.all(); // -> ["cms", "tsp", "crmf", "cmp", "csrattrs", "trustanchor", "ocsp-request", "ocsp-response", "pkcs12", "pkcs8", "csr", "attrcert", "attrcert-v1", "crl", "x509"]
|
|
159
166
|
*/
|
|
160
167
|
function all() { return FORMATS.map(function (f) { return f.name; }); }
|
|
161
168
|
|
|
@@ -368,6 +375,8 @@ module.exports = {
|
|
|
368
375
|
decodeExtensions: crmf.decodeExtensions, decodeExtension: crmf.decodeExtension },
|
|
369
376
|
cmp: { parse: cmp.parse, pemDecode: cmp.pemDecode, pemEncode: cmp.pemEncode },
|
|
370
377
|
csrattrs: { parse: csrattrs.parse },
|
|
378
|
+
trustanchor: { parse: trustanchor.parse, parseInfo: trustanchor.parseInfo,
|
|
379
|
+
pemDecode: trustanchor.pemDecode, pemEncode: trustanchor.pemEncode },
|
|
371
380
|
attrcert: { parse: attrcert.parse, pemDecode: attrcert.pemDecode, pemEncode: attrcert.pemEncode,
|
|
372
381
|
decodeExtensions: attrcert.decodeExtensions, decodeExtension: attrcert.decodeExtension },
|
|
373
382
|
smime: { parseSigningCertificate: smime.parseSigningCertificate, parseSigningCertificateV2: smime.parseSigningCertificateV2, parseSmimeCapabilities: smime.parseSmimeCapabilities, decodeAttribute: smime.decodeAttribute },
|
package/lib/schema-engine.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
var asn1 = require("./asn1-der.js");
|
|
30
|
+
var intrinsic = require("./guard-intrinsic");
|
|
30
31
|
|
|
31
32
|
var TAGS = asn1.TAGS;
|
|
32
33
|
|
|
@@ -339,8 +340,12 @@ function _walkSeq(schema, node, ctx) {
|
|
|
339
340
|
var kids = _assertShape(schema, node, ctx);
|
|
340
341
|
_assertArity(schema, kids, ctx);
|
|
341
342
|
|
|
342
|
-
|
|
343
|
-
|
|
343
|
+
/** @internal Prototype-less, so writing a field creates an own property instead of dispatching
|
|
344
|
+
* through an accessor of the same name on Object.prototype. Every format parser's record is
|
|
345
|
+
* built here, so a getter-only slot planted under any field name a schema declares would
|
|
346
|
+
* otherwise throw out of an ordinary parse, and a setter would swallow the decoded value. The
|
|
347
|
+
* absent-member test below reads it the same way. */
|
|
348
|
+
var fields = intrinsic.create(null);
|
|
344
349
|
var idx = 0;
|
|
345
350
|
for (var f = 0; f < schema.fields.length; f++) {
|
|
346
351
|
var fld = schema.fields[f];
|
package/lib/schema-pkix.js
CHANGED
|
@@ -1456,6 +1456,44 @@ function _extensionRow(ext, opts, index, state, decoded, code, profile) {
|
|
|
1456
1456
|
* impossible to READ a certificate carrying a private critical extension, which is what
|
|
1457
1457
|
* `pki.inspect` and `pki.lint` are for. RFC 5280 sec. 4.2's reject-on-critical rule is the
|
|
1458
1458
|
* caller's to apply, and the two facts it needs, `critical` and `state`, are on the row. */
|
|
1459
|
+
/** @internal RFC 5937 sec. 3.2: "If a basic constraints extension is associated with the trust
|
|
1460
|
+
* anchor and contains a pathLenConstraint value, set the max_path_length state variable equal to
|
|
1461
|
+
* the pathLenConstraint value from the basic constraints extension." A trust anchor associates
|
|
1462
|
+
* one in three ways: the certificate it is supplied as, the `exts` of an RFC 5914
|
|
1463
|
+
* `TrustAnchorInfo`, and that anchor's `certPath.pathLenConstraint`. The first two are an
|
|
1464
|
+
* extension list, so both read it here and neither restates the decode. Returns null only where
|
|
1465
|
+
* the list states no path length. An extension that does not decode is a refusal, not an absent
|
|
1466
|
+
* limit: nothing validates the anchor's own certificate, so reading an unreadable constraint as
|
|
1467
|
+
* "no constraint" would leave the anchor less restricted than the store that carries it says. */
|
|
1468
|
+
function anchorPathLenFromExtensions(list, ns, label) {
|
|
1469
|
+
if (!intrinsic.isArray(list)) return null;
|
|
1470
|
+
var bcOid = ns.oid.byName("basicConstraints");
|
|
1471
|
+
var decode = certExtensionDecoders(ns).byOid[bcOid];
|
|
1472
|
+
if (typeof decode !== "function") return null;
|
|
1473
|
+
var found = null;
|
|
1474
|
+
_forEach(list, function (ext) {
|
|
1475
|
+
if (!ext || ext.oid !== bcOid || found !== null) return;
|
|
1476
|
+
var value;
|
|
1477
|
+
try { value = decode(ext.value); }
|
|
1478
|
+
catch (e) {
|
|
1479
|
+
throw ns.E(ns.prefix + "/bad-basic-constraints", (label || "the trust anchor") +
|
|
1480
|
+
" carries a basicConstraints extension that does not decode, so the path length it states " +
|
|
1481
|
+
"cannot be read; a trust anchor's constraints are never checked against a path above it, " +
|
|
1482
|
+
"so this is refused rather than read as no constraint", e);
|
|
1483
|
+
}
|
|
1484
|
+
if (value && intrinsic.isInteger(value.pathLenConstraint)) found = value.pathLenConstraint;
|
|
1485
|
+
});
|
|
1486
|
+
return found;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
/** @internal The stricter of two path lengths an anchor states, which is the only direction
|
|
1490
|
+
* RFC 5937 sec. 3.2 allows an anchor to move a validation. */
|
|
1491
|
+
function lowerPathLen(a, b) {
|
|
1492
|
+
if (!intrinsic.isInteger(a)) return intrinsic.isInteger(b) ? b : null;
|
|
1493
|
+
if (!intrinsic.isInteger(b)) return a;
|
|
1494
|
+
return a < b ? a : b;
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1459
1497
|
function decodeExtensionList(list, opts) {
|
|
1460
1498
|
var out = [];
|
|
1461
1499
|
for (var i = 0; i < list.length; i++) _append(out, decodeOneExtension(list[i], i, opts));
|
|
@@ -2409,6 +2447,8 @@ module.exports = {
|
|
|
2409
2447
|
scopedCertDecoder: scopedCertDecoder,
|
|
2410
2448
|
crlExtensionDecoders: crlExtensionDecoders,
|
|
2411
2449
|
decodeExtensionList: decodeExtensionList,
|
|
2450
|
+
anchorPathLenFromExtensions: anchorPathLenFromExtensions,
|
|
2451
|
+
lowerPathLen: lowerPathLen,
|
|
2412
2452
|
extensionDoor: extensionDoor,
|
|
2413
2453
|
_decodeHelpers: _decodeHelpers,
|
|
2414
2454
|
attribute: attribute,
|