@blamejs/pki 0.5.7 → 0.5.8

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 (104) hide show
  1. package/CHANGELOG.md +405 -386
  2. package/MIGRATING.md +43 -0
  3. package/README.md +12 -12
  4. package/lib/acme.js +31 -31
  5. package/lib/asn1-der.js +10 -10
  6. package/lib/attrcert-sign.js +19 -19
  7. package/lib/byte-reader.js +6 -6
  8. package/lib/byte-writer.js +5 -5
  9. package/lib/cbor-det.js +27 -24
  10. package/lib/cmc-build.js +97 -92
  11. package/lib/cmc-verify.js +106 -30
  12. package/lib/cmp-build.js +25 -25
  13. package/lib/cmp-session.js +70 -70
  14. package/lib/cmp-verify.js +71 -57
  15. package/lib/cms-compress.js +7 -7
  16. package/lib/cms-decrypt.js +90 -72
  17. package/lib/cms-encrypt.js +32 -32
  18. package/lib/cms-sign.js +74 -55
  19. package/lib/cms-verify.js +97 -75
  20. package/lib/composite-sig.js +13 -13
  21. package/lib/constants.js +4 -4
  22. package/lib/crl-sign.js +22 -22
  23. package/lib/crl-verify.js +7 -6
  24. package/lib/crmf-sign.js +14 -14
  25. package/lib/csr-sign.js +8 -8
  26. package/lib/ct.js +37 -37
  27. package/lib/edwards-point.js +7 -7
  28. package/lib/est.js +98 -55
  29. package/lib/framework-error.js +5 -5
  30. package/lib/guard-all.js +3 -3
  31. package/lib/guard-async.js +4 -4
  32. package/lib/guard-bytes.js +79 -79
  33. package/lib/guard-compress.js +17 -17
  34. package/lib/guard-crypto.js +1 -1
  35. package/lib/guard-encoding.js +15 -15
  36. package/lib/guard-header.js +3 -3
  37. package/lib/guard-identifier.js +16 -16
  38. package/lib/guard-json.js +15 -15
  39. package/lib/guard-limits.js +7 -7
  40. package/lib/guard-name.js +81 -16
  41. package/lib/guard-parsed.js +80 -80
  42. package/lib/guard-range.js +19 -19
  43. package/lib/guard-secret.js +11 -10
  44. package/lib/guard-text.js +6 -6
  45. package/lib/guard-time.js +10 -10
  46. package/lib/hpke.js +18 -17
  47. package/lib/http-digest.js +35 -35
  48. package/lib/http-retry-after.js +13 -13
  49. package/lib/http-transport.js +20 -19
  50. package/lib/inspect.js +53 -53
  51. package/lib/ip-utils.js +2 -2
  52. package/lib/jose.js +13 -13
  53. package/lib/key.js +16 -16
  54. package/lib/lint.js +51 -51
  55. package/lib/merkle.js +51 -36
  56. package/lib/mime.js +18 -18
  57. package/lib/ocsp-verify.js +10 -10
  58. package/lib/ocsp.js +13 -13
  59. package/lib/oid.js +29 -29
  60. package/lib/path-validate.js +114 -113
  61. package/lib/pbes2.js +16 -16
  62. package/lib/pkcs12-build.js +53 -53
  63. package/lib/pki-build.js +21 -19
  64. package/lib/rc2.js +1 -1
  65. package/lib/rfc3339.js +5 -5
  66. package/lib/schema-all.js +31 -31
  67. package/lib/schema-attrcert.js +12 -12
  68. package/lib/schema-c509.js +144 -142
  69. package/lib/schema-cmc.js +58 -58
  70. package/lib/schema-cmp.js +43 -43
  71. package/lib/schema-cms.js +45 -45
  72. package/lib/schema-crl.js +7 -7
  73. package/lib/schema-crmf.js +28 -28
  74. package/lib/schema-csr.js +12 -12
  75. package/lib/schema-csrattrs.js +16 -16
  76. package/lib/schema-engine.js +18 -18
  77. package/lib/schema-ocsp.js +15 -15
  78. package/lib/schema-pkcs12.js +20 -20
  79. package/lib/schema-pkcs8.js +2 -2
  80. package/lib/schema-pkix.js +131 -126
  81. package/lib/schema-smime.js +19 -19
  82. package/lib/schema-tsp.js +12 -12
  83. package/lib/schema-x509.js +3 -3
  84. package/lib/shbs.js +18 -18
  85. package/lib/sign-scheme.js +13 -13
  86. package/lib/sigstore.js +10 -11
  87. package/lib/sleep.js +1 -1
  88. package/lib/smime.js +308 -96
  89. package/lib/tls-cert-compress.js +18 -18
  90. package/lib/trust.js +27 -27
  91. package/lib/tsp-sign.js +17 -17
  92. package/lib/validator-all.js +1 -1
  93. package/lib/validator-attcert.js +1 -1
  94. package/lib/validator-cose.js +43 -44
  95. package/lib/validator-keydesc.js +3 -3
  96. package/lib/validator-sig.js +13 -13
  97. package/lib/validator-tls.js +11 -11
  98. package/lib/validator-tpm.js +20 -19
  99. package/lib/webauthn-mds.js +66 -66
  100. package/lib/webauthn.js +33 -33
  101. package/lib/webcrypto.js +15 -15
  102. package/lib/x509-sign.js +13 -13
  103. package/package.json +3 -2
  104. package/sbom.cdx.json +6 -6
