@blamejs/pki 0.6.14 → 0.6.16

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 (112) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/lib/acme.js +59 -815
  3. package/lib/asn1-der.js +7 -245
  4. package/lib/attrcert-sign.js +12 -260
  5. package/lib/attrcert-verify.js +1 -7
  6. package/lib/byte-reader.js +0 -8
  7. package/lib/byte-writer.js +0 -11
  8. package/lib/cbor-det.js +0 -54
  9. package/lib/cmc-build.js +15 -357
  10. package/lib/cmc-verify.js +6 -239
  11. package/lib/cmp-build.js +41 -317
  12. package/lib/cmp-session.js +73 -760
  13. package/lib/cmp-verify.js +32 -488
  14. package/lib/cms-compress.js +3 -32
  15. package/lib/cms-decrypt.js +29 -294
  16. package/lib/cms-encrypt.js +14 -234
  17. package/lib/cms-sign.js +29 -324
  18. package/lib/cms-verify.js +9 -500
  19. package/lib/composite-kem.js +2 -102
  20. package/lib/composite-sig.js +1 -77
  21. package/lib/constants.js +0 -249
  22. package/lib/crl-sign.js +9 -237
  23. package/lib/crl-verify.js +1 -10
  24. package/lib/crmf-sign.js +19 -198
  25. package/lib/crmf-verify.js +1 -12
  26. package/lib/csr-sign.js +3 -34
  27. package/lib/csr-verify.js +1 -12
  28. package/lib/ct.js +28 -253
  29. package/lib/edwards-point.js +10 -44
  30. package/lib/est.js +28 -764
  31. package/lib/framework-error.js +4 -182
  32. package/lib/guard-all.js +1 -58
  33. package/lib/guard-async.js +1 -36
  34. package/lib/guard-bytes.js +6 -650
  35. package/lib/guard-compress.js +5 -102
  36. package/lib/guard-crypto.js +1 -40
  37. package/lib/guard-der.js +2 -93
  38. package/lib/guard-encoding.js +2 -60
  39. package/lib/guard-header.js +1 -36
  40. package/lib/guard-identifier.js +7 -531
  41. package/lib/guard-intrinsic.js +1 -150
  42. package/lib/guard-json.js +10 -73
  43. package/lib/guard-limits.js +1 -77
  44. package/lib/guard-list.js +1 -49
  45. package/lib/guard-name.js +3 -209
  46. package/lib/guard-parsed.js +7 -335
  47. package/lib/guard-range.js +1 -71
  48. package/lib/guard-secret.js +1 -102
  49. package/lib/guard-text.js +1 -64
  50. package/lib/guard-time.js +1 -97
  51. package/lib/hpke.js +3 -105
  52. package/lib/http-digest.js +14 -142
  53. package/lib/http-retry-after.js +1 -47
  54. package/lib/http-transport.js +21 -131
  55. package/lib/inspect.js +30 -284
  56. package/lib/ip-utils.js +6 -47
  57. package/lib/jose.js +7 -142
  58. package/lib/key.js +2 -67
  59. package/lib/lint.js +9 -194
  60. package/lib/merkle.js +1 -27
  61. package/lib/mime.js +9 -82
  62. package/lib/ocsp-request-verify.js +1 -14
  63. package/lib/ocsp-verify.js +1 -82
  64. package/lib/ocsp.js +11 -169
  65. package/lib/oid.js +5 -337
  66. package/lib/path-validate.js +103 -1492
  67. package/lib/pbes2.js +2 -89
  68. package/lib/pkcs12-build.js +31 -379
  69. package/lib/pki-build.js +64 -290
  70. package/lib/rc2.js +2 -18
  71. package/lib/rfc3339.js +4 -27
  72. package/lib/scep.js +140 -286
  73. package/lib/schema-all.js +0 -122
  74. package/lib/schema-attrcert.js +4 -146
  75. package/lib/schema-c509.js +153 -802
  76. package/lib/schema-cmc.js +5 -220
  77. package/lib/schema-cmp.js +2 -223
  78. package/lib/schema-cms.js +13 -427
  79. package/lib/schema-crl.js +5 -68
  80. package/lib/schema-crmf.js +6 -167
  81. package/lib/schema-csr.js +1 -54
  82. package/lib/schema-csrattrs.js +2 -87
  83. package/lib/schema-engine.js +0 -152
  84. package/lib/schema-ocsp.js +0 -117
  85. package/lib/schema-pkcs12.js +2 -93
  86. package/lib/schema-pkcs8.js +3 -35
  87. package/lib/schema-pkix.js +24 -655
  88. package/lib/schema-smime.js +0 -54
  89. package/lib/schema-tsp.js +3 -99
  90. package/lib/schema-x509.js +4 -63
  91. package/lib/shbs.js +11 -95
  92. package/lib/sign-scheme.js +2 -97
  93. package/lib/sigstore.js +9 -169
  94. package/lib/sleep.js +2 -8
  95. package/lib/smime.js +15 -408
  96. package/lib/tls-cert-compress.js +0 -62
  97. package/lib/trust.js +19 -185
  98. package/lib/tsp-sign.js +16 -270
  99. package/lib/validator-all.js +1 -30
  100. package/lib/validator-attcert.js +2 -46
  101. package/lib/validator-cose.js +2 -153
  102. package/lib/validator-keydesc.js +1 -37
  103. package/lib/validator-sig.js +1 -46
  104. package/lib/validator-tls.js +1 -88
  105. package/lib/validator-tpm.js +19 -122
  106. package/lib/verify-seam.js +1 -24
  107. package/lib/webauthn-mds.js +3 -400
  108. package/lib/webauthn.js +12 -833
  109. package/lib/webcrypto.js +5 -485
  110. package/lib/x509-sign.js +4 -108
  111. package/package.json +1 -1
  112. package/sbom.cdx.json +6 -6
