@blamejs/pki 0.5.7 → 0.5.9

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 (105) hide show
  1. package/CHANGELOG.md +418 -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 +5 -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-der.js +152 -0
  36. package/lib/guard-encoding.js +15 -15
  37. package/lib/guard-header.js +3 -3
  38. package/lib/guard-identifier.js +16 -16
  39. package/lib/guard-json.js +15 -15
  40. package/lib/guard-limits.js +7 -7
  41. package/lib/guard-name.js +81 -16
  42. package/lib/guard-parsed.js +80 -80
  43. package/lib/guard-range.js +19 -19
  44. package/lib/guard-secret.js +11 -10
  45. package/lib/guard-text.js +6 -6
  46. package/lib/guard-time.js +10 -10
  47. package/lib/hpke.js +18 -17
  48. package/lib/http-digest.js +35 -35
  49. package/lib/http-retry-after.js +13 -13
  50. package/lib/http-transport.js +20 -19
  51. package/lib/inspect.js +53 -53
  52. package/lib/ip-utils.js +2 -2
  53. package/lib/jose.js +13 -13
  54. package/lib/key.js +16 -16
  55. package/lib/lint.js +51 -51
  56. package/lib/merkle.js +51 -36
  57. package/lib/mime.js +18 -18
  58. package/lib/ocsp-verify.js +10 -10
  59. package/lib/ocsp.js +13 -13
  60. package/lib/oid.js +29 -29
  61. package/lib/path-validate.js +114 -113
  62. package/lib/pbes2.js +16 -16
  63. package/lib/pkcs12-build.js +53 -53
  64. package/lib/pki-build.js +48 -20
  65. package/lib/rc2.js +1 -1
  66. package/lib/rfc3339.js +5 -5
  67. package/lib/schema-all.js +31 -31
  68. package/lib/schema-attrcert.js +12 -12
  69. package/lib/schema-c509.js +149 -197
  70. package/lib/schema-cmc.js +58 -58
  71. package/lib/schema-cmp.js +43 -43
  72. package/lib/schema-cms.js +45 -45
  73. package/lib/schema-crl.js +7 -7
  74. package/lib/schema-crmf.js +28 -28
  75. package/lib/schema-csr.js +12 -12
  76. package/lib/schema-csrattrs.js +16 -16
  77. package/lib/schema-engine.js +18 -18
  78. package/lib/schema-ocsp.js +15 -15
  79. package/lib/schema-pkcs12.js +20 -20
  80. package/lib/schema-pkcs8.js +2 -2
  81. package/lib/schema-pkix.js +131 -126
  82. package/lib/schema-smime.js +19 -19
  83. package/lib/schema-tsp.js +12 -12
  84. package/lib/schema-x509.js +3 -3
  85. package/lib/shbs.js +18 -18
  86. package/lib/sign-scheme.js +13 -13
  87. package/lib/sigstore.js +10 -11
  88. package/lib/sleep.js +1 -1
  89. package/lib/smime.js +308 -96
  90. package/lib/tls-cert-compress.js +18 -18
  91. package/lib/trust.js +27 -27
  92. package/lib/tsp-sign.js +17 -17
  93. package/lib/validator-all.js +1 -1
  94. package/lib/validator-attcert.js +1 -1
  95. package/lib/validator-cose.js +43 -44
  96. package/lib/validator-keydesc.js +3 -3
  97. package/lib/validator-sig.js +13 -13
  98. package/lib/validator-tls.js +11 -11
  99. package/lib/validator-tpm.js +20 -19
  100. package/lib/webauthn-mds.js +66 -66
  101. package/lib/webauthn.js +33 -33
  102. package/lib/webcrypto.js +15 -15
  103. package/lib/x509-sign.js +13 -13
  104. package/package.json +3 -2
  105. package/sbom.cdx.json +6 -6
@@ -11,23 +11,23 @@
11
11
  * @intro
12
12
  * S/MIME Enhanced Security Services signed-attribute values per RFC 5035 (ESS)
13
13
  * and RFC 8551 (S/MIME 4.0). These are the DER-decoded VALUES of CMS signed
14
- * attributes -- they ride inside a `SignerInfo.signedAttrs`, so this is a
15
- * companion decoder a CMS consumer invokes by attribute OID, NOT a top-level
14
+ * attributes: they ride inside a `SignerInfo.signedAttrs`, so this is a
15
+ * companion decoder a CMS consumer invokes by attribute OID, not a top-level
16
16
  * format the schema orchestrator auto-routes.
17
17
  *
18
18
  * `parseSigningCertificate` / `parseSigningCertificateV2` decode the ESS
19
19
  * signing-certificate attributes that bind a signature to the exact certificate
20
- * that made it: each surfaces its list of `ESSCertID`(v2) -- the certificate hash
20
+ * that made it: each surfaces its list of `ESSCertID`(v2) (the certificate hash
21
21
  * (raw), the hash algorithm (decoded for v2, or the implied SHA-1 for v1), and
22
22
  * the optional `issuerSerial` (issuer `GeneralNames` validated + surfaced raw,
23
- * serial as a BigInt + hex) -- plus the optional certificate policies.
23
+ * serial as a BigInt + hex)) plus the optional certificate policies.
24
24
  * `parseSmimeCapabilities` decodes the ordered `SMIMECapabilities` list (each a
25
25
  * capability OID + raw parameters). `decodeAttribute` takes a CMS-shaped
