@blamejs/pki 0.8.58 → 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.
Files changed (66) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/lib/acme.js +53 -30
  3. package/lib/alt-sig.js +3 -1
  4. package/lib/asn1-der.js +98 -39
  5. package/lib/attrcert-sign.js +19 -16
  6. package/lib/byte-writer.js +63 -13
  7. package/lib/cbor-det.js +9 -3
  8. package/lib/cmc-build.js +16 -10
  9. package/lib/cmp-build.js +45 -34
  10. package/lib/cmp-session.js +19 -9
  11. package/lib/cms-decrypt.js +28 -10
  12. package/lib/cms-encrypt.js +23 -17
  13. package/lib/cms-sign.js +65 -43
  14. package/lib/cms-verify.js +11 -7
  15. package/lib/crl-sign.js +27 -20
  16. package/lib/csr-sign.js +5 -2
  17. package/lib/ct.js +37 -17
  18. package/lib/est.js +55 -32
  19. package/lib/guard-bytes.js +5 -1
  20. package/lib/guard-der.js +6 -1
  21. package/lib/guard-identifier.js +1 -1
  22. package/lib/guard-intrinsic.js +12 -4
  23. package/lib/guard-list.js +64 -0
  24. package/lib/guard-name.js +1 -1
  25. package/lib/hpke.js +10 -3
  26. package/lib/http-transport.js +12 -3
  27. package/lib/inspect.js +10 -2
  28. package/lib/jose.js +3 -1
  29. package/lib/key.js +11 -7
  30. package/lib/lint.js +236 -152
  31. package/lib/mime.js +9 -5
  32. package/lib/ocsp.js +25 -22
  33. package/lib/path-validate.js +48 -18
  34. package/lib/pbes2.js +6 -2
  35. package/lib/pkcs11-uri.js +3 -1
  36. package/lib/pkcs12-build.js +14 -11
  37. package/lib/pki-build.js +18 -14
  38. package/lib/possession.js +3 -1
  39. package/lib/rc2.js +6 -2
  40. package/lib/revocation-fetch.js +78 -19
  41. package/lib/scep.js +14 -6
  42. package/lib/schema-attrcert.js +4 -2
  43. package/lib/schema-c509.js +94 -78
  44. package/lib/schema-cmc.js +5 -2
  45. package/lib/schema-cmp.js +6 -3
  46. package/lib/schema-cms.js +7 -4
  47. package/lib/schema-crl.js +1 -1
  48. package/lib/schema-crmf.js +1 -1
  49. package/lib/schema-csr.js +3 -3
  50. package/lib/schema-engine.js +36 -18
  51. package/lib/schema-pkcs1.js +7 -3
  52. package/lib/schema-pkcs12.js +9 -6
  53. package/lib/schema-pkix.js +19 -3
  54. package/lib/schema-sec1.js +4 -1
  55. package/lib/schema-tsp.js +4 -1
  56. package/lib/shbs.js +7 -3
  57. package/lib/sign-scheme.js +4 -4
  58. package/lib/smime.js +18 -14
  59. package/lib/tlog.js +17 -11
  60. package/lib/tuf.js +3 -1
  61. package/lib/validator-keydesc.js +4 -1
  62. package/lib/validator-tls.js +7 -2
  63. package/lib/webcrypto.js +14 -8
  64. package/lib/x509-sign.js +20 -15
  65. package/package.json +1 -1
  66. package/sbom.cdx.json +6 -6
@@ -24,6 +24,9 @@ var x509 = require("./schema-x509");
24
24
  var signScheme = require("./sign-scheme");
25
25
  var guard = require("./guard-all");
26
26
  var intrinsic = require("./guard-intrinsic");
