@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/schema-cms.js CHANGED
@@ -12,13 +12,13 @@
12
12
  * CMS handling per RFC 5652 (sec. 3 ContentInfo envelope). `parse` turns a DER or PEM
13
13
  * (`CMS`) message into a structured object and is an OID-dispatch envelope --
14
14
  * ContentInfo reads its `contentType` and structurally decodes SignedData (sec. 5),
15
- * EnvelopedData (sec. 6, with all five RecipientInfo kinds -- key-transport,
15
+ * EnvelopedData (sec. 6, with all five RecipientInfo kinds: key-transport,
16
16
  * key-agreement per RFC 5753, KEK, password, and other, including the RFC 9629
17
17
  * KEMRecipientInfo carried under `id-ori-kem` with ML-KEM per RFC 9936),
18
18
  * EncryptedData (sec. 8), AuthenticatedData (sec. 9), and AuthEnvelopedData (RFC 5083,
19
19
  * with RFC 5084 AES-GCM/CCM parameter validation); the remaining PKCS#7 content
20
20
  * types are recognized and rejected with a precise `cms/unsupported-content-type`
21
- * rather than a generic unknown-format error. A SignedData surfaces its version,
21
+ * in place of a generic unknown-format error. A SignedData surfaces its version,
22
22
  * digest algorithms, encapsulated content, certificate / CRL sets, and signer
23
23
  * infos; an EnvelopedData its recipient infos and encrypted content info; an
24
24
  * EncryptedData its encrypted content info; an AuthenticatedData its MAC
@@ -27,11 +27,11 @@
27
27
  * content, validated AEAD parameters, and raw `mac`.
28
28
  *
29
29
  * CMS is a signed container: the bytes an external verifier must hash are
30
- * surfaced RAW and never re-serialized. `encapContentInfo.eContent` is the raw
30
+ * surfaced raw and never re-serialized. `encapContentInfo.eContent` is the raw
31
31
  * content (or `null` for a detached signature); each SignerInfo's `signature` is
32
32
  * raw, and `signedAttrsBytes` is the on-wire `[0]` SignedAttributes TLV so a
33
33
  * verifier can re-tag it to the universal SET the signature is computed over
34
- * (sec. 5.4) -- `authAttrsBytes` plays the same role for the sec. 9.2 MAC input and the
34
+ * (sec. 5.4); `authAttrsBytes` plays the same role for the sec. 9.2 MAC input and the
35
35
  * RFC 5083 sec. 2.2 AAD. Embedded certificates and CRLs are surfaced as raw DER +
36
36
  * their outer tag, validated against the closed CertificateChoices /
37
37
  * RevocationInfoChoice tag sets, so an obsolete alternative never fails the
@@ -63,7 +63,7 @@ var ALGORITHM_IDENTIFIER = pkix.algorithmIdentifier(NS);
63
63
  var ATTRIBUTE = pkix.attribute(NS);
64
64
  var NAME = pkix.name(NS);
65
65
 
66
- // CMSVersion ::= INTEGER -- the SignedData version is {1,3,4,5} and the SignerInfo
66
+ // CMSVersion ::= INTEGER, where the SignedData version is {1,3,4,5} and the SignerInfo
67
67
  // version is {1,3} (RFC 5652 sec. 5.1, sec. 5.3). Wider accept maps than any other format.
68
68
  var SIGNED_DATA_VERSION = pkix.versionReader(NS, { "1": 1, "3": 3, "4": 4, "5": 5 });
69
69
  var SIGNER_VERSION = pkix.versionReader(NS, { "1": 1, "3": 3 });
@@ -188,7 +188,7 @@ function _checkContentBindingAttrs(attrs, mode) {
188
188
  // content-type attribute (what it signs has no content type).
189
189
  if (mode === "countersig") throw NS.E("cms/misplaced-attr", "a countersignature's signedAttrs must not carry a content-type attribute (RFC 5652 sec. 11.4)");
190
190
  if (a.values.length !== 1) throw NS.E("cms/bad-content-type-attr", "the content-type attribute must be single-valued");
191
- // ContentType ::= OBJECT IDENTIFIER (RFC 5652 sec. 11.1) -- validate the value's
191
+ // ContentType ::= OBJECT IDENTIFIER (RFC 5652 sec. 11.1): validate the value's
192
192
  // full syntax (tag AND minimal base-128 OID content), not just the tag, so a
193
193
  // truncated / non-minimal subidentifier is rejected here, not at verify time.
194
194
  try { asn1.read.oid(asn1.decode(a.values[0])); }
@@ -196,7 +196,7 @@ function _checkContentBindingAttrs(attrs, mode) {
196
196
  } else if (a.type === OID_MESSAGE_DIGEST) {
197
197
  md += 1;
198
198
  if (a.values.length !== 1) throw NS.E("cms/bad-message-digest-attr", "the message-digest attribute must be single-valued");
199
- // MessageDigest ::= OCTET STRING (RFC 5652 sec. 11.2) -- validate the full syntax.
199
+ // MessageDigest ::= OCTET STRING (RFC 5652 sec. 11.2): validate the full syntax.
200
200
  try { asn1.read.octetString(asn1.decode(a.values[0])); }
201
201
  catch (e) { throw NS.E("cms/bad-message-digest-attr", "the message-digest attribute value must be an OCTET STRING", e); }
202
202
  } else if (a.type === OID_SIGNING_TIME) {
@@ -214,7 +214,7 @@ function _checkContentBindingAttrs(attrs, mode) {
214
214
 
215
215
  // looksLikeSignedAttributes(bytes) -> boolean.
216
216
  //
217
- // Does `bytes` parse as a DER SignedAttributes block -- a SET OF Attribute carrying BOTH the
217
+ // Does `bytes` parse as a DER SignedAttributes block, a SET OF Attribute carrying both the
218
218
  // content-type and message-digest attributes RFC 5652 sec. 5.3 makes mandatory whenever signed
219
219
  // attributes are present?
220
220
  //
@@ -224,20 +224,20 @@ function _checkContentBindingAttrs(attrs, mode) {
224
224
  // re-presented as one made over content: drop the signedAttrs field and set the encapsulated
225
225
  // content to the DER of those same attributes. Sec. 5.4 then says the signature is over the content
226
226
  // itself, which is exactly what it covers, and with no attributes there is no message-digest or
227
- // content-type attribute left to disagree. The proposed standards fixes are protocol changes -- a
228
- // context string naming which mode was signed -- that no verifier can apply on its own.
227
+ // content-type attribute left to disagree. The proposed standards fixes are protocol changes (a
228
+ // context string naming which mode was signed) that no verifier can apply on its own.
229
229
  //
230
230
  // What a verifier CAN do is refuse the shape. Every message produced by the attack has, as its
231
231
  // content, the encoded SignedAttributes of a real message, and sec. 5.3 requires those to carry
232
232
  // both attributes named above. That makes their presence a NECESSARY condition of the attack rather
233
233
  // than a guess, and the shape is one ordinary content does not have: a certificate, a JSON payload,
234
234
  // arbitrary bytes, and even a SET OF other attributes all fail it. The cost is a message whose
235
- // legitimate content really is an encoded SignedAttributes block signed WITHOUT attributes, which
235
+ // legitimate content really is an encoded SignedAttributes block signed without attributes, which
236
236
  // is refused as genuinely ambiguous -- sign it with attributes and it is unambiguous again.
237
237
  //
238
238
  // One mandatory attribute value, held to all three conditions a real SignedAttributes meets:
239
239
  // exactly one value (RFC 5652 sec. 11.1 / sec. 11.2 make both single-valued), the right tag, and a
240
- // body that actually READS as that type. All three together, for each attribute -- checking the
240
+ // body that actually reads as that type. All three together, for each attribute; checking the
241
241
  // cardinality and the tag while letting an undecodable body through would refuse content the real
242
242
  // SignedAttributes parser could never have produced, which is the false positive this whole
243
243
  // detector is shaped to avoid.
@@ -280,10 +280,10 @@ function looksLikeSignedAttributes(bytes) {
280
280
  if (!schema.isUniversal(node, asn1.TAGS.SET) || !node.constructed) return false;
281
281
  var kids = node.children || [];
282
282
  if (!kids.length) return false;
283
- // Every rule _checkContentBindingAttrs applies to a REAL SignedAttributes is applied here, and
283
+ // Every rule _checkContentBindingAttrs applies to a real SignedAttributes is applied here, and
284
284
  // for one reason: the detector must match only what a conforming block can be. A set the real
285
285
  // parser would have rejected cannot be the preimage of any signature, so matching it would refuse
286
- // content no attack could have produced. Enumerated against that function rather than discovered
286
+ // content no attack could have produced. Enumerated against that function, never discovered
287
287
  // one rule at a time -- no duplicate attribute types (sec. 5.3), content-type single-valued and a
288
288
  // readable OID (sec. 11.1), message-digest single-valued and a readable OCTET STRING (sec. 11.2),
289
289
  // signing-time when present single-valued and a readable Time (sec. 11.3).
@@ -317,7 +317,7 @@ function looksLikeSignedAttributes(bytes) {
317
317
  // deliberately not applied: this decoder caps values per attribute as a resource limit of its
318
318
  // own, and a limit this implementation chose is not a fact about what a signature can cover.
319
319
  // An external signer may sign a conforming set larger than that cap, and the stripped message
320
- // presents those bytes as opaque content where the cap never applies -- refusing to recognize
320
+ // presents those bytes as opaque content where the cap never applies, so refusing to recognize
321
321
  // it because of a local limit would miss exactly the preimage the attack reuses.
322
322
  var n = (vs.children || []).length;
323
323
  if (n < 1) return false;
@@ -325,7 +325,7 @@ function looksLikeSignedAttributes(bytes) {
325
325
  // The two mandatory attributes are checked down to their VALUES, not just their type OIDs.
326
326
  // RFC 5652 sec. 11.1 makes content-type a single OBJECT IDENTIFIER and sec. 11.2 makes
327
327
  // message-digest a single OCTET STRING, so a set carrying those OIDs over an empty or
328
- // wrongly-typed value CANNOT be the preimage of a real signature -- and refusing it would be a
328
+ // wrongly-typed value cannot be the preimage of a real signature, and refusing it would be a
329
329
  // false positive on content that merely resembles the shape. The detector has to stay a
330
330
  // necessary condition of the attack; anything broader costs a legitimate caller.
331
331
  var vals = vs.children || [];
@@ -344,17 +344,17 @@ function looksLikeSignedAttributes(bytes) {
344
344
  return sawContentType && sawMessageDigest;
345
345
  }
346
346
 
347
- // RFC 5652 sec. 5.3 / sec. 9.3 -- when a content-type attribute is present, it MUST
347
+ // RFC 5652 sec. 5.3 / sec. 9.3: when a content-type attribute is present, it MUST
348
348
  // be single-valued (sec. 11.1) and its value MUST equal the eContentType (a
349
349
  // cross-field consistency both parsed here). Shared by SignedData signedAttrs,
350
- // AuthenticatedData authAttrs, and AuthEnvelopedData authAttrs -- the single-value
350
+ // AuthenticatedData authAttrs, and AuthEnvelopedData authAttrs, where the single-value
351
351
  // rule holds even where content-type is not REQUIRED (RFC 5083), so an
352
352
  // expected-first-value-plus-extra set can never surface as ambiguous.
353
353
  function _assertContentTypeMatchesAttrs(attrs, eContentType) {
354
354
  for (var i = 0; i < attrs.length; i++) {
355
355
  if (attrs[i].type !== OID_CONTENT_TYPE) continue;
356
356
  if (attrs[i].values.length !== 1) throw NS.E("cms/bad-content-type-attr", "the content-type attribute must be single-valued (RFC 5652 sec. 11.1)");
357
- // ContentType ::= OBJECT IDENTIFIER -- validate the value's full syntax (tag AND
357
+ // ContentType ::= OBJECT IDENTIFIER: validate the value's full syntax (tag and
358
358
  // minimal base-128 OID content) with the CMS typed verdict, so a malformed value
359
359
  // on a path that does not run _checkContentBindingAttrs (AuthEnvelopedData,
360
360
  // RFC 5083 sec. 2.1) surfaces cms/bad-content-type-attr, not the raw asn1/* error.
@@ -366,8 +366,8 @@ function _assertContentTypeMatchesAttrs(attrs, eContentType) {
366
366
  }
367
367
 
368
368
  // RFC 5652 sec. 5.3 -- an attribute set MUST NOT include multiple instances of the
369
- // same attribute type. AuthEnvelopedData authAttrs (RFC 5083 sec. 2.1) gets ONLY this
370
- // duplicate check -- NOT the content-type/message-digest presence rules (RFC 5652
369
+ // same attribute type. AuthEnvelopedData authAttrs (RFC 5083 sec. 2.1) gets only this
370
+ // duplicate check, and not the content-type/message-digest presence rules (RFC 5652
371
371
  // sec. 11.1/sec. 11.2 bind only signed-data and authenticated-data), so it must not reuse
372
372
  // _checkContentBindingAttrs, which would over-enforce.
373
373
  function _checkNoDuplicateAttrs(attrs) {
@@ -418,7 +418,7 @@ function _validateAeadParams(alg, macLen) {
418
418
  }
419
419
  var legal = kind === "gcm" ? AEAD_GCM_ICVLENS : AEAD_CCM_ICVLENS;
420
420
  if (!legal.has(icvLen)) throw NS.E("cms/bad-aead-params", "the AES-" + K + " aes-ICVlen " + icvLen + " is not an allowed value (RFC 5084)");
421
- // X.690 sec. 11.5: a DEFAULT value MUST be omitted in DER -- an encoded ICVlen equal
421
+ // X.690 sec. 11.5: a DEFAULT value MUST be omitted in DER, so an encoded ICVlen equal
422
422
  // to the default 12 is non-canonical.
423
423
  if (icvEncoded && icvLen === 12) throw NS.E("cms/non-canonical-default", "the AEAD aes-ICVlen equal to the DEFAULT 12 MUST be omitted (X.690 sec. 11.5)");
424
424
  // RFC 5084 sec. 3.1/sec. 3.2: aes-ICVlen MUST match the AuthEnvelopedData mac length.
@@ -426,7 +426,7 @@ function _validateAeadParams(alg, macLen) {
426
426
  return { kind: kind, nonce: nonce, icvLen: icvLen };
427
427
  }
428
428
 
429
- // RFC 5652 sec. 5.3 / sec. 9.1 + RFC 5083 sec. 2.1 -- a signed / authenticated attribute SET
429
+ // RFC 5652 sec. 5.3 / sec. 9.1 + RFC 5083 sec. 2.1: a signed / authenticated attribute SET
430
430
  // MUST be DER encoded even when the enclosing structure was decoded as BER (its
431
431
  // bytes feed the sec. 5.4 / sec. 9.2 re-tagged hash / MAC input, so a non-DER TLV makes
432
432
  // the surfaced raw bytes unusable for verification). Strictly re-decoding the
@@ -437,8 +437,8 @@ function _assertDerEncodedAttrs(node, code) {
437
437
  catch (e) { throw NS.E(code, "the attribute set must be DER encoded even inside a BER envelope (RFC 5652 sec. 5.3)", e); }
438
438
  }
439
439
 
440
- // A CertificateChoices / RevocationInfoChoice element, surfaced RAW (its DER +
441
- // outer tag) rather than recursively parsed -- the obsolete CHOICE alternatives
440
+ // A CertificateChoices / RevocationInfoChoice element, surfaced raw (its DER +
441
+ // outer tag) and never recursively parsed: the obsolete CHOICE alternatives
442
442
  // (extendedCertificate, attribute certs, otherRevocationInfo) never fail the
443
443
  // parse, and a caller re-parses a `certificate`/`CertificateList` element itself.
444
444
  function rawElement(item) {
@@ -515,7 +515,7 @@ var ISSUER_AND_SERIAL = schema.seq([
515
515
  });
516
516
 
517
517
  // SignerIdentifier ::= CHOICE { issuerAndSerialNumber IssuerAndSerialNumber,
518
- // subjectKeyIdentifier [0] IMPLICIT OCTET STRING } (RFC 5652 sec. 5.3) -- the arm is
518
+ // subjectKeyIdentifier [0] IMPLICIT OCTET STRING } (RFC 5652 sec. 5.3), where the arm is
519
519
  // disambiguated by tag (universal SEQUENCE vs context [0]).
520
520
  var SIGNER_IDENTIFIER = schema.choice([
521
521
  { when: { tagClass: "universal", tagNumber: asn1.TAGS.SEQUENCE }, schema: ISSUER_AND_SERIAL },
@@ -526,10 +526,10 @@ var SIGNER_IDENTIFIER = schema.choice([
526
526
  // signedAttrs [0] IMPLICIT OPTIONAL, signatureAlgorithm, signature OCTET STRING,
527
527
  // unsignedAttrs [1] IMPLICIT OPTIONAL } (RFC 5652 sec. 5.3). signedAttrs/unsignedAttrs
528
528
  // are positional optionals (a required signatureAlgorithm sits between them, so
529
- // they cannot be a trailing block). ONE definition drives both consumers -- the
529
+ // they cannot be a trailing block). One definition drives both consumers: the
530
530
  // signerInfos of a SignedData (mode "content") and a countersignature attribute
531
531
  // value (mode "countersig", RFC 5652 sec. 11.4: syntactically a SignerInfo whose
532
- // signedAttrs MUST carry message-digest and MUST NOT carry content-type) -- so
532
+ // signedAttrs MUST carry message-digest and MUST NOT carry content-type), so
533
533
  // the two can never diverge structurally.
534
534
  function makeSignerInfo(mode) {
535
535
  return schema.seq([
@@ -574,7 +574,7 @@ function makeSignerInfo(mode) {
574
574
  // sec. 11.4 -- every countersignature value IS a SignerInfo (validated by
575
575
  // content, never accepted on the attribute type alone). Multiple
576
576
  // countersignature instances are explicitly permitted here, and a
577
- // countersignature's own unsignedAttrs may nest further ones -- the
577
+ // countersignature's own unsignedAttrs may nest further ones, so the
578
578
  // recursion is bounded by the decoder's depth cap.
579
579
  for (var u = 0; u < unsignedAttrs.length; u++) {
580
580
  if (unsignedAttrs[u].type !== OID_COUNTERSIGNATURE) continue;
@@ -605,7 +605,7 @@ var COUNTERSIGNATURE_SIGNER_INFO = makeSignerInfo("countersig");
605
605
  // SignedData ::= SEQUENCE { version CMSVersion, digestAlgorithms SET OF,
606
606
  // encapContentInfo, certificates [0] IMPLICIT OPTIONAL, crls [1] IMPLICIT
607
607
  // OPTIONAL, signerInfos SET OF } (RFC 5652 sec. 5.1). digestAlgorithms and
608
- // signerInfos are min:0 -- a degenerate certs-only SignedData carries neither.
608
+ // signerInfos are min:0, since a degenerate certs-only SignedData carries neither.
609
609
  var SIGNED_DATA = schema.seq([
610
610
  schema.field("version", SIGNED_DATA_VERSION),
611
611
  schema.field("digestAlgorithms", schema.setOf(ALGORITHM_IDENTIFIER, { min: 0, code: "cms/bad-digest-algorithms", what: "digestAlgorithms" })),
@@ -658,10 +658,10 @@ var T = asn1.TAGS;
658
658
 
659
659
  // EncryptedContentInfo ::= SEQUENCE { contentType OID, contentEncryptionAlgorithm
660
660
  // AlgorithmIdentifier, encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL } (RFC
661
- // 5652 sec. 6.1). encryptedContent is [0] IMPLICIT (context PRIMITIVE) -- its content
661
+ // 5652 sec. 6.1). encryptedContent is [0] IMPLICIT (context primitive), so its content
662
662
  // octets ARE the ciphertext directly, so it reads through implicitOctetString(0),
663
- // NOT the [0] EXPLICIT shape ENCAP_CONTENT_INFO uses (which would double-strip a
664
- // length header). The ciphertext + algorithm parameters are surfaced RAW.
663
+ // and not the [0] EXPLICIT shape ENCAP_CONTENT_INFO uses (which would double-strip a
664
+ // length header). The ciphertext + algorithm parameters are surfaced raw.
665
665
  var ENCRYPTED_CONTENT_INFO = schema.seq([
666
666
  schema.field("contentType", schema.oidLeaf()),
667
667
  schema.field("contentEncryptionAlgorithm", ALGORITHM_IDENTIFIER),
@@ -678,7 +678,7 @@ var ENCRYPTED_CONTENT_INFO = schema.seq([
678
678
  });
679
679
 
680
680
  // RecipientIdentifier ::= CHOICE { issuerAndSerialNumber, subjectKeyIdentifier [0]
681
- // IMPLICIT OCTET STRING } (RFC 5652 sec. 6.2.1) -- structurally identical to
681
+ // IMPLICIT OCTET STRING } (RFC 5652 sec. 6.2.1), structurally identical to
682
682
  // SignerIdentifier; reuse ISSUER_AND_SERIAL + the implicitOctetString(0) leaf.
683
683
  var RECIPIENT_IDENTIFIER = schema.choice([
684
684
  { when: { tagClass: "universal", tagNumber: T.SEQUENCE }, schema: ISSUER_AND_SERIAL },
@@ -712,7 +712,7 @@ var KEY_TRANS_RECIPIENT_INFO = schema.seq([
712
712
  });
713
713
 
714
714
  // OriginatorPublicKey ::= SEQUENCE { algorithm, publicKey BIT STRING } (RFC 5753
715
- // sec. 3.1.1), reached as originatorKey [1] IMPLICIT -- SPKI-shaped but cannot reuse
715
+ // sec. 3.1.1), reached as originatorKey [1] IMPLICIT: SPKI-shaped but cannot reuse
716
716
  // pkix.spki (which asserts a universal SEQUENCE), so assert:"constructed".
717
717
  var ORIGINATOR_PUBLIC_KEY = schema.seq([
718
718
  schema.field("algorithm", ALGORITHM_IDENTIFIER),
@@ -732,7 +732,7 @@ var ORIGINATOR_IDENTIFIER_OR_KEY = schema.choice([
732
732
 
733
733
  // RecipientKeyIdentifier (RFC 5652 sec. 6.2.2) and KEKIdentifier (sec. 6.2.3) are one
734
734
  // shape -- { <keyId> OCTET STRING, date GeneralizedTime OPTIONAL, other
735
- // OtherKeyAttribute OPTIONAL } -- differing only in the key-id field's name and
735
+ // OtherKeyAttribute OPTIONAL }, differing only in the key-id field's name and
736
736
  // the enclosing tag form. One factory defines both so the OPTIONAL handling
737
737
  // (date and the raw-surfaced OtherKeyAttribute) cannot diverge between them.
738
738
  function keyIdentifierSchema(keyIdName, assert, code, what) {
@@ -752,7 +752,7 @@ function keyIdentifierSchema(keyIdName, assert, code, what) {
752
752
  });
753
753
  }
754
754
 
755
- // Reached as rKeyId [0] IMPLICIT (a SEQUENCE -- constructed, unlike ktri's [0] leaf).
755
+ // Reached as rKeyId [0] IMPLICIT (a SEQUENCE, constructed, unlike ktri's [0] leaf).
756
756
  var RECIPIENT_KEY_IDENTIFIER = keyIdentifierSchema("subjectKeyIdentifier",
757
757
  "constructed", "cms/bad-recipient-key-identifier", "RecipientKeyIdentifier");
758
758
 
@@ -945,7 +945,7 @@ var RECIPIENT_INFO = schema.choice([
945
945
  ], { code: "cms/bad-recipient-info", what: "RecipientInfo" });
946
946
 
947
947
  // OriginatorInfo ::= [0] IMPLICIT SEQUENCE { certs [0] IMPLICIT OPTIONAL, crls [1]
948
- // IMPLICIT OPTIONAL } (RFC 5652 sec. 6.1). Members surfaced RAW (their outer tag feeds
948
+ // IMPLICIT OPTIONAL } (RFC 5652 sec. 6.1). Members surfaced raw (their outer tag feeds
949
949
  // the version rule).
950
950
  var ORIGINATOR_INFO = schema.seq([
951
951
  schema.optional("certs", schema.implicitSetOf(0, schema.any(), { min: 1, code: "cms/bad-originator-certs", what: "certs" }), { tag: 0 }),
@@ -977,8 +977,8 @@ function _expectedEnvelopedDataVersion(originatorInfo, recipientInfos, hasUnprot
977
977
  }
978
978
 
979
979
  // RFC 5652 sec. 9.1 -- the exact AuthenticatedData CMSVersion, from originatorInfo's raw
980
- // cert/crl outer tags ONLY. Unlike EnvelopedData sec. 6.1, the recipient-info kinds do
981
- // NOT influence the version. IF originatorInfo present AND (other-cert [3] OR
980
+ // cert/crl outer tags only. Unlike EnvelopedData sec. 6.1, the recipient-info kinds do
981
+ // not influence the version. If originatorInfo is present and (other-cert [3] or
982
982
  // other-crl [1]) -> 3; ELSE IF originatorInfo present AND v2AttrCert [2] -> 1; ELSE 0.
983
983
  function _expectedAuthDataVersion(originatorInfo) {
984
984
  if (!originatorInfo) return 0;
@@ -991,7 +991,7 @@ function _expectedAuthDataVersion(originatorInfo) {
991
991
  // EnvelopedData ::= SEQUENCE { version, originatorInfo [0] IMPLICIT OPTIONAL,
992
992
  // recipientInfos RecipientInfos (SET SIZE 1..MAX), encryptedContentInfo,
993
993
  // unprotectedAttrs [1] IMPLICIT OPTIONAL } (RFC 5652 sec. 6.1). recipientInfos is
994
- // min:1 (an empty SET is non-conformant -- the INVERSE of SignedData's degenerate
994
+ // min:1 (an empty SET is non-conformant, the inverse of SignedData's degenerate
995
995
  // signerInfos).
996
996
  var ENVELOPED_DATA = schema.seq([
997
997
  schema.field("version", ENVELOPED_DATA_VERSION),
@@ -1021,7 +1021,7 @@ var ENVELOPED_DATA = schema.seq([
1021
1021
  });
1022
1022
 
1023
1023
  // EncryptedData ::= SEQUENCE { version, encryptedContentInfo, unprotectedAttrs [1]
1024
- // IMPLICIT OPTIONAL } (RFC 5652 sec. 8) -- no recipients, no originatorInfo; the CEK is
1024
+ // IMPLICIT OPTIONAL } (RFC 5652 sec. 8): no recipients, no originatorInfo; the CEK is
1025
1025
  // distributed out of band. version is 0, or 2 iff unprotectedAttrs are present.
1026
1026
  var ENCRYPTED_DATA = schema.seq([
1027
1027
  schema.field("version", ENCRYPTED_DATA_VERSION),
@@ -1150,7 +1150,7 @@ var AUTH_ENVELOPED_DATA = schema.seq([
1150
1150
  // sec. 2.2 AAD is the re-tagged DER SET). No content-type/message-digest
1151
1151
  // presence rules bind here (sec. 11.1/sec. 11.2 name signed-data and
1152
1152
  // authenticated-data; sec. 2.1 says message-digest SHOULD NOT appear), so only
1153
- // the duplicate rule, the sec. 11 placement rows, and -- when a content-type
1153
+ // the duplicate rule, the sec. 11 placement rows, and, when a content-type
1154
1154
  // attribute IS present -- the value == contentType coherence apply.
1155
1155
  _assertDerEncodedAttrs(m.fields.authAttrs.node, "cms/bad-auth-attrs");
1156
1156
  authAttrs = m.fields.authAttrs.value.items.map(function (it) { return it.value.result; });
@@ -1265,8 +1265,8 @@ var CONTENT_INFO = schema.seq([
1265
1265
  * `{ type: "ori", oriType, oriValue, kemri }` with the parsed KEMRecipientInfo in
1266
1266
  * `kemri`. Every result additionally carries `contentType` (the dotted OID) and
1267
1267
  * `contentTypeName` (its registry name) naming which of the five shapes was
1268
- * dispatched. Raw byte ranges an external verifier hashes -- `eContent`,
1269
- * `signature`, `signedAttrsBytes`, `authAttrsBytes`, `mac` -- are surfaced
1268
+ * dispatched. The raw byte ranges an external verifier hashes (`eContent`,
1269
+ * `signature`, `signedAttrsBytes`, `authAttrsBytes`, `mac`) are surfaced
1270
1270
  * exactly as on the wire. The remaining PKCS#7 types throw `cms/unsupported-content-type`; an
1271
1271
  * unrecognized OID throws `cms/unknown-content-type`; a malformed structure
1272
1272
  * throws a typed `CmsError` (`cms/*`) and a leaf-level codec fault surfaces as
package/lib/schema-crl.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * rules, and the raw `tbsCertList` bytes are returned for signature checking.
20
20
  *
21
21
  * @card
22
- * Parse DER / PEM X.509 CRLs into structured, validated fields -- revoked
22
+ * Parse DER / PEM X.509 CRLs into structured, validated fields: revoked
23
23
  * serials with real-`Date` revocation times, named extensions, fail-closed.
24
24
  */
25
25
 
@@ -34,14 +34,14 @@ var PemError = frameworkError.PemError;
34
34
  var TAGS = asn1.TAGS;
35
35
 
36
36
 
37
- // CRLReason ::= ENUMERATED (RFC 5280 sec. 5.3.1) -- value 7 is unused/reserved.
37
+ // CRLReason ::= ENUMERATED (RFC 5280 sec. 5.3.1). Value 7 is unused/reserved.
38
38
  // The legal set lives once in pkix.CRL_REASON_NAMES (shared with the OCSP
39
39
  // RevokedInfo decoder, which surfaces the name; this decoder the numeric code).
40
40
  var CRL_REASONS = pkix.CRL_REASON_NAMES;
41
41
 
42
- // Extension-value decoding is keyed off the STABLE dotted OID (resolved once at
43
- // load from the canonical name), not the mutable display name -- a caller's
44
- // pki.oid.register() display override must not change parse behaviour.
42
+ // Extension-value decoding is keyed off the stable dotted OID (resolved once at
43
+ // load from the canonical name) and not the mutable display name, so a caller's
44
+ // pki.oid.register() display override cannot change parse behaviour.
45
45
  var OID_CRL_NUMBER = oid.byName("cRLNumber");
46
46
  var OID_REASON_CODE = oid.byName("reasonCode");
47
47
  var OID_INVALIDITY_DATE = oid.byName("invalidityDate");
@@ -58,9 +58,9 @@ var EXTENSIONS = pkix.extensions(NS);
58
58
  // UTCTime). invalidityDate stays GeneralizedTime-only (sec. 5.3.2, decodeExt).
59
59
  var TIME = pkix.time(NS);
60
60
 
61
- // CRL Version ::= INTEGER { v1(0), v2(1) } -- a BARE INTEGER (not [0] EXPLICIT).
61
+ // CRL Version ::= INTEGER { v1(0), v2(1) }, a bare INTEGER (not [0] EXPLICIT).
62
62
  // A CRL is at most v2; reject an explicit v1 (DER forbids the default) and any
63
- // value >= 2. Do NOT reuse the certificate readVersion (it maps 2 -> v3).
63
+ // value >= 2. Do not reuse the certificate readVersion (it maps 2 -> v3).
64
64
  var CRL_VERSION = pkix.versionReader(NS, { "1": 2 });
65
65
 
66
66
  // The three cheap, high-value CRL extension values are decoded from their raw
@@ -24,13 +24,13 @@
24
24
  * when supplied, MUST be 2 (RFC 4211 sec. 5); certReqId is an unbounded signed
25
25
  * INTEGER (the RFC 9483 `-1` sentinel is legal). The `CertRequest` byte range
26
26
  * the proof-of-possession signature covers, and each `poposkInput`, are surfaced
27
- * RAW for a downstream verifier; registration controls / info values and the
28
- * keyEncipherment / keyAgreement POP arms are surfaced RAW rather than recursed.
27
+ * raw for a downstream verifier; registration controls / info values and the
28
+ * keyEncipherment / keyAgreement POP arms are surfaced raw and never recursed.
29
29
  * DER-only, fail-closed.
30
30
  *
31
31
  * @card
32
32
  * Parse DER / PEM RFC 4211 CertReqMessages into requested-certificate templates,
33
- * proof-of-possession, and registration controls -- dual-accepted names, raw
33
+ * proof-of-possession, and registration controls: dual-accepted names, raw
34
34
  * verifier inputs, fail-closed.
35
35
  */
36
36
 
@@ -102,7 +102,7 @@ var OPTIONAL_VALIDITY = schema.seq([
102
102
  });
103
103
 
104
104
  // ---- ProofOfPossession (sec. 4) ------------------------------------------
105
- // raVerified [0] NULL -- the RA has already verified POP out of band.
105
+ // raVerified [0] NULL: the RA has already verified POP out of band.
106
106
  var POPO_RAVERIFIED = schema.decode(function (n, ctx) {
107
107
  try { asn1.read.nullImplicit(n, 0); }
108
108
  catch (e) { throw ctx.E("crmf/bad-popo", "raVerified [0] must be an IMPLICIT NULL", e); }
@@ -110,9 +110,9 @@ var POPO_RAVERIFIED = schema.decode(function (n, ctx) {
110
110
  });
111
111
 
112
112
  // When poposkInput is present the POP signature is over the DER of the
113
- // POPOSigningKeyInput VALUE (RFC 4211 sec. 4.1), which is a SEQUENCE -- but on the wire
113
+ // POPOSigningKeyInput value (RFC 4211 sec. 4.1), which is a SEQUENCE. But on the wire
114
114
  // poposkInput is an IMPLICIT [0] field, so its bytes lead with the context tag
115
- // (0xA0) rather than the SEQUENCE tag a verifier hashes. `asn1.sequenceTlv` recovers
115
+ // (0xA0) and not the SEQUENCE tag a verifier hashes. `asn1.sequenceTlv` recovers
116
116
  // the SEQUENCE-tagged signed region from the field's content; `signedBytes` is that
117
117
  // region and `bytes` keeps the raw wire [0] TLV, so a verifier can use either
118
118
  // encoding its peer produced.
@@ -120,7 +120,7 @@ var POPO_RAVERIFIED = schema.decode(function (n, ctx) {
120
120
  // POPOSigningKeyInput ::= SEQUENCE { authInfo CHOICE { sender [0] GeneralName,
121
121
  // publicKeyMAC PKMACValue }, publicKey SubjectPublicKeyInfo } (sec. 4.1). Structurally
122
122
  // validated (not deferred raw), so an empty or malformed poposkInput fails closed
123
- // rather than surfacing a signed region that was never a well-formed POP input.
123
+ // and never surfaces a signed region that was not a well-formed POP input.
124
124
  // PKMACValue ::= SEQUENCE { algId AlgorithmIdentifier, value BIT STRING }. The
125
125
  // MAC value is octet-string algorithm output handed to an external verifier;
126
126
  // with no in-tree POP verify layer, octet alignment is enforced at parse.
@@ -130,7 +130,7 @@ var PKMAC_VALUE = schema.seq([
130
130
  ], {
131
131
  assert: "sequence", arity: { exact: 2 }, code: "crmf/bad-popo", what: "PKMACValue",
132
132
  build: function (m, ctx) {
133
- // The parsed BIT STRING structure { unusedBits, bytes } -- a structural
133
+ // The parsed BIT STRING structure { unusedBits, bytes }, a structural
134
134
  // octet-alignment check on the unused-bit COUNT, not a comparison of the
135
135
  // MAC secret (there is no in-tree POP verify), so no timing oracle exists.
136
136
  var macBitString = m.fields.value.value;
@@ -142,7 +142,7 @@ var PKMAC_VALUE = schema.seq([
142
142
  });
143
143
 
144
144
  // authInfo CHOICE: sender [0] GeneralName is EXPLICIT (GeneralName is itself a
145
- // CHOICE); publicKeyMAC is a bare PKMACValue SEQUENCE -- disjoint by tag class.
145
+ // CHOICE); publicKeyMAC is a bare PKMACValue SEQUENCE, disjoint by tag class.
146
146
  var POPOSK_AUTH_INFO = schema.choice([
147
147
  { when: { tagClass: "context", tagNumber: 0 }, schema: schema.explicit(0, pkix.generalName(NS, { code: "crmf/bad-popo" }), { code: "crmf/bad-popo" }) },
148
148
  { when: { tagClass: "universal", tagNumber: TAGS.SEQUENCE }, schema: PKMAC_VALUE },
@@ -154,7 +154,7 @@ var POPOSK_INPUT = schema.seq([
154
154
  ], { assert: "implicit", implicitTag: 0, arity: { exact: 2 }, code: "crmf/bad-popo", what: "POPOSigningKeyInput" });
155
155
 
156
156
  // POPOSigningKey ::= SEQUENCE { poposkInput [0] POPOSigningKeyInput OPTIONAL,
157
- // algorithmIdentifier AlgorithmIdentifier, signature BIT STRING } -- IMPLICIT [1].
157
+ // algorithmIdentifier AlgorithmIdentifier, signature BIT STRING }, IMPLICIT [1].
158
158
  var POPO_SIGNING_KEY = schema.seq([
159
159
  schema.optional("poposkInput", schema.decode(function (n, ctx) {
160
160
  // Validate the full POPOSigningKeyInput structure fail-closed, then surface the
@@ -187,9 +187,9 @@ var POPO_SIGNING_KEY = schema.seq([
187
187
  // keyEncipherment [2] / keyAgreement [3] POPOPrivKey (sec. 4). POPOPrivKey is a
188
188
  // 5-arm CHOICE { thisMessage [0], subsequentMessage [1], dhMAC [2], agreeMAC [3],
189
189
  // encryptedKey [4] }, so X.680 sec. 31.2.7 forces the outer [2]/[3] tag to be EXPLICIT
190
- // (a CHOICE has no single tag to replace). Validate that shell -- a constructed
191
- // wrapper around exactly one inner context [0]..[4] alternative -- before surfacing
192
- // the arm RAW, so a primitive / empty / mis-tagged node is rejected rather than
190
+ // (a CHOICE has no single tag to replace). Validate that shell, a constructed
191
+ // wrapper around exactly one inner context [0]..[4] alternative, before surfacing
192
+ // the arm raw, so a primitive, empty or mis-tagged node is rejected and never
193
193
  // reported to a verifier as a well-formed POP. The inner alternative's own value
194
194
  // (incl. the encryptedKey [4] EnvelopedData) stays deferred to the verify layer.
195
195
  // POPOPrivKey ::= CHOICE { thisMessage [0] BIT STRING (deprecated), subsequentMessage
@@ -240,7 +240,7 @@ function popoPrivKey(type) {
240
240
  try { schema.embeddedDer(PKMAC_VALUE, asn1.sequenceTlv(inner), NS, { code: "crmf/bad-popo", what: "agreeMAC [3] PKMACValue" }); }
241
241
  catch (e) { throw ctx.E("crmf/bad-popo", "agreeMAC [3] must be a PKMACValue SEQUENCE { algId, BIT STRING } (RFC 4211 sec. 4.2)", e); }
242
242
  }
243
- // encryptedKey [4] EnvelopedData -- validate the CMS structure fail-closed by
243
+ // encryptedKey [4] EnvelopedData: validate the CMS structure fail-closed by
244
244
  // composing the shared EnvelopedData decoder (retag the IMPLICIT [4] to the
245
245
  // universal SEQUENCE it decodes as). The EncKeyWithID identity check lives inside
246
246
  // the ENCRYPTED content, so it stays a verify-layer concern.
@@ -248,12 +248,12 @@ function popoPrivKey(type) {
248
248
  var env;
249
249
  try { env = cms.walkEnvelopedData(asn1.decode(asn1.sequenceTlv(inner))); }
250
250
  catch (e) { throw ctx.E("crmf/bad-popo", "encryptedKey [4] must be a well-formed EnvelopedData (RFC 4211 sec. 4.2, RFC 5652 sec. 6.1)", e); }
251
- // RFC 4211 sec. 4.2 -- the enveloped content type MUST be id-ct-encKeyWithID (the
251
+ // RFC 4211 sec. 4.2: the enveloped content type MUST be id-ct-encKeyWithID (the
252
252
  // ContentType OID is in the clear even though the content itself is encrypted).
253
253
  if (env.encryptedContentInfo.contentType !== oid.byName("encKeyWithID")) {
254
254
  throw ctx.E("crmf/bad-popo", "encryptedKey [4] EnvelopedData content type MUST be id-ct-encKeyWithID (RFC 4211 sec. 4.2)");
255
255
  }
256
- // The encrypted key material MUST be present -- CMS allows a detached
256
+ // The encrypted key material MUST be present. CMS allows a detached
257
257
  // EnvelopedData (encryptedContent OPTIONAL), but a POP with no key to verify
258
258
  // or archive is meaningless. The shared CMS assert rejects a null OR
259
259
  // zero-length attached ciphertext (the rule the EST / PKCS#12 siblings hold).
@@ -275,7 +275,7 @@ var PROOF_OF_POSSESSION = schema.choice([
275
275
 
276
276
  // ---- Controls / regInfo (sec. 5, sec. 6, sec. 7) ---------------------------------
277
277
  // AttributeTypeAndValue ::= SEQUENCE { type OBJECT IDENTIFIER, value ANY DEFINED BY
278
- // type }. The list is decoded; each value stays RAW (the per-OID value semantics
278
+ // type }. The list is decoded; each value stays raw (the per-OID value semantics
279
279
  // are deferred). Shared shape for both controls and regInfo.
280
280
  var CONTROL = schema.seq([
281
281
  schema.field("type", schema.oidLeaf()),
@@ -293,10 +293,10 @@ var CONTROLS = schema.seqOf(CONTROL, { assert: "sequence", min: 1, code: "crmf/b
293
293
  // regInfo ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue (sec. 7).
294
294
  var REG_INFO = schema.seqOf(CONTROL, { assert: "sequence", min: 1, code: "crmf/bad-reg-info", what: "regInfo", build: mapControls });
295
295
 
296
- // ---- CertTemplate (sec. 5) -- the IMPLICIT-TAGS core ----------------------
296
+ // ---- CertTemplate (sec. 5), the IMPLICIT-TAGS core ------------------------
297
297
  // CertTemplate ::= SEQUENCE { version [0], serialNumber [1], signingAlg [2],
298
298
  // issuer [3] Name, validity [4] OptionalValidity, subject [5] Name, publicKey [6]
299
- // SubjectPublicKeyInfo, issuerUID [7], subjectUID [8], extensions [9] } -- every
299
+ // SubjectPublicKeyInfo, issuerUID [7], subjectUID [8], extensions [9] }, where every
300
300
  // field IMPLICIT and OPTIONAL, so the whole body is one ascending [0..9] trailing
301
301
  // run. issuer/subject Name and the [4] validity times are the CHOICE exceptions.
302
302
  var CERT_TEMPLATE = schema.seq([
@@ -323,9 +323,9 @@ var CERT_TEMPLATE = schema.seq([
323
323
  // existing certificate -- serialNumber and issuer present -- inside a CMP
324
324
  // RevDetails (RFC 9810 sec. 5.3.9). Every field is surfaced so both the request
325
325
  // omission check and the revocation consumer read them off one result.
326
- // The ONE profile override: RFC 9810 Appendix D.6 profiles the CMP
326
+ // The single profile override: RFC 9810 Appendix D.6 profiles the CMP
327
327
  // cross-certification (ccr) template as "version v1 or v3", so the caller
328
- // opts in to v1 (0) via ctx.allowV1Version -- the same base-section-vs-
328
+ // opts in to v1 (0) via ctx.allowV1Version, the same base-section-vs-
329
329
  // profile-appendix override mechanism as the signingAlg relaxation below.
330
330
  if (f.version.present && f.version.value !== 2n &&
331
331
  !(ctx.allowV1Version && f.version.value === 0n)) {
@@ -365,7 +365,7 @@ var CERT_REQUEST = schema.seq([
365
365
  // hazard), so a request template that sets any of them is rejected
366
366
  // fail-closed. The check lives HERE, not in CERT_TEMPLATE, because the same
367
367
  // structure legitimately carries serialNumber/issuer in a CMP RevDetails.
368
- // A cross-certification request (ccr) is the ONE exception: RFC 9810 Appendix
368
+ // A cross-certification request (ccr) is the one exception: RFC 9810 Appendix
369
369
  // D.6 profiles its template with signingAlg PRESENT (the requesting CA states
370
370
  // the algorithm it wants the cross-certificate signed with), so the caller
371
371
  // relaxes that single field via ctx.allowSigningAlg; serialNumber and the UID
@@ -406,7 +406,7 @@ var CERT_REQ_MSG = schema.seq([
406
406
  // to sign / MAC over, and a verifier would be bound to the wrong identity/key.
407
407
  var complete = certReq.certTemplate.subject !== null && certReq.certTemplate.publicKey !== null;
408
408
  // RFC 4211 sec. 4.1 -- for a signature POP, poposkInput's presence is fixed by the
409
- // CertTemplate: it MUST be omitted when the template carries BOTH subject and
409
+ // CertTemplate: it MUST be omitted when the template carries both subject and
410
410
  // publicKey (the signature is then over the DER of the CertRequest), and MUST be
411
411
  // present otherwise.
412
412
  if (popo && popo.type === "signature") {
@@ -438,7 +438,7 @@ var CERT_REQ_MSG = schema.seq([
438
438
  },
439
439
  });
440
440
 
441
- // CertReqMessages ::= SEQUENCE SIZE(1..MAX) OF CertReqMsg (sec. 3) -- an empty sequence
441
+ // CertReqMessages ::= SEQUENCE SIZE(1..MAX) OF CertReqMsg (sec. 3), where an empty sequence
442
442
  // is malformed. The top-level reject code predates the
443
443
  // `<prefix>/not-a-<structure>` convention and stays frozen on the public
444
444
  // error-code surface.
@@ -461,16 +461,16 @@ var CERT_REQ_MESSAGES = schema.seqOf(CERT_REQ_MSG, {
461
461
  * `{ messages: [ { certReq, popo, regInfo } ] }`. Each `certReq` is
462
462
  * `{ certReqId, certReqIdHex, certTemplate, controls, certReqBytes }`, and
463
463
  * `certTemplate` carries the requestable certificate fields (`version`, `issuer`,
464
- * `validity`, `subject`, `publicKey`, `extensions` -- each `null` when absent). The
464
+ * `validity`, `subject`, `publicKey`, `extensions`, each `null` when absent). The
465
465
  * CA-assigned / deprecated fields RFC 4211 sec. 5 requires a request to omit
466
466
  * (`serialNumber`, `signingAlg`, `issuerUID`, `subjectUID`) are rejected, not
467
467
  * surfaced. `popo` is
468
468
  * `null`, `{ type: "raVerified" }`, `{ type: "signature", poposkInput,
469
469
  * algorithmIdentifier, signature }`, or `{ type: "keyEncipherment" |
470
470
  * "keyAgreement", method, bytes }` (where `method` is the POPOPrivKey alternative --
471
- * `thisMessage` / `subsequentMessage` / `dhMAC` / `agreeMAC` / `encryptedKey` -- each
471
+ * `thisMessage` / `subsequentMessage` / `dhMAC` / `agreeMAC` / `encryptedKey`, each
472
472
  * structurally validated, the `encryptedKey` EnvelopedData included). When present, `poposkInput` is
473
- * `{ bytes, signedBytes, publicKey }` -- `bytes` is the raw wire `[0]` TLV,
473
+ * `{ bytes, signedBytes, publicKey }`, where `bytes` is the raw wire `[0]` TLV,
474
474
  * `signedBytes` is the `POPOSigningKeyInput` re-tagged to the `SEQUENCE` DER the
475
475
  * signature actually covers, and `publicKey` is the canonical
476
476
  * `SubjectPublicKeyInfo` DER the RFC 4211 sec. 4.1 template-match check compares
@@ -503,7 +503,7 @@ var parse = pkix.makeParser({
503
503
  * @related pki.schema.crmf.parse
504
504
  *
505
505
  * Extract the DER bytes from a PEM block (RFC 4211 registers no RFC 7468 label, so
506
- * the first block is taken unless `label` is given -- CRMF rides inside CMP / EST as
506
+ * the first block is taken unless `label` is given; CRMF rides inside CMP / EST as
507
507
  * DER in practice). Throws `PemError` on a missing envelope or a non-base64 body.
508
508
  *
509
509
  * @example
package/lib/schema-csr.js CHANGED
@@ -25,7 +25,7 @@
25
25
  * certificate/CRL guards.
26
26
  *
27
27
  * @card
28
- * Parse DER / PEM PKCS#10 CSRs into structured, validated fields -- subject DN,
28
+ * Parse DER / PEM PKCS#10 CSRs into structured, validated fields: subject DN,
29
29
  * public key, requested attributes, signature, fail-closed.
30
30
  */
31
31
 
@@ -45,14 +45,14 @@ var NS = pkix.makeNS("csr", CsrError, oid);
45
45
  var NAME = pkix.name(NS);
46
46
  var SPKI = pkix.spki(NS);
47
47
 
48
- // CertificationRequestInfo version ::= INTEGER { v1(0) } (RFC 2986 sec. 4.1). A BARE
49
- // mandatory INTEGER whose ONLY legal value is 0 -- the inverse of the cert/CRL
48
+ // CertificationRequestInfo version ::= INTEGER { v1(0) } (RFC 2986 sec. 4.1). A bare
49
+ // mandatory INTEGER whose one legal value is 0, the inverse of the cert/CRL
50
50
  // readers, which reject 0 as the DER-forbidden default. Surface v1 as 1. A
51
51
  // cert-shaped [0] EXPLICIT wrapper at this position makes asn1.read.integer throw
52
52
  // asn1/* (fail-closed).
53
53
  var CSR_VERSION = pkix.versionReader(NS, { "0": 1 });
54
54
 
55
- // Attribute ::= SEQUENCE { type OID, values SET OF ANY } -- the shared pkix factory
55
+ // Attribute ::= SEQUENCE { type OID, values SET OF ANY }, the shared pkix factory
56
56
  // under the csr NS (values raw DER, SET SIZE(1..MAX), no uniqueness). The same
57
57
  // factory serves the PKCS#8 private-key attributes.
58
58
  var ATTRIBUTE = pkix.attribute(NS);
@@ -76,8 +76,8 @@ var DIRECTORY_STRING_TAGS = [
76
76
  var RECOGNIZED_ATTRIBUTE_VALUE = {};
77
77
  RECOGNIZED_ATTRIBUTE_VALUE[oid.byName("extensionRequest")] = function (node, ctx) {
78
78
  // Surface the requested extensions decoded (same {oid,name,critical,value}
79
- // shape as a certificate's extensions) so a CA pipeline -- and the EST
80
- // re-enroll guard -- reads them off the attribute instead of re-walking the
79
+ // shape as a certificate's extensions) so a CA pipeline, and the EST
80
+ // re-enroll guard, read them off the attribute instead of re-walking the
81
81
  // raw Extensions bytes. Returned as an enrichment merged onto the attribute.
82
82
  try { return { extensions: schema.walk(EXTENSIONS, node, ctx).result }; }
83
83
  catch (e) {
@@ -101,7 +101,7 @@ RECOGNIZED_ATTRIBUTE_VALUE[oid.byName("challengePassword")] = function (node, ct
101
101
  // subjectPKInfo SubjectPublicKeyInfo, attributes [0] IMPLICIT SET OF Attribute }.
102
102
  // attributes is a REQUIRED field (a CRI omitting [0] is a missing-required-field
103
103
  // fault, not silently accepted) modeled as an IMPLICIT [0] SET OF with min:0 (an
104
- // empty attributes SET is legal). subject MAY be empty -- no non-empty-DN guard.
104
+ // empty attributes SET is legal). subject MAY be empty, so there is no non-empty-DN guard.
105
105
  var CERTIFICATION_REQUEST_INFO = schema.seq([
106
106
  schema.field("version", CSR_VERSION),
107
107
  schema.field("subject", NAME),
@@ -134,11 +134,11 @@ var CERTIFICATION_REQUEST_INFO = schema.seq([
134
134
  });
135
135
 
136
136
  // CertificationRequest ::= SEQUENCE { certificationRequestInfo, signatureAlgorithm,
137
- // signature BIT STRING } -- the shared SIGNED envelope. DIVERGENCE from the
138
- // cert/CRL builders: OMIT the outer-vs-inner signatureAlgorithm agreement check
139
- // (the CRI has no inner signature AlgorithmIdentifier) and the non-empty-subject
140
- // guard (a CSR subject MAY be empty). The omission is structural -- this build
141
- // simply never references the agreement bytes.
137
+ // signature BIT STRING }, the shared SIGNED envelope. It diverges from the
138
+ // cert/CRL builders by omitting the outer-vs-inner signatureAlgorithm agreement
139
+ // check (the CRI has no inner signature AlgorithmIdentifier) and the
140
+ // non-empty-subject guard (a CSR subject MAY be empty). The omission is
141
+ // structural: this build simply never references the agreement bytes.
142
142
  var CERTIFICATION_REQUEST = pkix.signedEnvelope(NS, CERTIFICATION_REQUEST_INFO, {
143
143
  code: "csr/not-a-certification-request", what: "CertificationRequest",
144
144
  build: function (e) {