package/lib/cmc-build.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright (c) blamejs contributors
3
3
  "use strict";
4
4
  //
5
- // @internal -- the pki.cmc.build implementation. So the pki.cmc namespace has ONE @module home,
5
+ // @internal -- the pki.cmc.build implementation. So the pki.cmc namespace has one @module home,
6
6
  // the operator-facing @module pki.cmc + the @primitive pki.cmc.build documentation block live in
7
7
  // cmc-verify.js, which re-exports this build function.
8
8
  //
@@ -19,8 +19,8 @@
19
19
  * The witness rule is the load-bearing one. RFC 5272 sec. 6.2.1 step 1 says the
20
20
  * value to be validated is "The PKIData reqSequence field (encoded exactly as it
21
21
  * appears in the Full PKI Request including the sequence type and length)". So
22
- * the reqSequence TLV is built ONCE and both the message and the witness are
23
- * derived from that single buffer -- computing the witness over a second
22
+ * the reqSequence TLV is built once and both the message and the witness are
23
+ * derived from that single buffer; computing the witness over a second
24
24
  * serialization would agree with itself while disagreeing with the wire the
25
25
  * moment any encoding detail differed.
26
26
  */
@@ -46,10 +46,10 @@ var OID_IDENTIFICATION = O("id-cmc-identification");
46
46
  var OID_SHA256 = O("sha256");
47
47
  var OID_HMAC_SHA256 = O("hmacWithSHA256");
48
48
 
49
- // The identity-bearing controls a renewal must NOT carry: RFC 5272 sec. 3.2 (a)
50
- // -- "The Identification and Identity Proof controls are absent."
49
+ // The identity-bearing controls a renewal must not carry: RFC 5272 sec. 3.2 (a),
50
+ // "The Identification and Identity Proof controls are absent."
51
51
  //
52
- // "Identity Proof" is BOTH versions: the original id-cmc-identityProof (sec.
52
+ // "Identity Proof" covers both versions: the original id-cmc-identityProof (sec.
53
53
  // 6.2.2) and identityProofV2 (sec. 6.2.1). Listing only V2 would leave a renewal
54
54
  // able to carry the v1 control, which is the same nonconformance the rule names.
55
55
  var RENEWAL_FORBIDDEN = {};
@@ -57,14 +57,14 @@ RENEWAL_FORBIDDEN[OID_IDENTIFICATION] = "Identification";
57
57
  RENEWAL_FORBIDDEN[O("id-cmc-identityProof")] = "Identity Proof";
58
58
  RENEWAL_FORBIDDEN[OID_IDENTITY_PROOF_V2] = "Identity Proof V2";
59
59
 
60
- // RFC 6402 sec. 2.6: responseBody appears ONLY in a PKIResponse. Enforced at
61
- // BUILD time as well as at parse, so a caller cannot emit a message its own
60
+ // RFC 6402 sec. 2.6: responseBody appears only in a PKIResponse. Enforced at
61
+ // build time as well as at parse, so a caller cannot emit a message its own
62
62
  // decoder would refuse.
63
63
  var OID_RESPONSE_BODY = O("id-cmc-responseBody");
64
64
 
65
65
  // RFC 5272 sec. 6.2.1 says "Implementations MUST be able to support tokens at
66
- // least 16 characters long" -- a requirement on what an implementation must be
67
- // ABLE to accept, not a floor every token has to clear. Reading it as a minimum
66
+ // least 16 characters long", a requirement on what an implementation must be
67
+ // able to accept, not a floor every token has to clear. Reading it as a minimum
68
68
  // inverts it, and would refuse a shorter secret a CA legitimately provisioned.
69
69
  // The shared secret's strength is the deploying CA's policy; what this layer can
70
70
  // say is that an empty string is not a credential at all.
@@ -72,12 +72,12 @@ var OID_RESPONSE_BODY = O("id-cmc-responseBody");
72
72
  var POP_LINK_RANDOM_BYTES = 64;
73
73
 
74
74
  // The spec fields pki.cmc.build understands. Anything else is a caller mistake