27
+ /** @internal The append every list here is built with: `push` stores at the index and a store
28
+ * consults a setter inherited there, and these lists become the bytes that get signed. */
29
+ var _push = intrinsic.append;
27
30
  /** @internal The promise a signature verdict is awaited through, built from the constructor captured at
28
31
  * load. `Promise.resolve` builds from its RECEIVER, so reading the global binding at the call hands the
29
32
  * construction to whatever that binding holds: one settling without awaiting its argument drops the
@@ -195,7 +198,7 @@ function _issuerSerialContent(is) {
195
198
  var parts = [_b.encodeGeneralNames(_gnList(is.issuer)), _b.serialInteger(is.serial)];
196
199
  if (is.issuerUID != null) {
197
200
  if (!Buffer.isBuffer(is.issuerUID)) throw _err("attrcert/bad-input", "baseCertificateID.issuerUID must be a Buffer");
198
- parts.push(b.bitString(is.issuerUID, 0));
201
+ _push(parts,b.bitString(is.issuerUID, 0));
199
202
  }
200
203
  return Buffer.concat(parts);
201
204
  }
@@ -251,8 +254,8 @@ function _encodeRole(role) {
251
254
  _assertFields(role, KNOWN_ROLE_KEYS, "role");
252
255
  if (role.roleName == null) throw _err("attrcert/bad-input", "role must be an object with a roleName GeneralName");
253
256
  var parts = [];
254
- if (role.roleAuthority != null) parts.push(_b.encodeGeneralNames(_gnList(role.roleAuthority), 0));
255
- parts.push(b.explicit(1, _b.encodeGeneralName(role.roleName)));
257
+ if (role.roleAuthority != null) _push(parts,_b.encodeGeneralNames(_gnList(role.roleAuthority), 0));
258
+ _push(parts,b.explicit(1, _b.encodeGeneralName(role.roleName)));
256
259
  return b.sequence(parts);
257
260
  }
258
261
  function _encodeClearance(cl) {
@@ -269,11 +272,11 @@ function _encodeClearance(cl) {
269
272
  return pos;
270
273
  });
271
274
  var isDefault = positions.length === 1 && positions[0] === CLASSLIST_BIT.unclassified;
272
- if (!isDefault) parts.push(b.namedBitString(positions));
275
+ if (!isDefault) _push(parts,b.namedBitString(positions));
273
276
  }
274
277
  if (cl.securityCategories != null) {
275
278
  if (!Array.isArray(cl.securityCategories) || !cl.securityCategories.length) throw _err("attrcert/bad-input", "clearance.securityCategories must be a non-empty array");
276
- parts.push(b.set(guard.list.copyMap(cl.securityCategories, _encodeSecurityCategory)));
279
+ _push(parts,b.set(guard.list.copyMap(cl.securityCategories, _encodeSecurityCategory)));
277
280
  }
278
281
  return b.sequence(parts);
279
282
  }
@@ -291,8 +294,8 @@ function _encodeIetfAttrSyntax(ia) {
291
294
  _assertFields(ia, KNOWN_IETF_ATTR_KEYS, "IetfAttrSyntax");
292
295
  if (!Array.isArray(ia.values) || !ia.values.length) throw _err("attrcert/bad-input", "an IetfAttrSyntax attribute must be an object with a non-empty values array");
293
296
  var parts = [];
294
- if (ia.policyAuthority != null) parts.push(_b.encodeGeneralNames(_gnList(ia.policyAuthority), 0));
295
- parts.push(b.sequence(guard.list.copyMap(ia.values, function (v) {
297
+ if (ia.policyAuthority != null) _push(parts,_b.encodeGeneralNames(_gnList(ia.policyAuthority), 0));
298
+ _push(parts,b.sequence(guard.list.copyMap(ia.values, function (v) {
296
299
  if (v == null || typeof v !== "object") throw _err("attrcert/bad-input", "each IetfAttrSyntax value must be { octets }, { oid }, or { string }");
297
300
  _assertFields(v, KNOWN_IETF_ATTR_VALUE_KEYS, "IetfAttrSyntax value");
298
301
  if (v.octets != null) { if (!Buffer.isBuffer(v.octets)) throw _err("attrcert/bad-input", "IetfAttrSyntax octets must be a Buffer"); return b.octetString(v.octets); }
@@ -310,7 +313,7 @@ function _encodeSvceAuthInfo(sai, authInfoAllowed, label) {
310
313
  if (sai.authInfo != null) {
311
314
  if (!authInfoAllowed) throw _err("attrcert/bad-input", "accessIdentity must not carry authInfo (RFC 5755 sec. 4.4.2)");
312
315
  if (!Buffer.isBuffer(sai.authInfo)) throw _err("attrcert/bad-input", label + " authInfo must be a Buffer");
313
- parts.push(b.octetString(sai.authInfo));
316
+ _push(parts,b.octetString(sai.authInfo));
314
317
  }
315
318
  return b.sequence(parts);
316
319
  }
@@ -349,11 +352,11 @@ function _encodeAAControls(aac) {
349
352
  var parts = [];
350
353
  if (aac.pathLenConstraint != null) {
351
354
  if (typeof aac.pathLenConstraint !== "number" || !Number.isInteger(aac.pathLenConstraint) || aac.pathLenConstraint < 0 || aac.pathLenConstraint > 0x7fffffff) throw _err("attrcert/bad-input", "aaControls.pathLenConstraint must be an integer in 0..2147483647 (RFC 5755 sec. 7.4)");
352
- parts.push(b.integer(BigInt(aac.pathLenConstraint)));
355
+ _push(parts,b.integer(BigInt(aac.pathLenConstraint)));
353
356
  }
354
- if (aac.permittedAttrs != null) parts.push(_attrSpec(aac.permittedAttrs, 0, "permittedAttrs"));
355
- if (aac.excludedAttrs != null) parts.push(_attrSpec(aac.excludedAttrs, 1, "excludedAttrs"));
356
- if (aac.permitUnSpecified === false) parts.push(b.boolean(false));
357
+ if (aac.permittedAttrs != null) _push(parts,_attrSpec(aac.permittedAttrs, 0, "permittedAttrs"));
358
+ if (aac.excludedAttrs != null) _push(parts,_attrSpec(aac.excludedAttrs, 1, "excludedAttrs"));
359
+ if (aac.permitUnSpecified === false) _push(parts,b.boolean(false));
357
360
  else if (aac.permitUnSpecified != null && aac.permitUnSpecified !== true) throw _err("attrcert/bad-input", "aaControls.permitUnSpecified must be a boolean");
358
361
  return b.sequence(parts);
359
362
  }
@@ -388,7 +391,7 @@ function _buildAttributes(attrSpec) {
388
391
  if (seen[type]) throw _err("attrcert/duplicate-attribute", "duplicate " + (oid.name(type) || type) + " attribute (RFC 5755 sec. 4.2.7)");
389
392
  seen[type] = true;
390
393
  _assertAttributeProfile(type, attrcert.validateAttributeValue(type, valueTlv));
391
- attrs.push(b.sequence([b.oid(type), b.set([valueTlv])]));
394
+ _push(attrs,b.sequence([b.oid(type), b.set([valueTlv])]));
392
395
  }
393
396
  if (Array.isArray(attrSpec)) {
394
397
  /** @internal Through the captured walk, never the caller's own `forEach`: these attributes are the
@@ -409,7 +412,7 @@ function _buildAttributes(attrSpec) {
409
412
  catch (err) { if (err instanceof AttrCertError) throw err; throw _err("attrcert/bad-input", "pre-encoded " + (oid.name(at) || at) + " attribute value is malformed", err); }
410
413
  _assertAttributeProfile(at, decoded);
411
414
  });
412
- attrs.push(b.raw(der));
415
+ _push(attrs,b.raw(der));
413
416
  });
414
417
  if (!attrs.length) throw _err("attrcert/bad-attributes", "attributes must carry at least one Attribute (RFC 5755 sec. 4.2.7)");
415
418
  return b.sequence(attrs);
@@ -442,7 +445,7 @@ function _emitNamedExtension(out, seen, k, val, ctx) {
442
445
  seen[eOid] = true;
443
446
  var valueDer = _extensionValue(k, val, ctx);
444
447
  _assertExtensionProfile(eOid, _decodeExtensionValue(eOid, valueDer), ctx);
445
- out.push(_b.ext(eOid, meta.critical, valueDer));
448
+ _push(out,_b.ext(eOid, meta.critical, valueDer));
446
449
  }
447
450
  function _buildExtensions(extSpec, ctx) {
448
451
  if (extSpec == null) extSpec = {};
@@ -593,7 +596,7 @@ function _sign(spec, issuer, opts) {
593
596
  b.integer(1n), holderDer, issuerDer, scheme.sigAlgId,
594
597
  _b.serialInteger(spec.serialNumber), validityDer, attributesDer,
595
598
  ];
596
- if (extsDer) acinfoChildren.push(extsDer);
599
+ if (extsDer) _push(acinfoChildren,extsDer);
597
600
  var acinfoDer = b.sequence(acinfoChildren);
598
601
 
599
602
  return signScheme.signOverTbs(scheme, issuer.key, acinfoDer, _signE).then(function (sig) {
@@ -18,20 +18,58 @@
18
18
  * in a format module.
19
19
  */