package/lib/constants.js CHANGED
@@ -32,8 +32,6 @@ var frameworkError = require("./framework-error");
32
32
 
33
33
  var ConstantsError = frameworkError.ConstantsError;
34
34
 
35
- // _positive(n, who) is the shared guard every scale helper runs. Config-
36
- // time tier: a bad scale argument is an authoring bug, so it throws.
37
35
  function _positive(n, who) {
38
36
  if (typeof n !== "number" || !isFinite(n) || n < 0) {
39
37
  throw new ConstantsError(
@@ -44,11 +42,6 @@ function _positive(n, who) {
44
42
  return n;
45
43
  }
46
44
 
47
- // _scale(n, who, factor) validates the argument and the product. A finite
48
- // operand can still overflow the multiplication (days(1e304) -> Infinity),
49
- // and an Infinity handed onward silently disables any bound compared
50
- // against it (`len > Infinity` is always false), so a product outside the
51
- // safe-integer range throws instead of returning.
52
45
  function _scale(n, who, factor) {
53
46
  var out = Math.round(_positive(n, who) * factor);
54
47
  if (!Number.isSafeInteger(out)) {
@@ -115,265 +108,61 @@ var BYTES = {
115
108
  gib: function (n) { return _scale(n, "C.BYTES.gib", BYTES_PER_KIB * BYTES_PER_KIB * BYTES_PER_KIB); },
116
109
  };
117
110
 
118
- // LIMITS -- shared codec ceilings. A DER document larger than this, or
119
- // nested deeper than this, is refused before the parser walks it: an
120
- // unbounded length prefix or a pathologically-nested SEQUENCE is a
121
- // classic decoder-DoS, so the bound is a fail-closed default rather
122
- // than a tunable an operator must remember to set.
123
- //
124
- // DER_MAX_INTEGER_BYTES and OID_MAX_SUBIDENTIFIER_BYTES are per-value
125
- // ceilings the whole-document cap can't provide: a single INTEGER or OID
126
- // sub-identifier under the 16 MiB limit can still carry hundreds of KiB,
127
- // so a value reader that scales super-linearly in its content length is a
128
- // decoder-DoS the document cap does not stop. 16 KiB covers any real key
129
- // material (an RSA-131072 modulus), and 32 bytes covers any real OID arc:
130
- // the largest standard sub-identifier is a 128-bit UUID-based arc (X.667,
131
- // e.g. 2.25.<uuid>), which is 19 base-128 bytes -- so the cap must exceed
132
- // that, not sit at 16. Anything larger than 32 bytes is refused as hostile.
133
111
  var LIMITS = {
134
112
  DER_MAX_BYTES: BYTES.mib(16),
135
113
  DER_MAX_DEPTH: 64,
136
- // Total decoded-node ceiling: the DER decoder builds an eager node tree, so a
137
- // dense run of tiny TLVs (a 2-byte NULL is a node) fans a small input into a
138
- // huge tree -- ~350 B/node, so a 16 MiB input of NULLs is ~8M nodes ~= 2.8 GiB.
139
- // 4M sits well above the largest realistic structure (a full 16 MiB CRL carries
140
- // ~500k revoked entries ~= 2.5M nodes) and below the dense-bomb count; the
141
- // operator may override via opts.maxItems. (The CBOR sibling caps at 1M, too
142
- // low for DER's legitimate large CRLs.)
143
114
  DER_MAX_ITEMS: 4000000,
144
- // Hard stack-safe ceiling on the recursion depth of the DER / CBOR
145
- // decoders, independent of the (operator-tunable) maxDepth. Both decoders
146
- // are recursive descent; a maxDepth raised above the engine's native call-
147
- // stack limit would let deeply nested input overflow the C stack with a raw
148
- // RangeError instead of the typed too-deep verdict, defeating the fail-closed
149
- // contract. A maxDepth above this ceiling is refused at config time. 256 is
150
- // four times the default cap and far deeper than any real PKI / CBOR nesting
151
- // (a certificate is ~6 levels; the deepest bounded re-decode is 16), while
152
- // staying well below the overflow threshold on any supported platform.
153
115
  MAX_DECODE_DEPTH_CEILING: 256,
154
116
  PEM_MAX_BYTES: BYTES.mib(16),
155
117
  DER_MAX_INTEGER_BYTES: BYTES.kib(16),
156
118
  OID_MAX_SUBIDENTIFIER_BYTES: 32,
157
- // Network transport response ceiling (pki.transport / the EST client). A remote
158
- // server's HTTP response body is bounded WHILE it streams -- the accumulator
159
- // aborts the socket the instant the running total crosses this cap, before the
160
- // body reaches a decoder, so a malicious length field cannot drive unbounded
161
- // allocation (RFC 7030 sec. 6). Sized above a base64-inflated DER_MAX_BYTES
162
- // document plus multipart/header overhead (16 MiB * 4/3 ~= 21.3 MiB); 24 MiB
163
- // clears it. An operator may only tighten it DOWNWARD via opts.maxResponseBytes.
164
119
  HTTP_MAX_RESPONSE_BYTES: BYTES.mib(24),
165
- // A single untrusted WWW-Authenticate challenge header, bounded BEFORE the string
166
- // is copied/tokenized so a hostile server cannot drive unbounded work parsing it
167
- // (CWE-770). 8 KiB clears any realistic multi-scheme Digest challenge.
168
120
  HTTP_AUTH_HEADER_MAX_BYTES: BYTES.kib(8),
169
- // Deterministic-CBOR codec ceilings (RFC 8949), the DER neighbors' siblings:
170
- // a whole-document cap refused before the walk, a nesting cap, and a per-value
171
- // bignum ceiling the document cap can't provide. Unlike DER_MAX_INTEGER_BYTES,
172
- // the bignum cap carries NO +1 sign octet -- a CBOR tag-2/3 bignum body is pure
173
- // unsigned big-endian magnitude (RFC 8949 sec. 3.4.3), so 16 KiB is the exact
174
- // byte ceiling (covers an RSA-131072 modulus).
175
121
  CBOR_MAX_BYTES: BYTES.mib(16),
176
122
  CBOR_MAX_DEPTH: 64,
177
123
  CBOR_MAX_BIGUINT_BYTES: BYTES.kib(16),
178
- // Total decoded-item ceiling. A definite-length array or map can declare a
179
- // huge element count that stays under the byte cap yet allocates one node per
180
- // element -- e.g. a 16 MiB input of `9a00fffffb` followed by ~16 million
181
- // one-byte items would build ~16 million nodes and exhaust memory before a
182
- // typed verdict. The decoder counts every item it builds and refuses past this
183
- // cap, so a high-fanout bomb fails closed with cbor/too-many-items instead of
184
- // OOM-ing. 1,000,000 is far above any real CBOR-encoded PKI structure (a C509
185
- // certificate or COSE message is hundreds of items) while bounding the tree.
186
124
  CBOR_MAX_ITEMS: 1000000,
187
- // Certificate Transparency SCT-list bounds (RFC 6962 sec. 3.3). The outer sct_list
188
- // vector carries a 2-byte length prefix, so a well-formed list body is at most
189
- // 2^16-1 = 65535 bytes and the full TLS blob (prefix + body) is at most 65537.
190
- // The byte cap sits at that structural maximum, so the largest conforming list
191
- // is accepted while an oversized inner OCTET STRING (up to the DER document cap)
192
- // is refused BEFORE the list is walked. The per-list count cap is asserted per
193
- // element DURING the walk (an element count is unknowable before walking
194
- // variable-length elements), bounding total work at SCT_MAX_COUNT+1 elements
195
- // regardless of a hostile length prefix (the CVE-2022-0778 class: crafted bytes
196
- // inside a certificate extension pinning a validator). A real chain carries
197
- // 2-5 SCTs; 256 is far above policy.
198
125
  SCT_MAX_BYTES: BYTES.kib(64) + 1,
199
126
  SCT_MAX_COUNT: 256,
200
- // Merkle-proof node-count ceiling (RFC 6962 / RFC 9162). A DoS backstop that
201
- // rejects a pathologically long proof array BEFORE the O(log n) fold does any
202
- // digest work. 65 is the exact structural maximum: a tree size is a uint64, so
203
- // an audit (inclusion) path is at most ceil(log2(2^64)) = 64 nodes, but a
204
- // consistency proof is at most ceil(log2(newSize)) + 1 = 65 nodes (the extra
205
- // node is the SUBPROOF terminal for a non-power-of-two old size near 2^64). Real
206
- // CT logs are 2^30-2^40 (30-40-node proofs), so 65 is generous headroom while
207
- // still bounding hostile work. The PRECISE per-proof guard is the geometry
208
- // check in each verify (the node count must equal what the coordinates require);
209
- // this is the coarse cap. A node count, not a byte size.
210
127
  MERKLE_MAX_PROOF_NODES: 65,
211
- // Certification-path length ceiling: bounds the per-cert asymmetric verify
212
- // work on an untrusted certificate bundle (a real chain is well under this;
213
- // the operator may override via opts.maxPathCerts).
214
128
  PATH_MAX_CERTS: 100,
215
- // Valid-policy-tree node ceiling: bounds the RFC 5280 6.1.3(d) tree a
216
- // policy-rich hostile chain can grow (the CVE-2023-0464 class). A real
217
- // chain's tree holds a handful of nodes; the operator may override via
218
- // opts.maxPolicyNodes.
219
129
  PATH_MAX_POLICY_NODES: 4096,
220
- // Certification-path BUILDING bounds (pki.path.build). The pool of candidate
221
- // issuers is untrusted, so a cross-certificate cycle or Bridge-CA fan-out can
222
- // grow the number and length of candidate paths without bound (RFC 4158 sec.
223
- // 8.1). PATH_BUILD_MAX_DEPTH caps the chain length explored from the leaf --
224
- // well under PATH_MAX_CERTS so a built path clears the validator's own bound
225
- // on hand-off; a real hierarchy is a handful of hops. PATH_BUILD_MAX_CANDIDATES
226
- // is the total-work ceiling: the builder ticks it once per candidate-issuer
227
- // expansion, so a hostile mesh terminates deterministically. Both are operator
228
- // overridable (opts.maxDepth / opts.maxCandidatesConsidered).
229
130
  PATH_BUILD_MAX_DEPTH: 20,
230
131
  PATH_BUILD_MAX_CANDIDATES: 1000,
231
- // AIA caIssuers network-fetch bounds (pki.path.build with opts.fetchAia). Fetching an issuer over the
232
- // network from an untrusted certificate's authorityInfoAccess opens an SSRF / amplification surface (a
233
- // hostile mesh where each fetched cert advertises a fresh caIssuers URL). PATH_AIA_MAX_FETCHES is the
234
- // TOTAL network GET budget across a whole build() call (a breach throws path/aia-fetch-limit);
235
- // PATH_AIA_MAX_PER_CERT caps how many caIssuers URIs are tried for a single certificate (an AIA MAY carry
236
- // many). Both are small by default and operator-overridable (opts.maxAiaFetches / opts.maxAiaPerCert).
237
132
  PATH_AIA_MAX_FETCHES: 10,
238
133
  PATH_AIA_MAX_PER_CERT: 3,
239
- // A caIssuers response is one certificate or a short chain -- never a 24 MiB bundle. Bounding the AIA
240
- // fetch below the general HTTP ceiling (and capping the certificate COUNT a single response contributes)
241
- // stops a hostile-but-TLS-trusted AIA endpoint from forcing tens of thousands of certificate parses per
242
- // fetch (parse work bounded by COUNT, not only by bytes). Both operator-overridable (opts.maxResponseBytes
243
- // tightens downward only; the count cap is a fixed defense).
244
134
  PATH_AIA_MAX_RESPONSE_BYTES: BYTES.mib(1),
245
135
  PATH_AIA_MAX_CERTS_PER_RESPONSE: 16,
246
- // PKCS#12 container ceilings. A PFX carries lists at three altitudes
247
- // (ContentInfos per AuthenticatedSafe, SafeBags per SafeContents,
248
- // attributes per bag) and can chain fresh DER blobs inside OCTET STRINGs,
249
- // where every re-decode would otherwise restart the depth cap from zero.
250
- // A real keystore holds a handful of keys and certificates; thousands of
251
- // elements or dozens of chained re-decodes is hostile input, not a store.
252
136
  PKCS12_MAX_ELEMENTS: 1024,
253
137
  PKCS12_MAX_REDECODES: 64,
254
138
  PKCS12_MAX_BAG_DEPTH: 16,
255
- // BER constructed-string reassembly copies each nesting level's payload, so
256
- // nesting multiplies transient memory. Real producers segment one level
257
- // deep; nesting past this cap is amplification, not a store.
258
139
  BER_MAX_STRING_NESTING: 8,
259
- // A single attribute's value SET -- no deployed attribute carries more than
260
- // a handful of values; a list at this scale is amplification.
261
140
  ATTRIBUTE_MAX_VALUES: 256,
262
- // JSON message bounds for the JOSE / ACME layer (RFC 8555). Directories and
263
- // resource objects are small (certificates travel as PEM, not JSON); 1 MiB is
264
- // generous headroom. Depth 32 clears the deepest real nesting (a problem
265
- // document's subproblems nest one level) with margin below any stack risk;
266
- // enforced BEFORE parsing so a hostile document is refused up front.
267
141
  JSON_MAX_BYTES: BYTES.mib(1),
268
142
  JSON_MAX_DEPTH: 32,
269
- // The CT log-list JSON ceiling -- the full "all logs" variant (with historical logs) exceeds the
270
- // 1 MiB JSON_MAX_BYTES used for small ACME resource objects; 4 MiB gives headroom while staying bounded.
271
143
  CT_LOG_LIST_MAX_BYTES: BYTES.mib(4),
272
- // PBKDF2 iteration ceiling on the DECRYPT side (RFC 8018 pwri / PBES2). An attacker-supplied
273
- // iterationCount is attacker-controlled work; a message above this is refused before any
274
- // derivation (typed cms/iteration-limit), and a caller may cap it lower via opts.maxIterations.
275
- // 10M clears the authoring default (600k) with generous headroom for high-security policies.
276
144
  PBKDF2_MAX_ITERATIONS: 10000000,
277
145
  PBKDF2_MAX_SALT: 1024,
278
- // A MIME entity / S/MIME message size ceiling -- bounds the header + body decode before a copy.
279
146
  MIME_MAX_BYTES: BYTES.mib(16),
280
- // RFC 5322 sec. 2.1.1: a header line MUST be <= 998 octets excluding the CRLF. A composer that emits a
281
- // longer unfolded field line risks a relay re-folding or rejecting the message -- for multipart/signed
282
- // that re-fold changes the signed bytes and breaks verification -- so an emitted field line is capped here.
283
147
  HEADER_LINE_MAX_OCTETS: 998,
284
- // The decompressed-output ceiling for CMS CompressedData (RFC 3274) -- bounds the inflate BEFORE the
285
- // output is materialized (a decompression-bomb / resource-exhaustion defense, CWE-409); a caller may
286
- // tighten it DOWNWARD via opts.maxOutputBytes, never loosen it.
287
148
  COMPRESS_MAX_BYTES: BYTES.mib(16),
288
- // The largest TLS handshake message body. RFC 8446 sec. 4 frames every Handshake with a uint24
289
- // length, so a Certificate message cannot exceed 2^24-1 bytes -- the ceiling RFC 8879 sec. 5
290
- // requires a CompressedCertificate to respect ("they MUST apply the same limit as if no
291
- // compression were used"). That section spells the number 16777216, which is one MORE than any
292
- // uint24 can express; the field width governs, so this is deliberately not mib(16).
293
149
  TLS_CERT_MSG_MAX_BYTES: BYTES.mib(16) - 1,
294
- // The most CertificateEntry elements a TLS Certificate message may carry. The byte ceiling
295
- // alone does not bound this: the smallest legal entry is 6 bytes (a uint24 length, one payload
296
- // octet, an empty uint16 extensions vector), so a message inside the framing limit can declare
297
- // millions of them and each costs far more heap than wire -- an allocation DoS (CWE-770) that
298
- // terminates but exhausts memory. This matches PATH_MAX_CERTS: a chain longer than the path
299
- // validator will ever accept has nothing to offer, so refusing it at the decoder is free.
300
150
  TLS_CERT_MAX_ENTRIES: 100,
301
- // A FIDO Metadata Service BLOB is a JWS whose payload carries every registered authenticator's
302
- // metadata; the live one runs about 10 MB across ~500 entries. The byte cap bounds the decode
303
- // before the payload is materialized, and the entry and anchor caps bound the per-entry work
304
- // (each anchor is a DER certificate parse), since a byte ceiling alone does not bound how many
305
- // items are declared inside it (CWE-770).
306
151
  MDS_BLOB_MAX_BYTES: BYTES.mib(32),
307
- // The BLOB's JWS protected header is read BEFORE the signature is checked, so it carries its own,
308
- // far smaller ceiling: a header is a few hundred bytes plus the x5c chain, and the envelope cap
309
- // would otherwise let unauthenticated input buy heap ahead of every authentication step.
310
152
  MDS_BLOB_HEADER_MAX_BYTES: BYTES.kib(256),
311
- // The JWS signature, likewise read before anything is authenticated. Every algorithm this reader
312
- // supports has a tightly bounded signature: 64/96/132 bytes for ECDSA P-256/384/521, 64 and 114
313
- // for Ed25519 and Ed448, the modulus size for RSA, and 2420 / 3309 / 4627 for ML-DSA-44/65/87
314
- // (FIPS 204). The bound has to clear the LARGEST of those -- an accepted algorithm whose ordinary
315
- // signature the ceiling refuses is a row that can never verify -- so 8 KiB, which covers ML-DSA-87
316
- // and an RSA-16384 key with room to spare while still refusing a segment whose only purpose is to
317
- // make the verifier allocate.
318
153
  MDS_BLOB_SIG_MAX_BYTES: BYTES.kib(8),
319
154
  MDS_MAX_ENTRIES: 4096,
320
- // A model's certification history: bounded like the other repeated per-entry structures, because
321
- // the status gate walks the whole array on every verification.
322
155
  MDS_MAX_STATUS_REPORTS_PER_ENTRY: 256,
323
156
  MDS_MAX_ANCHORS_PER_ENTRY: 16,
324
- // A U2F authenticator carries no AAGUID, so its entry is keyed by the key identifiers of its
325
- // attestation certificates instead -- a batch-attested product line legitimately registers dozens.
326
157
  MDS_MAX_KEY_IDS_PER_ENTRY: 64,
327
- // The most nested statements a WebAuthn compound attestation (sec. 8.9) may carry. The syntax
328
- // says "2*" -- unbounded -- so this is a resource bound this toolkit chooses, NOT a spec MUST.
329
- // The CBOR parse caps bound the decode; they do not bound the crypto, and each element costs a
330
- // signature verification plus, for some formats, a full certificate-path validation. Seven
331
- // non-compound formats are registered, so a conforming statement carrying one of each is 7.
332
158
  WEBAUTHN_COMPOUND_MAX_STATEMENTS: 16,
333
- // The most certificates a WebAuthn attestation chain may carry, in an attStmt x5c array or a JWS
334
- // x5c header. A real attestation chain is one to four; the byte ceiling on a single entry does
335
- // not bound the COUNT, so an array of thousands of small certificates is an unbounded parse and
336
- // signature-check fanout (CWE-770) that terminates but costs far more CPU than wire. This is a
337
- // resource bound this toolkit chooses -- no specification states it -- and it is far tighter than
338
- // PATH_MAX_CERTS because an attestation chain is not a general PKI path.
339
159
  WEBAUTHN_X5C_MAX_CERTS: 10,
340
- // A WebAuthn android-safetynet attestation statement carries the SafetyNet response as a JWS
341
- // compact serialization: two small JSON objects plus a signature, with the certificate chain
342
- // inline in the header. Real ones run a few kilobytes. The cap bounds the text decode before the
343
- // string is materialized, so an oversized statement is refused rather than allocated (CWE-770).
344
160
  SAFETYNET_JWS_MAX_BYTES: BYTES.kib(64),
345
- // One x5c entry is a single DER certificate; PATH_MAX_CERT_BYTES is the ceiling the path
346
- // validator already applies to any certificate it will accept, and an entry above it could not
347
- // chain even if it decoded.
348
161
  SAFETYNET_CERT_MAX_BYTES: BYTES.kib(64),
349
- // ACME challenge token entropy floor (RFC 8555 sec. 8, errata 6950): >= 128
350
- // bits of base64url is >= 22 characters. A shorter token is refused before use.
351
162
  ACME_TOKEN_MIN_CHARS: 22,
352
- // SCEP transactionID length ceiling (RFC 8894 sec. 3.2.1.1). The RFC sets no
353
- // length; a real transaction id is a short hash or key fingerprint, so the
354
- // builder caps the caller-supplied PrintableString here rather than emitting
355
- // an unbounded attribute.
356
163
  SCEP_TRANSACTION_ID_MAX: 255,
357
- // OCSP embedded-certificate ceiling. A BasicOCSPResponse (or an OCSP request
358
- // Signature) carries the responder / requestor certificate plus at most a short
359
- // chain; the delegated-responder authorization loop verifies each candidate
360
- // BEFORE the response signature is checked, so an attacker-crafted stapled /
361
- // relayed response with a huge certs list would drive unbounded pre-auth
362
- // signature verifies. 32 is generous headroom over a real chain.
363
164
  OCSP_MAX_CERTS: 32,
364
- // HSS hierarchy depth (RFC 8554 sec. 6.1: L is 1..8). The HSS verifier caps
365
- // its per-level parse loop at this from the registry, never at the blob's own
366
- // Nspk, so a hostile signature cannot drive an unbounded level walk.
367
165
  HSS_MAX_LEVELS: 8,
368
- // Trust-store ingestion ceilings (Mozilla/NSS certdata.txt + CCADB CSV).
369
- // Every cap is refused BEFORE the offending allocation with a typed trust/*
370
- // error -- never a silent truncate. A live certdata.txt is a few MiB and a
371
- // CCADB all-records export a few MiB more, so 16 MiB whole-input headroom
372
- // matches the codec siblings. A root certificate (or a CCADB PEM cell) is a
373
- // few KiB; a MULTILINE_OCTAL blob or CSV field past 64 KiB is amplification,
374
- // not a root. The real store is ~150 roots x 2 object blocks (and one CCADB
375
- // row per root), so 10000 objects / rows is generous headroom while bounding
376
- // a block/row bomb.
377
166
  TRUST_MAX_BYTES: BYTES.mib(16),
378
167
  TRUST_MAX_OCTAL_BYTES: BYTES.kib(64),
379
168
  TRUST_MAX_OBJECTS: 10000,
@@ -381,19 +170,7 @@ var LIMITS = {
381
170
  TRUST_MAX_CSV_FIELD_BYTES: BYTES.kib(64),
382
171
  };
383
172
 
384
- // NAMES -- display-naming conventions shared by the human-readable renderers
385
- // (pki.inspect today; a future lint / CLI report tomorrow). Centralized so every
386
- // consumer speaks ONE convention -- the OpenSSL-familiar labels an operator expects
387
- // -- rather than each renderer copying a table that silently drifts. These are
388
- // DISPLAY strings, not wire identifiers (those resolve through pki.oid): a value here
389
- // never affects parse or verify, only how a decoded field is titled in a report.
390
173
  var NAMES = {
391
- // ==== Distinguished-name attribute short names (RFC 4514 sec. 3 + RFC 4519 / CABF) ==
392
- // The single source of truth: this table was previously copied in both
393
- // lib/inspect.js and lib/schema-pkix.js and had already drifted (STREET vs street,
394
- // SERIALNUMBER vs serialNumber). An entry whose type the OID registry does not yet
395
- // resolve is simply never hit -- forward entries (jurisdiction*, organizationIdentifier)
396
- // are harmless until their arc is registered.
397
174
  DN_SHORT: {
398
175
  commonName: "CN", surname: "SN", serialNumber: "SERIALNUMBER", countryName: "C",
399
176
  localityName: "L", stateOrProvinceName: "ST", streetAddress: "STREET",
@@ -404,8 +181,6 @@ var NAMES = {
404
181
  jurisdictionCountryName: "jurisdictionC", jurisdictionStateOrProvinceName: "jurisdictionST",
405
182
  jurisdictionLocalityName: "jurisdictionL", organizationIdentifier: "organizationIdentifier",
406
183
  },
407
- // ==== X.509v3 extension section titles (OpenSSL-familiar); an extension absent
408
- // here is titled from the OID registry name / dotted OID ====
409
184
  EXTENSION: {
410
185
  basicConstraints: "X509v3 Basic Constraints", keyUsage: "X509v3 Key Usage",
411
186
  extKeyUsage: "X509v3 Extended Key Usage", subjectAltName: "X509v3 Subject Alternative Name",
@@ -420,43 +195,29 @@ var NAMES = {
420
195
  invalidityDate: "Invalidity Date", certificateIssuer: "X509v3 Certificate Issuer",
421
196
  signedCertificateTimestampList: "CT Precertificate SCTs", precertificatePoison: "CT Precertificate Poison",
422
197
  },
423
- // ==== KeyUsage bits (RFC 5280 sec. 4.2.1.3, bit order) ====
424
198
  KEY_USAGE: {
425
199
  digitalSignature: "Digital Signature", nonRepudiation: "Non Repudiation", keyEncipherment: "Key Encipherment",
426
200
  dataEncipherment: "Data Encipherment", keyAgreement: "Key Agreement", keyCertSign: "Certificate Sign",
427
201
  cRLSign: "CRL Sign", encipherOnly: "Encipher Only", decipherOnly: "Decipher Only",
428
202
  },
429
- // ==== ExtendedKeyUsage purposes (RFC 5280 sec. 4.2.1.12 + common); an unlisted
430
- // purpose shows its registry name / OID ====
431
203
  EXT_KEY_USAGE: {
432
204
  anyExtendedKeyUsage: "Any Extended Key Usage", serverAuth: "TLS Web Server Authentication",
433
205
  clientAuth: "TLS Web Client Authentication", codeSigning: "Code Signing",
434
206
  emailProtection: "E-mail Protection", timeStamping: "Time Stamping", ocspSigning: "OCSP Signing",
435
207
  },
436
- // ==== GeneralName CHOICE labels, by context tag number (RFC 5280 sec. 4.2.1.6) ====
437
208
  GENERAL_NAME: { 0: "othername", 1: "email", 2: "DNS", 3: "X400Name", 4: "DirName", 5: "EdiPartyName", 6: "URI", 7: "IP Address", 8: "Registered ID" },
438
- // ==== Named-curve -> NIST alias, for the EC key line ====
439
209
  NIST_CURVE: { prime256v1: "P-256", secp384r1: "P-384", secp521r1: "P-521" },
440
- // ==== ReasonFlags BIT STRING bit -> name (RFC 5280 sec. 4.2.1.13, a CRL
441
- // distribution point's revocation scope; bit 0 is "unused"). Distinct from the
442
- // CRLReason ENUMERATED below -- a BIT STRING of scopes, not a single code. ====
443
210
  REASON_FLAGS: {
444
211
  1: "Key Compromise", 2: "CA Compromise", 3: "Affiliation Changed", 4: "Superseded",
445
212
  5: "Cessation Of Operation", 6: "Certificate Hold", 7: "Privilege Withdrawn", 8: "AA Compromise",
446
213
  },
447
- // ==== CRLReason ENUMERATED value names (RFC 5280 sec. 5.3.1; value 7 is unused) ====
448
214
  CRL_REASON: {
449
215
  "0": "unspecified", "1": "keyCompromise", "2": "cACompromise", "3": "affiliationChanged",
450
216
  "4": "superseded", "5": "cessationOfOperation", "6": "certificateHold",
451
217
  "8": "removeFromCRL", "9": "privilegeWithdrawn", "10": "aACompromise",
452
218
  },
453
- // ==== OCSPResponseStatus value names (RFC 6960 sec. 4.2.1; value 4 is unassigned) ====
454
219
  OCSP_STATUS: { "0": "successful", "1": "malformedRequest", "2": "internalError", "3": "tryLater", "5": "sigRequired", "6": "unauthorized" },
455
- // ==== Attribute-cert objectDigestInfo digested-object types (RFC 5755 sec. 4.4.2) ====
456
220
  OBJECT_DIGEST_TYPE: { "0": "publicKey", "1": "publicKeyCert", "2": "otherObjectTypes" },
457
- // ==== Public-key / signature algorithm display names, classical + PQC. Forward-
458
- // looking: the toolkit is PQC-first, so the FIPS 203/204/205 names render as-is;
459
- // a consumer that finds no entry shows the OID registry name / dotted OID ====
460
221
  ALGORITHM: {
461
222
  rsaEncryption: "rsaEncryption", rsassaPss: "rsassaPss", rsaesOaep: "rsaesOaep", ecPublicKey: "id-ecPublicKey",
462
223
  ed25519: "ED25519", ed448: "ED448", x25519: "X25519", x448: "X448",
@@ -467,19 +228,9 @@ var NAMES = {
467
228
  },
468
229
  };
469
230
 
470
- // NAMES is BOTH a display table (pki.inspect) and the strict parsers' legal-value
471
- // allow-list: the CRL reasonCode, OCSP response-status, and attribute-cert object-
472
- // digest decoders check membership against CRL_REASON / OCSP_STATUS / OBJECT_DIGEST_TYPE
473
- // to fail closed on an RFC-reserved / undefined value. Deep-freeze it so a caller can
474
- // NEVER widen what those decoders accept by mutating the "display-only" table (e.g.
475
- // adding CRLReason 7, RFC-reserved, which would otherwise make the decoders fail open).
476
231
  Object.keys(NAMES).forEach(function (k) { Object.freeze(NAMES[k]); });
477
232
  Object.freeze(NAMES);
478
233
 
479
- // Single-sourced from the package manifest so the reported version can
480
- // never drift from the published package (package.json is always present
481
- // in the installed tarball). A hand-maintained literal here silently
482
- // shipped 0.1.0 on a 0.1.1 release.
483
234
  var VERSION = require("../package.json").version;
484
235
 
485
236
  module.exports = {