26
26
  * `{ type, values }` attribute, enforces the single-`AttributeValue` rule
27
27
  * (RFC 8551 sec. 2.5.2), routes on the attribute OID, and recognize-and-defers an
28
28
  * unknown attribute type with its raw values intact.
29
29
  *
30
- * Structure is decoded; verification is the consumer's -- the parser surfaces
30
+ * Structure is decoded; verification is the consumer's. The parser surfaces
31
31
  * `certHash` + `hashAlgorithm` + `issuerSerial` so a verifier recomputes the
32
32
  * certificate hash (compose `webcrypto`) and matches the issuer/serial against
33
33
  * the actual signing certificate; it never recomputes a hash or trusts a cert.
@@ -62,15 +62,15 @@ var OID_SIGNING_CERTIFICATE_V2 = oid.byName("signingCertificateV2");
62
62
  var OID_SMIME_CAPABILITIES = oid.byName("smimeCapabilities");
63
63
 
64
64
  // IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber CertificateSerialNumber }
65
- // (RFC 5035 App A). A bare universal SEQUENCE of exactly two fields -- distinct
65
+ // (RFC 5035 App A). A bare universal SEQUENCE of exactly two fields, distinct
66
66
  // from the RFC 5755 attribute-certificate IssuerSerial (three fields, reached
67
67
  // IMPLICIT-tagged), so declared per-format. `issuer` composes the shared
68
68
  // GeneralNames factory (every CHOICE arm validated + surfaced raw, SIZE 1..MAX)
69
69
  // and is surfaced unchanged here: the RFC 5035 sec. 5 directoryName narrowing applies
70
70
  // only to a non-attribute (public-key) certificate reference, and an ESSCertID
71
71
  // entry may reference an attribute certificate whose issuer is a full GeneralNames.
72
- // The FIRST cert is known to be the signing public-key cert (RFC 5035 sec. 3), so the
73
- // directoryName rule is enforced there -- in the SigningCertificate build -- not here.
72
+ // The first cert is known to be the signing public-key cert (RFC 5035 sec. 3), so the
73
+ // directoryName rule is enforced in the SigningCertificate build and not here.
74
74
  var GENERAL_NAME_DIRECTORY = 4;