75
- // caught at the entry point rather than silently dropped from the message.
75
+ // caught at the entry point, never silently dropped from the message.
76
76
  var KNOWN_SPEC_KEYS = {
77
77
  requests: 1, controls: 1, cmsSequence: 1, otherMsgSequence: 1,
78
- // NOT `identification`: the Identification control is attached through
78
+ // `identification` is deliberately absent: the Identification control is attached through
79
79
  // identityProof.identity, which is what emits it. Listing a key nothing reads
80
- // would recreate the very hole this table closes -- accepted at the door and
80
+ // would recreate the very hole this table closes, accepted at the door and
81
81
  // silently absent from the message.
82
82
  identityProof: 1, popLink: 1, renewal: 1,
83
83
  // The exchange binding (RFC 5272 sec. 6.6 / 6.4). First-class here because
@@ -91,20 +91,20 @@ var OID_TRANSACTION_ID = O("id-cmc-transactionId");
91
91
  var OID_SENDER_NONCE = O("id-cmc-senderNonce");
92
92
  var OID_DATA_RETURN = O("id-cmc-dataReturn");
93
93
 
94
- // AlgorithmIdentifier { OID } with no parameters -- the form the MAC / hash
94
+ // AlgorithmIdentifier { OID } with no parameters: the form the MAC / hash
95
95
  // algorithm identifiers in these two controls take.
96
96
  function algId(o) { return b.sequence([b.oid(o)]); }
97
97
 
98
98
  // ---- body part identity ---------------------------------------------
99
99
 
100
- // RFC 5272 sec. 3.2.2: identifiers are unique across the WHOLE message and 0 is
100
+ // RFC 5272 sec. 3.2.2: identifiers are unique across the whole message and 0 is
101
101
  // reserved for the reference to the current PKIData. The allocator therefore
102
- // starts at 1, and a caller-supplied value is validated rather than adjusted --
102
+ // starts at 1, and a caller-supplied value is validated, never adjusted;
103
103
  // silently renumbering would break any control that already references it.
104
104
  function makeIdAllocator() {
105
105
  var used = Object.create(null);
106
106
  // Reserved ahead of allocation and not yet consumed by the element that owns
107
- // it. Kept distinct from `used` so an element re-claiming its OWN reservation
107
+ // it. Kept distinct from `used` so an element re-claiming its own reservation
108
108
  // is a no-op, while a second element asking for the same value is still the
109
109
  // duplicate the rule forbids.
110
110
  var pending = Object.create(null);
@@ -151,11 +151,11 @@ function makeIdAllocator() {
151
151
 
152
152
  // TaggedRequest ::= CHOICE { tcr [0], crm [1], orm [2] }, IMPLICIT tags. For the
153
153
  // crm arm the identity is the CertReqMsg's own certReqId (sec. 3.2.2), so it is
154
- // read back out of the supplied message rather than allocated -- allocating one
154
+ // read back out of the supplied message and never allocated; allocating one
155
155
  // would put a second, contradictory identifier on the wire.
156
- // The identifier a request FIXES, or null when it leaves the choice to us. Read
156
+ // The identifier a request fixes, or null when it leaves the choice to us. Read
157
157
  // in a pre-pass so every caller-determined value is reserved before a single
158
- // generated one is handed out -- otherwise acceptance depends on the order the
158
+ // generated one is handed out; otherwise acceptance depends on the order the
159
159
  // caller happened to write the list in, which is not a property of the message.
160
160
  // The fields a request descriptor understands -- the same door KNOWN_SPEC_KEYS
161
161
  // closes on the spec, on the objects nested inside it. A misspelled `bodyPartID`
@@ -165,9 +165,9 @@ function makeIdAllocator() {
165
165
  var KNOWN_REQUEST_KEYS = { tcr: 1, crm: 1, orm: 1, bodyPartID: 1 };
166
166
  // The same door on the other descriptors nested in a spec. A control's identifier
167
167
  // is always allocated, so a `bodyPartID` written on one is ignored outright; and a
168
- // misspelled `identity` does not merely go missing -- the Identification control
168
+ // misspelled `identity` does not merely go missing: the Identification control
169
169
  // it would have emitted is what tells the server to derive the Identity Proof key
170
- // from the secret AND the identity, so the message would carry a witness no
170
+ // from the secret and the identity, so the message would carry a witness no
171
171
  // conforming server can reproduce.
172
172
  var KNOWN_CONTROL_KEYS = { type: 1, value: 1 };
173
173
  var KNOWN_IDENTITY_PROOF_KEYS = { identity: 1, secret: 1 };
@@ -185,12 +185,12 @@ function fixedRequestId(req, index) {
185
185
  "each request names exactly one of tcr / crm / orm, got " + (arms.length ? arms.join(" + ") : "none") +
186
186
  " (request " + index + ")");
187
187
  }
188
- // A crm arm's identity is its CertReqMsg's own certReqId, so it is ALWAYS fixed
189
- // -- there is nothing to allocate and nothing that may displace it. A caller who
190
- // ALSO writes bodyPartID is stating an identity, and the only reason to state one
188
+ // A crm arm's identity is its CertReqMsg's own certReqId, so it is always fixed:
189
+ // there is nothing to allocate and nothing that may displace it. A caller who
190
+ // also writes bodyPartID is stating an identity, and the only reason to state one
191
191
  // is that something already references it; taking the certReqId silently would
192
- // sign a message whose control points at no request in it. Equal is accepted --
193
- // the caller is agreeing with the message, not overriding it.
192
+ // sign a message whose control points at no request in it. Equal is accepted,
193
+ // since the caller is agreeing with the message, not overriding it.
194
194
  if (req.crm != null) {
195
195
  var crmId = _certReqIdOf(_asCertReqMsg(_der(req.crm, "a crm CertReqMsg")));
196
196
  if (req.bodyPartID != null && _asBigInt(req.bodyPartID, "a crm request bodyPartID") !== BigInt(crmId)) {
@@ -205,7 +205,7 @@ function fixedRequestId(req, index) {
205
205
 
206
206
  function encodeRequest(req, ids, index) {
207
207
  if (req.tcr != null) {
208
- // A tcr arm IS a PKCS#10 CertificationRequest, so it is parsed rather than
208
+ // A tcr arm is a PKCS#10 CertificationRequest, so it is parsed and never
209
209
  // taken on the tag: the readback of the assembled message checks the CMC
210
210
  // structure around it, and would pass an empty SEQUENCE here as happily as a
211
211
  // real request. Signing a request body that is not one produces an enrolment
@@ -231,12 +231,12 @@ function encodeRequest(req, ids, index) {
231
231
  // CLAIM, not just read. The certReqId was reserved in the pre-pass with every
232
232
  // other caller-determined identifier; leaving the reservation outstanding lets
233
233
  // a later cmsSequence or otherMsg element asking for the same number be taken
234
- // for its owner, and the message would then carry the identifier twice -- a
234
+ // for its owner, and the message would then carry the identifier twice: a
235
235
  // PKIData this toolkit's own parser refuses. The tcr and orm arms already
236
236
  // claim; this arm is the same rule.
237
237
  var certReqId = ids.claim(_certReqIdOf(msg), "a crm request");
238
- // IMPLICIT [1]: the tag REPLACES the CertReqMsg SEQUENCE tag, so the content
239
- // is re-headered rather than nested.
238
+ // IMPLICIT [1]: the tag replaces the CertReqMsg SEQUENCE tag, so the content
239
+ // is re-headered, not nested.
240
240
  var node = asn1.decode(msg);
241
241
  var headerLen = node.header.end - node.header.start;
242
242
  return { bodyPartID: certReqId, der: b.contextConstructed(1, node.bytes.subarray(headerLen)) };
@@ -253,17 +253,17 @@ function encodeRequest(req, ids, index) {
253
253
  };
254
254
  }
255
255
 
256
- // A TaggedRequest's crm arm carries ONE CertReqMsg, but `pki.crmf.build` returns
257
- // a CertReqMessages (SEQUENCE SIZE(1..MAX) OF CertReqMsg) -- which is what a
256
+ // A TaggedRequest's crm arm carries one CertReqMsg, but `pki.crmf.build` returns
257
+ // a CertReqMessages (SEQUENCE SIZE(1..MAX) OF CertReqMsg), which is what a
258
258
  // caller naturally has in hand. Both are accepted, told apart structurally:
259
259
  //
260
260
  // CertReqMsg ::= SEQUENCE { certReq CertRequest, ... } first child is a
261
- // SEQUENCE whose OWN first child is an INTEGER (certReqId)
261
+ // SEQUENCE whose own first child is an INTEGER (certReqId)
262
262
  // CertReqMessages ::= SEQUENCE OF CertReqMsg first child is a
263
263
  // CertReqMsg, whose own first child is a SEQUENCE
264
264
  //
265
- // A CertReqMessages carrying more than one message is REFUSED rather than having
266
- // its first taken: each CertReqMsg is its own TaggedRequest with its own identity,
265
+ // A CertReqMessages carrying more than one message is refused, never reduced to
266
+ // its first: each CertReqMsg is its own TaggedRequest with its own identity,
267
267
  // so silently dropping the rest would emit a request the caller did not ask for.
268
268
  function _asCertReqMsg(der) {
269
269
  var node = asn1.decode(der);
@@ -294,9 +294,9 @@ function _certReqIdOf(msg) {
294
294
  }
295
295
 
296
296
  // A pre-encoded TaggedContentInfo / OtherMsg supplied by the caller. Only its
297
- // leading bodyPartID is read -- the payload is the caller's and stays untouched --
297
+ // leading bodyPartID is read (the payload is the caller's and stays untouched),
298
298
  // so the identifier joins the same allocation space every other element draws
299
- // from and a collision is refused here rather than discovered by the parser.
299
+ // from and a collision is refused here, never discovered later by the parser.
300
300
  function _claimRawElement(el, ids, what) {
301
301
  var der = _der(el, what);
302
302
  var node = asn1.decode(der);
@@ -309,9 +309,9 @@ function _claimRawElement(el, ids, what) {
309
309
  return der;
310
310
  }
311
311
 
312
- // The binding controls have a named spec field AND can be hand-encoded into
312
+ // The binding controls have a named spec field and can also be hand-encoded into
313
313
  // spec.controls. Emitting both would put two of the same control in one message,
314
- // and duplicates of these three are what decide what the response must echo -- two
314
+ // and duplicates of these three are what decide what the response must echo: two
315
315
  // values means no value. Also refuses two hand-encoded copies, since the same
316
316
  // ambiguity arrives that way.
317
317
  var BINDING_BY_OID = {};
@@ -319,9 +319,9 @@ BINDING_BY_OID[O("id-cmc-transactionId")] = "transactionId";
319
319
  BINDING_BY_OID[O("id-cmc-senderNonce")] = "senderNonce";
320
320
  BINDING_BY_OID[O("id-cmc-dataReturn")] = "dataReturn";
321
321
 
322
- // ... and the type each one carries. The CMC parser keeps every control value RAW,
322
+ // ... and the type each one carries. The CMC parser keeps every control value raw,
323
323
  // so nothing downstream of the builder objects to a Transaction Identifier encoded
324
- // as an OCTET STRING -- but these three are read, not carried: pki.cmc.verify
324
+ // as an OCTET STRING. But these three are read, not carried: pki.cmc.verify
325
325
  // compares them against the response, and pki.est.fullcmc reads them back out of
326
326
  // the request before it goes out. A hand-encoded value of the wrong type therefore
327
327
  // signs a request that this toolkit's own client will refuse to send. The type is
@@ -377,9 +377,9 @@ function _oidOf(v) {
377
377
 
378
378
  // TaggedAttribute ::= SEQUENCE { bodyPartID, attrType, attrValues SET OF ANY }.
379
379
  // Controls this builder will not put in a Full PKI Request. A row per control with
380
- // the reason it does not belong in this direction -- id-cmc-responseBody by an
380
+ // the reason it does not belong in this direction: id-cmc-responseBody by an
381
381
  // explicit RFC 6402 sec. 2.6 MUST NOT, the two status controls because RFC 5272
382
- // sec. 6.1 makes them what a SERVER emits and a client processes in a PKI Response:
382
+ // sec. 6.1 makes them what a server emits and a client processes in a PKI Response.
383
383
  // a request has no verdict of its own to report, so one written here is a fabricated
384
384
  // answer to a question nobody asked.
385
385
  //
@@ -408,6 +408,11 @@ function encodeControl(attrType, values, ids) {
408
408
  // ---- the witnesses ---------------------------------------------------
409
409
 
410
410
  function _assertSecret(secret, what) {
411
+ // An entry-tier argument check: this tests the TYPE and whether the string is empty, and
412
+ // compares no secret-dependent content. The length of a caller's own argument is already
413
+ // known to that caller, so there is no secret for a timing-safe compare to protect. The
414
+ // MAC comparisons this rule exists for route through guard.crypto.constantTimeEqual.
415
+ // nosemgrep: pki-non-constant-time-secret-compare
411
416
  if (typeof secret !== "string" || secret.length === 0) {
412
417
  throw E("cmc/bad-input",
413
418
  what + " requires the shared secret as a non-empty string; got " +
@@ -417,10 +422,10 @@ function _assertSecret(secret, what) {
417
422
 
418
423
  // IdentifyProofV2 ::= SEQUENCE { hashAlgID, macAlgID, witness OCTET STRING }.
419
424
  // key = hash(shared-secret as a UTF8 string); witness = MAC(reqSequenceBytes, key).
420
- // `reqSequenceBytes` is the buffer that will BE the message's reqSequence -- not
425
+ // `reqSequenceBytes` is the buffer that becomes the message's reqSequence, never
421
426
  // a re-encode of it (RFC 5272 sec. 6.2.1 step 1).
422
427
  // Tracks a buffer this module allocated that carries secret material, so the caller clears it
423
- // on every exit. The shared secret ARRIVES as a JS string, which is immutable and cannot be
428
+ // on every exit. The shared secret arrives as a JS string, which is immutable and cannot be
424
429
  // cleared; what this closes is every copy the toolkit itself makes of it.
425
430
  function _ownSecret(buf, owned) {
426
431
  owned.push(buf);
@@ -430,17 +435,17 @@ function _ownSecret(buf, owned) {
430
435
  function identityProofV2(secret, reqSequenceBytes, identity) {
431
436
  _assertSecret(secret, "an Identity Proof V2 control");
432
437
  // RFC 5272 sec. 6.2.3: the Identification control is OPTIONAL ("servers MAY
433
- // require" it), but when it IS present the key derivation is ALTERED -- "the
438
+ // require" it), but when it is present the key derivation changes: "the
434
439
  // hash of the concatenation of the shared-secret and the UTF8 identity value
435
440
  // (without the type and length bytes) are hashed rather than just the
436
441
  // shared-secret". Same controls on the wire, different key: a producer that
437
442
  // emits the Identification control while hashing the secret alone computes a
438
443
  // witness every conforming server rejects.
439
- // EVERY allocation that carries the shared secret is cleared, not only the derived key.
444
+ // Every allocation that carries the shared secret is cleared, not only the derived key.
440
445
  // The derivation input holds the secret in the clear, and with an identity present the
441
- // concatenation leaves two more copies of it behind -- the operand and the joined buffer.
446
+ // concatenation leaves two more copies of it behind: the operand and the joined buffer.
442
447
  // Wiping the key while those survive clears the cheapest copy and keeps the rest. The
443
- // derivation runs INSIDE the try so a throw partway still reaches the clear.
448
+ // derivation runs inside the try so a throw partway still reaches the clear.
444
449
  var owned = [];
445
450
  var key = null;
446
451
  try {
@@ -480,7 +485,7 @@ function popLinkWitnessV2(secret, R) {
480
485
  // The operator-facing @primitive block for this function lives beside its
481
486
  // re-export in cmc-verify.js, the pki.cmc @module home.
482
487
  function build(spec, signer, opts) {
483
- // Every caller-owned argument copied at entry and released when the call settles -- see the note
488
+ // Every caller-owned argument copied at entry and released when the call settles; see the note
484
489
  // on the same call in x509-sign. It matters most here: the Identity Proof and POP Link witnesses
485
490
  // are computed over the bytes this builder is about to emit, so a spec that changed in between
486
491
  // would witness a different request than the one that goes out.
@@ -495,9 +500,9 @@ function _build(spec, signer, opts) {
495
500
  throw E("cmc/bad-input", "the CMC request spec must be an object");
496
501
  }
497
502
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw E("cmc/bad-input", "pki.cmc.build options must be an object");
498
- // A misspelled or unsupported spec field fails OPEN in the quietest way there is:
503
+ // A misspelled or unsupported spec field fails open in the quietest way there is:
499
504
  // the message builds, is signed, and simply does not carry what was asked for.
500
- // That is worst for the exchange-binding fields below -- a request built without
505
+ // That is worst for the exchange-binding fields below: a request built without
501
506
  // them has no replay defence, and pki.cmc.verify cannot enforce a binding the
502
507
  // client never sent, so the omission is invisible from both ends.
503
508
  guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, E, "cmc/bad-input", "unknown spec field ");
@@ -508,16 +513,16 @@ function _build(spec, signer, opts) {
508
513
 
509
514
  var ids = makeIdAllocator();
510
515
 
511
- // EVERY identifier the CALLER determines is reserved before a single generated
516
+ // Every identifier the caller determines is reserved before a single generated
512
517
  // one is handed out. There are four sources, and reserving only some of them
513
- // makes acceptance depend on the order the caller wrote things in rather than
514
- // on the message:
518
+ // makes acceptance depend on the order the caller wrote things in, not on
519
+ // the message:
515
520
  // 1. a request's explicit bodyPartID
516
521
  // 2. a crm arm's certReqId, which is fixed by the CertReqMsg itself
517
522
  // 3. a cmsSequence element's bodyPartID
518
523
  // 4. an otherMsgSequence element's bodyPartID
519
524
  // Auto-allocation walks upward from 1, so anything minted before these were
520
- // claimed could take a value the caller already spent -- and the caller's own
525
+ // claimed could take a value the caller already spent, and the caller's own
521
526
  // element would then be rejected as a duplicate of whatever displaced it.
522
527
  requests.forEach(function (r, i) {
523
528
  var fixed = fixedRequestId(r, i);
@@ -554,7 +559,7 @@ function _build(spec, signer, opts) {
554
559
  // A renewal is authenticated by the certificate being renewed: sec. 6.3.3 says
555
560
  // "the outermost signature layer is created using the current signing
556
561
  // certificate, which allows the original identity to be associated with the
557
- // certification request". That identity is the whole mechanism -- it is what
562
+ // certification request". That identity is the whole mechanism: it is what
558
563
  // replaces the Identity Proof this mode just refused. A key-only signer has no
559
564
  // certificate and so carries no prior identity, leaving a message with nothing
560
565
  // for the CA to authenticate the renewal against.
@@ -583,13 +588,13 @@ function _build(spec, signer, opts) {
583
588
 
584
589
  // The exchange binding (RFC 5272 sec. 6.6 Transaction Identifier / Sender Nonce,
585
590
  // sec. 6.4 Data Return). These are what pki.cmc.verify checks the response
586
- // against, and a request that omits them has no replay defence -- so they are
587
- // named fields here rather than something the caller hand-encodes into
591
+ // against, and a request that omits them has no replay defence, so they are
592
+ // named fields here and not something the caller hand-encodes into
588
593
  // spec.controls and can silently get wrong.
589
594
  // A named field and a hand-encoded control of the same type would emit the
590
- // control TWICE, and a message carrying two of them has no single value the
591
- // response can be bound to -- this toolkit's own /fullcmc refuses exactly that.
592
- // Refuse it at the source rather than sign something no one can bind to.
595
+ // control twice, and a message carrying two of them has no single value the
596
+ // response can be bound to; this toolkit's own /fullcmc refuses exactly that.
597
+ // Refuse it at the source, before signing something no one can bind to.
593
598
  _assertNoDuplicateBinding(callerControls, spec);
594
599
  if (spec.transactionId != null) {
595
600
  controls.push(encodeControl(OID_TRANSACTION_ID,
@@ -612,7 +617,7 @@ function _build(spec, signer, opts) {
612
617
  throw E("cmc/bad-input", "identityProof.identity is the UTF8String the Identification control carries");
613
618
  }
614
619
  // The pair is emitted together when an identity is given, because the two are
615
- // coupled: the Identification control tells the server WHICH shared secret to
620
+ // coupled: the Identification control tells the server which shared secret to
616
621
  // look up, and its presence is what changes how the key is derived. Letting a
617
622
  // caller supply one without the other would put that coupling out of reach.
618
623
  if (identity != null) controls.push(encodeControl(OID_IDENTIFICATION, [b.utf8(identity)], ids));
@@ -637,8 +642,8 @@ function _build(spec, signer, opts) {
637
642
  }
638
643
 
639
644
  // PKIData ::= SEQUENCE { controlSequence, reqSequence, cmsSequence,
640
- // otherMsgSequence } -- all four emitted, the unused ones empty (sec. 3.2.1).
641
- // reqSequenceBytes is spliced in as the SAME buffer the witness was computed
645
+ // otherMsgSequence }: all four emitted, the unused ones empty (sec. 3.2.1).
646
+ // reqSequenceBytes is spliced in as the same buffer the witness was computed
642
647
  // over, which is the whole of IP1.
643
648
  var pkiData = b.sequence([
644
649
  b.sequence(controls),
@@ -648,13 +653,13 @@ function _build(spec, signer, opts) {
648
653
  ]);
649
654
 
650
655
  // Read the assembled message back through the shipped parser before signing it.
651
- // Every arm here splices CALLER-supplied DER -- a tcr's CertificationRequest, a
652
- // cmsSequence TaggedContentInfo, an otherMsg's value -- and checking each shape
656
+ // Every arm here splices caller-supplied DER (a tcr's CertificationRequest, a
657
+ // cmsSequence TaggedContentInfo, an otherMsg's value), and checking each shape
653
658
  // by hand would restate the parser's rules in a second place, where they would
654
659
  // drift and where a newly added arm would silently miss them. One round-trip
655
660
  // covers them all, including arms not yet written: whatever the parser refuses,
656
- // this refuses at build time rather than emitting a message whose recipient --
657
- // this toolkit's own decoder included -- cannot read it.
661
+ // this refuses at build time, so no message goes out whose recipient (this
662
+ // toolkit's own decoder included) cannot read it.
658
663
  try {
659
664
  cmcFmt.parsePkiData(pkiData);
660
665
  } catch (e) {
@@ -668,13 +673,13 @@ function _build(spec, signer, opts) {
668
673
  // The signer is copied for the same reason the message was assembled at the
669
674
  // call: cms.sign reads `key` inside its own promise chain, so a caller who
670
675
  // swaps signer.key on the next line would have the request signed by the
671
- // replacement while the original certificate stays embedded -- a message whose
676
+ // replacement while the original certificate stays embedded: a message whose
672
677
  // signature does not belong to the certificate beside it.
673
678
  //
674
679
  // cms.sign resolves eContentType through oid.byName, so it takes the registry
675
- // NAME; handing it the dotted value resolves to undefined.
676
- // Copying a private key makes a SECOND copy of a secret, so it is cleared once signing has
677
- // settled rather than left for the collector -- the same discipline the MAC keys above follow.
680
+ // name; handing it the dotted value resolves to undefined.
681
+ // Copying a private key makes a second copy of a secret, so it is cleared once signing has
682
+ // settled and never left for the collector, the same discipline the MAC keys above follow.
678
683
  // The clear covers the rejecting path too: a wrong or malformed key is the case a caller can
679
684
  // reach, and a success-only wipe would keep the secret exactly when it matters.
680
685
  var ownedKeyBytes = [];
@@ -694,12 +699,12 @@ function _build(spec, signer, opts) {
694
699
  // Each signer descriptor, and every byte value in it. cms.sign reads these inside
695
700
  // its own promise chain, so both levels matter: re-pointing signer.key is one way
696
701
  // to change who signs, and rewriting the PKCS#8 buffer it already points at is
697
- // the other. A CryptoKey handle is passed through as-is -- it is an opaque
702
+ // the other. A CryptoKey handle is passed through as-is: it is an opaque
698
703
  // reference the caller is meant to share, and there is nothing to copy.
699
- // `owned` collects the buffers THIS function allocated that hold PRIVATE KEY material, so the
704
+ // `owned` collects the buffers this function allocated that hold private key material, so the
700
705
  // caller can clear them once signing has settled. Only the key is listed: the other copied
701
706
  // values are certificates and identifiers, which are public and outlive the call by design.
702
- // The caller's own key is never written to -- only our copy of it.
707
+ // The caller's own key is never written to; only our copy of it is.
703
708
  function _copySigners(signer, owned) {
704
709
  function one(s) {
705
710
  if (!s || typeof s !== "object") return s;
@@ -710,9 +715,9 @@ function _copySigners(signer, owned) {
710
715
  }
711
716
  return out;
712
717
  }
713
- // One level further for a COMPOSITE key, which is an object of component keys
714
- // ({ mldsa, trad }) rather than a buffer. Copying only the top level would leave
715
- // those components -- the actual PKCS#8 bytes that sign -- the caller's to
718
+ // One level further for a composite key, which is an object of component keys
719
+ // ({ mldsa, trad }) and not a buffer. Copying only the top level would leave
720
+ // those components, the actual PKCS#8 bytes that sign, the caller's to
716
721
  // replace or zeroize while cms.sign reads them in a later turn. A CryptoKey is
717
722
  // an opaque handle and is passed through as-is.
718
723
  function copyValue(v, isSecret) {
@@ -737,7 +742,7 @@ function _copySigners(signer, owned) {
737
742
 
738
743
  /**
739
744
  * RFC 5272 sec. 3.2, the three rules that apply when the signature is made with
740
- * the private key of a certification request the message carries rather than with
745
+ * the private key of a certification request the message carries, and not with
741
746
  * an already-certified key:
742
747
  *
743
748
  * a. that request MUST include a Subject Key Identifier extension;
@@ -748,15 +753,15 @@ function _copySigners(signer, owned) {
748
753
  * signer. (a) and (c) are about agreement between the signer and the requests
749
754
  * beside it, which is checked here: an identifier the requests never declare
750
755
  * leaves the CA unable to tie the signature to the key being enrolled, so the
751
- * request is signed but unusable -- and it is the producer's job to catch that,
756
+ * request is signed but unusable, and it is the producer's job to catch that,
752
757
  * not the CA's to guess.
753
758
  *
754
- * This lives HERE rather than in pki.cms.sign because it is a CMC rule: only this
759
+ * This lives here, not in pki.cms.sign, because it is a CMC rule: only this
755
760
  * layer knows the content is a PKIData and which requests are in it. Teaching the
756
761
  * generic CMS signer to parse CMC content would put the protocol's rules in the
757
762
  * wrong module.
758
763
  *
759
- * A signer WITH a certificate is untouched -- it identifies itself by that
764
+ * A signer that carries a certificate is untouched: it identifies itself by that
760
765
  * certificate, and the clause does not reach it.
761
766
  */
762
767
  function _assertKeyOnlySigner(signer, requests) {
@@ -775,7 +780,7 @@ function _assertKeyOnlySigner(signer, requests) {
775
780
  keyOnly.forEach(function (so) { _assertKeyOnlySignerBinding(so, requests); });
776
781
  }
777
782
 
778
- // The sec. 3.2a/3.2c binding for ONE key-only signer.
783
+ // The sec. 3.2a/3.2c binding for a single key-only signer.
779
784
  function _assertKeyOnlySignerBinding(so, requests) {
780
785
  var id = so.keyIdentifier;
781
786
  var idBytes = (Buffer.isBuffer(id) || id instanceof Uint8Array) ? Buffer.from(id) : null;
@@ -790,7 +795,7 @@ function _assertKeyOnlySignerBinding(so, requests) {
790
795
  var declaredSki = false, sawRequest = false;
791
796
  for (var i = 0; i < requests.length; i++) {
792
797
  var req = requests[i];
793
- // BOTH key-bearing arms: sec. 3.2 says the signing key may belong to a request
798
+ // Both key-bearing arms: sec. 3.2 says the signing key may belong to a request
794
799
  // "included in the TaggedRequest tcr or crm fields", so reading only PKCS#10
795
800
  // would reject every conforming CRMF enrolment of a brand-new key.
796
801
  var declaredBy;
@@ -801,11 +806,11 @@ function _assertKeyOnlySignerBinding(so, requests) {
801
806
  if (req && (req.tcr != null || req.crm != null)) sawRequest = true;
802
807
  if (!declaredBy || !declaredBy.ski) continue;
803
808
  declaredSki = true;
804
- // The identifier AND the key. Matching the identifier alone would accept a
805
- // signer holding key A while the request it points at asks to certify key B --
809
+ // The identifier and the key together. Matching the identifier alone would accept a
810
+ // signer holding key A while the request it points at asks to certify key B:
806
811
  // the SKI is caller-chosen, so the two can be made to agree while the keys do
807
812
  // not, and a CA resolving the SID to the requested key could then not verify
808
- // the carrier at all. The identifier says WHICH request; the key is what makes
813
+ // the carrier at all. The identifier says which request; the key is what makes
809
814
  // the claim true. The comparison runs through the toolkit's shared byte
810
815
  // equality; neither value here is secret, but there is one way to compare.
811
816
  if (guard.crypto.constantTimeEqual(declaredBy.ski, idBytes) &&
@@ -828,14 +833,14 @@ function _assertKeyOnlySignerBinding(so, requests) {
828
833
  "to be the one asking for this very public key (RFC 5272 sec. 3.2)");
829
834
  }
830
835
 
831
- // { ski, spki } for a CRMF certification request -- the identifier it declares and
836
+ // { ski, spki } for a CRMF certification request: the identifier it declares and
832
837
  // the key it asks to have certified. The CertTemplate carries extensions directly,
833
838
  // so there is no attribute wrapper to unwrap; the extnValue is the same DER
834
839
  // SubjectKeyIdentifier OCTET STRING.
835
840
  function _crmKeyIdentity(crmDer) {
836
841
  var msg = _asCertReqMsg(_der(crmDer, "a crm CertReqMsg"));
837
842
  // pki.schema.crmf reads CertReqMessages (SEQUENCE OF CertReqMsg); one message is
838
- // wrapped rather than decoded here, so the CRMF rules stay in the CRMF parser.
843
+ // wrapped here and decoded there, so the CRMF rules stay in the CRMF parser.
839
844
  var msgs = crmf.parse(b.sequence([msg])).messages;
840
845
  var tmpl = msgs && msgs[0] && msgs[0].certReq && msgs[0].certReq.certTemplate;
841
846
  var found = null;
@@ -844,7 +849,7 @@ function _crmKeyIdentity(crmDer) {
844
849
  found = asn1.read.octetString(asn1.decode(e.value));
845
850
  });
846
851
  // RFC 4211 sec. 4.1: the requested key may live in the signature POP's
847
- // POPOSigningKeyInput rather than the CertTemplate, and the CRMF parser surfaces
852
+ // POPOSigningKeyInput instead of the CertTemplate, and the CRMF parser surfaces
848
853
  // it there. Reading only the template would refuse a key-only signer whose
849
854
  // request is perfectly conforming.
850
855
  var msg0 = msgs && msgs[0];