20
20
 
21
+ var intrinsic = require("./guard-intrinsic");
22
+ /** @internal Every operation this writer decides a field's width, range or bytes with is bound at
23
+ * load. Each one participates in what gets emitted: the integer tests decide whether a value fits
24
+ * the field, the allocation decides how wide the field is, and the concatenation decides the byte
25
+ * string a caller signs or sends. */
26
+ var _isInteger = intrinsic.isInteger;
27
+ var _isSafeInteger = intrinsic.isSafeInteger;
28
+ var _bufferAlloc = intrinsic.bufferAlloc;
29
+ var _isBuffer = intrinsic.isBuffer;
30
+ var _bufferConcat = intrinsic.bufferConcat;
31
+ var _BigInt = intrinsic.BigInt;
32
+ var _taSet = intrinsic.typedArraySet;
33
+ /** @internal The two writes that place an integer into its field, bound at load. A bound's own
34
+ * `valueOf` runs inside the comparison the length is checked by, which is a window to replace a
35
+ * method the write that follows would otherwise read off the prototype: measured, a vector declared
36
+ * a length of 0 over a payload of two bytes that way. */
37
+ var _writeUIntBE = intrinsic.uncurry(Buffer.prototype.writeUIntBE);
38
+ var _writeBigUInt64BE = intrinsic.uncurry(Buffer.prototype.writeBigUInt64BE);
39
+
40
+ /** @internal A real copy of the bytes, in this writer's own allocation. A slice of a view shares the
41
+ * backing buffer, so a buffer that can be resized takes the slice out of bounds with it, and the
42
+ * copy has to be taken before anything else in the call can run code. */
43
+ function _copyOf(view) {
44
+ var n = intrinsic.sizeOf(view);
45
+ var out = _bufferAlloc(n);
46
+ if (n !== 0) _taSet(out, view, 0);
47
+ return out;
48
+ }
49
+
21
50
  function ByteWriter(E, defaultCode) {
22
51
  this.parts = [];
23
52
  this.len = 0;
24
53
  this.E = E;
25
54
  this.defaultCode = defaultCode || "byte-writer/bad-value";
26
55
  }