75
75
  var ISSUER_SERIAL = schema.seq([
76
76
  schema.field("issuer", pkix.generalNames(NS, { code: "smime/bad-general-names" })),
@@ -111,7 +111,7 @@ var POLICY_INFORMATION = schema.seq([
111
111
  var qualifiers = null;
112
112
  if (m.fields.policyQualifiers.present) {
113
113
  // The qualifier body stays raw (per the ESS scope), but the RFC 5280
114
- // sec. 4.2.1.4 structure is validated fail-closed by the shared assertion -- the
114
+ // sec. 4.2.1.4 structure is validated fail-closed by the shared assertion, the
115
115
  // same PolicyInformation shape the certificatePolicies decoder enforces.
116
116
  var q = m.fields.policyQualifiers.node;
117
117
  pkix.assertPolicyQualifiers(q, function (msg, cause) { throw ctx.E("smime/bad-policy-information", msg, cause); });
@@ -132,8 +132,8 @@ var POLICIES = schema.seqOf(POLICY_INFORMATION, {
132
132
  });
133
133
 
134
134
  // ESSCertID ::= SEQUENCE { certHash Hash, issuerSerial IssuerSerial OPTIONAL }
135
- // (RFC 5035 sec. 5.4.2). Hash ::= OCTET STRING -- for v1 it is the SHA-1 hash of the
136
- // whole certificate with NO algorithm field, so the hash algorithm is SYNTHESIZED
135
+ // (RFC 5035 sec. 5.4.2). Hash ::= OCTET STRING; for v1 it is the SHA-1 hash of the
136
+ // whole certificate with no algorithm field, so the hash algorithm is synthesized
137
137
  // as the implied SHA-1 to make v1 shape-compatible with v2 for a verifier.
138
138
  var ESS_CERT_ID = schema.seq([
139
139
  schema.field("certHash", schema.octetString()),
@@ -169,7 +169,7 @@ var ESS_CERT_ID_V2 = schema.seq([
169
169
  // to it is a non-canonical DEFAULT and is rejected fail-closed (the
170
170
  // structured-value analogue of the primitive-DEFAULT rejection the toolkit
171
171
  // already enforces). A present hashAlgorithm carrying a redundant NULL
172
- // parameters is NOT byte-equal to the params-absent default and decodes.
172
+ // parameters is not byte-equal to the params-absent default and decodes.
173
173
  if (alg.oid === OID_SHA256 && alg.parameters === null) {
174
174
  throw ctx.E("smime/non-canonical-default",
175
175
  "ESSCertIDv2 hashAlgorithm equal to the DEFAULT {algorithm id-sha256} MUST be omitted (X.690 sec. 11.5)");
@@ -188,8 +188,8 @@ var ESS_CERT_ID_V2 = schema.seq([
188
188
 
189
189
  // SigningCertificate ::= SEQUENCE { certs SEQUENCE OF ESSCertID,
190
190
  // policies SEQUENCE OF PolicyInformation OPTIONAL } (RFC 5035 sec. 5.4.2). certs is
191
- // order-preserving -- RFC 5035 sec. 3 makes the FIRST element the signing certificate
192
- // -- and non-empty (an empty certs cannot name a signing cert).
191
+ // order-preserving (RFC 5035 sec. 3 makes the first element the signing certificate)
192
+ // and non-empty (an empty certs cannot name a signing cert).
193
193
  function signingCertificateSchema(essCertId, code, what) {
194
194
  return schema.seq([
195
195
  schema.field("certs", schema.seqOf(essCertId, { assert: "sequence", min: 1, code: "smime/bad-certs", what: "certs" })),
@@ -226,7 +226,7 @@ var SMIME_CAPABILITY = schema.seq([
226
226
  };
227
227
  },
228
228
  });
229
- // SMIMECapabilities ::= SEQUENCE OF SMIMECapability -- ordered by preference
229
+ // SMIMECapabilities ::= SEQUENCE OF SMIMECapability, ordered by preference
230
230
  // (RFC 8551 sec. 2.5.2), never sorted; an empty list is legal.
231
231
  var SMIME_CAPABILITIES = schema.seqOf(SMIME_CAPABILITY, {
232
232
  assert: "sequence", min: 0, code: "smime/bad-capabilities", what: "SMIMECapabilities",
@@ -241,7 +241,7 @@ var SMIME_CAPABILITIES = schema.seqOf(SMIME_CAPABILITY, {
241
241
  * @spec RFC 5035, RFC 2634
242
242
  * @related pki.schema.smime.parseSigningCertificateV2, pki.schema.smime.decodeAttribute
243
243
  *
244
- * Decode an ESS v1 `SigningCertificate` attribute value (RFC 5035 sec. 5.4.2) -- the
244
+ * Decode an ESS v1 `SigningCertificate` attribute value (RFC 5035 sec. 5.4.2): the
245
245
  * raw `AttributeValue` a CMS consumer plucks off `SignerInfo.signedAttrs`. Returns
246
246
  * `{ certs, policies }`: each `certs` entry is `{ certHash, hashAlgorithm,
247
247
  * issuerSerial }` in wire order (the first is the signing certificate), where
@@ -291,7 +291,7 @@ var parseSigningCertificateV2 = pkix.makeParser({ pemLabel: null, PemError: PemE
291
291
  * @related pki.schema.smime.decodeAttribute
292
292
  *
293
293
  * Decode an `SMIMECapabilities` attribute value (RFC 8551 sec. 2.5.2) into
294
- * `{ capabilities }` -- an ORDERED list (preference order, never sorted), each
294
+ * `{ capabilities }`, an ordered list (preference order, never sorted), each
295
295
  * `{ capabilityID, name, parameters }` with `parameters` the raw
296
296
  * `ANY DEFINED BY capabilityID` bytes (or `null`). Throws a typed `smime/*` error
297
297
  * on malformed input.
@@ -315,8 +315,8 @@ var parseSmimeCapabilities = pkix.makeParser({ pemLabel: null, PemError: PemErro
315
315
  * OID-dispatch convenience over the three value decoders for a CMS-shaped
316
316
  * `{ type, values }` attribute (the shape `cms.parse` surfaces on
317
317
  * `signerInfos[i].signedAttrs`). Enforces the single-`AttributeValue` rule
318
- * (RFC 8551 sec. 2.5.2 / sec. 2.5) -- a `values` length other than 1 is rejected
319
- * `smime/multi-valued-attribute` -- then routes on `attr.type`:
318
+ * (RFC 8551 sec. 2.5.2 / sec. 2.5), so a `values` length other than 1 is rejected
319
+ * `smime/multi-valued-attribute`, then routes on `attr.type`:
320
320
  * `signingCertificate` / `signingCertificateV2` / `smimeCapabilities` decode to
321
321
  * `{ kind, ...result }`; any other type is recognize-and-deferred
322
322
  * `smime/unsupported-attribute` (its `type`, registry `name`, and raw `values`
package/lib/schema-tsp.js CHANGED
@@ -28,7 +28,7 @@
28
28
  * verification-layer concerns above parse altitude. DER-only, fail-closed.
29
29
  *
30
30
  * @card
31
- * Parse DER / PEM RFC 3161 timestamp responses and tokens -- per-response status,
31
+ * Parse DER / PEM RFC 3161 timestamp responses and tokens: per-response status,
32
32
  * the TSTInfo payload (imprint, genTime, serial, nonce, accuracy), raw verifier
33
33
  * inputs, single-signer token composition over CMS, fail-closed.
34
34
  */
@@ -48,7 +48,7 @@ var NS = pkix.makeNS("tsp", TspError, oid);
48
48
  var ALGORITHM_IDENTIFIER = pkix.algorithmIdentifier(NS);
49
49
  var EXTENSION = pkix.extension(NS);
50
50
 
51
- // TSTInfo.version is INTEGER { v1(1) } -- the only legal value is 1.
51
+ // TSTInfo.version is INTEGER { v1(1) }; the only legal value is 1.
52
52
  var VERSION = pkix.versionReader(NS, { "1": 1 });
53
53
 
54
54
  // id-ct-TSTInfo is the eContentType that identifies a timestamp token (RFC 3161
@@ -77,7 +77,7 @@ var FAILURE_BITS = {
77
77
  // RFC 3161 genTime may carry sub-second precision (X.690 sec. 11.7 fractional profile).
78
78
  var GEN_TIME = pkix.generalizedTime(NS, { code: "tsp/bad-gentime", message: "genTime must be a GeneralizedTime (RFC 3161 sec. 2.4.2)", allowFractional: true });
79
79
 
80
- // tsa [0] EXPLICIT GeneralName (RFC 3161 sec. 2.4.2) -- validated + surfaced raw via the
80
+ // tsa [0] EXPLICIT GeneralName (RFC 3161 sec. 2.4.2), validated and surfaced raw via the
81
81
  // shared pkix.generalName primitive (RFC 5280 sec. 4.2.1.6), which checks the chosen
82
82
  // alternative's form and content so a malformed GeneralName fails closed.
83
83
  var GENERAL_NAME_RAW = pkix.generalName(NS, { code: "tsp/bad-tsa" });
@@ -88,7 +88,7 @@ var UTF8_TEXT = pkix.utf8Text(NS, { code: "tsp/bad-status-info", message: "PKIFr
88
88
  // ---- MessageImprint --------------------------------------------------
89
89
 
90
90
  // MessageImprint ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, hashedMessage
91
- // OCTET STRING } (RFC 3161 sec. 2.4.1). hashedMessage is a digest -- surfaced RAW.
91
+ // OCTET STRING } (RFC 3161 sec. 2.4.1). hashedMessage is a digest, surfaced raw.
92
92
  var MESSAGE_IMPRINT = schema.seq([
93
93
  schema.field("hashAlgorithm", ALGORITHM_IDENTIFIER),
94
94
  schema.field("hashedMessage", schema.octetString()),
@@ -224,9 +224,9 @@ function _assertMinimalNamedBits(unusedBits, bytes) {
224
224
  }
225
225
 
226
226
  // Decode the set NamedBitList bits to their RFC 3161 names (bit 0 = MSB of byte 0).
227
- // A set bit outside the defined set is an unsupported PKIFailureInfo value -- a client
227
+ // A set bit outside the defined set is an unsupported PKIFailureInfo value, and a client
228
228
  // MUST error on a failInfo it does not understand (RFC 3161 sec. 2.4.2), so reject it
229
- // rather than surfacing an opaque "bitN".
229
+ // instead of surfacing an opaque "bitN".
230
230
  function _namedBits(bytes) {
231
231
  var out = [];
232
232
  for (var i = 0; i < bytes.length * 8; i++) {
@@ -257,11 +257,11 @@ var TIME_STAMP_RESP = schema.seq([
257
257
  var granted = status.status === 0 || status.status === 1;
258
258
  if (granted && !present) throw NS.E("tsp/missing-token", "a granted TimeStampResp must carry a timeStampToken (RFC 3161 sec. 2.4.2)");
259
259
  if (!granted && present) throw NS.E("tsp/unexpected-token", "a non-granted TimeStampResp must not carry a timeStampToken (RFC 3161 sec. 2.4.2)");
260
- // failInfo is the reason a request was rejected, so it is present ONLY when the
261
- // status is rejection(2) -- not on granted(0/1) nor on waiting / revocation* (3/4/5).
260
+ // failInfo is the reason a request was rejected, so it is present only when the
261
+ // status is rejection(2), never on granted(0/1) nor on waiting / revocation* (3/4/5).
262
262
  if (status.status !== 2 && status.failInfo) throw NS.E("tsp/unexpected-failinfo", "failInfo is present only when the status is rejection(2) (RFC 3161 sec. 2.4.2)");
263
- // A granted response's timeStampToken MUST be a well-formed TimeStampToken --
264
- // decode it (composing the CMS parser) rather than surfacing arbitrary SEQUENCE
263
+ // A granted response's timeStampToken MUST be a well-formed TimeStampToken, so
264
+ // decode it (composing the CMS parser) instead of surfacing arbitrary SEQUENCE
265
265
  // bytes as a token; a malformed token fails the response parse.
266
266
  return {
267
267
  status: status.status,
@@ -407,9 +407,9 @@ var parse = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: Ts
407
407
  * attached (`tsp/detached-token`), the single-signer rule (`tsp/multi-signer`,
408
408
  * RFC 3161 sec. 2.4.2), and that the signerInfo carries a SigningCertificate or
409
409
  * SigningCertificateV2 signed attribute (`tsp/missing-signing-certificate`,
410
- * RFC 3161 sec. 2.4.2 / RFC 5816 -- the hash-vs-certificate binding stays a
410
+ * RFC 3161 sec. 2.4.2 / RFC 5816; the hash-vs-certificate binding stays a
411
411
  * verification-layer concern), then decodes the inner `TSTInfo`. Returns
412
- * `{ tstInfo, eContent, signerInfo, certificates }` -- the decoded payload, the raw
412
+ * `{ tstInfo, eContent, signerInfo, certificates }`: the decoded payload, the raw
413
413
  * eContent bytes a verifier hashes for the CMS message-digest, and the CMS signer
414
414
  * material.
415
415
  *
@@ -20,9 +20,9 @@
20
20
  * is named where the registry knows it.
21
21
  *
22
22
  * The raw `tbsCertificate` bytes are returned alongside the parsed
23
- * fields so a signature-verification layer can hash exactly the bytes
24
- * that were signed rather than re-encoding and hoping for round-trip
25
- * fidelity.
23
+ * fields. A signature-verification layer hashes exactly the bytes that
24
+ * were signed, with no re-encoding step whose round-trip fidelity it
25
+ * would have to trust.
26
26
  *
27
27
  * @card
28
28
  * Parse DER / PEM X.509 certificates into structured, validated fields
package/lib/shbs.js CHANGED
@@ -7,14 +7,14 @@
7
7
  * @title Stateful hash-based
8
8
  * @intro Stateful hash-based signature VERIFICATION -- HSS/LMS (RFC 8554),
9
9
  * carried in X.509 by RFC 9802 and in CMS by RFC 9708, profiled by NIST
10
- * SP 800-208. VERIFY ONLY, by deliberate design: stateful hash-based SIGNING
11
- * is catastrophic to get wrong -- each one-time key must be used exactly once,
10
+ * SP 800-208. Verify only, by deliberate design: stateful hash-based signing
11
+ * is catastrophic to get wrong. Each one-time key must be used exactly once,
12
12
  * so the private key embeds a monotonic index whose state must advance and
13
13
  * persist atomically across every signature and every process restart. A single
14
14
  * index reuse (a restored VM snapshot, a crashed writer, a concurrent signer)
15
15
  * forfeits security and can leak enough one-time-key material to forge, which is
16
16
  * why SP 800-208 sec. 8 constrains signing-state handling to hardware. So this
17
- * module NEVER mints a signature -- it verifies signatures produced in an HSM
17
+ * module never mints a signature; it verifies signatures produced in an HSM
18
18
  * elsewhere. Verification is pure public-input SHA-256 / SHAKE256 hashing
19
19
  * (no secret, no side-channel surface), so a pure-JavaScript verifier is safe.
20
20
  * @spec RFC 8554, RFC 9802, RFC 9708, NIST SP 800-208
@@ -104,8 +104,8 @@ function _hash(family, n, parts) {
104
104
  }
105
105
 
106
106
  // ---- bounded big-endian reader (bounds-before-slice; the ct.js TlsReader model
107
- // for a non-DER positional wire, kept shbs-local -- shbs needs u32 typecodes +
108
- // fixed-n reads, not CT's length-prefixed vector helpers) --------------------
107
+ // for a non-DER positional wire, kept shbs-local because shbs needs u32 typecodes
108
+ // and fixed-n reads, not CT's length-prefixed vector helpers) ----------------
109
109
 
110
110
  function Reader(buf, code, label) { this.buf = buf; this.pos = 0; this.code = code; this.label = label; }
111
111
  Reader.prototype._need = function (k) {
@@ -177,7 +177,7 @@ function _lmsVerify(pubBytes, message, sigBytes) {
177
177
  var T1 = pr.take(m);
178
178
 
179
179
  // -- signature (RFC 8554 Algorithm 6a). q first, then the LM-OTS signature,
180
- // then the LMS typecode (AFTER the LM-OTS sig), then the auth path. --
180
+ // then the LMS typecode (after the LM-OTS sig), then the auth path. --
181
181
  if (sigBytes.length < 8) throw _err("shbs/bad-signature", "LMS signature is shorter than 8 bytes");
182
182
  var sr = new Reader(sigBytes, "shbs/bad-signature", "LMS signature");
183
183
  var q = sr.u32();
@@ -185,14 +185,14 @@ function _lmsVerify(pubBytes, message, sigBytes) {
185
185
  // The public key -- never the attacker-controlled signature -- is the authority
186
186
  // (downgrade defense): a signature whose OTS typecode does not equal the one the
187
187
  // public key commits to cannot verify against it. RFC 8554 Algorithm 6a checks
188
- // the typecode (step 2c, and 2g for the LMS type below) BEFORE the length (steps
189
- // 2d / 2i), and returns INVALID -- a verification FAILURE (false), not a
190
- // structural error. So a mismatch is `false` at this point EVEN for a blob too
188
+ // the typecode (step 2c, and 2g for the LMS type below) before the length (steps
189
+ // 2d / 2i), and returns INVALID, a verification failure (false) and not a
190
+ // structural error. So a mismatch is `false` at this point even for a blob too
191
191
  // short to be a complete signature: the mismatch is decidable once q + typecode
192
192
  // are read (the bounded reader already threw if those 8 bytes are absent). A
193
193
  // matching typecode with a truncated body still throws below (bounds-before-
194
- // slice). Re-sizing the body by the signature's own mismatched typecode -- to
195
- // "fully validate before returning false" -- would violate this order and reject
194
+ // slice). Re-sizing the body by the signature's own mismatched typecode, so as to
195
+ // "fully validate before returning false", would violate this order and reject
196
196
  // a legitimate typecode-mutation test vector as malformed instead of INVALID.
197
197
  if (otsSigType !== otsSet.code) return false;
198
198
  var n = otsSet.n, p = otsSet.p;
@@ -204,10 +204,10 @@ function _lmsVerify(pubBytes, message, sigBytes) {
204
204
  var path = [];
205
205
  for (var pi = 0; pi < h; pi++) path.push(sr.take(m));
206
206
  if (!sr.atEnd()) throw _err("shbs/bad-signature", "LMS signature has " + sr.remaining() + " trailing byte(s)");
207
- // RFC 8554 Algorithm 6a step 2i: a leaf index q >= 2^h is INVALID -- a
208
- // verification FAILURE (false), NOT a structural error. Checked here, AFTER the
209
- // exact-length validation above (a truncated / trailing blob already threw
210
- // typed), against the REGISTRY height, never the blob. 2^h fits Number (h<=25).
207
+ // RFC 8554 Algorithm 6a step 2i: a leaf index q >= 2^h is INVALID, a
208
+ // verification failure (false) and not a structural error. Checked here, after
209
+ // the exact-length validation above (a truncated or trailing blob already threw
210
+ // typed), against the registry height and never the blob. 2^h fits Number (h<=25).
211
211
  if (q >= Math.pow(2, h)) return false;
212
212
 
213
213
  // -- recompute the LM-OTS public-key candidate, then fold the Merkle path --
@@ -272,7 +272,7 @@ function _hssVerify(pubBytes, message, sigBytes) {
272
272
 
273
273
  var sr = new Reader(sigBytes, "shbs/bad-signature", "HSS signature");
274
274
  var Nspk = sr.u32();
275
- // The level-count gate, checked BEFORE parsing any component (RFC 8554 sec. 6.3).
275
+ // The level-count gate, checked before parsing any component (RFC 8554 sec. 6.3).
276
276
  if (Nspk + 1 !== L) throw _err("shbs/bad-signature", "HSS Nspk+1 (" + (Nspk + 1) + ") does not equal the public-key level count L (" + L + ")");
277
277
 
278
278
  var key = topKey;
@@ -312,7 +312,7 @@ function _asBytes(x, label) { return guard.bytes.source(x, ShbsError, "shbs/bad-
312
312
  * Returns true for a valid signature, false for a well-formed signature that does
313
313
  * not verify; a malformed blob (bad length, unknown or unapproved typecode,
314
314
  * truncation, a typecode disagreeing between the key and the signature) throws a
315
- * typed `ShbsError`. VERIFY ONLY -- this module never signs.
315
+ * typed `ShbsError`. Verification only: this module never signs.
316
316
  *
317
317
  * @example
318
318
  * // throws: shbs/bad-public-key -- an Ed25519 key is not an HSS public key, and
@@ -337,7 +337,7 @@ function verify(publicKey, message, signature) {
337
337
  * @spec RFC 8554 sec. 5
338
338
  * @related pki.shbs.verify
339
339
  *
340
- * Verify a single-tree LMS (Leighton-Micali Signature) over `message` -- the
340
+ * Verify a single-tree LMS (Leighton-Micali Signature) over `message`: the
341
341
  * component an HSS hierarchy composes at each level, and a standalone algorithm
342
342
  * in its own right. Same verdict contract as `pki.shbs.verify`: true / false for
343
343
  * a well-formed signature, a typed `ShbsError` for a malformed blob.
@@ -4,10 +4,10 @@
4
4
  //
5
5
  // @internal -- no operator-facing namespace. The signature-scheme resolver + signer shared by
6
6
  // every producer that signs a raw preimage with a certificate's key: pki.cms.sign (SignerInfo),
7
- // pki.ocsp.sign (BasicOCSPResponse), and future X.509 / CRL issuance. It owns the ONE key ->
7
+ // pki.ocsp.sign (BasicOCSPResponse), and future X.509 / CRL issuance. It owns the single key ->
8
8
  // { signatureAlgorithm, WebCrypto import/sign params } dispatch across the whole algorithm set
9
9
  // (RSA-PKCS1 / RSA-PSS / ECDSA P-256/384/521 / Ed25519 / Ed448 / ML-DSA / SLH-DSA / composite
10
- // ML-DSA), so a new signer surface inherits the full registry -- PQC included -- instead of
10
+ // ML-DSA), so a new signer surface inherits the full registry, PQC included, instead of
11
11
  // re-deriving a partial, drifting copy (Hard rule #2: registry not switch; and no second signer).
12
12
  //
13
13
  // Error-parameterized like the guard / validator families: the caller passes its typed error
@@ -31,8 +31,8 @@ var HASH = { sha256: "SHA-256", sha384: "SHA-384", sha512: "SHA-512" };
31
31
  var NODE_DIGEST = { sha256: "sha256", sha384: "sha384", sha512: "sha512", shake128: "shake128", shake256: "shake256" };
32
32
  var PSS_SALT = { "SHA-256": 32, "SHA-384": 48, "SHA-512": 64 };
33
33
  var ECDSA_ALG = { sha256: "ecdsaWithSHA256", sha384: "ecdsaWithSHA384", sha512: "ecdsaWithSHA512" };
34
- // RSA-PKCS1 signatures fold the digest into a combined signature OID when there is NO separate
35
- // digestAlgorithm field to carry it (X.509 / CRL / OCSP -- RFC 5280 sec. 4.1.1.2, RFC 6960). CMS
34
+ // RSA-PKCS1 signatures fold the digest into a combined signature OID when there is no separate
35
+ // digestAlgorithm field to carry it (X.509 / CRL / OCSP; RFC 5280 sec. 4.1.1.2, RFC 6960). CMS
36
36
  // SignerInfo has that field, so it signs under the bare rsaEncryption key OID instead.
37
37
  var RSA_PKCS1_SIG = { sha256: "sha256WithRSAEncryption", sha384: "sha384WithRSAEncryption", sha512: "sha512WithRSAEncryption" };
38
38
  var HASH_NAME_BY_OID = {};
@@ -115,8 +115,8 @@ function _pssHashFromSpki(cert, E) {
115
115
  function pssSpkiPinnedHash(cert, E) {
116
116
  var d = _pssHashFromSpki(cert, E);
117
117
  if (!d) return null;
118
- // A pin this toolkit has no WebCrypto hash for -- SHA-1, which RSASSA-PSS-params names by DEFAULT
119
- // -- is still a pin. Returning undefined here would hand the caller a falsy value it reads as
118
+ // A pin this toolkit has no WebCrypto hash for (SHA-1, which RSASSA-PSS-params names by DEFAULT)
119
+ // is still a pin. Returning undefined here would hand the caller a falsy value it reads as
120
120
  // "unrestricted", which is the same fail-open the DEFAULT reading above exists to close, one
121
121
  // layer up.
122
122
  if (!HASH[d]) throw E("unsupported-algorithm", "the id-RSASSA-PSS key is restricted to " + d + ", which this toolkit does not verify with");
@@ -124,7 +124,7 @@ function pssSpkiPinnedHash(cert, E) {
124
124
  }
125
125
 
126
126
  // resolveSignScheme(cert, so, noSignedAttrs, E) -> the signature scheme from the signer cert's
127
- // public-key algorithm + per-signer opts (so.digestAlgorithm / so.pss / so.combinedRsaSig -- the
127
+ // public-key algorithm + per-signer opts (so.digestAlgorithm / so.pss / so.combinedRsaSig, the
128
128
  // last folds the digest into a combined RSA signature OID for a caller with no digestAlgorithm
129
129
  // field). Returns
130
130
  // { composite?, digest, digestAlgId, sigAlgId, imp?, sign?, ecdsaDer?, coordLen? }. `digest`/
@@ -188,14 +188,14 @@ function resolveSignScheme(cert, so, noSignedAttrs, E) {
188
188
  // A CryptoKey's algorithm must match the resolved scheme (name / hash / curve).
189
189
  function _assertKeyMatchesScheme(key, imp, E) {
190
190
  var ka = key.algorithm || {};
191
- // WebCrypto algorithm names are ASCII-case-insensitive (RSASSA-PKCS1-v1_5 == RSASSA-PKCS1-V1_5 is the SAME
192
- // algorithm), so compare case-folded -- a genuine mismatch (e.g. RSASSA-PKCS1-v1_5 vs ECDSA) still fails.
191
+ // WebCrypto algorithm names are ASCII-case-insensitive (RSASSA-PKCS1-v1_5 and RSASSA-PKCS1-V1_5 are one
192
+ // algorithm), so compare case-folded; a genuine mismatch (e.g. RSASSA-PKCS1-v1_5 vs ECDSA) still fails.
193
193
  if (String(ka.name).toUpperCase() !== String(imp.name).toUpperCase()) throw E("bad-input", "the signer CryptoKey algorithm (" + ka.name + ") does not match the certificate's key algorithm (" + imp.name + ")");
194
194
  if (imp.hash && (!ka.hash || ka.hash.name !== imp.hash)) throw E("bad-input", "the signer CryptoKey hash (" + (ka.hash && ka.hash.name) + ") does not match the signing digest (" + imp.hash + ")");
195
195
  if (imp.namedCurve && ka.namedCurve !== imp.namedCurve) throw E("bad-input", "the signer CryptoKey curve (" + ka.namedCurve + ") does not match the certificate curve (" + imp.namedCurve + ")");
196
196
  }
197
197
  function _normPkcs8(k, label, E) {
198
- // A caller's own Buffer is BORROWED, not copied -- the same rule _importKey states below. Every
198
+ // A caller's own Buffer is borrowed, not copied, the same rule _importKey states below. Every
199
199
  // other form is copied, and neither copy is duplicated further, so a private key never gains a
200
200
  // plaintext duplicate this module cannot account for.
201
201
  if (Buffer.isBuffer(k)) return guard.bytes.view(k, E, "bad-input", label);
@@ -217,8 +217,8 @@ function _importKey(key, imp, E) {
217
217
  // signs with. One whose material this process cannot reach is refused with that as the reason.
218
218
  return webcrypto.adoptKey(key, imp, ["sign"], E, "bad-input");
219
219
  }
220
- // A Uint8Array is copied here and a PEM string is decoded here, so both leave a SECOND copy of a
221
- // private key that nothing else can reach -- wiped once the engine has imported it, which is the
220
+ // A Uint8Array is copied here and a PEM string is decoded here, so both leave a second copy of a
221
+ // private key that nothing else can reach, wiped once the engine has imported it, which is the
222
222
  // only thing that reads it. A caller's own Buffer is passed through untouched: they hold a live
223
223
  // reference and will use it again, so clearing it would destroy their key.
224
224
  var der, owned = false;
@@ -243,7 +243,7 @@ function _importKey(key, imp, E) {
243
243
 
244
244
  // signOverTbs(scheme, key, signedBytes, E) -> Promise<Buffer> the raw signature over signedBytes.
245
245
  // The classical path imports the key + signs (re-encoding ECDSA to canonical DER); the composite
246
- // path signs BOTH component keys and returns mldsaSig || tradSig (composite-sig.js owns it).
246
+ // path signs both component keys and returns mldsaSig || tradSig (composite-sig.js owns it).
247
247
  function signOverTbs(scheme, key, signedBytes, E) {
248
248
  if (scheme.composite) {
249
249
  return compositeSig.compositeSign(scheme.composite, _normCompositeKeys(key, scheme.composite, E), signedBytes).then(function (sig) { return Buffer.from(sig); });
package/lib/sigstore.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * @module pki.sigstore
6
6
  * @nav Supply chain
7
7
  * @title Sigstore
8
- * @intro Zero-dependency verifier for a Sigstore bundle -- the exact artifact
8
+ * @intro Zero-dependency verifier for a Sigstore bundle, the exact artifact
9
9
  * `npm publish --provenance` produces and the npm registry serves at its
10
10
  * attestations API. A bundle is a keyless (Fulcio) signature over a DSSE-wrapped
11
11
  * in-toto SLSA provenance attestation, with a Rekor transparency-log inclusion
@@ -114,7 +114,7 @@ function _b64(s, label) {
114
114
  * Buffer) fail-closed: a non-object, malformed JSON, an oversize input, an
115
115
  * unknown `mediaType`, or a missing required member throws a typed
116
116
  * `sigstore/bad-bundle` / `sigstore/bad-bundle-version`. Returns the validated
117
- * bundle object (structure only -- no cryptographic verification).
117
+ * bundle object (structure only, no cryptographic verification).
118
118
  *
119
119
  * @example
120
120
  * // requires: `bundle` -- a Sigstore bundle as cosign or npm provenance emits it
@@ -604,18 +604,17 @@ function _statement(payload, payloadType, expectedPredicate) {
604
604
  * the log entry bound to this exact signature; and the in-toto SLSA statement.
605
605
  * Any leg failing throws a typed `sigstore/*` error. On success returns
606
606
  * `{ verified: true, payload, statement, subjects, predicateType, predicate,
607
- * identity, identityChecked, integratedTime }` -- `payload` is the RAW verified
607
+ * identity, identityChecked, integratedTime }`. `payload` is the raw verified
608
608
  * envelope bytes (never a re-serialization), and the caller confirms a
609
609
  * `subjects[].digest` matches the published artifact.
610
610
  *
611
- * `verified: true` says the artifact was signed and logged -- not that a party you
612
- * trust signed it. Fulcio issues a certificate to anyone who completes an OIDC
613
- * flow, so WHO signed is decided only by `opts.identity`, and `identityChecked`
614
- * reports which of its fields were compared (`{ san, issuer, sourceRepositoryURI }`,
615
- * each a boolean). An `identity` naming none of them is refused rather than
616
- * satisfied, since it would accept every signer while reading as a policy; so is an
617
- * unrecognized field name, which would otherwise pin nothing under a spelling the
618
- * operator believes constrains the signer.
611
+ * `verified: true` says the artifact was signed and logged; it says nothing about
612
+ * who. Fulcio issues a certificate to anyone who completes an OIDC flow, so who
613
+ * signed is decided only by `opts.identity`, and `identityChecked` reports which of
614
+ * its fields were compared (`{ san, issuer, sourceRepositoryURI }`, each a boolean).
615
+ * An `identity` naming none of them is refused, since it would accept every signer
616
+ * while reading as a policy; so is an unrecognized field name, which would otherwise
617
+ * pin nothing under a spelling the operator believes constrains the signer.
619
618
  *
620
619
  * @opts
621
620
  * fulcioRoots: Array, // the Fulcio CA anchors: a DER Buffer or { der, validFor } each
package/lib/sleep.js CHANGED
@@ -6,7 +6,7 @@
6
6
  // pki.cmp.session). A delay above Node's 32-bit setTimeout ceiling is SPLIT into chained maximum-size
7
7
  // chunks: a bare setTimeout(fn, > 2^31-1) is silently clamped to 1 ms (a TimeoutOverflowWarning) and would
8
8
  // then rapidly re-poll instead of waiting the full interval. Each client's opts.sleep overrides this in
9
- // tests, so this default -- the ONLY sleeper that touches a real timer -- is never driven by a test wait.
9
+ // tests, so this default, the one sleeper that touches a real timer, is never driven by a test wait.
10
10
 
11
11
  var SETTIMEOUT_MAX_MS = 2147483647; // 2^31 - 1: Node's setTimeout delay ceiling
12
12