@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/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 = Object.keys(rdnSpec);
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
  }
@@ -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 = Object.keys(h);
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) { var o = Object.create(null); for (var k in table) if (Object.prototype.hasOwnProperty.call(table, k)) o[table[k]] = k; return o; }
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, k;
625
- for (k in headers) {
626
- if (!Object.prototype.hasOwnProperty.call(headers, k)) continue;
627
- if (_foldLower(String(k)) === name) { found = headers[k]; seen += 1; }
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, Object.assign({}, headers), opts, transport, budgets);
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 ? Object.assign({}, opts.tls) : opts.tls,
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 ? Object.assign({}, opts.tls) : opts.tls, maxRedirects: opts.maxRedirects, allowCrossOriginRedirect: opts.allowCrossOriginRedirect, timeout: opts.timeout, maxResponseBytes: opts.maxResponseBytes, proxy: _snapshotProxy(opts.proxy) };
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) { var o = {}, k; for (k in _TRANSPORT_KEYS) o[k] = 1; for (k in extra) o[k] = 1; return o; }
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 },
@@ -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
- // allow:registry-table-inherits-object-prototype -- the record a schema's own check and build callbacks read as m.fields, whose keys are the field names that schema declared rather than anything the input supplies
343
- var fields = {};
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];
@@ -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,