27
- ByteWriter.prototype._push = function (buf) { this.parts.push(buf); this.len += buf.length; };
56
+ /** @internal The piece is APPENDED by defining its index, not stored by `push`. A store walks the
57
+ * prototype chain for a setter, so an accessor installed at an array index receives each piece as it
58
+ * is added and can define something else in its place, and these pieces are the bytes this writer
59
+ * emits. The length is accumulated from the buffer's own byte length rather than a `length`
60
+ * property, so a view that overstates itself cannot make the declared length disagree with the
61
+ * bytes. */
62
+ ByteWriter.prototype._push = function (buf) {
63
+ intrinsic.append(this.parts, buf);
64
+ this.len += intrinsic.sizeOf(buf);
65
+ };
28
66
  ByteWriter.prototype._uint = function (v, width, code) {
29
- if (!Number.isInteger(width) || width < 1 || width > 4) throw new this.E(code || this.defaultCode, "an integer width must be 1..4, got " + width);
67
+ if (!_isInteger(width) || width < 1 || width > 4) throw new this.E(code || this.defaultCode, "an integer width must be 1..4, got " + width);
30
68
  var max = width === 4 ? 0xffffffff : (1 << (8 * width)) - 1;
31
- if (typeof v !== "number" || !Number.isSafeInteger(v) || v < 0 || v > max) {
69
+ if (typeof v !== "number" || !_isSafeInteger(v) || v < 0 || v > max) {
32
70
  throw new this.E(code || this.defaultCode, "a uint" + (8 * width) + " must be an integer in 0.." + max + ", got " + v);
33
71
  }
34
- var b = Buffer.alloc(width); b.writeUIntBE(v, 0, width); this._push(b);
72
+ var b = _bufferAlloc(width); _writeUIntBE(b, v, 0, width); this._push(b);
35
73
  };
36
74
  ByteWriter.prototype.u8 = function (v, code) { this._uint(v, 1, code); return this; };
37
75
  ByteWriter.prototype.u16 = function (v, code) { this._uint(v, 2, code); return this; };
@@ -40,25 +78,37 @@ ByteWriter.prototype.u32 = function (v, code) { this._uint(v, 4, code); return t
40
78
  ByteWriter.prototype.u64 = function (v, code) {
41
79
  var big;
42
80
  if (typeof v === "bigint") big = v;
43
- else if (typeof v === "number" && Number.isSafeInteger(v) && v >= 0) big = BigInt(v);
81
+ else if (typeof v === "number" && _isSafeInteger(v) && v >= 0) big = _BigInt(v);
44
82
  else throw new this.E(code || this.defaultCode, "a uint64 must be a non-negative integer or BigInt, got " + v);
45
83
  if (big < 0n || big > 0xffffffffffffffffn) throw new this.E(code || this.defaultCode, "a uint64 must be in 0..2^64-1");
46
- var b = Buffer.alloc(8); b.writeBigUInt64BE(big); this._push(b);
84
+ var b = _bufferAlloc(8); _writeBigUInt64BE(b, big); this._push(b);
47
85
  return this;
48
86
  };
49
87
  ByteWriter.prototype.bytes = function (buf, code) {
50
- if (!Buffer.isBuffer(buf)) throw new this.E(code || this.defaultCode, "bytes() requires a Buffer");
88
+ if (!_isBuffer(buf)) throw new this.E(code || this.defaultCode, "bytes() requires a Buffer");
51
89
  this._push(buf); return this;
52
90
  };
53
91
  ByteWriter.prototype.vector = function (lenWidth, min, max, body, code) {
54
- if (!Buffer.isBuffer(body)) throw new this.E(code || this.defaultCode, "vector() body must be a Buffer");
55
- if (body.length < min) throw new this.E(code || this.defaultCode, "vector body " + body.length + " below minimum " + min);
56
- if (max != null && body.length > max) throw new this.E(code || this.defaultCode, "vector body " + body.length + " above maximum " + max);
57
- this._uint(body.length, lenWidth, code);
58
- this._push(body);
92
+ if (!_isBuffer(body)) throw new this.E(code || this.defaultCode, "vector() body must be a Buffer");
93
+ /** @internal The body is COPIED before it is measured, and the copy is what gets written. The
94
+ * bounds, the length prefix and the bytes then all describe one byte string that nothing else
95
+ * holds. Measuring the caller's view instead left a window: a resizable backing buffer shrunk
96
+ * between the measurement and the write (a `min` whose `valueOf` resizes it is enough) and the
97
+ * vector declared two bytes over a payload of one. The bounds are converted to numbers up front
98
+ * for the same reason, so a bound cannot run code in the middle of the comparison it is part of. */
99
+ var bytes = _copyOf(body);
100
+ var bodyLen = intrinsic.sizeOf(bytes);
101
+ var lo = intrinsic.Number(min);
102
+ if (!_isSafeInteger(lo) || lo < 0) throw new this.E(code || this.defaultCode, "a vector minimum must be a non-negative integer, got " + lo);
103
+ var hi = max == null ? null : intrinsic.Number(max);
104
+ if (hi !== null && (!_isSafeInteger(hi) || hi < lo)) throw new this.E(code || this.defaultCode, "a vector maximum must be an integer not below the minimum, got " + hi);
105
+ if (bodyLen < lo) throw new this.E(code || this.defaultCode, "vector body " + bodyLen + " below minimum " + lo);
106
+ if (hi !== null && bodyLen > hi) throw new this.E(code || this.defaultCode, "vector body " + bodyLen + " above maximum " + hi);
107
+ this._uint(bodyLen, lenWidth, code);
108
+ this._push(bytes);
59
109
  return this;
60
110
  };
61
111
  ByteWriter.prototype.length = function () { return this.len; };
62
- ByteWriter.prototype.build = function () { return Buffer.concat(this.parts, this.len); };
112
+ ByteWriter.prototype.build = function () { return _bufferConcat(this.parts, this.len); };
63
113
 
64
114
  module.exports = ByteWriter;
package/lib/cbor-det.js CHANGED
@@ -40,6 +40,12 @@ var constants = require("./constants");
40
40
  var frameworkError = require("./framework-error");
41
41
  var asn1 = require("./asn1-der");
42
42
  var guard = require("./guard-all");
43
+ /** @internal The append every list in this module is built with. `push` STORES at the index, and a
44
+ * store walks the prototype chain for a setter, so an accessor inherited at an array index receives
45
+ * each element as it is appended and the index then reads back whatever its getter answers. The
46
+ * decoded children below are what every C509 field is read out of, so a replaced element there is a
47
+ * field this codec never decoded. */
48
+ var _push = guard.list.append;
43
49
 
44
50
  var CborError = frameworkError.CborError;
45
51
 
@@ -141,7 +147,7 @@ function _decodeItem(buf, start, limit, depth, maxD, rules, state) {
141
147
  var cp = contentStart;
142
148
  for (var i = 0n; i < argument; i++) {
143
149
  var el = _decodeItem(buf, cp, limit, depth + 1, maxD, rules, state);
144
- children.push(el.node);
150
+ _push(children, el.node);
145
151
  cp = el.end;
146
152
  }
147
153
  end = cp;
@@ -158,7 +164,7 @@ function _decodeItem(buf, start, limit, depth, maxD, rules, state) {
158
164
  if (cmp > 0) throw new CborError("cbor/unsorted-map-keys", "map keys are not in bytewise-ascending order");
159
165
  if (cmp === 0) throw new CborError("cbor/duplicate-map-key", "duplicate map key");
160
166
  }
161
- children.push([k.node, v.node]);
167
+ _push(children, [k.node, v.node]);
162
168
  }
163
169
  end = mp;
164
170
  } else if (mt === 6) {
@@ -682,7 +688,7 @@ var build = Object.assign(Object.create(null), {
682
688
  enc = guard.list.sortedCopy(enc, function (a, b) { return guard.bytes.compare(a[0], b[0]); });
683
689
  for (var i = 1; i < enc.length; i++) { if (guard.bytes.compare(enc[i - 1][0], enc[i][0]) === 0) throw new CborError("cbor/duplicate-map-key", "build.map: duplicate map key"); }
684
690
  var flat = [_head(5, pairs.length, "build.map")];
685
- enc.forEach(function (p) { flat.push(p[0], p[1]); });
691
+ enc.forEach(function (p) { _push(flat, p[0]); _push(flat, p[1]); });
686
692
  return _assertDecodes(Buffer.concat(flat), "build.map");
687
693
  },
688
694
  tag: function (tagNum, inner) { return _assertDecodes(Buffer.concat([_head(6, tagNum, "build.tag"), _cbItem(inner, "build.tag content")]), "build.tag"); },
package/lib/cmc-build.js CHANGED
@@ -22,6 +22,9 @@ var key = require("./key");
22
22
  var _createPublicKey = nodeCrypto.createPublicKey;
23
23
  var guard = require("./guard-all");
24
24
  var intrinsic = require("./guard-intrinsic");
25
+ /** @internal The append every list here is built with: `push` stores at the index and a store
26
+ * consults a setter inherited there, and these lists become the controls a request carries. */
27
+ var _push = intrinsic.append;
25
28
  var _hasOwn = intrinsic.hasOwn;
26
29
  var _isArray = intrinsic.isArray;
27
30
  var _isBuffer = intrinsic.isBuffer;
@@ -173,7 +176,10 @@ function fixedRequestId(req, index) {
173
176
  return "unknown field " + JSON.stringify(k) + " on request " + index +
174
177
  " -- a request names one of tcr / crm / orm, and optionally bodyPartID";
175
178
  });
176
- var arms = ["tcr", "crm", "orm"].filter(function (k) { return req[k] != null; });
179
+ /** @internal `selectList`, not the live `filter`: the selection decides which request arm this
180
+ * message carries, and `Array.prototype.filter` is both read off the prototype and specified to
181
+ * build its result through the species constructor. */
182
+ var arms = intrinsic.selectList(["tcr", "crm", "orm"], function (k) { return req[k] != null; });
177
183
  if (arms.length !== 1) {
178
184
  throw E("cmc/bad-input",
179
185
  "each request names exactly one of tcr / crm / orm, got " + (arms.length ? arms.join(" + ") : "none") +
@@ -446,7 +452,7 @@ function _assertSecret(secret, what) {
446
452
  }
447
453
 
448
454
  function _ownSecret(buf, owned) {
449
- owned.push(buf);
455
+ _push(owned,buf);
450
456
  return buf;
451
457
  }
452
458
 
@@ -801,15 +807,15 @@ async function _build(spec, signer, opts) {
801
807
 
802
808
  _assertNoDuplicateBinding(callerControls, spec);
803
809
  if (spec.transactionId != null) {
804
- controls.push(encodeControl(OID_TRANSACTION_ID,
810
+ _push(controls,encodeControl(OID_TRANSACTION_ID,
805
811
  [b.integer(_asBigInt(spec.transactionId, "spec.transactionId"))], ids));
806
812
  }
807
813
  if (spec.senderNonce != null) {
808
- controls.push(encodeControl(OID_SENDER_NONCE,
814
+ _push(controls,encodeControl(OID_SENDER_NONCE,
809
815
  [b.octetString(_der(spec.senderNonce, "spec.senderNonce"))], ids));
810
816
  }
811
817
  if (spec.dataReturn != null) {
812
- controls.push(encodeControl(OID_DATA_RETURN,
818
+ _push(controls,encodeControl(OID_DATA_RETURN,
813
819
  [b.octetString(_der(spec.dataReturn, "spec.dataReturn"))], ids));
814
820
  }
815
821
 
@@ -836,8 +842,8 @@ async function _build(spec, signer, opts) {
836
842
  if (identity != null && typeof identity !== "string") {
837
843
  throw E("cmc/bad-input", "identityProof.identity is the UTF8String the Identification control carries");
838
844
  }
839
- if (identity != null) controls.push(encodeControl(OID_IDENTIFICATION, [b.utf8(identity)], ids));
840
- controls.push(encodeControl(OID_IDENTITY_PROOF_V2,
845
+ if (identity != null) _push(controls,encodeControl(OID_IDENTIFICATION, [b.utf8(identity)], ids));
846
+ _push(controls,encodeControl(OID_IDENTITY_PROOF_V2,
841
847
  [identityProofV2(spec.identityProof.secret, reqSequenceBytes, carriedIdentity)], ids));
842
848
  }
843
849
 
@@ -930,8 +936,8 @@ async function _build(spec, signer, opts) {
930
936
  throw E("cmc/bad-input", "popLinkRandomBytes must be a positive integer");
931
937
  }
932
938
  var R = nodeCrypto.randomBytes(rBytes);
933
- controls.push(encodeControl(OID_POP_LINK_RANDOM, [b.octetString(R)], ids));
934
- controls.push(encodeControl(O("id-cmc-popLinkWitnessV2"),
939
+ _push(controls,encodeControl(OID_POP_LINK_RANDOM, [b.octetString(R)], ids));
940
+ _push(controls,encodeControl(O("id-cmc-popLinkWitnessV2"),
935
941
  [popLinkWitnessV2(spec.popLink.secret, R)], ids));
936
942
  }
937
943
 
@@ -1013,7 +1019,7 @@ function _copySigners(signer, owned) {
1013
1019
  return c;
1014
1020
  }
1015
1021
  function _own(buf, isSecret) {
1016
- if (isSecret && owned) owned.push(buf);
1022
+ if (isSecret && owned) _push(owned,buf);
1017
1023
  return buf;
1018
1024
  }
1019
1025
  return Array.isArray(signer) ? guard.list.copyMap(signer, one) : one(signer);
package/lib/cmp-build.js CHANGED
@@ -29,6 +29,7 @@ var cmp = require("./schema-cmp");
29
29
  var crmf = require("./crmf-sign");
30
30
  var schemaCrmf = require("./schema-crmf");
31
31
  var intrinsic = require("./guard-intrinsic");
32
+ var _strTrim = intrinsic.uncurry(String.prototype.trim);
32
33
  /** @internal The promise a signature self-check is awaited through, built from the constructor captured
33
34
  * at load. `Promise.resolve` builds from its RECEIVER, so reading the global binding at the call hands
34
35
  * the construction to whatever that binding holds, and one settling without awaiting its argument runs
@@ -55,7 +56,9 @@ var _bufferConcat = intrinsic.bufferConcat;
55
56
  var _map = intrinsic.map;
56
57
  var _keys = intrinsic.keys;
57
58
  var _forEach = intrinsic.forEach;
58
- var _push = intrinsic.push;
59
+ /** @internal `append`, not a captured `push`: a store at an index walks the prototype chain for a
60
+ * setter, so an accessor there takes the element being appended. `append` defines it. */
61
+ var _push = intrinsic.append;
59
62
  var _stringify = intrinsic.stringify;
60
63
  var _bigInt = intrinsic.BigInt;
61
64
  var _Date = intrinsic.Date;
@@ -166,7 +169,7 @@ function _encodeInfoTypeAndValue(itav) {
166
169
  if (typeof itav.infoType !== "string" || O(itav.infoType) == null) throw _err("cmp/bad-name", "unknown infoType " + guard.text.showValue(itav.infoType));
167
170
  var children = [b.oid(O(itav.infoType))];
168
171
  var val = _encodeInfoValue(itav);
169
- if (val != null) children.push(val);
172
+ if (val != null) _push(children,val);
170
173
  return b.sequence(children);
171
174
  }
172
175
 
@@ -237,16 +240,16 @@ function _encodeHeader(headerSpec, protectionAlgDer, pvno) {
237
240
  ];
238
241
  if (headerSpec.messageTime != null) {
239
242
  guard.time.assertEncodable(headerSpec.messageTime, _err, "cmp/bad-input", "header.messageTime");
240
- children.push(b.explicit(0, b.generalizedTime(headerSpec.messageTime)));
243
+ _push(children,b.explicit(0, b.generalizedTime(headerSpec.messageTime)));
241
244
  }
242
- if (protectionAlgDer != null) children.push(b.explicit(1, b.raw(protectionAlgDer)));
243
- if (headerSpec.senderKID != null) children.push(b.explicit(2, _reqOctets(headerSpec.senderKID, "header.senderKID")));
244
- if (headerSpec.recipKID != null) children.push(b.explicit(3, _reqOctets(headerSpec.recipKID, "header.recipKID")));
245
- if (headerSpec.transactionID != null) children.push(b.explicit(4, _reqOctets(headerSpec.transactionID, "header.transactionID")));
246
- if (headerSpec.senderNonce != null) children.push(b.explicit(5, _reqOctets(headerSpec.senderNonce, "header.senderNonce")));
247
- if (headerSpec.recipNonce != null) children.push(b.explicit(6, _reqOctets(headerSpec.recipNonce, "header.recipNonce")));
248
- if (headerSpec.freeText != null) children.push(b.explicit(7, _encodePkiFreeText(headerSpec.freeText, "cmp/bad-freetext", "header.freeText")));
249
- if (headerSpec.generalInfo != null) children.push(b.explicit(8, _encodeGeneralInfo(headerSpec.generalInfo, "cmp/bad-general-info", "header.generalInfo")));
245
+ if (protectionAlgDer != null) _push(children,b.explicit(1, b.raw(protectionAlgDer)));
246
+ if (headerSpec.senderKID != null) _push(children,b.explicit(2, _reqOctets(headerSpec.senderKID, "header.senderKID")));
247
+ if (headerSpec.recipKID != null) _push(children,b.explicit(3, _reqOctets(headerSpec.recipKID, "header.recipKID")));
248
+ if (headerSpec.transactionID != null) _push(children,b.explicit(4, _reqOctets(headerSpec.transactionID, "header.transactionID")));
249
+ if (headerSpec.senderNonce != null) _push(children,b.explicit(5, _reqOctets(headerSpec.senderNonce, "header.senderNonce")));
250
+ if (headerSpec.recipNonce != null) _push(children,b.explicit(6, _reqOctets(headerSpec.recipNonce, "header.recipNonce")));
251
+ if (headerSpec.freeText != null) _push(children,b.explicit(7, _encodePkiFreeText(headerSpec.freeText, "cmp/bad-freetext", "header.freeText")));
252
+ if (headerSpec.generalInfo != null) _push(children,b.explicit(8, _encodeGeneralInfo(headerSpec.generalInfo, "cmp/bad-general-info", "header.generalInfo")));
250
253
  return b.sequence(children);
251
254
  }
252
255
 
@@ -266,8 +269,8 @@ function _encodePkiStatusInfo(si, code) {
266
269
  if (!si || typeof si !== "object" || Buffer.isBuffer(si)) throw _err(code, "a PKIStatusInfo must be an object { status, statusString?, failInfo? }");
267
270
  if (typeof si.status !== "number" || !Number.isInteger(si.status) || si.status < 0 || si.status > 6) throw _err(code, "statusInfo.status must be a PKIStatus 0..6 (RFC 9810 sec. 5.2.3)");
268
271
  var children = [b.integer(BigInt(si.status))];
269
- if (si.statusString != null) children.push(_encodePkiFreeText(si.statusString, code, "statusInfo.statusString"));
270
- if (si.failInfo != null) children.push(_encodeFailInfo(si.failInfo, code));
272
+ if (si.statusString != null) _push(children,_encodePkiFreeText(si.statusString, code, "statusInfo.statusString"));
273
+ if (si.failInfo != null) _push(children,_encodeFailInfo(si.failInfo, code));
271
274
  return b.sequence(children);
272
275
  }
273
276
 
@@ -277,10 +280,10 @@ function _encodeCertStatus(cs, state) {
277
280
  _reqOctets(cs.certHash, "certConf certHash"),
278
281
  b.integer(_reqIdInt(cs.certReqId, "cmp/bad-cert-status", "CertStatus certReqId")),
279
282
  ];
280
- if (cs.statusInfo != null) children.push(_encodePkiStatusInfo(cs.statusInfo, "cmp/bad-cert-status"));
283
+ if (cs.statusInfo != null) _push(children,_encodePkiStatusInfo(cs.statusInfo, "cmp/bad-cert-status"));
281
284
  if (cs.hashAlg != null) {
282
285
  if (typeof cs.hashAlg !== "string" || !CERT_CONF_HASH_ALGS[cs.hashAlg]) throw _err("cmp/bad-name", "certConf hashAlg must be a hash algorithm (sha256 / sha384 / sha512 / sha3-256 / sha3-512 / sha1); got " + guard.text.showValue(cs.hashAlg));
283
- children.push(b.explicit(0, _algIdNoParams(cs.hashAlg)));
286
+ _push(children,b.explicit(0, _algIdNoParams(cs.hashAlg)));
284
287
  state.usesCmp2021 = true;
285
288
  }
286
289
  return b.sequence(children);
@@ -316,7 +319,7 @@ function _encodeRevDetails(rd) {
316
319
  certDetails = b.raw(crmf.buildCertTemplate(rd.certDetails));
317
320
  }
318
321
  var children = [certDetails];
319
- if (rd.crlEntryDetails != null) children.push(b.raw(_encodeCrlEntryDetails(rd.crlEntryDetails)));
322
+ if (rd.crlEntryDetails != null) _push(children,b.raw(_encodeCrlEntryDetails(rd.crlEntryDetails)));
320
323
  return b.sequence(children);
321
324
  }
322
325
 
@@ -418,12 +421,12 @@ function _encodeCertifiedKeyPair(ckp, state) {
418
421
  var children = [_encodeCertOrEncCert(ckp, state)];
419
422
  if (ckp.privateKey != null) {
420
423
  var pk = _b.reqDer(ckp.privateKey, "certifiedKeyPair.privateKey (a pre-encoded EncryptedKey DER)");
421
- children.push(b.explicit(0, b.raw(pk)));
424
+ _push(children,b.explicit(0, b.raw(pk)));
422
425
  var pkNode;
423
426
  try { pkNode = asn1.decode(pk); } catch (e) { throw _err("cmp/bad-cert-response", "certifiedKeyPair.privateKey is not valid DER", e); }
424
427
  if (pkNode.tagClass === "context" && pkNode.tagNumber === 0) state.usesCmp2021 = true;
425
428
  }
426
- if (ckp.publicationInfo != null) children.push(b.explicit(1, b.raw(_b.reqDer(ckp.publicationInfo, "certifiedKeyPair.publicationInfo (a pre-encoded DER)"))));
429
+ if (ckp.publicationInfo != null) _push(children,b.explicit(1, b.raw(_b.reqDer(ckp.publicationInfo, "certifiedKeyPair.publicationInfo (a pre-encoded DER)"))));
427
430
  return b.sequence(children);
428
431
  }
429
432
 
@@ -434,8 +437,8 @@ function _encodeCertResponse(cr, state) {
434
437
  if (hasCkp && cr.status.failInfo != null) throw _err("cmp/bad-cert-response", "a CertResponse must not carry both failInfo and certifiedKeyPair");
435
438
  if (hasCkp && cr.status.status !== 0 && cr.status.status !== 1) throw _err("cmp/bad-cert-response", "a CertResponse certifiedKeyPair is allowed only under a granting status (accepted / grantedWithMods)");
436
439
  var children = [b.integer(_reqIdInt(cr.certReqId, "cmp/bad-cert-response", "CertResponse certReqId")), _encodePkiStatusInfo(cr.status, "cmp/bad-cert-response")];
437
- if (hasCkp) children.push(_encodeCertifiedKeyPair(cr.certifiedKeyPair, state));
438
- if (cr.rspInfo != null) children.push(_reqOctets(cr.rspInfo, "CertResponse.rspInfo"));
440
+ if (hasCkp) _push(children,_encodeCertifiedKeyPair(cr.certifiedKeyPair, state));
441
+ if (cr.rspInfo != null) _push(children,_reqOctets(cr.rspInfo, "CertResponse.rspInfo"));
439
442
  return b.sequence(children);
440
443
  }
441
444
 
@@ -445,9 +448,9 @@ function _encodeCertRepMessage(spec, state, arm) {
445
448
  var children = [];
446
449
  if (spec.caPubs != null) {
447
450
  if (!Array.isArray(spec.caPubs) || !spec.caPubs.length) throw _err("cmp/bad-cert-rep", arm + ".caPubs must be a non-empty array of certificate DERs");
448
- children.push(b.explicit(1, b.sequence(spec.caPubs.map(function (c) { return _certRaw(c, "cmp/bad-cert-rep", "a caPubs entry"); }))));
451
+ _push(children,b.explicit(1, b.sequence(spec.caPubs.map(function (c) { return _certRaw(c, "cmp/bad-cert-rep", "a caPubs entry"); }))));
449
452
  }
450
- children.push(b.sequence(spec.response.map(function (cr) { return _encodeCertResponse(cr, state); })));
453
+ _push(children,b.sequence(spec.response.map(function (cr) { return _encodeCertResponse(cr, state); })));
451
454
  return b.sequence(children);
452
455
  }
453
456
 
@@ -467,11 +470,11 @@ function _encodeRevRepContent(spec) {
467
470
  var children = [b.sequence(spec.status.map(function (si) { return _encodePkiStatusInfo(si, "cmp/bad-rev-rep"); }))];
468
471
  if (spec.revCerts != null) {
469
472
  if (!Array.isArray(spec.revCerts) || !spec.revCerts.length) throw _err("cmp/bad-rev-rep", "rp.revCerts must be a non-empty array of CertId");
470
- children.push(b.explicit(0, b.sequence(spec.revCerts.map(_encodeCertIdRr))));
473
+ _push(children,b.explicit(0, b.sequence(spec.revCerts.map(_encodeCertIdRr))));
471
474
  }
472
475
  if (spec.crls != null) {
473
476
  if (!Array.isArray(spec.crls) || !spec.crls.length) throw _err("cmp/bad-rev-rep", "rp.crls must be a non-empty array of CertificateList DERs");
474
- children.push(b.explicit(1, b.sequence(spec.crls.map(function (c) {
477
+ _push(children,b.explicit(1, b.sequence(spec.crls.map(function (c) {
475
478
  var der = _b.reqDerSequence(c, "crls entry (a CertificateList DER)");
476
479
  try { crl.parse(der); }
477
480
  catch (e) { if (e instanceof CmpError) throw e; throw _err("cmp/bad-rev-rep", "a crls entry is not a valid CRL (CertificateList)", e); }
@@ -485,8 +488,8 @@ function _encodeErrorMsgContent(spec) {
485
488
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("cmp/bad-error", "error must be an object { pKIStatusInfo, errorCode?, errorDetails? }");
486
489
  if (spec.pKIStatusInfo == null) throw _err("cmp/bad-error", "error.pKIStatusInfo is required");
487
490
  var children = [_encodePkiStatusInfo(spec.pKIStatusInfo, "cmp/bad-error")];
488
- if (spec.errorCode != null) children.push(b.integer(_reqIdInt(spec.errorCode, "cmp/bad-error", "error.errorCode")));
489
- if (spec.errorDetails != null) children.push(_encodePkiFreeText(spec.errorDetails, "cmp/bad-error", "error.errorDetails"));
491
+ if (spec.errorCode != null) _push(children,b.integer(_reqIdInt(spec.errorCode, "cmp/bad-error", "error.errorCode")));
492
+ if (spec.errorDetails != null) _push(children,_encodePkiFreeText(spec.errorDetails, "cmp/bad-error", "error.errorDetails"));
490
493
  return b.sequence(children);
491
494
  }
492
495
 
@@ -496,7 +499,7 @@ function _encodePollRepContent(list) {
496
499
  if (!pr || typeof pr !== "object" || Buffer.isBuffer(pr)) throw _err("cmp/bad-poll-rep", "each pollRep entry must be an object");
497
500
  if (typeof pr.checkAfter !== "number" || !Number.isInteger(pr.checkAfter) || pr.checkAfter < 0 || pr.checkAfter > 0x7fffffff) throw _err("cmp/bad-poll-rep", "pollRep checkAfter must be a non-negative uint31 delay in seconds (RFC 9810 sec. 5.3.22)");
498
501
  var kids = [b.integer(_reqIdInt(pr.certReqId, "cmp/bad-poll-rep", "pollRep certReqId")), b.integer(BigInt(pr.checkAfter))];
499
- if (pr.reason != null) kids.push(_encodePkiFreeText(pr.reason, "cmp/bad-poll-rep", "pollRep reason"));
502
+ if (pr.reason != null) _push(kids,_encodePkiFreeText(pr.reason, "cmp/bad-poll-rep", "pollRep reason"));
500
503
  return b.sequence(kids);
501
504
  }));
502
505
  }
@@ -505,14 +508,14 @@ function _encodeKeyRecRepContent(spec, state) {
505
508
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("cmp/bad-key-rec-rep", "krp must be an object { status, newSigCert?, caCerts?, keyPairHist? }");
506
509
  if (spec.status == null) throw _err("cmp/bad-key-rec-rep", "krp.status is required");
507
510
  var children = [_encodePkiStatusInfo(spec.status, "cmp/bad-key-rec-rep")];
508
- if (spec.newSigCert != null) children.push(b.explicit(0, _certRaw(spec.newSigCert, "cmp/bad-key-rec-rep", "krp.newSigCert")));
511
+ if (spec.newSigCert != null) _push(children,b.explicit(0, _certRaw(spec.newSigCert, "cmp/bad-key-rec-rep", "krp.newSigCert")));
509
512
  if (spec.caCerts != null) {
510
513
  if (!Array.isArray(spec.caCerts) || !spec.caCerts.length) throw _err("cmp/bad-key-rec-rep", "krp.caCerts must be a non-empty array of certificate DERs");
511
- children.push(b.explicit(1, b.sequence(spec.caCerts.map(function (c) { return _certRaw(c, "cmp/bad-key-rec-rep", "a krp.caCerts entry"); }))));
514
+ _push(children,b.explicit(1, b.sequence(spec.caCerts.map(function (c) { return _certRaw(c, "cmp/bad-key-rec-rep", "a krp.caCerts entry"); }))));
512
515
  }
513
516
  if (spec.keyPairHist != null) {
514
517
  if (!Array.isArray(spec.keyPairHist) || !spec.keyPairHist.length) throw _err("cmp/bad-key-rec-rep", "krp.keyPairHist must be a non-empty array of CertifiedKeyPair");
515
- children.push(b.explicit(2, b.sequence(spec.keyPairHist.map(function (ckp) { return _encodeCertifiedKeyPair(ckp, state); }))));
518
+ _push(children,b.explicit(2, b.sequence(spec.keyPairHist.map(function (ckp) { return _encodeCertifiedKeyPair(ckp, state); }))));
516
519
  }
517
520
  return b.sequence(children);
518
521
  }
@@ -890,7 +893,7 @@ async function _build(message, opts) {
890
893
  var protectionBits = await prot.computeBits(protectedPartDer);
891
894
  var msgChildren = [headerTLV, bodyTLV, b.explicit(0, protectionBits)];
892
895
  var extraCertsDers = _collectExtraCerts(opts, prot.certDer);
893
- if (extraCertsDers.length) msgChildren.push(b.explicit(1, b.sequence(extraCertsDers)));
896
+ if (extraCertsDers.length) _push(msgChildren,b.explicit(1, b.sequence(extraCertsDers)));
894
897
  var der = b.sequence(msgChildren);
895
898
 
896
899
  cmp.parse(der);
@@ -904,14 +907,14 @@ async function _build(message, opts) {
904
907
 
905
908
  function _collectExtraCerts(opts, protCertDer) {
906
909
  var out = [];
907
- if (protCertDer != null) out.push(b.raw(protCertDer));
910
+ if (protCertDer != null) _push(out,b.raw(protCertDer));
908
911
  if (opts.extraCerts != null) {
909
912
  if (!Array.isArray(opts.extraCerts)) throw _err("cmp/bad-extra-certs", "opts.extraCerts must be an array of certificate DERs");
910
913
  opts.extraCerts.forEach(function (c) {
911
914
  var der = _b.reqDerSequence(c, "extraCerts entry (a Certificate DER)");
912
915
  try { x509.parse(der); }
913
916
  catch (e) { if (e instanceof CmpError) throw e; throw _err("cmp/bad-extra-certs", "an extraCerts entry is not a valid X.509 certificate", e); }
914
- out.push(b.raw(der));
917
+ _push(out,b.raw(der));
915
918
  });
916
919
  }
917
920
  return out;
@@ -1012,7 +1015,15 @@ function _tlsForTransfer(opts) {
1012
1015
  return guard.identifier.pickSettings(opts.tls, TLS_SETTINGS);
1013
1016
  }
1014
1017
 
1015
- function _ctypeToken(headers) { return String((headers || {})["content-type"] || "").split(";")[0].trim().toLowerCase(); }
1018
+ /** @internal The media type is read through the captured operations, and on the delimiter CHARACTER
1019
+ * rather than through `split`, which hard rule 11 bans in lib/ because the separator's own
1020
+ * `Symbol.split` is part of that operation. The token decides which parser a response body is
1021
+ * handed to. */
1022
+ function _ctypeToken(headers) {
1023
+ var raw = intrinsic.String((headers || {})["content-type"] || "");
1024
+ var parts = intrinsic.splitChar(raw, 59);
1025
+ return intrinsic.toLowerCase(_strTrim(parts.length ? parts[0] : ""));
1026
+ }
1016
1027
  function _isPkixcmp(headers) { var t = _ctypeToken(headers); return t === PKIXCMP || t === PKIXCMP_POLL; }
1017
1028
 
1018
1029
  /** @internal The sentinel is added at the one exit rather than at each `return`, so a branch added