@blamejs/blamejs-shop 0.5.19 → 0.5.21

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 (194) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +1 -0
  3. package/SECURITY.md +17 -0
  4. package/lib/addresses.js +2 -2
  5. package/lib/admin.js +49 -45
  6. package/lib/affiliates.js +7 -23
  7. package/lib/announcement-bar.js +5 -22
  8. package/lib/api-keys.js +4 -13
  9. package/lib/asset-manifest.json +1 -1
  10. package/lib/banner-ab-tests.js +5 -9
  11. package/lib/blog-articles.js +8 -26
  12. package/lib/captcha-gate.js +7 -17
  13. package/lib/carrier-accounts.js +3 -10
  14. package/lib/catalog-drafts.js +5 -12
  15. package/lib/category-navigation.js +4 -20
  16. package/lib/cms-blocks.js +4 -7
  17. package/lib/compliance-export.js +4 -11
  18. package/lib/consent-ledger.js +2 -4
  19. package/lib/cost-layers.js +56 -21
  20. package/lib/customer-import.js +2 -2
  21. package/lib/customer-notes.js +7 -23
  22. package/lib/customer-roles.js +3 -5
  23. package/lib/customer-segments.js +17 -14
  24. package/lib/customer-surveys.js +7 -14
  25. package/lib/customers.js +2 -4
  26. package/lib/dispute-resolution.js +5 -13
  27. package/lib/dropship-forwarding.js +3 -5
  28. package/lib/dunning.js +2 -7
  29. package/lib/email-ab-tests.js +4 -8
  30. package/lib/email-campaigns.js +25 -14
  31. package/lib/email-warmup.js +2 -7
  32. package/lib/experiments.js +6 -10
  33. package/lib/externaldb-d1.js +78 -44
  34. package/lib/geolocation.js +18 -28
  35. package/lib/gift-options.js +5 -23
  36. package/lib/knowledge-base.js +7 -22
  37. package/lib/line-gift-wrap.js +3 -17
  38. package/lib/live-chat.js +5 -18
  39. package/lib/metered-usage.js +3 -8
  40. package/lib/notifications.js +3 -7
  41. package/lib/operator-accounts.js +3 -5
  42. package/lib/operator-approvals.js +6 -8
  43. package/lib/operator-audit-log.js +2 -7
  44. package/lib/operator-help-center.js +5 -21
  45. package/lib/operator-inbox.js +4 -11
  46. package/lib/operator-roles.js +5 -7
  47. package/lib/order-escalation.js +2 -2
  48. package/lib/order-export.js +24 -20
  49. package/lib/order-notes.js +4 -14
  50. package/lib/order-ratings.js +4 -10
  51. package/lib/payment-methods.js +5 -13
  52. package/lib/payment-retries.js +2 -7
  53. package/lib/payment.js +103 -58
  54. package/lib/pixel-events.js +8 -23
  55. package/lib/plan-changes.js +2 -7
  56. package/lib/product-qa.js +4 -8
  57. package/lib/promo-banners.js +7 -15
  58. package/lib/purchase-orders.js +3 -6
  59. package/lib/push-notifications.js +7 -32
  60. package/lib/pwa-manifest.js +6 -11
  61. package/lib/quotes.js +5 -9
  62. package/lib/referrals.js +10 -6
  63. package/lib/reviews.js +4 -10
  64. package/lib/robots-config.js +6 -14
  65. package/lib/sales-tax-filings.js +2 -2
  66. package/lib/search-facets.js +5 -5
  67. package/lib/search-ranking.js +4 -7
  68. package/lib/search-synonyms.js +7 -21
  69. package/lib/security-middleware.js +125 -70
  70. package/lib/seller-signup.js +10 -26
  71. package/lib/sidebar-widgets.js +6 -15
  72. package/lib/site-redirects.js +49 -137
  73. package/lib/sitemap-generator.js +3 -7
  74. package/lib/sms-dispatcher.js +7 -23
  75. package/lib/stock-receipts.js +4 -10
  76. package/lib/storefront-dashboards.js +2 -10
  77. package/lib/storefront-forms.js +9 -22
  78. package/lib/storefront-pages.js +6 -20
  79. package/lib/storefront.js +21 -23
  80. package/lib/subscription-billing.js +3 -8
  81. package/lib/subscription-controls.js +2 -7
  82. package/lib/suggestion-box.js +9 -26
  83. package/lib/support-tickets.js +6 -24
  84. package/lib/tax-remittance.js +2 -2
  85. package/lib/tenants.js +2 -7
  86. package/lib/text-guard.js +137 -35
  87. package/lib/theme-assets.js +4 -16
  88. package/lib/translations.js +3 -6
  89. package/lib/trust-badges.js +4 -7
  90. package/lib/vendor/MANIFEST.json +107 -97
  91. package/lib/vendor/blamejs/CHANGELOG.md +180 -0
  92. package/lib/vendor/blamejs/NOTICE +14 -10
  93. package/lib/vendor/blamejs/README.md +17 -5
  94. package/lib/vendor/blamejs/index.js +2 -0
  95. package/lib/vendor/blamejs/lib/acme.js +9 -9
  96. package/lib/vendor/blamejs/lib/api-snapshot.js +35 -16
  97. package/lib/vendor/blamejs/lib/app-shutdown.js +1 -1
  98. package/lib/vendor/blamejs/lib/archive-adapters.js +1 -1
  99. package/lib/vendor/blamejs/lib/archive.js +13 -24
  100. package/lib/vendor/blamejs/lib/auth/access-lock.js +2 -1
  101. package/lib/vendor/blamejs/lib/auth/bot-challenge.js +3 -6
  102. package/lib/vendor/blamejs/lib/auth/ciba.js +32 -3
  103. package/lib/vendor/blamejs/lib/auth/oauth.js +65 -8
  104. package/lib/vendor/blamejs/lib/auth/password.js +1 -1
  105. package/lib/vendor/blamejs/lib/auth/saml.js +21 -3
  106. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +3 -3
  107. package/lib/vendor/blamejs/lib/backup/index.js +5 -5
  108. package/lib/vendor/blamejs/lib/case-fold-classes.js +491 -0
  109. package/lib/vendor/blamejs/lib/codepoint-class.js +131 -0
  110. package/lib/vendor/blamejs/lib/constants.js +79 -0
  111. package/lib/vendor/blamejs/lib/db-declare-view.js +8 -2
  112. package/lib/vendor/blamejs/lib/error-page.js +20 -1
  113. package/lib/vendor/blamejs/lib/external-db.js +5 -1
  114. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +24 -6
  115. package/lib/vendor/blamejs/lib/flag.js +28 -2
  116. package/lib/vendor/blamejs/lib/framework-schema.js +14 -3
  117. package/lib/vendor/blamejs/lib/guard-regex.js +2345 -89
  118. package/lib/vendor/blamejs/lib/http-client.js +217 -40
  119. package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
  120. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  121. package/lib/vendor/blamejs/lib/mail-dav.js +26 -26
  122. package/lib/vendor/blamejs/lib/mail-deploy.js +10 -10
  123. package/lib/vendor/blamejs/lib/mail-scan.js +3 -0
  124. package/lib/vendor/blamejs/lib/mail-store.js +7 -1
  125. package/lib/vendor/blamejs/lib/mail.js +5 -1
  126. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -2
  127. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +1 -1
  128. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -1
  129. package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +3 -2
  130. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  131. package/lib/vendor/blamejs/lib/middleware/compression.js +1 -1
  132. package/lib/vendor/blamejs/lib/middleware/cors.js +1 -1
  133. package/lib/vendor/blamejs/lib/middleware/csp-report.js +5 -5
  134. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +2 -1
  135. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +2 -2
  136. package/lib/vendor/blamejs/lib/middleware/deny-response.js +2 -1
  137. package/lib/vendor/blamejs/lib/middleware/dpop.js +2 -2
  138. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +2 -1
  139. package/lib/vendor/blamejs/lib/middleware/flag-context.js +17 -0
  140. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +10 -8
  141. package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +3 -2
  142. package/lib/vendor/blamejs/lib/middleware/require-aal.js +3 -2
  143. package/lib/vendor/blamejs/lib/middleware/require-auth.js +4 -3
  144. package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +4 -3
  145. package/lib/vendor/blamejs/lib/middleware/require-content-type.js +3 -2
  146. package/lib/vendor/blamejs/lib/middleware/require-methods.js +3 -2
  147. package/lib/vendor/blamejs/lib/middleware/require-mtls.js +3 -2
  148. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -1
  149. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -1
  150. package/lib/vendor/blamejs/lib/network-dns-resolver.js +1 -1
  151. package/lib/vendor/blamejs/lib/network-dns.js +3 -3
  152. package/lib/vendor/blamejs/lib/network-nts.js +35 -14
  153. package/lib/vendor/blamejs/lib/network-proxy.js +42 -4
  154. package/lib/vendor/blamejs/lib/network-smtp-policy.js +1 -1
  155. package/lib/vendor/blamejs/lib/network-tls.js +341 -11
  156. package/lib/vendor/blamejs/lib/nist-crosswalk.js +2 -2
  157. package/lib/vendor/blamejs/lib/ntp-check.js +30 -19
  158. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +1 -1
  159. package/lib/vendor/blamejs/lib/object-store/gcs.js +1 -1
  160. package/lib/vendor/blamejs/lib/object-store/http-put.js +2 -1
  161. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -5
  162. package/lib/vendor/blamejs/lib/object-store/sigv4.js +2 -2
  163. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +4 -2
  164. package/lib/vendor/blamejs/lib/openapi.js +1 -1
  165. package/lib/vendor/blamejs/lib/pqc-agent.js +4 -7
  166. package/lib/vendor/blamejs/lib/problem-details.js +2 -1
  167. package/lib/vendor/blamejs/lib/redis-client.js +12 -1
  168. package/lib/vendor/blamejs/lib/regex-linear.js +1349 -0
  169. package/lib/vendor/blamejs/lib/render.js +531 -7
  170. package/lib/vendor/blamejs/lib/request-helpers.js +181 -5
  171. package/lib/vendor/blamejs/lib/router.js +37 -13
  172. package/lib/vendor/blamejs/lib/safe-async.js +142 -0
  173. package/lib/vendor/blamejs/lib/safe-icap.js +3 -0
  174. package/lib/vendor/blamejs/lib/safe-sql.js +15 -3
  175. package/lib/vendor/blamejs/lib/self-update.js +2 -2
  176. package/lib/vendor/blamejs/lib/testing.js +54 -7
  177. package/lib/vendor/blamejs/lib/validate-opts.js +56 -0
  178. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +62 -25
  179. package/lib/vendor/blamejs/lib/vendor/blamejs-pki.cjs +2004 -142
  180. package/lib/vendor/blamejs/lib/vendor/browser/noble-ciphers.mjs +727 -0
  181. package/lib/vendor/blamejs/lib/vendor/browser/noble-hashes.mjs +1070 -0
  182. package/lib/vendor/blamejs/lib/vendor/browser/noble-post-quantum.mjs +1090 -0
  183. package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +510 -227
  184. package/lib/vendor/blamejs/lib/webhook-hmac.js +19 -2
  185. package/lib/vendor/blamejs/lib/webhook.js +1 -1
  186. package/lib/vendor/blamejs/lib/ws-client.js +24 -2
  187. package/lib/vendor/blamejs/package.json +1 -1
  188. package/lib/vendor/blamejs/sbom.cdx.json +6 -6
  189. package/lib/vendor-invoices.js +3 -6
  190. package/lib/vendors.js +5 -19
  191. package/lib/webhook-receiver.js +46 -83
  192. package/lib/webhook-subscriptions.js +3 -13
  193. package/lib/wishlist-sharing.js +5 -10
  194. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- // @blamejs/pki v0.4.3 — vendored (Apache-2.0). Zero-dep pure CJS.
1
+ // @blamejs/pki v0.4.13 — vendored (Apache-2.0). Zero-dep pure CJS.
2
2
  // https://github.com/blamejs/pki Exports: x509, crl, pkcs12, key, webcrypto, schema, csr, cms, ...
3
3
  // Backs lib/mtls-engine-default.js (PQC-capable CA + PKCS#12 engine).
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -139,7 +139,7 @@ var require_package = __commonJS({
139
139
  "node_modules/@blamejs/pki/package.json"(exports2, module2) {
140
140
  module2.exports = {
141
141
  name: "@blamejs/pki",
142
- version: "0.4.3",
142
+ version: "0.4.13",
143
143
  description: "Pure-JavaScript PKI toolkit that owns its stack \u2014 X.509, ASN.1/DER, CMS, PQC-first.",
144
144
  license: "Apache-2.0",
145
145
  author: "blamejs contributors",
@@ -454,6 +454,51 @@ var require_constants = __commonJS({
454
454
  // terminates but exhausts memory. This matches PATH_MAX_CERTS: a chain longer than the path
455
455
  // validator will ever accept has nothing to offer, so refusing it at the decoder is free.
456
456
  TLS_CERT_MAX_ENTRIES: 100,
457
+ // A FIDO Metadata Service BLOB is a JWS whose payload carries every registered authenticator's
458
+ // metadata; the live one runs about 10 MB across ~500 entries. The byte cap bounds the decode
459
+ // before the payload is materialized, and the entry and anchor caps bound the per-entry work
460
+ // (each anchor is a DER certificate parse), since a byte ceiling alone does not bound how many
461
+ // items are declared inside it (CWE-770).
462
+ MDS_BLOB_MAX_BYTES: BYTES.mib(32),
463
+ // The BLOB's JWS protected header is read BEFORE the signature is checked, so it carries its own,
464
+ // far smaller ceiling: a header is a few hundred bytes plus the x5c chain, and the envelope cap
465
+ // would otherwise let unauthenticated input buy heap ahead of every authentication step.
466
+ MDS_BLOB_HEADER_MAX_BYTES: BYTES.kib(256),
467
+ // The JWS signature, likewise read before anything is authenticated. Every algorithm this reader
468
+ // supports has a tightly bounded signature: 64/96/132 bytes for ECDSA P-256/384/521, and the
469
+ // modulus size for RSA. 2 KiB covers an RSA-16384 key with room to spare, and refuses a segment
470
+ // whose only purpose is to make the verifier allocate.
471
+ MDS_BLOB_SIG_MAX_BYTES: BYTES.kib(2),
472
+ MDS_MAX_ENTRIES: 4096,
473
+ // A model's certification history: bounded like the other repeated per-entry structures, because
474
+ // the status gate walks the whole array on every verification.
475
+ MDS_MAX_STATUS_REPORTS_PER_ENTRY: 256,
476
+ MDS_MAX_ANCHORS_PER_ENTRY: 16,
477
+ // A U2F authenticator carries no AAGUID, so its entry is keyed by the key identifiers of its
478
+ // attestation certificates instead -- a batch-attested product line legitimately registers dozens.
479
+ MDS_MAX_KEY_IDS_PER_ENTRY: 64,
480
+ // The most nested statements a WebAuthn compound attestation (sec. 8.9) may carry. The syntax
481
+ // says "2*" -- unbounded -- so this is a resource bound this toolkit chooses, NOT a spec MUST.
482
+ // The CBOR parse caps bound the decode; they do not bound the crypto, and each element costs a
483
+ // signature verification plus, for some formats, a full certificate-path validation. Seven
484
+ // non-compound formats are registered, so a conforming statement carrying one of each is 7.
485
+ WEBAUTHN_COMPOUND_MAX_STATEMENTS: 16,
486
+ // The most certificates a WebAuthn attestation chain may carry, in an attStmt x5c array or a JWS
487
+ // x5c header. A real attestation chain is one to four; the byte ceiling on a single entry does
488
+ // not bound the COUNT, so an array of thousands of small certificates is an unbounded parse and
489
+ // signature-check fanout (CWE-770) that terminates but costs far more CPU than wire. This is a
490
+ // resource bound this toolkit chooses -- no specification states it -- and it is far tighter than
491
+ // PATH_MAX_CERTS because an attestation chain is not a general PKI path.
492
+ WEBAUTHN_X5C_MAX_CERTS: 10,
493
+ // A WebAuthn android-safetynet attestation statement carries the SafetyNet response as a JWS
494
+ // compact serialization: two small JSON objects plus a signature, with the certificate chain
495
+ // inline in the header. Real ones run a few kilobytes. The cap bounds the text decode before the
496
+ // string is materialized, so an oversized statement is refused rather than allocated (CWE-770).
497
+ SAFETYNET_JWS_MAX_BYTES: BYTES.kib(64),
498
+ // One x5c entry is a single DER certificate; PATH_MAX_CERT_BYTES is the ceiling the path
499
+ // validator already applies to any certificate it will accept, and an entry above it could not
500
+ // chain even if it decoded.
501
+ SAFETYNET_CERT_MAX_BYTES: BYTES.kib(64),
457
502
  // ACME challenge token entropy floor (RFC 8555 sec. 8, errata 6950): >= 128
458
503
  // bits of base64url is >= 22 characters. A shorter token is refused before use.
459
504
  ACME_TOKEN_MIN_CHARS: 22,
@@ -1160,7 +1205,15 @@ var require_guard_identifier = __commonJS({
1160
1205
  if (root < 2n && second > 39n) throw E(bcode, who + " second arc must be 0..39 under roots 0 and 1 (X.660)");
1161
1206
  return str;
1162
1207
  }
1163
- module2.exports = { assertCanonicalOid };
1208
+ function assertKnownKeys(obj, known, E, code, message) {
1209
+ var describe = typeof message === "function" ? message : function(k) {
1210
+ return message + JSON.stringify(k);
1211
+ };
1212
+ Object.keys(obj).forEach(function(k) {
1213
+ if (!Object.prototype.hasOwnProperty.call(known, k)) throw E(code, describe(k));
1214
+ });
1215
+ }
1216
+ module2.exports = { assertCanonicalOid, assertKnownKeys };
1164
1217
  }
1165
1218
  });
1166
1219
 
@@ -1271,6 +1324,26 @@ var require_guard_compress = __commonJS({
1271
1324
  }
1272
1325
  });
1273
1326
 
1327
+ // node_modules/@blamejs/pki/lib/guard-secret.js
1328
+ var require_guard_secret = __commonJS({
1329
+ "node_modules/@blamejs/pki/lib/guard-secret.js"(exports2, module2) {
1330
+ "use strict";
1331
+ var bytes = require_guard_bytes();
1332
+ function zeroize(value, ErrorClass, code, label) {
1333
+ if (value === null || value === void 0) return value;
1334
+ var view = bytes.view(value, ErrorClass, code, label);
1335
+ view.fill(0);
1336
+ return value;
1337
+ }
1338
+ function zeroizeAll(list, ErrorClass, code, label) {
1339
+ if (!list) return list;
1340
+ for (var i = 0; i < list.length; i++) zeroize(list[i], ErrorClass, code, label);
1341
+ return list;
1342
+ }
1343
+ module2.exports = { zeroize, zeroizeAll };
1344
+ }
1345
+ });
1346
+
1274
1347
  // node_modules/@blamejs/pki/lib/guard-all.js
1275
1348
  var require_guard_all = __commonJS({
1276
1349
  "node_modules/@blamejs/pki/lib/guard-all.js"(exports2, module2) {
@@ -1287,6 +1360,7 @@ var require_guard_all = __commonJS({
1287
1360
  var identifier = require_guard_identifier();
1288
1361
  var header = require_guard_header();
1289
1362
  var compress = require_guard_compress();
1363
+ var secret = require_guard_secret();
1290
1364
  module2.exports = {
1291
1365
  bytes,
1292
1366
  text,
@@ -1299,7 +1373,8 @@ var require_guard_all = __commonJS({
1299
1373
  json,
1300
1374
  identifier,
1301
1375
  header,
1302
- compress
1376
+ compress,
1377
+ secret
1303
1378
  };
1304
1379
  }
1305
1380
  });
@@ -2612,7 +2687,14 @@ var require_oid = __commonJS({
2612
2687
  // id-pe-tlsfeature (RFC 7633) -- the TLS Feature (formerly "must-staple") extension.
2613
2688
  tlsFeature: 24,
2614
2689
  // id-pe-qcStatements (RFC 3739 sec. 3.2.6) -- the qualified-certificate-statements extension.
2615
- qcStatements: 3
2690
+ qcStatements: 3,
2691
+ // RFC 3779 -- the IP-address and AS-number delegation extensions that carry a resource
2692
+ // certificate's authority (RPKI). Each has an RFC 8360 "v2" twin with identical syntax and
2693
+ // stricter path-validation semantics, so both are registered here.
2694
+ ipAddrBlocks: 7,
2695
+ autonomousSysIds: 8,
2696
+ ipAddrBlocksV2: 28,
2697
+ autonomousSysIdsV2: 29
2616
2698
  } },
2617
2699
  // RFC 3739 sec. 3.2.6.1 id-qcs -- the PKIX QCStatement statementIds carrying SemanticsInformation.
2618
2700
  pkixQcSyntax: { base: [1, 3, 6, 1, 5, 5, 7, 11], of: { qcsPkixQCSyntaxV1: 1, qcsPkixQCSyntaxV2: 2 } },
@@ -3282,11 +3364,26 @@ var require_oid = __commonJS({
3282
3364
  function paramsMustBeAbsent(dotted) {
3283
3365
  return _PARAMS_ABSENT.has(dotted);
3284
3366
  }
3367
+ var KEM_PARAMS = /* @__PURE__ */ Object.create(null);
3368
+ [
3369
+ ["id-ml-kem-512", 800, 1632, 768, 32],
3370
+ ["id-ml-kem-768", 1184, 2400, 1088, 32],
3371
+ ["id-ml-kem-1024", 1568, 3168, 1568, 32]
3372
+ ].forEach(function(r) {
3373
+ var row = Object.freeze({ ek: r[1], dk: r[2], ct: r[3], ss: r[4] });
3374
+ KEM_PARAMS[byName(r[0])] = row;
3375
+ KEM_PARAMS[r[0]] = row;
3376
+ });
3377
+ Object.freeze(KEM_PARAMS);
3378
+ function kemParams(oidOrName) {
3379
+ return KEM_PARAMS[oidOrName];
3380
+ }
3285
3381
  module2.exports = {
3286
3382
  name,
3287
3383
  byName,
3288
3384
  has,
3289
3385
  paramsMustBeAbsent,
3386
+ kemParams,
3290
3387
  register,
3291
3388
  registerFamily,
3292
3389
  all,
@@ -3415,7 +3512,15 @@ var require_webcrypto = __commonJS({
3415
3512
  this.usages = usages ? usages.slice() : [];
3416
3513
  Object.defineProperty(this, "_handle", { value: handle, enumerable: false });
3417
3514
  }
3515
+ function _requireOwnKey(key, who) {
3516
+ if (key instanceof CryptoKey) return;
3517
+ if (isCryptoKeyLike(key)) {
3518
+ throw new WebCryptoError("webcrypto/invalid-access", who + ": the key was created by a different WebCrypto implementation; re-import it through this one");
3519
+ }
3520
+ throw new WebCryptoError("webcrypto/invalid-access", who + ": a CryptoKey is required");
3521
+ }
3418
3522
  function _requireUsage(key, usage) {
3523
+ _requireOwnKey(key, usage);
3419
3524
  if (key.usages.indexOf(usage) === -1) {
3420
3525
  throw new WebCryptoError("webcrypto/invalid-access", "key is not permitted for '" + usage + "' (usages: " + key.usages.join(",") + ")");
3421
3526
  }
@@ -3721,6 +3826,7 @@ var require_webcrypto = __commonJS({
3721
3826
  var name = alg.name;
3722
3827
  if (name === "ECDH" || name === "X25519" || name === "X448") {
3723
3828
  _requireAlgMatch(alg, alg.public, name + " public key");
3829
+ _requireOwnKey(alg.public, "deriveBits public key");
3724
3830
  var secret = nodeCrypto.diffieHellman({ privateKey: key._handle, publicKey: alg.public._handle });
3725
3831
  if (length == null) return _toArrayBuffer(secret);
3726
3832
  _requireDeriveLength(length, name);
@@ -3731,8 +3837,13 @@ var require_webcrypto = __commonJS({
3731
3837
  }
3732
3838
  if (name === "HKDF") {
3733
3839
  _requireDeriveLength(length, "HKDF");
3734
- var derived = nodeCrypto.hkdfSync(_hashNode(alg.hash, "HKDF"), _secretBytes(key), _toBuf(alg.salt, "HKDF salt"), _toBuf(alg.info || Buffer.alloc(0), "HKDF info"), length / 8);
3735
- return derived instanceof ArrayBuffer ? derived : _toArrayBuffer(Buffer.from(derived));
3840
+ var ikm = _secretBytes(key);
3841
+ try {
3842
+ var derived = nodeCrypto.hkdfSync(_hashNode(alg.hash, "HKDF"), ikm, _toBuf(alg.salt, "HKDF salt"), _toBuf(alg.info || Buffer.alloc(0), "HKDF info"), length / 8);
3843
+ return derived instanceof ArrayBuffer ? derived : _toArrayBuffer(Buffer.from(derived));
3844
+ } finally {
3845
+ guard.secret.zeroize(ikm, WebCryptoError, "webcrypto/operation", "the HKDF input key material");
3846
+ }
3736
3847
  }
3737
3848
  if (name === "PBKDF2") {
3738
3849
  _requireDeriveLength(length, "PBKDF2");
@@ -3797,7 +3908,11 @@ var require_webcrypto = __commonJS({
3797
3908
  } catch (e) {
3798
3909
  throw new WebCryptoError("webcrypto/operation", "encapsulateBits: ML-KEM encapsulation failed", e);
3799
3910
  }
3800
- return { sharedKey: _toArrayBuffer(Buffer.from(r.sharedKey)), ciphertext: _toArrayBuffer(Buffer.from(r.ciphertext)) };
3911
+ try {
3912
+ return { sharedKey: _toArrayBuffer(r.sharedKey), ciphertext: _toArrayBuffer(r.ciphertext) };
3913
+ } finally {
3914
+ guard.secret.zeroize(r.sharedKey, WebCryptoError, "webcrypto/operation", "the KEM shared secret");
3915
+ }
3801
3916
  };
3802
3917
  SubtleCrypto.prototype.decapsulateBits = async function decapsulateBits(algorithm, decapsulationKey, ciphertext) {
3803
3918
  var alg = _normalizeAlg(algorithm, "decapsulateBits");
@@ -3806,13 +3921,24 @@ var require_webcrypto = __commonJS({
3806
3921
  _requireAlgMatch(alg, decapsulationKey, "decapsulateBits");
3807
3922
  if (decapsulationKey.type !== "private") throw new WebCryptoError("webcrypto/invalid-access", "decapsulateBits requires a private (decapsulation) key, got " + JSON.stringify(decapsulationKey.type));
3808
3923
  var ct = _toBuf(ciphertext, "decapsulateBits ciphertext");
3924
+ var kemRow = oid.kemParams("id-" + ML_KEM_NODE[alg.name]);
3925
+ if (kemRow && ct.length !== kemRow.ct) {
3926
+ throw new WebCryptoError(
3927
+ "webcrypto/bad-kem-ciphertext",
3928
+ "decapsulateBits: " + alg.name + " expects a " + kemRow.ct + "-octet ciphertext, got " + ct.length + " (FIPS 203 sec. 7.3)"
3929
+ );
3930
+ }
3809
3931
  var ss;
3810
3932
  try {
3811
3933
  ss = nodeCrypto.decapsulate(decapsulationKey._handle, ct);
3812
3934
  } catch (e) {
3813
3935
  throw new WebCryptoError("webcrypto/operation", "decapsulateBits: ML-KEM decapsulation failed (malformed or wrong-length ciphertext)", e);
3814
3936
  }
3815
- return _toArrayBuffer(Buffer.from(ss));
3937
+ try {
3938
+ return _toArrayBuffer(ss);
3939
+ } finally {
3940
+ guard.secret.zeroize(ss, WebCryptoError, "webcrypto/operation", "the KEM shared secret");
3941
+ }
3816
3942
  };
3817
3943
  SubtleCrypto.prototype.wrapKey = async function wrapKey(format, key, wrappingKey, wrapAlgorithm) {
3818
3944
  var exported = await this.exportKey(format, key);
@@ -3825,11 +3951,15 @@ var require_webcrypto = __commonJS({
3825
3951
  if (bytes.length < 16 || bytes.length % 8 !== 0) {
3826
3952
  throw new WebCryptoError("webcrypto/operation", "wrapKey: AES-KW requires the serialized key be a multiple of 8 bytes (>= 16); got " + bytes.length + " -- format " + JSON.stringify(format) + " is not AES-KW-wrappable");
3827
3953
  }
3954
+ var wkBytes = null;
3828
3955
  try {
3829
- var c = nodeCrypto.createCipheriv("aes" + wrappingKey.algorithm.length + "-wrap", _secretBytes(wrappingKey), Buffer.from("A6A6A6A6A6A6A6A6", "hex"));
3956
+ wkBytes = _secretBytes(wrappingKey);
3957
+ var c = nodeCrypto.createCipheriv("aes" + wrappingKey.algorithm.length + "-wrap", wkBytes, Buffer.from("A6A6A6A6A6A6A6A6", "hex"));
3830
3958
  return _toArrayBuffer(Buffer.concat([c.update(bytes), c.final()]));
3831
3959
  } catch (e) {
3832
3960
  throw new WebCryptoError("webcrypto/operation", "wrapKey: AES-KW key wrap failed", e);
3961
+ } finally {
3962
+ guard.secret.zeroize(wkBytes, WebCryptoError, "webcrypto/operation", "the AES-KW wrapping key");
3833
3963
  }
3834
3964
  }
3835
3965
  var wrapKeyClone = _cloneWithUsage(wrappingKey, "encrypt");
@@ -3846,11 +3976,15 @@ var require_webcrypto = __commonJS({
3846
3976
  if (wrapped.length < 24 || wrapped.length % 8 !== 0) {
3847
3977
  throw new WebCryptoError("webcrypto/operation", "unwrapKey: AES-KW wrapped key must be a multiple of 8 bytes (>= 24); got " + wrapped.length);
3848
3978
  }
3979
+ var kwBytes = null;
3849
3980
  try {
3850
- var d = nodeCrypto.createDecipheriv("aes" + unwrappingKey.algorithm.length + "-wrap", _secretBytes(unwrappingKey), Buffer.from("A6A6A6A6A6A6A6A6", "hex"));
3981
+ kwBytes = _secretBytes(unwrappingKey);
3982
+ var d = nodeCrypto.createDecipheriv("aes" + unwrappingKey.algorithm.length + "-wrap", kwBytes, Buffer.from("A6A6A6A6A6A6A6A6", "hex"));
3851
3983
  bytes = Buffer.concat([d.update(wrapped), d.final()]);
3852
3984
  } catch (e) {
3853
3985
  throw new WebCryptoError("webcrypto/operation", "unwrapKey: AES-KW key unwrap failed (integrity or length)", e);
3986
+ } finally {
3987
+ guard.secret.zeroize(kwBytes, WebCryptoError, "webcrypto/operation", "the AES-KW unwrapping key");
3854
3988
  }
3855
3989
  } else {
3856
3990
  var unwrapKeyClone = _cloneWithUsage(unwrappingKey, "decrypt");
@@ -3871,7 +4005,11 @@ var require_webcrypto = __commonJS({
3871
4005
  } else {
3872
4006
  keyData = bytes;
3873
4007
  }
3874
- return this.importKey(format, keyData, unwrappedKeyAlgorithm, extractable, keyUsages);
4008
+ try {
4009
+ return await this.importKey(format, keyData, unwrappedKeyAlgorithm, extractable, keyUsages);
4010
+ } finally {
4011
+ guard.secret.zeroize(bytes, WebCryptoError, "webcrypto/operation", "the unwrapped key material");
4012
+ }
3875
4013
  };
3876
4014
  function _cloneWithUsage(key, usage) {
3877
4015
  var k = new CryptoKey(key.type, key.extractable, key.algorithm, key.usages.concat([usage]), key._handle);
@@ -3891,9 +4029,10 @@ var require_webcrypto = __commonJS({
3891
4029
  }
3892
4030
  }
3893
4031
  var ML_KEM_INNER = {};
3894
- ML_KEM_INNER[oid.byName("id-ml-kem-512")] = { ek: 800, dk: 1632 };
3895
- ML_KEM_INNER[oid.byName("id-ml-kem-768")] = { ek: 1184, dk: 2400 };
3896
- ML_KEM_INNER[oid.byName("id-ml-kem-1024")] = { ek: 1568, dk: 3168 };
4032
+ ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function(n) {
4033
+ var row = oid.kemParams(n);
4034
+ ML_KEM_INNER[oid.byName(n)] = { ek: row.ek, dk: row.dk };
4035
+ });
3897
4036
  function _isOctet(node, size) {
3898
4037
  return node && node.tagClass === "universal" && node.tagNumber === asn1.TAGS.OCTET_STRING && !node.constructed && node.content && node.content.length === size;
3899
4038
  }
@@ -4056,12 +4195,17 @@ var require_webcrypto = __commonJS({
4056
4195
  return void 0;
4057
4196
  }
4058
4197
  SubtleCrypto.prototype.exportKey = async function exportKey(format, key) {
4198
+ _requireOwnKey(key, "exportKey");
4059
4199
  if (!key.extractable) throw new WebCryptoError("webcrypto/invalid-access", "key is not extractable");
4060
4200
  if (format === "jwk") return key._handle.export({ format: "jwk" });
4061
4201
  if (key.type === "secret") {
4062
4202
  var raw = key._handle.export();
4063
- if (format === "raw") return _toArrayBuffer(raw);
4064
- throw new WebCryptoError("webcrypto/not-supported", "exportKey: secret keys support 'raw' / 'jwk' only");
4203
+ try {
4204
+ if (format === "raw") return _toArrayBuffer(raw);
4205
+ throw new WebCryptoError("webcrypto/not-supported", "exportKey: secret keys support 'raw' / 'jwk' only");
4206
+ } finally {
4207
+ guard.secret.zeroize(raw, WebCryptoError, "webcrypto/operation", "the exported secret key");
4208
+ }
4065
4209
  }
4066
4210
  if (format === "spki") return _toArrayBuffer(key._handle.export({ format: "der", type: "spki" }));
4067
4211
  if (format === "pkcs8") return _toArrayBuffer(key._handle.export({ format: "der", type: "pkcs8" }));
@@ -4099,13 +4243,66 @@ var require_webcrypto = __commonJS({
4099
4243
  throw E(code, "EC point is not on curve " + nodeCurve + " (de-compression failed)", e);
4100
4244
  }
4101
4245
  }
4246
+ var _crypto = new Crypto();
4247
+ var _EXPORT_FORMAT = Object.assign(/* @__PURE__ */ Object.create(null), { "private": "pkcs8", "public": "spki", "secret": "raw" });
4248
+ function isCryptoKeyLike(x) {
4249
+ return !!x && typeof x === "object" && typeof x.type === "string" && typeof x.extractable === "boolean" && !!x.algorithm && typeof x.algorithm === "object" && typeof x.algorithm.name === "string" && Array.isArray(x.usages);
4250
+ }
4251
+ function exportAnyKey(key, E, code) {
4252
+ var format = _EXPORT_FORMAT[key && key.type];
4253
+ if (!format) throw E(code, "a CryptoKey with a private, public, or secret type is required");
4254
+ if (key instanceof CryptoKey) {
4255
+ return Promise.resolve().then(function() {
4256
+ return _crypto.subtle.exportKey(format, key);
4257
+ }).then(function(b) {
4258
+ return Buffer.from(b);
4259
+ });
4260
+ }
4261
+ if (!key.extractable) {
4262
+ throw E(code, "the CryptoKey comes from a different WebCrypto implementation and is not extractable, so its key material cannot be reached; import it through pki.webcrypto.subtle, or pass the key as DER");
4263
+ }
4264
+ var handle = key._handle;
4265
+ if (handle instanceof nodeCrypto.KeyObject && handle.type === key.type) {
4266
+ return Promise.resolve().then(function() {
4267
+ return format === "raw" ? handle.export() : handle.export({ format: "der", type: format });
4268
+ }).then(function(b) {
4269
+ return Buffer.from(b);
4270
+ }, function(e) {
4271
+ throw E(code, "the CryptoKey comes from a different copy of this WebCrypto engine and its key material could not be read; import it through pki.webcrypto.subtle, or pass the key as DER", e);
4272
+ });
4273
+ }
4274
+ return Promise.resolve().then(function() {
4275
+ return nodeCrypto.webcrypto.subtle.exportKey(format, key);
4276
+ }).then(function(b) {
4277
+ return Buffer.from(b);
4278
+ }, function(e) {
4279
+ throw E(code, "the CryptoKey comes from a different WebCrypto implementation and could not be exported for re-import; import it through pki.webcrypto.subtle, or pass the key as DER", e);
4280
+ });
4281
+ }
4282
+ function adoptKey(key, importParams, usages, E, code) {
4283
+ if (key instanceof CryptoKey) return Promise.resolve(key);
4284
+ if (!Array.isArray(key.usages)) throw E(code, "a CryptoKey carrying its permitted usages is required");
4285
+ for (var i = 0; i < usages.length; i++) {
4286
+ if (key.usages.indexOf(usages[i]) === -1) {
4287
+ throw E(code, "the CryptoKey is not permitted for '" + usages[i] + "' (usages: " + key.usages.join(",") + ")");
4288
+ }
4289
+ }
4290
+ return Promise.resolve().then(function() {
4291
+ return exportAnyKey(key, E, code);
4292
+ }).then(function(der) {
4293
+ return _crypto.subtle.importKey(_EXPORT_FORMAT[key.type], der, importParams || key.algorithm, false, usages);
4294
+ });
4295
+ }
4102
4296
  module2.exports = {
4103
- webcrypto: new Crypto(),
4297
+ webcrypto: _crypto,
4104
4298
  Crypto,
4105
4299
  SubtleCrypto,
4106
4300
  CryptoKey,
4107
4301
  WebCryptoError,
4108
- decompressEcPoint
4302
+ decompressEcPoint,
4303
+ isCryptoKeyLike,
4304
+ exportAnyKey,
4305
+ adoptKey
4109
4306
  };
4110
4307
  }
4111
4308
  });
@@ -5269,6 +5466,7 @@ var require_validator_tpm = __commonJS({
5269
5466
  "node_modules/@blamejs/pki/lib/validator-tpm.js"(exports2, module2) {
5270
5467
  "use strict";
5271
5468
  var ByteReader = require_byte_reader();
5469
+ var guard = require_guard_all();
5272
5470
  var TPM_GENERATED_VALUE = 4283712327;
5273
5471
  var TPM_ST_ATTEST_CERTIFY = 32791;
5274
5472
  var TPM_ALG = { RSA: 1, SHA1: 4, SHA256: 11, SHA384: 12, SHA512: 13, NULL: 16, ECC: 35 };
@@ -5308,12 +5506,43 @@ var require_validator_tpm = __commonJS({
5308
5506
  r.u16();
5309
5507
  }
5310
5508
  }
5509
+ var TPMA_OBJECT_BITS = Object.assign(/* @__PURE__ */ Object.create(null), {
5510
+ fixedTPM: 1,
5511
+ stClear: 2,
5512
+ fixedParent: 4,
5513
+ sensitiveDataOrigin: 5,
5514
+ userWithAuth: 6,
5515
+ adminWithPolicy: 7,
5516
+ firmwareLimited: 8,
5517
+ svnLimited: 9,
5518
+ noDA: 10,
5519
+ encryptedDuplication: 11,
5520
+ restricted: 16,
5521
+ decrypt: 17,
5522
+ sign: 18,
5523
+ x509sign: 19
5524
+ });
5525
+ var TPMA_OBJECT_RESERVED = 4293980169;
5526
+ function _decodeAttributes(oa) {
5527
+ var out = {};
5528
+ Object.keys(TPMA_OBJECT_BITS).forEach(function(n) {
5529
+ out[n] = (oa >>> TPMA_OBJECT_BITS[n] & 1) === 1;
5530
+ });
5531
+ return out;
5532
+ }
5311
5533
  function parsePubArea(buf, E, code) {
5312
5534
  var r = new ByteReader(buf, 0, buf.length, E, code);
5313
5535
  var type = r.u16(), nameAlg = r.u16();
5314
- r.u32();
5315
- r.vector(2, 0, null);
5316
- var pub = { type, nameAlg, nameAlgBytes: buf.subarray(2, 4) };
5536
+ var objectAttributes = r.u32();
5537
+ var authPolicy = r.vector(2, 0, null);
5538
+ var pub = {
5539
+ type,
5540
+ nameAlg,
5541
+ nameAlgBytes: buf.subarray(2, 4),
5542
+ objectAttributes: objectAttributes >>> 0,
5543
+ attributes: _decodeAttributes(objectAttributes),
5544
+ authPolicy
5545
+ };
5317
5546
  if (type === TPM_ALG.RSA) {
5318
5547
  _symDef(r);
5319
5548
  _scheme(r);
@@ -5367,8 +5596,108 @@ var require_validator_tpm = __commonJS({
5367
5596
  }
5368
5597
  throw new E(code, "unsupported TPM pubArea key type");
5369
5598
  }
5599
+ var TPM_POLICY_PROFILES = Object.assign(/* @__PURE__ */ Object.create(null), {
5600
+ "hardware-bound": { fixedTPM: true, fixedParent: true, sensitiveDataOrigin: true, sign: true, restricted: false, x509sign: false }
5601
+ });
5602
+ var _TPM_POLICY_KEYS = Object.assign(/* @__PURE__ */ Object.create(null), { profile: 1, objectAttributes: 1, reservedBitsClear: 1, consistency: 1, authPolicy: 1 });
5603
+ var _AUTH_POLICY_KEYS = Object.assign(/* @__PURE__ */ Object.create(null), { present: 1, allow: 1 });
5604
+ function normalizeObjectAttributePolicy(policy, E, code) {
5605
+ if (policy === void 0) return null;
5606
+ if (!policy || typeof policy !== "object" || Array.isArray(policy)) throw new E(code, "opts.tpmPolicy must be an object");
5607
+ guard.identifier.assertKnownKeys(policy, _TPM_POLICY_KEYS, function(c, m) {
5608
+ return new E(c, m);
5609
+ }, code, "opts.tpmPolicy has an unknown key ");
5610
+ var want = {};
5611
+ if (policy.profile !== void 0) {
5612
+ var preset = TPM_POLICY_PROFILES[policy.profile];
5613
+ if (!preset) throw new E(code, "opts.tpmPolicy.profile " + JSON.stringify(policy.profile) + " is not a defined profile");
5614
+ Object.keys(preset).forEach(function(n) {
5615
+ want[n] = preset[n];
5616
+ });
5617
+ }
5618
+ var explicit = policy.objectAttributes;
5619
+ if (explicit !== void 0) {
5620
+ if (!explicit || typeof explicit !== "object" || Array.isArray(explicit)) throw new E(code, "opts.tpmPolicy.objectAttributes must be an object");
5621
+ Object.keys(explicit).forEach(function(n) {
5622
+ if (TPMA_OBJECT_BITS[n] === void 0) throw new E(code, "opts.tpmPolicy.objectAttributes has an unknown attribute " + JSON.stringify(n));
5623
+ if (typeof explicit[n] !== "boolean") throw new E(code, "opts.tpmPolicy.objectAttributes." + n + " must be a boolean");
5624
+ want[n] = explicit[n];
5625
+ });
5626
+ }
5627
+ if (want.sensitiveDataOrigin === true && want.fixedTPM !== true) {
5628
+ throw new E(code, "opts.tpmPolicy requires sensitiveDataOrigin without fixedTPM; on its own it does not establish that the TPM generated the key (TPM 2.0 Part 2 sec. 8.3.3.5)");
5629
+ }
5630
+ ["reservedBitsClear", "consistency"].forEach(function(k) {
5631
+ if (policy[k] !== void 0 && typeof policy[k] !== "boolean") throw new E(code, "opts.tpmPolicy." + k + " must be a boolean");
5632
+ });
5633
+ var ap = policy.authPolicy;
5634
+ var allow = null;
5635
+ if (ap !== void 0) {
5636
+ if (!ap || typeof ap !== "object" || Array.isArray(ap)) throw new E(code, "opts.tpmPolicy.authPolicy must be an object");
5637
+ guard.identifier.assertKnownKeys(ap, _AUTH_POLICY_KEYS, function(c, m) {
5638
+ return new E(c, m);
5639
+ }, code, "opts.tpmPolicy.authPolicy has an unknown key ");
5640
+ if (ap.present !== void 0 && typeof ap.present !== "boolean") throw new E(code, "opts.tpmPolicy.authPolicy.present must be a boolean");
5641
+ if (ap.allow !== void 0) {
5642
+ if (!Array.isArray(ap.allow)) throw new E(code, "opts.tpmPolicy.authPolicy.allow must be an array");
5643
+ allow = ap.allow.map(function(entry, i) {
5644
+ if (Buffer.isBuffer(entry)) return entry;
5645
+ if (typeof entry !== "string" || entry.length === 0 || entry.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(entry)) {
5646
+ throw new E(code, "opts.tpmPolicy.authPolicy.allow[" + i + "] must be a Buffer or an even-length hex string");
5647
+ }
5648
+ return Buffer.from(entry, "hex");
5649
+ });
5650
+ }
5651
+ }
5652
+ return {
5653
+ objectAttributes: want,
5654
+ reservedBitsClear: policy.reservedBitsClear === true,
5655
+ consistency: policy.consistency === true,
5656
+ authPolicy: ap ? { present: ap.present === true, allow } : null
5657
+ };
5658
+ }
5659
+ function assertObjectAttributePolicy(pub, policy, E, policyCode, structuralCode) {
5660
+ if (!policy) return;
5661
+ var oa = pub.objectAttributes >>> 0;
5662
+ if (policy.reservedBitsClear && (oa & TPMA_OBJECT_RESERVED) >>> 0 !== 0) {
5663
+ throw new E(structuralCode, "the TPMT_PUBLIC objectAttributes sets a reserved bit (TPM 2.0 Part 2 sec. 8.3.2 Table 33: shall be zero)");
5664
+ }
5665
+ if (policy.consistency) {
5666
+ if (pub.attributes.encryptedDuplication && pub.attributes.fixedTPM) {
5667
+ throw new E(structuralCode, "the TPMT_PUBLIC objectAttributes sets encryptedDuplication on an object with fixedTPM SET (TPM 2.0 Part 2 sec. 8.3.3.11)");
5668
+ }
5669
+ if (pub.attributes.sign && pub.attributes.decrypt && pub.attributes.restricted) {
5670
+ throw new E(structuralCode, "the TPMT_PUBLIC objectAttributes sets restricted with both sign and decrypt (TPM 2.0 Part 2 sec. 8.3.3)");
5671
+ }
5672
+ if (pub.authPolicy.length > 64) {
5673
+ throw new E(structuralCode, "the TPMT_PUBLIC authPolicy is " + pub.authPolicy.length + " octets, above the 64-octet TPM2B_DIGEST maximum");
5674
+ }
5675
+ }
5676
+ Object.keys(policy.objectAttributes).forEach(function(name) {
5677
+ var want = policy.objectAttributes[name];
5678
+ if (pub.attributes[name] !== want) {
5679
+ throw new E(policyCode, "the TPM credential key has " + name + " " + (pub.attributes[name] ? "SET" : "CLEAR") + "; opts.tpmPolicy requires it " + (want ? "SET" : "CLEAR"));
5680
+ }
5681
+ });
5682
+ var ap = policy.authPolicy;
5683
+ if (!ap) return;
5684
+ if (ap.present === true && pub.authPolicy.length === 0) {
5685
+ throw new E(policyCode, "the TPM credential key carries the Empty Policy; opts.tpmPolicy.authPolicy.present requires a policy digest");
5686
+ }
5687
+ if (ap.allow) {
5688
+ var got = pub.authPolicy;
5689
+ var ok = ap.allow.some(function(want) {
5690
+ return want.length === got.length && guard.crypto.constantTimeEqual(want, got);
5691
+ });
5692
+ if (!ok) throw new E(policyCode, "the TPM credential key authPolicy is not in opts.tpmPolicy.authPolicy.allow");
5693
+ }
5694
+ }
5370
5695
  module2.exports = {
5371
5696
  parsePubArea,
5697
+ TPMA_OBJECT_BITS,
5698
+ decodeObjectAttributes: _decodeAttributes,
5699
+ normalizeObjectAttributePolicy,
5700
+ assertObjectAttributePolicy,
5372
5701
  parseCertInfo,
5373
5702
  pubKeyEqualsCose,
5374
5703
  TPM_ALG_HASH
@@ -5491,7 +5820,22 @@ var require_rfc3339 = __commonJS({
5491
5820
  if (!isValid(v)) throw E(code, (label || "the value") + " is not a valid RFC 3339 date-time");
5492
5821
  return new Date(v);
5493
5822
  }
5494
- module2.exports = { isValid, parse };
5823
+ var FULL_DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
5824
+ function isValidDate(v) {
5825
+ if (typeof v !== "string") return false;
5826
+ var m = FULL_DATE_RE.exec(v);
5827
+ if (!m) return false;
5828
+ var year = +m[1], month = +m[2], day = +m[3];
5829
+ if (month < 1 || month > 12) return false;
5830
+ var leap = year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
5831
+ var daysInMonth = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
5832
+ return day >= 1 && day <= daysInMonth[month - 1];
5833
+ }
5834
+ function parseDate(v, E, code, label) {
5835
+ if (!isValidDate(v)) throw E(code, (label || "the value") + " is not a valid RFC 3339 full-date (YYYY-MM-DD)");
5836
+ return /* @__PURE__ */ new Date(v + "T00:00:00Z");
5837
+ }
5838
+ module2.exports = { isValid, parse, isValidDate, parseDate };
5495
5839
  }
5496
5840
  });
5497
5841
 
@@ -6439,9 +6783,7 @@ var require_ct = __commonJS({
6439
6783
  }
6440
6784
  async function fetchLogList(opts) {
6441
6785
  opts = opts || {};
6442
- Object.keys(opts).forEach(function(k) {
6443
- if (!KNOWN_FETCH_OPTS[k]) throw _ctErr("ct/bad-input", "unknown opts field " + JSON.stringify(k));
6444
- });
6786
+ guard.identifier.assertKnownKeys(opts, KNOWN_FETCH_OPTS, _ctErr, "ct/bad-input", "unknown opts field ");
6445
6787
  if (opts.signerKey == null) throw _ctErr("ct/bad-input", "opts.signerKey is required -- the caller-pinned CT log-list distributor SPKI (there is no baked-in key)");
6446
6788
  if (opts.url == null) throw _ctErr("ct/bad-input", "opts.url is required -- the log_list.json URL (there is no baked-in vendor URL)");
6447
6789
  var jsonParsed = _parseHttpsUrl(opts.url, "URL");
@@ -6934,6 +7276,62 @@ var require_schema_pkix = __commonJS({
6934
7276
  }
6935
7277
  });
6936
7278
  }
7279
+ var DISPLAY_TEXT_MAX = 200;
7280
+ function displayTextChars(str) {
7281
+ return Array.from(str).length;
7282
+ }
7283
+ var _DISPLAY_TEXT_TAGS = null;
7284
+ function _isDisplayTextNode(n) {
7285
+ if (!_DISPLAY_TEXT_TAGS) {
7286
+ _DISPLAY_TEXT_TAGS = {};
7287
+ _DISPLAY_TEXT_TAGS[_T.IA5_STRING] = 1;
7288
+ _DISPLAY_TEXT_TAGS[_T.VISIBLE_STRING] = 1;
7289
+ _DISPLAY_TEXT_TAGS[_T.BMP_STRING] = 1;
7290
+ _DISPLAY_TEXT_TAGS[_T.UTF8_STRING] = 1;
7291
+ }
7292
+ return !!n && n.tagClass === "universal" && _DISPLAY_TEXT_TAGS[n.tagNumber] === 1;
7293
+ }
7294
+ function _dtEntry(field, node) {
7295
+ var text;
7296
+ try {
7297
+ text = asn1.read.string(node);
7298
+ } catch (_e) {
7299
+ text = null;
7300
+ }
7301
+ return { field, tagNumber: node.tagNumber, text, chars: text === null ? null : displayTextChars(text) };
7302
+ }
7303
+ function _noticeNumbers(node) {
7304
+ if (!node || node.tagClass !== "universal" || node.tagNumber !== _T.SEQUENCE || !node.children) return null;
7305
+ var nums = [], ok = true;
7306
+ node.children.forEach(function(n) {
7307
+ try {
7308
+ nums.push(String(asn1.read.integer(n)));
7309
+ } catch (_e) {
7310
+ ok = false;
7311
+ }
7312
+ });
7313
+ return ok ? nums : null;
7314
+ }
7315
+ function userNoticeTexts(qualifier) {
7316
+ if (!qualifier || qualifier.tagClass !== "universal" || qualifier.tagNumber !== _T.SEQUENCE || !qualifier.children) return [];
7317
+ var kids = qualifier.children;
7318
+ if (kids.length > 2) return [];
7319
+ var i = 0, out = [];
7320
+ if (i < kids.length && kids[i].tagClass === "universal" && kids[i].tagNumber === _T.SEQUENCE) {
7321
+ var nr = kids[i];
7322
+ if (!nr.children || nr.children.length !== 2 || !_isDisplayTextNode(nr.children[0])) return [];
7323
+ var org = _dtEntry("organization", nr.children[0]);
7324
+ org.noticeNumbers = _noticeNumbers(nr.children[1]);
7325
+ out.push(org);
7326
+ i++;
7327
+ }
7328
+ if (i < kids.length) {
7329
+ if (!_isDisplayTextNode(kids[i])) return [];
7330
+ out.push(_dtEntry("explicitText", kids[i]));
7331
+ i++;
7332
+ }
7333
+ return i === kids.length ? out : [];
7334
+ }
6937
7335
  function _decodeHelpers(ns) {
6938
7336
  function decodeTop(buf, code, what) {
6939
7337
  var n;
@@ -7655,6 +8053,9 @@ var require_schema_pkix = __commonJS({
7655
8053
  signedEnvelopeTbs,
7656
8054
  rootSequenceChildren,
7657
8055
  assertPolicyQualifiers,
8056
+ DISPLAY_TEXT_MAX,
8057
+ displayTextChars,
8058
+ userNoticeTexts,
7658
8059
  signedEnvelope,
7659
8060
  attrValueToString,
7660
8061
  attributeTypeAndValue,
@@ -7748,6 +8149,12 @@ var require_schema_c509 = __commonJS({
7748
8149
  29: _name("freshestCRL"),
7749
8150
  30: _name("inhibitAnyPolicy"),
7750
8151
  31: _name("subjectInfoAccess"),
8152
+ // RFC 3779 resource-delegation extensions, and their RFC 8360 "v2" twins, which the draft
8153
+ // encodes "exactly like" the originals -- same two codecs, four registry rows (sec. 8.8).
8154
+ 32: _name("ipAddrBlocks"),
8155
+ 33: _name("autonomousSysIds"),
8156
+ 34: _name("ipAddrBlocksV2"),
8157
+ 35: _name("autonomousSysIdsV2"),
7751
8158
  36: _name("ocspNoCheck"),
7752
8159
  38: _name("tlsFeature")
7753
8160
  };
@@ -7770,7 +8177,11 @@ var require_schema_c509 = __commonJS({
7770
8177
  certificatePolicies: 1,
7771
8178
  policyMappings: 1,
7772
8179
  policyConstraints: 1,
7773
- subjectDirectoryAttributes: 1
8180
+ subjectDirectoryAttributes: 1,
8181
+ ipAddrBlocks: 1,
8182
+ autonomousSysIds: 1,
8183
+ ipAddrBlocksV2: 1,
8184
+ autonomousSysIdsV2: 1
7774
8185
  };
7775
8186
  var EKU_BY_INT = {
7776
8187
  0: _name("anyExtendedKeyUsage"),
@@ -7888,6 +8299,7 @@ var require_schema_c509 = __commonJS({
7888
8299
  if (node.majorType === 4 && node.children && node.children.length === 2) {
7889
8300
  var a = _oidName(node.children[0], code, label);
7890
8301
  if (node.children[1].majorType !== 2) throw _err(code, label + " algorithm parameters must be a CBOR byte string");
8302
+ if (node.children[1].content.length === 0) throw _err(code, label + " algorithm parameters must not be an empty byte string; omit them with the bare ~oid form (draft sec. 3.1.3)");
7891
8303
  return { name: a.name, oid: a.oid, parameters: node.children[1].content };
7892
8304
  }
7893
8305
  throw _err(code, label + " is not a C509 AlgorithmIdentifier (int / ~oid / [~oid, params])");
@@ -7905,6 +8317,29 @@ var require_schema_c509 = __commonJS({
7905
8317
  }
7906
8318
  throw _err("c509/bad-name", "an attribute value is not a C509 SpecialText (text / bytes / tag-48)");
7907
8319
  }
8320
+ var _HEX_OPTIMIZED = /^(?:[0-9a-f]{2})+$/;
8321
+ var _EUI64_TEXT = /^(?:[0-9A-F]{2}-){7}[0-9A-F]{2}$/;
8322
+ function _assertCanonicalSpecialText(node, isNative, E) {
8323
+ if (isNative) return;
8324
+ if (node.majorType === 3) {
8325
+ var t = cbor.read.textString(node);
8326
+ if (t.length >= 2 && _HEX_OPTIMIZED.test(t)) {
8327
+ throw _err(E, "a text attribute value of even-length hex characters must be encoded as a CBOR byte string (draft sec. 3.1.4)");
8328
+ }
8329
+ if (_EUI64_TEXT.test(t)) {
8330
+ throw _err(E, "a text attribute value in EUI-64 form must be encoded as a CBOR tag-48 MAC address (draft sec. 3.1.4)");
8331
+ }
8332
+ return;
8333
+ }
8334
+ if (node.majorType === 2) {
8335
+ if (node.content.length === 0) throw _err(E, "an empty attribute value must be encoded as a CBOR text string (draft sec. 3.1.4)");
8336
+ return;
8337
+ }
8338
+ var eui = node.children[0].content;
8339
+ if (eui.length === 8 && eui[3] === 255 && eui[4] === 254) {
8340
+ throw _err(E, "an EUI-64 of the form HH-HH-HH-FF-FE-HH-HH-HH must be encoded as a 48-bit MAC address (draft sec. 3.1.4)");
8341
+ }
8342
+ }
7908
8343
  function _assertAttrValue(rdn) {
7909
8344
  try {
7910
8345
  _reconAttrValue(rdn);
@@ -7917,6 +8352,7 @@ var require_schema_c509 = __commonJS({
7917
8352
  if (!isSubject && node.majorType === 7 && node.ai === 22) return null;
7918
8353
  if (node.majorType === 3 || node.majorType === 2 || node.majorType === 6) {
7919
8354
  var sv = _specialText(node);
8355
+ _assertCanonicalSpecialText(node, isNative, "c509/bad-name");
7920
8356
  if (sv.eui64) return { rdns: [{ type: "commonName", eui64: sv.eui64 }], eui64: sv.eui64, dn: "CN=" + _macToEui64String(sv.eui64) };
7921
8357
  var val = sv.text !== void 0 ? sv.text : sv.hex;
7922
8358
  var bareRdn = { type: "commonName", value: val };
@@ -7936,16 +8372,20 @@ var require_schema_c509 = __commonJS({
7936
8372
  var tname = ATTR_BY_INT[Math.abs(ti)];
7937
8373
  if (tname === void 0) throw _err("c509/bad-name", "attribute type integer " + ti + " has no C509 registry row");
7938
8374
  var v = _specialText(kids[i + 1]);
8375
+ _assertCanonicalSpecialText(kids[i + 1], isNative, "c509/bad-name");
7939
8376
  var vv = v.text !== void 0 ? v.text : v.hex !== void 0 ? v.hex : _macToEui64String(v.eui64);
7940
8377
  var rdn = { type: tname, value: vv, printable: ti < 0 };
7941
8378
  _assertAttrValue(rdn);
7942
8379
  rdns.push(rdn);
7943
8380
  parts.push(_shortName(tname) + "=" + guard.name.escapeDnValue(vv));
7944
8381
  }
7945
- return { rdns, dn: parts.join(",") };
8382
+ if (!isNative && rdns.length === 1 && rdns[0].type === "commonName" && !rdns[0].printable) {
8383
+ throw _err("c509/bad-name", "a Name holding a single +1 commonName must be encoded as a bare SpecialText, not an array (draft sec. 3.1.4)");
8384
+ }
8385
+ return { rdns, dn: parts.join(", ") };
7946
8386
  }
7947
8387
  function _shortName(n) {
7948
- return n === "commonName" ? "CN" : n === "countryName" ? "C" : n === "organizationName" ? "O" : n === "organizationalUnitName" ? "OU" : n === "localityName" ? "L" : n === "stateOrProvinceName" ? "ST" : n;
8388
+ return n && constants.NAMES.DN_SHORT[n] || n;
7949
8389
  }
7950
8390
  function _cborUint(node, label) {
7951
8391
  if (node.majorType !== 0) throw _err("c509/bad-extensions", "a " + label + " value must be a CBOR unsigned integer");
@@ -8154,6 +8594,222 @@ var require_schema_c509 = __commonJS({
8154
8594
  }
8155
8595
  return Buffer.concat([buf.subarray(0, addrLen), Buffer.from([prefixLen])]);
8156
8596
  }
8597
+ function _isUniversal(n, tagNumber) {
8598
+ return !!n && n.tagClass === "universal" && n.tagNumber === tagNumber;
8599
+ }
8600
+ function _ipSeqToInt(seq) {
8601
+ if (!seq.length || seq[0] > 7) return null;
8602
+ var head = Buffer.from([seq[0] + 1]);
8603
+ return BigInt("0x" + Buffer.concat([head, seq.subarray(1)]).toString("hex"));
8604
+ }
8605
+ function _ipIntToSeq(n) {
8606
+ if (n < 1n) return null;
8607
+ var out = [];
8608
+ for (var v = n; v > 0n; v >>= 8n) out.unshift(Number(v & 0xffn));
8609
+ if (out.length > 9 || out[0] < 1 || out[0] > 8) return null;
8610
+ out[0] -= 1;
8611
+ return Buffer.from(out);
8612
+ }
8613
+ var _IP_WIDTH = { 1: 4, 2: 16 };
8614
+ function _ipLow(seq, width) {
8615
+ var v = Buffer.alloc(width);
8616
+ seq.subarray(1).copy(v);
8617
+ return v;
8618
+ }
8619
+ function _ipHigh(seq, width) {
8620
+ var v = _ipLow(seq, width);
8621
+ var bits = (seq.length - 1) * 8 - seq[0];
8622
+ for (var i = bits; i < width * 8; i++) v[i >> 3] |= 128 >> (i & 7);
8623
+ return v;
8624
+ }
8625
+ function _ipOctCmp(a, b2) {
8626
+ for (var i = 0; i < a.length; i++) {
8627
+ if (a[i] !== b2[i]) return a[i] - b2[i];
8628
+ }
8629
+ return 0;
8630
+ }
8631
+ function _ipIsSuccessor(a, b2) {
8632
+ var carry = 1, inc = Buffer.from(a);
8633
+ for (var i = inc.length - 1; i >= 0 && carry; i--) {
8634
+ var s = inc[i] + carry;
8635
+ inc[i] = s & 255;
8636
+ carry = s >> 8;
8637
+ }
8638
+ if (carry) return false;
8639
+ return _ipOctCmp(inc, b2) === 0;
8640
+ }
8641
+ function _ipRangeIsPrefix(lo, hi) {
8642
+ var bits = lo.length * 8, n = 0;
8643
+ while (n < bits) {
8644
+ var byteAt = n >> 3, mask = 128 >> (n & 7);
8645
+ if ((lo[byteAt] & mask) !== (hi[byteAt] & mask)) break;
8646
+ n++;
8647
+ }
8648
+ for (var i = n; i < bits; i++) {
8649
+ var bt = i >> 3, mk = 128 >> (i & 7);
8650
+ if ((lo[bt] & mk) !== 0) return false;
8651
+ if ((hi[bt] & mk) === 0) return false;
8652
+ }
8653
+ return true;
8654
+ }
8655
+ function _famOctCmp(a, b2) {
8656
+ var n = Math.min(a.length, b2.length);
8657
+ for (var i = 0; i < n; i++) {
8658
+ if (a[i] !== b2[i]) return a[i] - b2[i];
8659
+ }
8660
+ return a.length - b2.length;
8661
+ }
8662
+ function _ipSeqBitsClear(seq) {
8663
+ var unused = seq[0], value = seq.subarray(1);
8664
+ if (!value.length) return unused === 0;
8665
+ if (unused === 0) return true;
8666
+ return (value[value.length - 1] & (1 << unused) - 1) === 0;
8667
+ }
8668
+ function _ipRangesCanonical(bounds) {
8669
+ for (var i = 1; i < bounds.length; i++) {
8670
+ var prev = bounds[i - 1], cur = bounds[i];
8671
+ if (_ipOctCmp(cur.lo, prev.hi) <= 0) return false;
8672
+ if (_ipIsSuccessor(prev.hi, cur.lo)) return false;
8673
+ }
8674
+ return true;
8675
+ }
8676
+ function _ipChoiceToDer(items, afi) {
8677
+ var out = [], prev = null, sawBytes = false, sawInt = false, seqs = [];
8678
+ var width = _IP_WIDTH[afi];
8679
+ if (!width) throw _err("c509/bad-extensions", "address family " + afi + " has no known address width, so its addresses cannot be checked (RFC 3779 sec. 2.2.3.3)");
8680
+ function widthOk(seq) {
8681
+ return seq.length - 1 <= width;
8682
+ }
8683
+ function absolute(node) {
8684
+ var seq;
8685
+ if (node.majorType === 2) {
8686
+ sawBytes = true;
8687
+ if (node.content.length === 0) throw _err("c509/bad-extensions", "an IPAddress byte sequence must be non-empty");
8688
+ if (node.content[0] > 7) throw _err("c509/bad-extensions", "an IPAddress unused-bit count must be 0..7 (DER)");
8689
+ seq = node.content;
8690
+ } else {
8691
+ sawInt = true;
8692
+ var d = _cborIntVal(node, "an IPAddress");
8693
+ var abs = prev === null ? d : prev + d;
8694
+ prev = abs;
8695
+ guard.range.uint64(abs, _err, "c509/bad-extensions", "an IPAddress");
8696
+ seq = _ipIntToSeq(abs);
8697
+ if (!seq) throw _err("c509/bad-extensions", "an IPAddress integer does not encode a DER BIT STRING (sec. 3.3)");
8698
+ }
8699
+ if (!widthOk(seq)) {
8700
+ throw _err("c509/bad-extensions", "an IPAddress is wider than address family " + afi + " permits (RFC 3779 sec. 2.2.3.8)");
8701
+ }
8702
+ if (!_ipSeqBitsClear(seq)) {
8703
+ throw _err("c509/bad-extensions", "an IPAddress must leave its declared unused bits zero (RFC 3779 sec. 2.2.3.8)");
8704
+ }
8705
+ return seq;
8706
+ }
8707
+ var bounds = [];
8708
+ for (var i = 0; i < items.length; i++) {
8709
+ var it = items[i];
8710
+ if (it.majorType === 4) {
8711
+ if (!it.children || it.children.length !== 2) throw _err("c509/bad-extensions", "an IPAddress range must be exactly [min, max]");
8712
+ var lo = absolute(it.children[0]), hi = absolute(it.children[1]);
8713
+ seqs.push(lo);
8714
+ seqs.push(hi);
8715
+ var rlo = _ipLow(lo, width), rhi = _ipHigh(hi, width);
8716
+ {
8717
+ if (_ipRangeIsPrefix(rlo, rhi)) throw _err("c509/bad-extensions", "an address range that is exactly a prefix must use the prefix form (RFC 3779 sec. 2.2.3.7)");
8718
+ bounds.push({ lo: rlo, hi: rhi });
8719
+ }
8720
+ out.push(b.sequence([b.bitString(lo.subarray(1), lo[0]), b.bitString(hi.subarray(1), hi[0])]));
8721
+ } else {
8722
+ var pfx = absolute(it);
8723
+ seqs.push(pfx);
8724
+ bounds.push({ lo: _ipLow(pfx, width), hi: _ipHigh(pfx, width) });
8725
+ out.push(b.bitString(pfx.subarray(1), pfx[0]));
8726
+ }
8727
+ }
8728
+ if (sawBytes && sawInt) throw _err("c509/bad-extensions", "an IPAddressFamily must use one address form throughout (sec. 3.3)");
8729
+ if (sawBytes && !seqs.some(function(s) {
8730
+ return s.length > 8;
8731
+ })) {
8732
+ throw _err("c509/bad-extensions", "an IPAddressFamily whose addresses all fit 8 octets must use the integer form (sec. 3.3)");
8733
+ }
8734
+ for (var r = 0; r < bounds.length; r++) {
8735
+ if (_ipOctCmp(bounds[r].lo, bounds[r].hi) > 0) throw _err("c509/bad-extensions", "an IPAddress range must not end below its start (RFC 3779 sec. 2.2.3.9)");
8736
+ }
8737
+ if (!_ipRangesCanonical(bounds)) {
8738
+ throw _err("c509/bad-extensions", "an IPAddressFamily must be sorted, non-overlapping and maximally merged (RFC 3779 sec. 2.2.3.6)");
8739
+ }
8740
+ return out;
8741
+ }
8742
+ function _ipChoiceFromDer(ch, afi) {
8743
+ if (!_isUniversal(ch, asn1.TAGS.SEQUENCE) || !ch.children || ch.children.length === 0) return null;
8744
+ var groups = [], flat = [];
8745
+ for (var i = 0; i < ch.children.length; i++) {
8746
+ var el = ch.children[i], pair;
8747
+ if (_isUniversal(el, asn1.TAGS.BIT_STRING)) {
8748
+ var bs = asn1.read.bitString(el);
8749
+ pair = [Buffer.concat([Buffer.from([bs.unusedBits]), bs.bytes])];
8750
+ } else if (_isUniversal(el, asn1.TAGS.SEQUENCE) && el.children && el.children.length === 2 && _isUniversal(el.children[0], asn1.TAGS.BIT_STRING) && _isUniversal(el.children[1], asn1.TAGS.BIT_STRING)) {
8751
+ var lo = asn1.read.bitString(el.children[0]), hi = asn1.read.bitString(el.children[1]);
8752
+ pair = [
8753
+ Buffer.concat([Buffer.from([lo.unusedBits]), lo.bytes]),
8754
+ Buffer.concat([Buffer.from([hi.unusedBits]), hi.bytes])
8755
+ ];
8756
+ } else return null;
8757
+ groups.push(pair);
8758
+ for (var k = 0; k < pair.length; k++) flat.push(pair[k]);
8759
+ }
8760
+ var width = _IP_WIDTH[afi];
8761
+ if (!width) return null;
8762
+ var bounds = [];
8763
+ for (var g = 0; g < groups.length; g++) {
8764
+ var bg = groups[g];
8765
+ if (bg[0].length - 1 > width || bg[bg.length - 1].length - 1 > width) return null;
8766
+ var blo = _ipLow(bg[0], width), bhi = _ipHigh(bg[bg.length - 1], width);
8767
+ if (bg.length === 2 && _ipRangeIsPrefix(blo, bhi)) return null;
8768
+ bounds.push({ lo: blo, hi: bhi });
8769
+ }
8770
+ for (var r = 0; r < bounds.length; r++) {
8771
+ if (_ipOctCmp(bounds[r].lo, bounds[r].hi) > 0) return null;
8772
+ }
8773
+ if (!_ipRangesCanonical(bounds)) return null;
8774
+ var useBytes = flat.some(function(s) {
8775
+ return s.length > 8;
8776
+ });
8777
+ var out = [];
8778
+ if (useBytes) {
8779
+ groups.forEach(function(p) {
8780
+ out.push(p.length === 1 ? cbor.build.byteString(p[0]) : cbor.build.array([cbor.build.byteString(p[0]), cbor.build.byteString(p[1])]));
8781
+ });
8782
+ return cbor.build.array(out);
8783
+ }
8784
+ var prev = null;
8785
+ function delta(seq) {
8786
+ var n = _ipSeqToInt(seq);
8787
+ if (n === null) return null;
8788
+ var d = prev === null ? n : n - prev;
8789
+ prev = n;
8790
+ return cbor.build.int(d);
8791
+ }
8792
+ for (var gi = 0; gi < groups.length; gi++) {
8793
+ var grp = groups[gi];
8794
+ if (grp.length === 1) {
8795
+ var one = delta(grp[0]);
8796
+ if (!one) return null;
8797
+ out.push(one);
8798
+ } else {
8799
+ var dlo = delta(grp[0]);
8800
+ var dhi = dlo ? delta(grp[1]) : null;
8801
+ if (!dlo || !dhi) return null;
8802
+ out.push(cbor.build.array([dlo, dhi]));
8803
+ }
8804
+ }
8805
+ return cbor.build.array(out);
8806
+ }
8807
+ function _asDelta(node, prev) {
8808
+ var d = _cborIntVal(node, "an ASIdentifier");
8809
+ var abs = prev === null ? d : prev + d;
8810
+ guard.range.int(abs, 0n, 4294967295n, _err, "c509/bad-extensions", "an ASIdentifier");
8811
+ return abs;
8812
+ }
8157
8813
  function _subtreesToDer(node, isNative) {
8158
8814
  if (node.majorType !== 4 || !node.children) throw _err("c509/bad-extensions", "a GeneralSubtrees value must be a CBOR array");
8159
8815
  var kids = node.children;
@@ -8350,8 +9006,8 @@ var require_schema_c509 = __commonJS({
8350
9006
  } else {
8351
9007
  items = [node];
8352
9008
  }
8353
- return b.sequence(items.map(function(it) {
8354
- return b.oid(_ekuPurposeOid(it));
9009
+ return b.sequence(items.map(function(it2) {
9010
+ return b.oid(_ekuPurposeOid(it2));
8355
9011
  }));
8356
9012
  }
8357
9013
  case "inhibitAnyPolicy":
@@ -8368,6 +9024,9 @@ var require_schema_c509 = __commonJS({
8368
9024
  case "subjectAltName":
8369
9025
  case "issuerAltName":
8370
9026
  if (node.majorType === 3) return b.sequence([b.contextPrimitive(2, _ia5Bytes(node, 2))]);
9027
+ if (!isNative && node.majorType === 4 && node.children && node.children.length === 2 && node.children[0].majorType === 0 && Number(cbor.read.int(node.children[0])) === 2 && node.children[1].majorType === 3) {
9028
+ throw _err("c509/bad-extensions", "a " + name + " holding exactly one dNSName must be encoded as a bare CBOR text string, not an array (draft sec. 3.3)");
9029
+ }
8371
9030
  return b.sequence(_generalNamesToDer(node, isNative));
8372
9031
  case "nameConstraints": {
8373
9032
  if (node.majorType !== 4 || !node.children || node.children.length !== 2) throw _err("c509/bad-extensions", "a nameConstraints value must be a 2-element CBOR array [ permitted, excluded ] (sec. 3.3)");
@@ -8393,6 +9052,71 @@ var require_schema_c509 = __commonJS({
8393
9052
  return b.sequence(node.children.map(function(dp) {
8394
9053
  return _dpToDer(dp, isNative);
8395
9054
  }));
9055
+ // IPAddrBlocks (and its RFC 8360 v2 twin): a FLAT array of (AFI, SAFI, choice) triples --
9056
+ // IPAddressFamily is a parenthesized CDDL group, so it splices rather than nesting.
9057
+ case "ipAddrBlocks":
9058
+ case "ipAddrBlocksV2": {
9059
+ if (node.majorType !== 4 || !node.children) throw _err("c509/bad-extensions", "an IPAddrBlocks value must be a CBOR array");
9060
+ var ipKids = node.children;
9061
+ if (ipKids.length === 0 || ipKids.length % 3 !== 0) throw _err("c509/bad-extensions", "an IPAddrBlocks array must be non-empty (AFI, SAFI, addresses) triples (sec. 3.3)");
9062
+ var families = [], prevFam = null;
9063
+ for (var fi = 0; fi + 2 < ipKids.length; fi += 3) {
9064
+ var afi = _cborUint(ipKids[fi], "an IPAddrBlocks AFI");
9065
+ if (afi > 0xffffn) throw _err("c509/bad-extensions", "an IPAddrBlocks AFI must fit two octets (RFC 3779 sec. 2.2.3.3)");
9066
+ var safiNode = ipKids[fi + 1], famBytes = [Number(afi >> 8n) & 255, Number(afi & 0xffn)];
9067
+ if (!_isCborNull(safiNode)) {
9068
+ var safi = _cborUint(safiNode, "an IPAddrBlocks SAFI");
9069
+ if (safi > 0xffn) throw _err("c509/bad-extensions", "an IPAddrBlocks SAFI must fit one octet (RFC 3779 sec. 2.2.3.3)");
9070
+ famBytes.push(Number(safi));
9071
+ }
9072
+ var famOct = Buffer.from(famBytes);
9073
+ if (prevFam !== null && _famOctCmp(prevFam, famOct) >= 0) {
9074
+ throw _err("c509/bad-extensions", "IPAddrBlocks address families must be unique and in ascending addressFamily order (RFC 3779 sec. 2.2.3.3)");
9075
+ }
9076
+ prevFam = famOct;
9077
+ var choice = ipKids[fi + 2], famFields = [b.octetString(famOct)];
9078
+ if (_isCborNull(choice)) {
9079
+ famFields.push(b.nullValue());
9080
+ } else {
9081
+ if (choice.majorType !== 4 || !choice.children || choice.children.length === 0) {
9082
+ throw _err("c509/bad-extensions", "an IPAddrBlocks address choice must be null (inherit) or a non-empty CBOR array");
9083
+ }
9084
+ famFields.push(b.sequence(_ipChoiceToDer(choice.children, Number(afi))));
9085
+ }
9086
+ families.push(b.sequence(famFields));
9087
+ }
9088
+ return b.sequence(families);
9089
+ }
9090
+ // ASIdentifiers (and its v2 twin): null = inherit, else a flat array of uint / [min,max].
9091
+ // Only the asnum field is representable -- a present rdi has no compact form (sec. 3.3), so a
9092
+ // certificate carrying one rides the ~oid byte-string form and never reaches this arm.
9093
+ case "autonomousSysIds":
9094
+ case "autonomousSysIdsV2": {
9095
+ if (_isCborNull(node)) return b.sequence([b.explicit(0, b.nullValue())]);
9096
+ if (node.majorType !== 4 || !node.children || node.children.length === 0) {
9097
+ throw _err("c509/bad-extensions", "an ASIdentifiers value must be null (inherit) or a non-empty CBOR array");
9098
+ }
9099
+ var asKids = node.children, asDers = [], asPrev = null, asPrevHigh = null;
9100
+ for (var asi2 = 0; asi2 < asKids.length; asi2++) {
9101
+ var it = asKids[asi2];
9102
+ if (it.majorType === 4) {
9103
+ if (!it.children || it.children.length !== 2) throw _err("c509/bad-extensions", "an ASIdentifiers range must be exactly [min, max]");
9104
+ var amin = _asDelta(it.children[0], asPrev), amax = _asDelta(it.children[1], amin);
9105
+ if (amax <= amin) throw _err("c509/bad-extensions", "an ASIdentifiers range must be ascending (RFC 3779 sec. 3.2.3.6)");
9106
+ if (asPrevHigh !== null && amin <= asPrevHigh + 1n) throw _err("c509/bad-extensions", "ASIdentifiers must be sorted, non-overlapping and maximally merged (RFC 3779 sec. 3.2.3.4)");
9107
+ asDers.push(b.sequence([b.integer(amin), b.integer(amax)]));
9108
+ asPrev = amax;
9109
+ asPrevHigh = amax;
9110
+ } else {
9111
+ var aid = _asDelta(it, asPrev);
9112
+ if (asPrevHigh !== null && aid <= asPrevHigh + 1n) throw _err("c509/bad-extensions", "ASIdentifiers must be sorted, non-overlapping and maximally merged (RFC 3779 sec. 3.2.3.4)");
9113
+ asDers.push(b.integer(aid));
9114
+ asPrev = aid;
9115
+ asPrevHigh = aid;
9116
+ }
9117
+ }
9118
+ return b.sequence([b.explicit(0, b.sequence(asDers))]);
9119
+ }
8396
9120
  case "certificatePolicies": {
8397
9121
  if (node.majorType !== 4 || !node.children) throw _err("c509/bad-extensions", "a certificatePolicies value must be a CBOR array");
8398
9122
  var cpKids = node.children;
@@ -8548,6 +9272,70 @@ var require_schema_c509 = __commonJS({
8548
9272
  return r.triple;
8549
9273
  }));
8550
9274
  }
9275
+ // IPAddrBlocks -> the flat (AFI, SAFI, choice) array. Any shape the compact form cannot
9276
+ // represent exactly returns null, so the extension rides the ~oid byte-string form intact.
9277
+ case "ipAddrBlocks":
9278
+ case "ipAddrBlocksV2": {
9279
+ if (!_isUniversal(node, asn1.TAGS.SEQUENCE) || !node.children || node.children.length === 0) return null;
9280
+ var ipOut = [], prevFamOct = null;
9281
+ for (var ifi = 0; ifi < node.children.length; ifi++) {
9282
+ var fam = node.children[ifi];
9283
+ if (!_isUniversal(fam, asn1.TAGS.SEQUENCE) || !fam.children || fam.children.length !== 2) return null;
9284
+ var famOct = asn1.read.octetString(fam.children[0]);
9285
+ if (famOct.length !== 2 && famOct.length !== 3) return null;
9286
+ if (prevFamOct !== null && _famOctCmp(prevFamOct, famOct) >= 0) return null;
9287
+ prevFamOct = famOct;
9288
+ var afiVal = famOct[0] << 8 | famOct[1];
9289
+ ipOut.push(cbor.build.uint(BigInt(afiVal)));
9290
+ ipOut.push(famOct.length === 3 ? cbor.build.uint(BigInt(famOct[2])) : cbor.build.nullValue());
9291
+ var ch = fam.children[1];
9292
+ if (_isUniversal(ch, asn1.TAGS.NULL)) {
9293
+ ipOut.push(cbor.build.nullValue());
9294
+ continue;
9295
+ }
9296
+ var chOut = _ipChoiceFromDer(ch, afiVal);
9297
+ if (!chOut) return null;
9298
+ ipOut.push(chOut);
9299
+ }
9300
+ return cbor.build.array(ipOut);
9301
+ }
9302
+ // ASIdentifiers -> null (inherit) or the flat delta array. Only asnum is representable: a
9303
+ // present rdi has no compact form (sec. 3.3), so such a certificate returns null here.
9304
+ case "autonomousSysIds":
9305
+ case "autonomousSysIdsV2": {
9306
+ if (!_isUniversal(node, asn1.TAGS.SEQUENCE) || !node.children || node.children.length !== 1) return null;
9307
+ var asnum = node.children[0];
9308
+ if (asnum.tagClass !== "context" || asnum.tagNumber !== 0 || !asnum.children || asnum.children.length !== 1) return null;
9309
+ var inner = asnum.children[0];
9310
+ if (_isUniversal(inner, asn1.TAGS.NULL)) return cbor.build.nullValue();
9311
+ if (!_isUniversal(inner, asn1.TAGS.SEQUENCE) || !inner.children || inner.children.length === 0) return null;
9312
+ var asOut = [], asPrevOut = null, asPrevHigh = null;
9313
+ for (var aoi = 0; aoi < inner.children.length; aoi++) {
9314
+ var el = inner.children[aoi], elLo, elHi;
9315
+ if (_isUniversal(el, asn1.TAGS.INTEGER)) {
9316
+ elLo = asn1.read.integer(el);
9317
+ elHi = elLo;
9318
+ if (elLo < 0n || elLo > 4294967295n) return null;
9319
+ } else if (_isUniversal(el, asn1.TAGS.SEQUENCE) && el.children && el.children.length === 2) {
9320
+ elLo = asn1.read.integer(el.children[0]);
9321
+ elHi = asn1.read.integer(el.children[1]);
9322
+ if (elLo < 0n || elHi > 4294967295n || elHi <= elLo) return null;
9323
+ } else return null;
9324
+ if (asPrevHigh !== null && elLo <= asPrevHigh + 1n) return null;
9325
+ if (el.tagNumber === asn1.TAGS.INTEGER) {
9326
+ asOut.push(cbor.build.int(asPrevOut === null ? elLo : elLo - asPrevOut));
9327
+ asPrevOut = elLo;
9328
+ } else {
9329
+ asOut.push(cbor.build.array([
9330
+ cbor.build.int(asPrevOut === null ? elLo : elLo - asPrevOut),
9331
+ cbor.build.int(elHi - elLo)
9332
+ ]));
9333
+ asPrevOut = elHi;
9334
+ }
9335
+ asPrevHigh = elHi;
9336
+ }
9337
+ return cbor.build.array(asOut);
9338
+ }
8551
9339
  case "certificatePolicies": {
8552
9340
  if (node.tagClass !== "universal" || node.tagNumber !== asn1.TAGS.SEQUENCE || !node.children || node.children.length < 1) return null;
8553
9341
  var cpOut = [];
@@ -8787,6 +9575,9 @@ var require_schema_c509 = __commonJS({
8787
9575
  var out = [];
8788
9576
  var kids = node.children || [];
8789
9577
  if (kids.length % 2 !== 0) throw _err("c509/bad-extensions", "a C509 extensions array must be id/value pairs (dangling extension identifier)");
9578
+ if (!isNative && kids.length === 2 && (kids[0].majorType === 0 || kids[0].majorType === 1) && (kids[1].majorType === 0 || kids[1].majorType === 1) && Math.abs(Number(cbor.read.int(kids[0]))) === 2) {
9579
+ throw _err("c509/bad-extensions", "an extensions field holding only keyUsage must be encoded as a single CBOR int, not an array (draft sec. 3.1.10)");
9580
+ }
8790
9581
  for (var i = 0; i + 1 < kids.length; i += 2) {
8791
9582
  var idNode = kids[i], valNode = kids[i + 1];
8792
9583
  var name, extOid, critical, valContent;
@@ -8902,15 +9693,20 @@ var require_schema_c509 = __commonJS({
8902
9693
  }
8903
9694
  function _reconstructDer(r, sigNode) {
8904
9695
  var sigAlgSeq = _reconAlgId(r.signatureAlgorithm);
9696
+ var subjectName = _reconName(r.subject);
9697
+ var spelledIssuer = r.issuer && r.issuer.rdns ? _reconName(r.issuer) : null;
9698
+ if (spelledIssuer !== null && spelledIssuer.equals(subjectName)) {
9699
+ throw _err("c509/bad-name", "an issuer identical to the subject must be encoded as the CBOR simple value null (draft sec. 3.1.4)");
9700
+ }
8905
9701
  var tbsFields = [
8906
9702
  b.explicit(0, b.integer(2n)),
8907
9703
  // version v3 (type-3 is X.509 v3)
8908
9704
  b.integer(r.serialNumber),
8909
9705
  sigAlgSeq,
8910
- _reconName(r.issuer && r.issuer.rdns ? r.issuer : r.subject),
9706
+ spelledIssuer === null ? subjectName : spelledIssuer,
8911
9707
  // null issuer -> issuer == subject
8912
9708
  b.sequence([_reconTime(r.validity.notBefore), _reconTime(r.validity.notAfter)]),
8913
- _reconName(r.subject),
9709
+ subjectName,
8914
9710
  _reconSpki(r.subjectPublicKeyAlgorithm, r.subjectPublicKey, r.rsaPublicKey)
8915
9711
  ];
8916
9712
  if (r.extensions.length) tbsFields.push(_reconExtensions(r.extensions));
@@ -9012,7 +9808,9 @@ var require_schema_c509 = __commonJS({
9012
9808
  }
9013
9809
  function _encSpecialText(rdn) {
9014
9810
  if (rdn.eui64) return cbor.build.tag(48, cbor.build.byteString(rdn.eui64));
9015
- return cbor.build.textString(String(rdn.value));
9811
+ var v = String(rdn.value);
9812
+ if (v.length >= 2 && _HEX_OPTIMIZED.test(v)) return cbor.build.byteString(Buffer.from(v, "hex"));
9813
+ return cbor.build.textString(v);
9016
9814
  }
9017
9815
  function _encName(name, isSubject) {
9018
9816
  if (name === null || name === void 0) {
@@ -9197,6 +9995,7 @@ var require_schema_c509 = __commonJS({
9197
9995
  } catch (e) {
9198
9996
  throw _err("c509/bad-input", "the input is not a valid X.509 certificate", e);
9199
9997
  }
9998
+ if (c.version !== 3) throw _err("c509/non-invertible", "C509 covers X.509 v3 certificates; got v" + c.version);
9200
9999
  if (!/^ecdsa/i.test(c.signatureAlgorithm.name || "")) throw _err("c509/non-invertible", "type-3 C509 encoding covers only ECDSA-signed certificates; got " + (c.signatureAlgorithm.name || "an unregistered algorithm"));
9201
10000
  if (c.subjectPublicKeyInfo.algorithm.name !== "ecPublicKey") throw _err("c509/non-invertible", "type-3 C509 encoding covers only EC (ecPublicKey) certificates in v1; got " + (c.subjectPublicKeyInfo.algorithm.name || "an unregistered algorithm"));
9202
10001
  var curveOid = asn1.read.oid(asn1.decode(c.subjectPublicKeyInfo.algorithm.parameters));
@@ -9210,7 +10009,13 @@ var require_schema_c509 = __commonJS({
9210
10009
  serialNumber: c.serialNumber,
9211
10010
  // no serialNumberHex -> the encoder uses the minimal ~biguint magnitude
9212
10011
  signatureAlgorithm: { name: c.signatureAlgorithm.name, oid: c.signatureAlgorithm.oid },
9213
- issuer: _c509NameFromDer(c.issuer.bytes),
10012
+ // sec. 3.1.4: "If the 'issuer' field is identical to the 'subject' field, e.g., in case of
10013
+ // self-signed certificates, then the 'issuer' field MUST be encoded as the CBOR simple value
10014
+ // null." Compared on the RAW DER bytes, not on a canonicalized name: the reconstruction rebuilds
10015
+ // a null issuer FROM the subject, so two names that merely compare equal (a PrintableString
10016
+ // against a UTF8String of the same characters) would rebuild different bytes and break the
10017
+ // signature that covers them. Byte-identical is exactly the condition under which that is safe.
10018
+ issuer: c.issuer.bytes.equals(c.subject.bytes) ? null : _c509NameFromDer(c.issuer.bytes),
9214
10019
  validity: { notBefore: c.validity.notBefore, notAfter: c.validity.notAfter.getTime() === _NO_EXPIRY ? null : c.validity.notAfter },
9215
10020
  subject: _c509NameFromDer(c.subject.bytes),
9216
10021
  subjectPublicKeyAlgorithm: { name: "ecPublicKey", oid: c.subjectPublicKeyInfo.algorithm.oid, curve },
@@ -9679,9 +10484,9 @@ var require_schema_cms = __commonJS({
9679
10484
  WRAP_KEK_LENGTHS[oid.byName("aes192-wrap")] = 24;
9680
10485
  WRAP_KEK_LENGTHS[oid.byName("aes256-wrap")] = 32;
9681
10486
  var KEM_CT_LENGTHS = {};
9682
- KEM_CT_LENGTHS[oid.byName("id-ml-kem-512")] = 768;
9683
- KEM_CT_LENGTHS[oid.byName("id-ml-kem-768")] = 1088;
9684
- KEM_CT_LENGTHS[oid.byName("id-ml-kem-1024")] = 1568;
10487
+ ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function(n) {
10488
+ KEM_CT_LENGTHS[oid.byName(n)] = oid.kemParams(n).ct;
10489
+ });
9685
10490
  var AEAD_GCM_ICVLENS = /* @__PURE__ */ new Set([12, 13, 14, 15, 16]);
9686
10491
  var AEAD_CCM_ICVLENS = /* @__PURE__ */ new Set([4, 6, 8, 10, 12, 14, 16]);
9687
10492
  var AEAD_ALGS = {};
@@ -14755,7 +15560,7 @@ var require_sign_scheme = __commonJS({
14755
15560
  function _importKey(key, imp, E) {
14756
15561
  if (key && typeof key === "object" && !Buffer.isBuffer(key) && !(key instanceof Uint8Array) && key.type === "private") {
14757
15562
  _assertKeyMatchesScheme(key, imp, E);
14758
- return Promise.resolve(key);
15563
+ return webcrypto.adoptKey(key, imp, ["sign"], E, "bad-input");
14759
15564
  }
14760
15565
  var der;
14761
15566
  if (Buffer.isBuffer(key)) der = key;
@@ -15005,9 +15810,7 @@ var require_pki_build = __commonJS({
15005
15810
  if (bc.cA != null && typeof bc.cA !== "boolean") throw E("bad-input", "basicConstraints cA must be a boolean");
15006
15811
  if (bc.critical != null && typeof bc.critical !== "boolean") throw E("bad-input", "basicConstraints critical must be a boolean");
15007
15812
  if (bc.pathLen != null) pathLen(bc.pathLen);
15008
- Object.keys(bc).forEach(function(k) {
15009
- if (k !== "cA" && k !== "pathLen" && k !== "critical") throw E("bad-input", "unknown basicConstraints field " + JSON.stringify(k));
15010
- });
15813
+ guard.identifier.assertKnownKeys(bc, BC_KEYS, E, "bad-input", "unknown basicConstraints field ");
15011
15814
  }
15012
15815
  function extBasicConstraints(spec) {
15013
15816
  var children = [];
@@ -15103,6 +15906,7 @@ var require_pki_build = __commonJS({
15103
15906
  var last = n.children[n.children.length - 1];
15104
15907
  if (last.tagNumber !== asn1.TAGS.OCTET_STRING || last.tagClass !== "universal") throw E("bad-input", "pre-encoded extension [" + idx + "] extnValue must be an OCTET STRING");
15105
15908
  }
15909
+ var BC_KEYS = { cA: 1, pathLen: 1, critical: 1 };
15106
15910
  var REQ_EXT_KEYS = {
15107
15911
  subjectAltName: 1,
15108
15912
  keyUsage: 1,
@@ -15139,8 +15943,8 @@ var require_pki_build = __commonJS({
15139
15943
  }));
15140
15944
  }
15141
15945
  if (!extSpec || typeof extSpec !== "object") throw E("bad-input", "requested extensions must be an object or an array of pre-encoded Extension DER");
15142
- Object.keys(extSpec).forEach(function(k) {
15143
- if (!REQ_EXT_KEYS[k]) throw E("bad-input", "unknown requested extension " + JSON.stringify(k) + "; pass a pre-encoded Extension DER via the array form for a custom extension");
15946
+ guard.identifier.assertKnownKeys(extSpec, REQ_EXT_KEYS, E, "bad-input", function(k) {
15947
+ return "unknown requested extension " + JSON.stringify(k) + "; pass a pre-encoded Extension DER via the array form for a custom extension";
15144
15948
  });
15145
15949
  var out = [];
15146
15950
  if (extSpec.subjectKeyIdentifier != null) {
@@ -15271,6 +16075,7 @@ var require_crmf_sign = __commonJS({
15271
16075
  var pkix = require_schema_pkix();
15272
16076
  var pkiBuild = require_pki_build();
15273
16077
  var frameworkError = require_framework_error();
16078
+ var guard = require_guard_all();
15274
16079
  var CrmfError = frameworkError.CrmfError;
15275
16080
  var b = asn1.build;
15276
16081
  function _err(code, message, cause) {
@@ -15294,6 +16099,7 @@ var require_crmf_sign = __commonJS({
15294
16099
  EXT_DECODERS
15295
16100
  });
15296
16101
  var KNOWN_SPEC_KEYS = { certReqId: 1, certTemplate: 1, controls: 1, regInfo: 1, pop: 1 };
16102
+ var KNOWN_BATCH_KEYS = { messages: 1 };
15297
16103
  var KNOWN_TEMPLATE_KEYS = { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1 };
15298
16104
  var REVOCATION_TEMPLATE_KEYS = { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1, serialNumber: 1 };
15299
16105
  function _ctlUtf8(v) {
@@ -15321,9 +16127,7 @@ var require_crmf_sign = __commonJS({
15321
16127
  function _encodeCertTemplate(tpl, opts) {
15322
16128
  if (!tpl || typeof tpl !== "object" || Buffer.isBuffer(tpl)) throw _err("crmf/bad-cert-template", "certTemplate must be an object");
15323
16129
  var allowed = opts && opts.revocation ? REVOCATION_TEMPLATE_KEYS : KNOWN_TEMPLATE_KEYS;
15324
- Object.keys(tpl).forEach(function(k) {
15325
- if (!allowed[k]) throw _err("crmf/bad-input", "unknown certTemplate field " + JSON.stringify(k));
15326
- });
16130
+ guard.identifier.assertKnownKeys(tpl, allowed, _err, "crmf/bad-input", "unknown certTemplate field ");
15327
16131
  var fields = [];
15328
16132
  if (tpl.version != null) {
15329
16133
  if (tpl.version !== 2) throw _err("crmf/bad-version", "certTemplate version MUST be 2 (v3) if supplied (RFC 4211 sec. 5)");
@@ -15368,9 +16172,11 @@ var require_crmf_sign = __commonJS({
15368
16172
  }
15369
16173
  if (!spec || typeof spec !== "object") throw _err("crmf/bad-input", label + " must be an object or an array of pre-encoded AttributeTypeAndValue DER");
15370
16174
  var out = [], seen = {};
16175
+ guard.identifier.assertKnownKeys(spec, valueMap, _err, "crmf/bad-input", function(k) {
16176
+ return "unknown " + label + " " + JSON.stringify(k) + "; pass a pre-encoded AttributeTypeAndValue DER via the array form for a " + label + " entry outside " + Object.keys(valueMap).join("/");
16177
+ });
15371
16178
  Object.keys(spec).forEach(function(k) {
15372
16179
  var enc = valueMap[k];
15373
- if (!enc) throw _err("crmf/bad-input", "unknown " + label + " " + JSON.stringify(k) + "; pass a pre-encoded AttributeTypeAndValue DER via the array form for a " + label + " entry outside " + Object.keys(valueMap).join("/"));
15374
16180
  var typeOid = O(k);
15375
16181
  if (seen[typeOid]) throw _err(code, "duplicate " + label + " type " + k);
15376
16182
  seen[typeOid] = true;
@@ -15441,9 +16247,7 @@ var require_crmf_sign = __commonJS({
15441
16247
  }
15442
16248
  function _buildCertReqMsg(spec, key, opts) {
15443
16249
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("crmf/bad-input", "each certificate-request-message spec must be an object");
15444
- Object.keys(spec).forEach(function(k) {
15445
- if (!KNOWN_SPEC_KEYS[k]) throw _err("crmf/bad-input", "unknown spec field " + JSON.stringify(k));
15446
- });
16250
+ guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "crmf/bad-input", "unknown spec field ");
15447
16251
  if (spec.certTemplate == null) throw _err("crmf/bad-input", "spec.certTemplate is required");
15448
16252
  var signingKey = key && typeof key === "object" && !Buffer.isBuffer(key) && !(key instanceof Uint8Array) && key.type == null && "key" in key ? key.key : key;
15449
16253
  var template = _encodeCertTemplate(spec.certTemplate);
@@ -15463,8 +16267,8 @@ var require_crmf_sign = __commonJS({
15463
16267
  var specs;
15464
16268
  if (spec.messages != null) {
15465
16269
  if (!Array.isArray(spec.messages)) throw _err("crmf/bad-input", "spec.messages must be an array of certificate-request-message specs");
15466
- Object.keys(spec).forEach(function(k) {
15467
- if (k !== "messages") throw _err("crmf/bad-input", "unknown batch-envelope field " + JSON.stringify(k) + " -- a batch spec carries only 'messages'");
16270
+ guard.identifier.assertKnownKeys(spec, KNOWN_BATCH_KEYS, _err, "crmf/bad-input", function(k) {
16271
+ return "unknown batch-envelope field " + JSON.stringify(k) + " -- a batch spec carries only 'messages'";
15468
16272
  });
15469
16273
  specs = spec.messages;
15470
16274
  } else {
@@ -15509,8 +16313,17 @@ var require_pbes2 = __commonJS({
15509
16313
  PRF_NODE_BY_OID[O(n)] = PRF_NODE_BY_NAME[n];
15510
16314
  });
15511
16315
  var CONTENT_KEYBITS = {};
15512
- [["aes128-CBC", 128], ["aes192-CBC", 192], ["aes256-CBC", 256], ["aes128-GCM", 128], ["aes192-GCM", 192], ["aes256-GCM", 256]].forEach(function(r) {
16316
+ var CONTENT_MODE = {};
16317
+ [
16318
+ ["aes128-CBC", 128, "cbc"],
16319
+ ["aes192-CBC", 192, "cbc"],
16320
+ ["aes256-CBC", 256, "cbc"],
16321
+ ["aes128-GCM", 128, "gcm"],
16322
+ ["aes192-GCM", 192, "gcm"],
16323
+ ["aes256-GCM", 256, "gcm"]
16324
+ ].forEach(function(r) {
15513
16325
  CONTENT_KEYBITS[O(r[0])] = r[1];
16326
+ CONTENT_MODE[O(r[0])] = r[2];
15514
16327
  });
15515
16328
  function passwordBytes(p, E, prefix) {
15516
16329
  if (Buffer.isBuffer(p)) return p;
@@ -15663,6 +16476,7 @@ var require_pbes2 = __commonJS({
15663
16476
  pbes2Encrypt,
15664
16477
  pbes2Decrypt,
15665
16478
  CONTENT_KEYBITS,
16479
+ CONTENT_MODE,
15666
16480
  pbmac1AlgId,
15667
16481
  pbmac1
15668
16482
  };
@@ -15769,6 +16583,7 @@ var require_cmp_build = __commonJS({
15769
16583
  var CRMF_BODY = { ir: 1, cr: 1, kur: 1 };
15770
16584
  var CERT_REP_ARM = { ip: 1, cp: 1, kup: 1, ccp: 1 };
15771
16585
  var KNOWN_OPTS_KEYS = { key: 1, cert: 1, mac: 1, extraCerts: 1, pem: 1, pss: 1, digestAlgorithm: 1 };
16586
+ var KNOWN_MESSAGE_KEYS = { header: 1, body: 1 };
15772
16587
  var KNOWN_MAC_KEYS = { secret: 1, salt: 1, iterationCount: 1, prf: 1, keyLength: 1, algorithm: 1 };
15773
16588
  var PBMAC1_DEFAULT_ITER = 1e5;
15774
16589
  var PBMAC1_DEFAULT_SALT_BYTES = 16;
@@ -15858,9 +16673,7 @@ var require_cmp_build = __commonJS({
15858
16673
  }
15859
16674
  function _encodeHeader(headerSpec, protectionAlgDer, pvno) {
15860
16675
  if (!headerSpec || typeof headerSpec !== "object" || Buffer.isBuffer(headerSpec)) throw _err("cmp/bad-input", "message.header must be an object");
15861
- Object.keys(headerSpec).forEach(function(k) {
15862
- if (!KNOWN_HEADER_KEYS[k]) throw _err("cmp/bad-input", "unknown header field " + JSON.stringify(k));
15863
- });
16676
+ guard.identifier.assertKnownKeys(headerSpec, KNOWN_HEADER_KEYS, _err, "cmp/bad-input", "unknown header field ");
15864
16677
  if (headerSpec.sender == null) throw _err("cmp/bad-input", "message.header.sender is required (GeneralName)");
15865
16678
  if (headerSpec.recipient == null) throw _err("cmp/bad-input", "message.header.recipient is required (GeneralName)");
15866
16679
  var children = [
@@ -16183,9 +16996,7 @@ var require_cmp_build = __commonJS({
16183
16996
  }
16184
16997
  var m = opts.mac;
16185
16998
  if (!m || typeof m !== "object" || Buffer.isBuffer(m)) throw _err("cmp/bad-input", "opts.mac must be an object { secret, salt?, iterationCount?, prf?, keyLength? }");
16186
- Object.keys(m).forEach(function(k) {
16187
- if (!KNOWN_MAC_KEYS[k]) throw _err("cmp/bad-input", "unknown opts.mac field " + JSON.stringify(k));
16188
- });
16999
+ guard.identifier.assertKnownKeys(m, KNOWN_MAC_KEYS, _err, "cmp/bad-input", "unknown opts.mac field ");
16189
17000
  if (m.algorithm != null && m.algorithm !== "pbmac1") throw _err("cmp/unsupported-algorithm", "opts.mac.algorithm " + JSON.stringify(m.algorithm) + " is not supported (v1 ships pbmac1; passwordBasedMac is deferred)");
16190
17001
  var secret = m.secret;
16191
17002
  if (typeof secret !== "string" || !secret) {
@@ -16224,12 +17035,10 @@ var require_cmp_build = __commonJS({
16224
17035
  function _build(message, opts) {
16225
17036
  opts = opts || {};
16226
17037
  if (!message || typeof message !== "object" || Buffer.isBuffer(message)) throw _err("cmp/bad-input", "the PKIMessage spec must be an object { header, body }");
16227
- Object.keys(message).forEach(function(k) {
16228
- if (k !== "header" && k !== "body") throw _err("cmp/bad-input", "unknown message field " + JSON.stringify(k) + " (a message carries only header + body)");
16229
- });
16230
- Object.keys(opts).forEach(function(k) {
16231
- if (!KNOWN_OPTS_KEYS[k]) throw _err("cmp/bad-input", "unknown opts field " + JSON.stringify(k));
17038
+ guard.identifier.assertKnownKeys(message, KNOWN_MESSAGE_KEYS, _err, "cmp/bad-input", function(k) {
17039
+ return "unknown message field " + JSON.stringify(k) + " (a message carries only header + body)";
16232
17040
  });
17041
+ guard.identifier.assertKnownKeys(opts, KNOWN_OPTS_KEYS, _err, "cmp/bad-input", "unknown opts field ");
16233
17042
  if (message.header == null) throw _err("cmp/bad-input", "message.header is required");
16234
17043
  if (message.body == null) throw _err("cmp/bad-input", "message.body is required");
16235
17044
  var prot = _resolveProtection(opts);
@@ -16338,9 +17147,7 @@ var require_cmp_build = __commonJS({
16338
17147
  }
16339
17148
  function _transfer(url, message, opts) {
16340
17149
  opts = opts || {};
16341
- Object.keys(opts).forEach(function(k) {
16342
- if (!KNOWN_TRANSFER_OPTS[k]) throw _err("cmp/bad-input", "unknown opts field " + JSON.stringify(k));
16343
- });
17150
+ guard.identifier.assertKnownKeys(opts, KNOWN_TRANSFER_OPTS, _err, "cmp/bad-input", "unknown opts field ");
16344
17151
  var der = _cmpMessageDer(message);
16345
17152
  var parsedUrl;
16346
17153
  try {
@@ -16387,8 +17194,8 @@ var require_cmp_build = __commonJS({
16387
17194
  var KNOWN_WELLKNOWN_OPTS = { label: 1, operation: 1 };
16388
17195
  function wellKnownUrl(base, opts) {
16389
17196
  opts = opts || {};
16390
- Object.keys(opts).forEach(function(k) {
16391
- if (!KNOWN_WELLKNOWN_OPTS[k]) throw _err("cmp/bad-input", "unknown wellKnownUrl option " + JSON.stringify(k) + " (expected label / operation)");
17197
+ guard.identifier.assertKnownKeys(opts, KNOWN_WELLKNOWN_OPTS, _err, "cmp/bad-input", function(k) {
17198
+ return "unknown wellKnownUrl option " + JSON.stringify(k) + " (expected label / operation)";
16392
17199
  });
16393
17200
  var u;
16394
17201
  try {
@@ -16885,9 +17692,7 @@ var require_cmp_verify = __commonJS({
16885
17692
  async function _verify(message, opts) {
16886
17693
  if (opts == null) opts = {};
16887
17694
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("cmp/bad-input", "opts must be an object");
16888
- Object.keys(opts).forEach(function(k) {
16889
- if (!KNOWN_VERIFY_OPTS[k]) throw _err("cmp/bad-input", "unknown opts field " + JSON.stringify(k));
16890
- });
17695
+ guard.identifier.assertKnownKeys(opts, KNOWN_VERIFY_OPTS, _err, "cmp/bad-input", "unknown opts field ");
16891
17696
  ["transactionID", "expectRecipNonce"].forEach(function(k) {
16892
17697
  if (opts[k] != null && !Buffer.isBuffer(opts[k]) && !(opts[k] instanceof Uint8Array)) throw _err("cmp/bad-input", "opts." + k + " must be a Buffer / Uint8Array");
16893
17698
  });
@@ -17271,9 +18076,7 @@ var require_cmp_session = __commonJS({
17271
18076
  function session(opts) {
17272
18077
  if (opts == null) opts = {};
17273
18078
  if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("cmp/bad-input", "opts must be an object");
17274
- Object.keys(opts).forEach(function(k) {
17275
- if (!KNOWN_SESSION_OPTS[k]) throw _err("cmp/bad-input", "unknown session opts field " + JSON.stringify(k));
17276
- });
18079
+ guard.identifier.assertKnownKeys(opts, KNOWN_SESSION_OPTS, _err, "cmp/bad-input", "unknown session opts field ");
17277
18080
  opts = Object.assign({}, opts);
17278
18081
  if (typeof opts.url !== "string" || !opts.url) throw _err("cmp/bad-input", "opts.url (the CMP endpoint) is required");
17279
18082
  var isSig = opts.key != null || opts.cert != null;
@@ -20338,15 +21141,26 @@ var require_cms_encrypt = __commonJS({
20338
21141
  var pub = await subtle.importKey("spki", cert.subjectPublicKeyInfo.bytes, { name: wcName }, false, ["encapsulateBits"]);
20339
21142
  var kem = await subtle.encapsulateBits({ name: wcName }, pub);
20340
21143
  var ss = Buffer.from(kem.sharedKey), kemct = Buffer.from(kem.ciphertext);
20341
- var ssKey = await subtle.importKey("raw", ss, { name: "HKDF" }, false, ["deriveBits"]);
20342
- var kek = Buffer.from(await subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: Buffer.alloc(0), info: _kemOtherInfo(wrapName, kekBytes, ukm) }, ssKey, kekBytes * 8));
20343
- var encryptedKey = await _aesKwWrap(kek, cek);
20344
- var rid = _rid(cert, opts.keyIdentifier);
20345
- var kemriKids = [b.integer(0n), rid.node, _algId(oid.name(keyOid), "absent"), b.octetString(kemct), _algId("hkdfWithSha256", "absent"), b.integer(BigInt(kekBytes))];
20346
- if (ukm) kemriKids.push(b.explicit(0, b.octetString(ukm)));
20347
- kemriKids.push(_algId(wrapName, "absent"), b.octetString(encryptedKey));
20348
- var kemri = b.sequence(kemriKids);
20349
- return { tag: 4, node: b.sequence([b.oid(O("kem")), kemri]) };
21144
+ var kek = null, kekAb = null;
21145
+ try {
21146
+ var ssKey = await subtle.importKey("raw", ss, { name: "HKDF" }, false, ["deriveBits"]);
21147
+ kekAb = await subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: Buffer.alloc(0), info: _kemOtherInfo(wrapName, kekBytes, ukm) }, ssKey, kekBytes * 8);
21148
+ kek = Buffer.from(kekAb);
21149
+ var encryptedKey = await _aesKwWrap(kek, cek);
21150
+ var rid = _rid(cert, opts.keyIdentifier);
21151
+ var kemriKids = [b.integer(0n), rid.node, _algId(oid.name(keyOid), "absent"), b.octetString(kemct), _algId("hkdfWithSha256", "absent"), b.integer(BigInt(kekBytes))];
21152
+ if (ukm) kemriKids.push(b.explicit(0, b.octetString(ukm)));
21153
+ kemriKids.push(_algId(wrapName, "absent"), b.octetString(encryptedKey));
21154
+ var kemri = b.sequence(kemriKids);
21155
+ return { tag: 4, node: b.sequence([b.oid(O("kem")), kemri]) };
21156
+ } finally {
21157
+ guard.secret.zeroizeAll(
21158
+ [ss, kek, kem.sharedKey ? new Uint8Array(kem.sharedKey) : null, kekAb ? new Uint8Array(kekAb) : null],
21159
+ CmsError,
21160
+ "cms/bad-input",
21161
+ "the KEM shared secret"
21162
+ );
21163
+ }
20350
21164
  }
20351
21165
  async function _aesKwWrap(kek, cek) {
20352
21166
  var kekKey = await subtle.importKey("raw", kek, { name: "AES-KW" }, false, ["wrapKey"]);
@@ -20602,6 +21416,7 @@ var require_cms_decrypt = __commonJS({
20602
21416
  return new CmsError("cms/decrypt-failed", "the CMS content could not be decrypted (uniform by design -- padding / integrity / key-unwrap failures are indistinguishable to defeat oracles)");
20603
21417
  }
20604
21418
  var CONTENT_KEYBITS = pbes2.CONTENT_KEYBITS;
21419
+ var CONTENT_MODE = pbes2.CONTENT_MODE;
20605
21420
  async function decrypt(input, keyMaterial, opts) {
20606
21421
  opts = opts || {};
20607
21422
  if (keyMaterial == null || typeof keyMaterial !== "object") throw _err("cms/bad-input", "decrypt requires a key-material object");
@@ -20619,6 +21434,7 @@ var require_cms_decrypt = __commonJS({
20619
21434
  var recips = parsed.recipientInfos || [];
20620
21435
  var candidates = _selectCandidates(recips, keyMaterial, opts);
20621
21436
  var eci = parsed.encryptedContentInfo;
21437
+ _assertContentCipherMode(eci, ct);
20622
21438
  for (var ci = 0; ci < candidates.length; ci++) {
20623
21439
  try {
20624
21440
  _assertSupported(candidates[ci].ri, keyMaterial);
@@ -20814,7 +21630,7 @@ var require_cms_decrypt = __commonJS({
20814
21630
  var inner = asn1.decode(kea.parameters);
20815
21631
  var innerOid = asn1.read.oid(inner.children[0]);
20816
21632
  var innerBits = CONTENT_KEYBITS[innerOid];
20817
- if (!innerBits || !/CBC/.test(oid.name(innerOid) || "")) throw _err("cms/unsupported-algorithm", "unsupported pwri inner cipher");
21633
+ if (!innerBits || CONTENT_MODE[innerOid] !== "cbc") throw _err("cms/unsupported-algorithm", "unsupported pwri inner cipher");
20818
21634
  var iv = asn1.read.octetString(inner.children[1]);
20819
21635
  var kek = nodeCrypto.pbkdf2Sync(pbes2.passwordBytes(km.password, _err, "cms"), pb.salt, pb.iterations, innerBits / 8, pb.prfNode);
20820
21636
  return _pwriUnwrap(kek, ri.encryptedKey, iv, innerBits);
@@ -20831,10 +21647,30 @@ var require_cms_decrypt = __commonJS({
20831
21647
  var wrapAlg = k.wrap;
20832
21648
  if (WRAP_KEK_LENGTHS[wrapAlg.oid] !== kekBytes) throw _fail();
20833
21649
  var priv = await subtle.importKey("pkcs8", _normKeyDer(km.key), { name: wcName }, false, ["decapsulateBits"]);
20834
- var ss = Buffer.from(await subtle.decapsulateBits({ name: wcName }, priv, kemct));
20835
- var ssKey = await subtle.importKey("raw", ss, { name: "HKDF" }, false, ["deriveBits"]);
20836
- var kek = Buffer.from(await subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: Buffer.alloc(0), info: _kemOtherInfo(wrapAlg.name, kekBytes, k.ukm || null) }, ssKey, kekBytes * 8));
20837
- return await _aesKwUnwrap(kek, k.encryptedKey);
21650
+ var ss = null, kek = null, ssAb = null, kekAb = null;
21651
+ try {
21652
+ ssAb = await subtle.decapsulateBits({ name: wcName }, priv, kemct);
21653
+ ss = Buffer.from(ssAb);
21654
+ var ssKey = await subtle.importKey("raw", ss, { name: "HKDF" }, false, ["deriveBits"]);
21655
+ kekAb = await subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: Buffer.alloc(0), info: _kemOtherInfo(wrapAlg.name, kekBytes, k.ukm || null) }, ssKey, kekBytes * 8);
21656
+ kek = Buffer.from(kekAb);
21657
+ return await _aesKwUnwrap(kek, k.encryptedKey);
21658
+ } finally {
21659
+ guard.secret.zeroizeAll(
21660
+ [ss, kek, ssAb ? new Uint8Array(ssAb) : null, kekAb ? new Uint8Array(kekAb) : null],
21661
+ CmsError,
21662
+ "cms/bad-input",
21663
+ "the KEM shared secret"
21664
+ );
21665
+ }
21666
+ }
21667
+ function _assertContentCipherMode(eci, ct) {
21668
+ var oidStr = eci.contentEncryptionAlgorithm.oid;
21669
+ if (!CONTENT_MODE[oidStr]) return;
21670
+ var wantMode = ct === "authEnvelopedData" ? "gcm" : "cbc";
21671
+ if (CONTENT_MODE[oidStr] !== wantMode) {
21672
+ throw _err("cms/unsupported-algorithm", "contentEncryptionAlgorithm " + oidStr + " is not a " + wantMode.toUpperCase() + " cipher, which " + ct + " requires (RFC 5083 sec. 2.1 / RFC 5084 sec. 3)");
21673
+ }
20838
21674
  }
20839
21675
  async function _openContent(parsed, eci, cek, ct) {
20840
21676
  var alg = eci.contentEncryptionAlgorithm;
@@ -20906,7 +21742,15 @@ var require_cms_decrypt = __commonJS({
20906
21742
  async function _aesKwUnwrap(kek, wrapped) {
20907
21743
  var kekKey = await subtle.importKey("raw", kek, { name: "AES-KW" }, false, ["unwrapKey"]);
20908
21744
  var raw = await subtle.unwrapKey("raw", wrapped, kekKey, { name: "AES-KW" }, { name: "HMAC", hash: "SHA-256" }, true, ["sign"]);
20909
- return Buffer.from(await subtle.exportKey("raw", raw));
21745
+ var rawAb = await subtle.exportKey("raw", raw);
21746
+ try {
21747
+ var view = new Uint8Array(rawAb);
21748
+ var out = Buffer.alloc(view.length);
21749
+ out.set(view);
21750
+ return out;
21751
+ } finally {
21752
+ guard.secret.zeroize(new Uint8Array(rawAb), CmsError, "cms/bad-input", "the unwrapped content key");
21753
+ }
20910
21754
  }
20911
21755
  function _eccSharedInfo(wrapName, ukm, kekBytes) {
20912
21756
  var kids = [b.sequence([b.oid(O(wrapName))])];
@@ -23209,8 +24053,8 @@ var require_x509_sign = __commonJS({
23209
24053
  return arr;
23210
24054
  }
23211
24055
  if (typeof extSpec !== "object") throw _err("x509/bad-input", "extensions must be an object or an array of pre-encoded Extension DER");
23212
- Object.keys(extSpec).forEach(function(k) {
23213
- if (!KNOWN_EXT_KEYS[k]) throw _err("x509/bad-input", "unknown extension " + JSON.stringify(k) + " in the extensions spec; pass a pre-encoded Extension DER via the array form for a custom extension");
24056
+ guard.identifier.assertKnownKeys(extSpec, KNOWN_EXT_KEYS, _err, "x509/bad-input", function(k) {
24057
+ return "unknown extension " + JSON.stringify(k) + " in the extensions spec; pass a pre-encoded Extension DER via the array form for a custom extension";
23214
24058
  });
23215
24059
  var bc = extSpec.basicConstraints;
23216
24060
  if (bc != null) _validateBcSpec(bc);
@@ -23384,7 +24228,9 @@ var require_csr_sign = __commonJS({
23384
24228
  var pkix = require_schema_pkix();
23385
24229
  var pkiBuild = require_pki_build();
23386
24230
  var frameworkError = require_framework_error();
24231
+ var guard = require_guard_all();
23387
24232
  var CsrError = frameworkError.CsrError;
24233
+ var KNOWN_SPEC_KEYS = { subject: 1, subjectPublicKey: 1, extensionRequest: 1, challengePassword: 1, attributes: 1 };
23388
24234
  var b = asn1.build;
23389
24235
  function _err(code, message, cause) {
23390
24236
  return new CsrError(code, message, cause);
@@ -23425,9 +24271,7 @@ var require_csr_sign = __commonJS({
23425
24271
  function _sign(spec, key, opts) {
23426
24272
  opts = opts || {};
23427
24273
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("csr/bad-input", "the certification-request spec must be an object");
23428
- Object.keys(spec).forEach(function(k) {
23429
- if (k !== "subject" && k !== "subjectPublicKey" && k !== "extensionRequest" && k !== "challengePassword" && k !== "attributes") throw _err("csr/bad-input", "unknown spec field " + JSON.stringify(k));
23430
- });
24274
+ guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "csr/bad-input", "unknown spec field ");
23431
24275
  var signingKey = key && typeof key === "object" && !Buffer.isBuffer(key) && !(key instanceof Uint8Array) && key.type == null && "key" in key ? key.key : key;
23432
24276
  if (signingKey == null) throw _err("csr/bad-input", "a signing key (the subject's private key) is required");
23433
24277
  var subjectSpki = _b.reqDer(spec.subjectPublicKey, "spec.subjectPublicKey (the SPKI DER of the requested key)");
@@ -23595,9 +24439,7 @@ var require_attrcert_sign = __commonJS({
23595
24439
  }
23596
24440
  function _encodeHolder(holder) {
23597
24441
  if (!holder || typeof holder !== "object" || Buffer.isBuffer(holder)) throw _err("attrcert/bad-input", "holder must be an object with exactly one form");
23598
- Object.keys(holder).forEach(function(k) {
23599
- if (!KNOWN_HOLDER_KEYS[k]) throw _err("attrcert/bad-input", "unknown holder form " + JSON.stringify(k));
23600
- });
24442
+ guard.identifier.assertKnownKeys(holder, KNOWN_HOLDER_KEYS, _err, "attrcert/bad-input", "unknown holder form ");
23601
24443
  var forms = Object.keys(holder).filter(function(k) {
23602
24444
  return holder[k] != null;
23603
24445
  });
@@ -23814,8 +24656,10 @@ var require_attrcert_sign = __commonJS({
23814
24656
  return b.sequence(attrs);
23815
24657
  }
23816
24658
  if (!attrSpec || typeof attrSpec !== "object") throw _err("attrcert/bad-input", "attributes must be an object or an array of pre-encoded Attribute DER");
24659
+ guard.identifier.assertKnownKeys(attrSpec, ATTR_VALUE_ENCODER, _err, "attrcert/bad-input", function(k) {
24660
+ return "unknown attribute " + JSON.stringify(k) + "; pass a pre-encoded Attribute DER via the array form for a custom attribute";
24661
+ });
23817
24662
  Object.keys(attrSpec).forEach(function(k) {
23818
- if (!ATTR_VALUE_ENCODER[k]) throw _err("attrcert/bad-input", "unknown attribute " + JSON.stringify(k) + "; pass a pre-encoded Attribute DER via the array form for a custom attribute");
23819
24663
  add(O(ATTR_OID_NAME[k]), ATTR_VALUE_ENCODER[k](attrSpec[k]));
23820
24664
  });
23821
24665
  if (!attrs.length) throw _err("attrcert/bad-attributes", "attributes must carry at least one Attribute (RFC 5755 sec. 4.2.7)");
@@ -23850,8 +24694,8 @@ var require_attrcert_sign = __commonJS({
23850
24694
  return b.sequence(exts);
23851
24695
  }
23852
24696
  if (typeof extSpec !== "object") throw _err("attrcert/bad-input", "extensions must be an object or an array of pre-encoded Extension DER");
23853
- Object.keys(extSpec).forEach(function(k) {
23854
- if (!EXT_META[k]) throw _err("attrcert/bad-input", "unknown extension " + JSON.stringify(k) + "; pass a pre-encoded Extension DER via the array form for a custom extension");
24697
+ guard.identifier.assertKnownKeys(extSpec, EXT_META, _err, "attrcert/bad-input", function(k) {
24698
+ return "unknown extension " + JSON.stringify(k) + "; pass a pre-encoded Extension DER via the array form for a custom extension";
23855
24699
  });
23856
24700
  var out = [], seen = {};
23857
24701
  Object.keys(extSpec).forEach(function(k) {
@@ -23872,9 +24716,7 @@ var require_attrcert_sign = __commonJS({
23872
24716
  function _sign(spec, issuer, opts) {
23873
24717
  opts = opts || {};
23874
24718
  if (!spec || typeof spec !== "object" || Buffer.isBuffer(spec)) throw _err("attrcert/bad-input", "the attribute-certificate spec must be an object");
23875
- Object.keys(spec).forEach(function(k) {
23876
- if (!KNOWN_SPEC_KEYS[k]) throw _err("attrcert/bad-input", "unknown spec field " + JSON.stringify(k));
23877
- });
24719
+ guard.identifier.assertKnownKeys(spec, KNOWN_SPEC_KEYS, _err, "attrcert/bad-input", "unknown spec field ");
23878
24720
  issuer = issuer || {};
23879
24721
  if (issuer.key == null) throw _err("attrcert/bad-input", "a signing key (issuer.key, the AA's PKCS#8 private key) is required");
23880
24722
  var issuerDnSpec, aaSpki;
@@ -24056,8 +24898,8 @@ var require_crl_sign = __commonJS({
24056
24898
  }
24057
24899
  function _idpValue(idp) {
24058
24900
  if (!idp || typeof idp !== "object" || Array.isArray(idp) || Buffer.isBuffer(idp)) throw _err("crl/bad-idp", "issuingDistributionPoint must be an object");
24059
- Object.keys(idp).forEach(function(k) {
24060
- if (!KNOWN_IDP_KEYS[k]) throw _err("crl/bad-idp", "unknown issuingDistributionPoint field " + JSON.stringify(k) + " (pass a pre-encoded Extension DER via the extensions array for an exotic field like onlySomeReasons)");
24901
+ guard.identifier.assertKnownKeys(idp, KNOWN_IDP_KEYS, _err, "crl/bad-idp", function(k) {
24902
+ return "unknown issuingDistributionPoint field " + JSON.stringify(k) + " (pass a pre-encoded Extension DER via the extensions array for an exotic field like onlySomeReasons)";
24061
24903
  });
24062
24904
  if (idp.onlyContainsAttributeCerts === true) throw _err("crl/bad-idp", "onlyContainsAttributeCerts=TRUE is not permitted for a conforming CRL issuer (RFC 5280 sec. 5.2.5)");
24063
24905
  var children = [];
@@ -24161,8 +25003,8 @@ var require_crl_sign = __commonJS({
24161
25003
  return { exts: out, isDelta };
24162
25004
  }
24163
25005
  if (typeof ext !== "object") throw _err("crl/bad-input", "extensions must be an object or an array of pre-encoded Extension DER");
24164
- Object.keys(ext).forEach(function(k) {
24165
- if (!KNOWN_CRL_EXT_KEYS[k]) throw _err("crl/bad-input", "unknown CRL extension " + JSON.stringify(k) + " in the extensions spec; pass a pre-encoded Extension DER via the array form");
25006
+ guard.identifier.assertKnownKeys(ext, KNOWN_CRL_EXT_KEYS, _err, "crl/bad-input", function(k) {
25007
+ return "unknown CRL extension " + JSON.stringify(k) + " in the extensions spec; pass a pre-encoded Extension DER via the array form";
24166
25008
  });
24167
25009
  isDelta = ext.deltaCRLIndicator != null;
24168
25010
  if (ext.authorityKeyIdentifier != null) push("authorityKeyIdentifier", false, _extAki(_akiKeyId(ext.authorityKeyIdentifier, ctx)));
@@ -24394,7 +25236,6 @@ var require_key = __commonJS({
24394
25236
  var guard = require_guard_all();
24395
25237
  var b = asn1.build;
24396
25238
  var subtle = webcrypto.webcrypto.subtle;
24397
- var CryptoKey = webcrypto.CryptoKey;
24398
25239
  var KeyError = frameworkError.KeyError;
24399
25240
  var PemError = frameworkError.PemError;
24400
25241
  function O(n) {
@@ -24435,7 +25276,7 @@ var require_key = __commonJS({
24435
25276
  INFER_ALG[O("id-slh-dsa-" + s)] = { name: ("SLH-DSA-" + s).toUpperCase() };
24436
25277
  });
24437
25278
  function _isCryptoKey(x) {
24438
- return x instanceof CryptoKey;
25279
+ return webcrypto.isCryptoKeyLike(x);
24439
25280
  }
24440
25281
  function _algName(a) {
24441
25282
  return typeof a === "string" ? a : a && a.name;
@@ -24443,7 +25284,7 @@ var require_key = __commonJS({
24443
25284
  async function _toPrivateKeyDer(input) {
24444
25285
  if (_isCryptoKey(input)) {
24445
25286
  if (input.type !== "private") throw _err("key/bad-input", "a private CryptoKey is required (got a " + input.type + " key)");
24446
- return Buffer.from(await subtle.exportKey("pkcs8", input));
25287
+ return webcrypto.exportAnyKey(input, _err, "key/bad-input");
24447
25288
  }
24448
25289
  return pkix.coerceToDer(input, { pemLabel: "PRIVATE KEY", PemError, ErrorClass: KeyError, prefix: "key" });
24449
25290
  }
@@ -24498,15 +25339,11 @@ var require_key = __commonJS({
24498
25339
  async function export_(key, opts) {
24499
25340
  opts = opts || {};
24500
25341
  if (!_isCryptoKey(key)) throw _err("key/bad-input", "export expects a WebCrypto CryptoKey");
24501
- var format, defaultLabel;
24502
- if (key.type === "private") {
24503
- format = "pkcs8";
24504
- defaultLabel = "PRIVATE KEY";
24505
- } else if (key.type === "public") {
24506
- format = "spki";
24507
- defaultLabel = "PUBLIC KEY";
24508
- } else throw _err("key/bad-input", "export supports asymmetric (private / public) CryptoKeys only");
24509
- var der = Buffer.from(await subtle.exportKey(format, key));
25342
+ var defaultLabel;
25343
+ if (key.type === "private") defaultLabel = "PRIVATE KEY";
25344
+ else if (key.type === "public") defaultLabel = "PUBLIC KEY";
25345
+ else throw _err("key/bad-input", "export supports asymmetric (private / public) CryptoKeys only");
25346
+ var der = await webcrypto.exportAnyKey(key, _err, "key/bad-input");
24510
25347
  var fmt = opts.format || "der";
24511
25348
  if (fmt === "der") return der;
24512
25349
  if (fmt === "pem") return pkix.pemEncode(der, opts.label || defaultLabel, PemError);
@@ -27751,7 +28588,8 @@ var require_jose = __commonJS({
27751
28588
  "node_modules/@blamejs/pki/lib/jose.js"(exports2, module2) {
27752
28589
  "use strict";
27753
28590
  var constants = require_constants();
27754
- var webcrypto = require_webcrypto().webcrypto;
28591
+ var wcEngine = require_webcrypto();
28592
+ var webcrypto = wcEngine.webcrypto;
27755
28593
  var frameworkError = require_framework_error();
27756
28594
  var guard = require_guard_all();
27757
28595
  var edwardsPoint = require_edwards_point();
@@ -27935,7 +28773,7 @@ var require_jose = __commonJS({
27935
28773
  var payload = opts.payload;
27936
28774
  if (!Buffer.isBuffer(payload)) throw E("jose/bad-input", "payload must be a Buffer (empty Buffer for POST-as-GET)");
27937
28775
  payload = guard.bytes.view(payload, JoseError, "jose/bad-input", "payload");
27938
- if (!opts.key || typeof opts.key !== "object" || typeof opts.key.algorithm !== "object") throw E("jose/bad-input", "a private or secret CryptoKey (opts.key) is required");
28776
+ if (!wcEngine.isCryptoKeyLike(opts.key)) throw E("jose/bad-input", "a private or secret CryptoKey (opts.key) is required");
27939
28777
  var checked = _checkHeader(header, opts.profile || "acme-outer");
27940
28778
  if ((checked.algRow.kty === "RSA" || checked.algRow.kty === "oct") && (!opts.key.algorithm.hash || opts.key.algorithm.hash.name !== checked.algRow.hash)) {
27941
28779
  throw E("jose/bad-key", "the signing key's hash does not match the algorithm " + checked.alg);
@@ -27948,7 +28786,8 @@ var require_jose = __commonJS({
27948
28786
  var payloadB64 = payload.length === 0 ? "" : b64uEncode(payload);
27949
28787
  var signingInput = Buffer.from(protectedB64 + "." + payloadB64, "ascii");
27950
28788
  var jwk = header.jwk || opts.jwk || {};
27951
- var sigBuf = Buffer.from(await webcrypto.subtle.sign(_cryptoAlg(checked.algRow, jwk, opts.key), opts.key, signingInput));
28789
+ var signKey = await wcEngine.adoptKey(opts.key, null, ["sign"], E, "jose/bad-input");
28790
+ var sigBuf = Buffer.from(await webcrypto.subtle.sign(_cryptoAlg(checked.algRow, jwk, signKey), signKey, signingInput));
27952
28791
  var want = _expectedSigBytes(checked.algRow, jwk, opts.key);
27953
28792
  if (want != null && sigBuf.length !== want) throw E("jose/bad-key", "the signing key produced a " + sigBuf.length + "-byte signature but " + checked.alg + " requires " + want + " (the key does not match the algorithm)");
27954
28793
  if (header.jwk) {
@@ -30077,6 +30916,7 @@ var require_inspect = __commonJS({
30077
30916
  }
30078
30917
  var NS = pkix.makeNS("inspect", InspectError, oid);
30079
30918
  var EXT_DECODERS = pkix.certExtensionDecoders(NS).byOid;
30919
+ var OID_UNOTICE = oid.byName("unotice");
30080
30920
  var HEX = "0123456789abcdef";
30081
30921
  function _hexColon(buf, opts) {
30082
30922
  opts = opts || {};
@@ -30187,14 +31027,14 @@ var require_inspect = __commonJS({
30187
31027
  }
30188
31028
  return _hexColon(buf, {});
30189
31029
  }
31030
+ function _gnDn(value) {
31031
+ return value && Array.isArray(value.rdns) ? _dnString(value) : value && value.dn || "";
31032
+ }
30190
31033
  function _gn(g) {
30191
31034
  if (!g || typeof g !== "object") return "";
30192
31035
  var t = g.tagNumber;
30193
31036
  if (t === 7 && Buffer.isBuffer(g.value)) return "IP Address:" + _ipString(g.value);
30194
- if (t === 4) {
30195
- var dn = g.value && Array.isArray(g.value.rdns) ? _dnString(g.value) : g.value && g.value.dn || "";
30196
- return "DirName:" + dn;
30197
- }
31037
+ if (t === 4) return "DirName:" + _gnDn(g.value);
30198
31038
  if (t === 0) return "othername:" + (Buffer.isBuffer(g.bytes) ? _hexColon(g.bytes, {}) : "<unsupported>");
30199
31039
  var kind = GN_KIND[t] || "tag" + t;
30200
31040
  var v = typeof g.value === "string" ? _clean(g.value) : Buffer.isBuffer(g.value) ? _hexColon(g.value, {}) : Buffer.isBuffer(g.bytes) ? _hexColon(g.bytes, {}) : "";
@@ -30325,6 +31165,18 @@ var require_inspect = __commonJS({
30325
31165
  label = oid.name(qid);
30326
31166
  } catch (_e) {
30327
31167
  }
31168
+ if (qid === OID_UNOTICE) {
31169
+ var texts = pkix.userNoticeTexts(q);
31170
+ if (texts.length && texts.every(function(t) {
31171
+ return t.text !== null && (t.field !== "organization" || t.noticeNumbers !== null);
31172
+ })) {
31173
+ texts.forEach(function(t) {
31174
+ var nums = t.noticeNumbers && t.noticeNumbers.length ? " #" + t.noticeNumbers.join(", ") : "";
31175
+ lines.push(inner + " " + (label || qid) + " " + t.field + ": " + _clean(t.text) + nums);
31176
+ });
31177
+ return;
31178
+ }
31179
+ }
30328
31180
  var val = q && !q.constructed && Buffer.isBuffer(q.content) && _printable(q.content) ? _clean(q.content.toString("latin1")) : _hexColon(q && Buffer.isBuffer(q.bytes) ? q.bytes : Buffer.alloc(0), {});
30329
31181
  lines.push(inner + " " + (label || qid) + ": " + val);
30330
31182
  });
@@ -30349,6 +31201,7 @@ var require_inspect = __commonJS({
30349
31201
  else if (loc.tag === 2) lv = "DNS:" + loc.value;
30350
31202
  else if (loc.tag === 1) lv = "email:" + loc.value;
30351
31203
  else if (loc.tag === 7) lv = "IP:" + _ipString(loc.value);
31204
+ else if (loc.tag === 4) lv = "DirName:" + _gnDn(loc.value);
30352
31205
  else lv = typeof loc.value === "string" ? loc.value : "[" + loc.tag + "]";
30353
31206
  return inner + (LABEL[m] || m || ad.accessMethod) + " - " + lv;
30354
31207
  }).join("\n");
@@ -30994,14 +31847,53 @@ var require_lint = __commonJS({
30994
31847
  return null;
30995
31848
  }
30996
31849
  }
30997
- function _criticalityRule(name, id, severity, citation, message) {
30998
- return {
30999
- id,
31000
- severity,
31001
- source: "rfc5280",
31002
- citation,
31003
- message,
31004
- appliesTo: function(cert, ctx) {
31850
+ var OID_UNOTICE = oid.byName("unotice");
31851
+ var _T_BMP = asn1.TAGS.BMP_STRING;
31852
+ var _T_VISIBLE = asn1.TAGS.VISIBLE_STRING;
31853
+ var _T_UTF8 = asn1.TAGS.UTF8_STRING;
31854
+ function _hasControlChar(str) {
31855
+ for (var i = 0; i < str.length; i++) {
31856
+ var c = str.charCodeAt(i);
31857
+ if (c <= 31 || c >= 127 && c <= 159) return true;
31858
+ }
31859
+ return false;
31860
+ }
31861
+ function _policyDisplayTexts(ctx) {
31862
+ var d = ctx.decode("certificatePolicies");
31863
+ if (!d || !Array.isArray(d.value)) return [];
31864
+ var out = [];
31865
+ d.value.forEach(function(pi) {
31866
+ if (!pi.qualifiersBytes || !pi.qualifiersBytes.length) return;
31867
+ var quals;
31868
+ try {
31869
+ quals = asn1.decode(pi.qualifiersBytes).children;
31870
+ } catch (_e) {
31871
+ return;
31872
+ }
31873
+ (quals || []).forEach(function(pq) {
31874
+ var qid;
31875
+ try {
31876
+ qid = asn1.read.oid(pq.children[0]);
31877
+ } catch (_e2) {
31878
+ return;
31879
+ }
31880
+ if (qid !== OID_UNOTICE) return;
31881
+ out = out.concat(pkix.userNoticeTexts(pq.children[1]));
31882
+ });
31883
+ });
31884
+ return out;
31885
+ }
31886
+ function _hasPolicyDisplayText(cert, ctx) {
31887
+ return _policyDisplayTexts(ctx).length > 0;
31888
+ }
31889
+ function _criticalityRule(name, id, severity, citation, message) {
31890
+ return {
31891
+ id,
31892
+ severity,
31893
+ source: "rfc5280",
31894
+ citation,
31895
+ message,
31896
+ appliesTo: function(cert, ctx) {
31005
31897
  return !!ctx.raw(name);
31006
31898
  },
31007
31899
  check: function(cert, ctx) {
@@ -31238,6 +32130,88 @@ var require_lint = __commonJS({
31238
32130
  check: function(cert, ctx) {
31239
32131
  return ctx.raw("subjectKeyIdentifier") ? null : true;
31240
32132
  }
32133
+ },
32134
+ // 4.2.1.4 governs the userNotice qualifier's DisplayText with one MUST NOT and three SHOULD-level
32135
+ // rules. None of them can live in the decoder: the section closes by directing certificate users to
32136
+ // "gracefully handle explicitText with more than 200 characters", so a verifier that rejected these
32137
+ // would refuse certificates that are in the wild and otherwise valid. Reporting them is exactly what
32138
+ // a linter is for, so each rule carries the severity its normative word does.
32139
+ {
32140
+ // DisplayText is SIZE (1..200) -- both ends -- but the two ends get SEPARATE ids rather than one
32141
+ // length rule, because the section treats them differently: it tells certificate users to handle a
32142
+ // notice ABOVE 200 gracefully, and says nothing of the sort about an empty one. An operator acting
32143
+ // on that advice suppresses the over-long finding; folding both into a single id would silently
32144
+ // suppress the empty case along with it, which has no such carve-out.
32145
+ id: "lint/rfc5280/explicit-text-too-long",
32146
+ severity: "warn",
32147
+ source: "rfc5280",
32148
+ citation: "RFC 5280 4.2.1.4",
32149
+ message: "a userNotice DisplayText should not exceed 200 characters",
32150
+ appliesTo: _hasPolicyDisplayText,
32151
+ check: function(cert, ctx) {
32152
+ var over = _policyDisplayTexts(ctx).filter(function(d) {
32153
+ return d.text !== null && d.chars > pkix.DISPLAY_TEXT_MAX;
32154
+ });
32155
+ return over.length ? { context: { count: over.length, longest: Math.max.apply(null, over.map(function(d) {
32156
+ return d.chars;
32157
+ })) } } : null;
32158
+ }
32159
+ },
32160
+ {
32161
+ id: "lint/rfc5280/explicit-text-empty",
32162
+ severity: "warn",
32163
+ source: "rfc5280",
32164
+ citation: "RFC 5280 4.2.1.4",
32165
+ message: "a userNotice DisplayText must not be empty (SIZE (1..200))",
32166
+ appliesTo: _hasPolicyDisplayText,
32167
+ check: function(cert, ctx) {
32168
+ var empty = _policyDisplayTexts(ctx).filter(function(d) {
32169
+ return d.text !== null && d.chars < 1;
32170
+ });
32171
+ return empty.length ? { context: { count: empty.length } } : null;
32172
+ }
32173
+ },
32174
+ {
32175
+ id: "lint/rfc5280/explicit-text-bad-encoding",
32176
+ severity: "error",
32177
+ source: "rfc5280",
32178
+ citation: "RFC 5280 4.2.1.4",
32179
+ message: "conforming CAs must not encode explicitText as VisibleString or BMPString",
32180
+ appliesTo: _hasPolicyDisplayText,
32181
+ check: function(cert, ctx) {
32182
+ var bad = _policyDisplayTexts(ctx).filter(function(d) {
32183
+ return d.field === "explicitText" && (d.tagNumber === _T_VISIBLE || d.tagNumber === _T_BMP);
32184
+ });
32185
+ return bad.length ? { context: { count: bad.length, encoding: bad[0].tagNumber === _T_BMP ? "BMPString" : "VisibleString" } } : null;
32186
+ }
32187
+ },
32188
+ {
32189
+ id: "lint/rfc5280/explicit-text-control-chars",
32190
+ severity: "warn",
32191
+ source: "rfc5280",
32192
+ citation: "RFC 5280 4.2.1.4",
32193
+ message: "an explicitText should not include control characters (U+0000 to U+001F, U+007F to U+009F)",
32194
+ appliesTo: _hasPolicyDisplayText,
32195
+ check: function(cert, ctx) {
32196
+ var bad = _policyDisplayTexts(ctx).filter(function(d) {
32197
+ return d.field === "explicitText" && d.text !== null && _hasControlChar(d.text);
32198
+ });
32199
+ return bad.length ? { context: { count: bad.length } } : null;
32200
+ }
32201
+ },
32202
+ {
32203
+ id: "lint/rfc5280/explicit-text-not-nfc",
32204
+ severity: "notice",
32205
+ source: "rfc5280",
32206
+ citation: "RFC 5280 4.2.1.4",
32207
+ message: "a UTF8String explicitText should be normalized to Unicode normalization form C (NFC)",
32208
+ appliesTo: _hasPolicyDisplayText,
32209
+ check: function(cert, ctx) {
32210
+ var bad = _policyDisplayTexts(ctx).filter(function(d) {
32211
+ return d.field === "explicitText" && d.text !== null && d.tagNumber === _T_UTF8 && d.text.normalize("NFC") !== d.text;
32212
+ });
32213
+ return bad.length ? { context: { count: bad.length } } : null;
32214
+ }
31241
32215
  }
31242
32216
  ];
31243
32217
  function _isTls(cert, ctx) {
@@ -31359,8 +32333,8 @@ var require_lint = __commonJS({
31359
32333
  }
31360
32334
  ];
31361
32335
  var ML_KEM_EK_LEN = {};
31362
- ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function(n, i) {
31363
- ML_KEM_EK_LEN[n] = [800, 1184, 1568][i];
32336
+ ["id-ml-kem-512", "id-ml-kem-768", "id-ml-kem-1024"].forEach(function(n) {
32337
+ ML_KEM_EK_LEN[n] = oid.kemParams(n).ek;
31364
32338
  });
31365
32339
  function _isMlKem(cert) {
31366
32340
  var spki = cert.subjectPublicKeyInfo;
@@ -31452,6 +32426,573 @@ var require_lint = __commonJS({
31452
32426
  }
31453
32427
  });
31454
32428
 
32429
+ // node_modules/@blamejs/pki/lib/webauthn-mds.js
32430
+ var require_webauthn_mds = __commonJS({
32431
+ "node_modules/@blamejs/pki/lib/webauthn-mds.js"(exports2, module2) {
32432
+ "use strict";
32433
+ var frameworkError = require_framework_error();
32434
+ var asn1 = require_asn1_der();
32435
+ var x509 = require_schema_x509();
32436
+ var guard = require_guard_all();
32437
+ var jose = require_jose();
32438
+ var rfc3339 = require_rfc3339();
32439
+ var constants = require_constants();
32440
+ var pathValidate = require_path_validate();
32441
+ var webcrypto = require_webcrypto();
32442
+ var nodeCrypto = require("crypto");
32443
+ var WebauthnError = frameworkError.WebauthnError;
32444
+ function _err(code, message, cause) {
32445
+ return new WebauthnError(code, message, cause);
32446
+ }
32447
+ var C = constants.LIMITS;
32448
+ var BLOB_ALGS = Object.assign(/* @__PURE__ */ Object.create(null), {
32449
+ ES256: { family: "EC", hash: "SHA-256", imp: { name: "ECDSA", namedCurve: "P-256" }, ver: { name: "ECDSA", hash: "SHA-256" } },
32450
+ ES384: { family: "EC", hash: "SHA-384", imp: { name: "ECDSA", namedCurve: "P-384" }, ver: { name: "ECDSA", hash: "SHA-384" } },
32451
+ ES512: { family: "EC", hash: "SHA-512", imp: { name: "ECDSA", namedCurve: "P-521" }, ver: { name: "ECDSA", hash: "SHA-512" } },
32452
+ RS256: { family: "RSA", hash: "SHA-256", imp: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, ver: { name: "RSASSA-PKCS1-v1_5" } },
32453
+ RS384: { family: "RSA", hash: "SHA-384", imp: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-384" }, ver: { name: "RSASSA-PKCS1-v1_5" } },
32454
+ RS512: { family: "RSA", hash: "SHA-512", imp: { name: "RSASSA-PKCS1-v1_5", hash: "SHA-512" }, ver: { name: "RSASSA-PKCS1-v1_5" } }
32455
+ });
32456
+ var DISQUALIFYING = Object.assign(/* @__PURE__ */ Object.create(null), {
32457
+ REVOKED: 1,
32458
+ ATTESTATION_KEY_COMPROMISE: 1,
32459
+ USER_KEY_REMOTE_COMPROMISE: 1,
32460
+ USER_KEY_PHYSICAL_COMPROMISE: 1,
32461
+ USER_VERIFICATION_BYPASS: 1
32462
+ });
32463
+ var CERT_SCOPED_STATUS = Object.assign(/* @__PURE__ */ Object.create(null), { ATTESTATION_KEY_COMPROMISE: 1 });
32464
+ var _BLOB_OPTS = Object.assign(/* @__PURE__ */ Object.create(null), {
32465
+ rootCertificates: 1,
32466
+ time: 1,
32467
+ previousNo: 1,
32468
+ requireRollbackCheck: 1,
32469
+ allowStale: 1,
32470
+ statusPolicy: 1,
32471
+ rejectUnknownStatus: 1
32472
+ });
32473
+ function _isPlainObject(v) {
32474
+ return !!v && typeof v === "object" && !Array.isArray(v);
32475
+ }
32476
+ var _verifiedResults = /* @__PURE__ */ new WeakSet();
32477
+ function isVerifiedResult(v) {
32478
+ return _isPlainObject(v) && _verifiedResults.has(v);
32479
+ }
32480
+ function _deepFreeze(v, depth) {
32481
+ if (!v || typeof v !== "object" || Object.isFrozen(v) || ArrayBuffer.isView(v)) return v;
32482
+ if (depth > C.JSON_MAX_DEPTH) return v;
32483
+ Object.freeze(v);
32484
+ Object.keys(v).forEach(function(k) {
32485
+ _deepFreeze(v[k], depth + 1);
32486
+ });
32487
+ return v;
32488
+ }
32489
+ var AAGUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
32490
+ var ZERO_AAGUID = "00000000-0000-0000-0000-000000000000";
32491
+ var UNDERSTOOD_HEADER = Object.assign(/* @__PURE__ */ Object.create(null), {
32492
+ alg: 1,
32493
+ typ: 1,
32494
+ cty: 1,
32495
+ crit: 1,
32496
+ jku: 1,
32497
+ jwk: 1,
32498
+ kid: 1,
32499
+ x5u: 1,
32500
+ x5c: 1,
32501
+ x5t: 1,
32502
+ "x5t#S256": 1
32503
+ });
32504
+ function _assertLeafSigns(leaf) {
32505
+ var exts = leaf.extensions || [];
32506
+ for (var i = 0; i < exts.length; i++) {
32507
+ if (exts[i].name !== "keyUsage" || exts[i].value == null) continue;
32508
+ var ku;
32509
+ try {
32510
+ ku = asn1.read.bitString(asn1.decode(exts[i].value));
32511
+ } catch (e) {
32512
+ throw _err("webauthn/bad-att-cert", "the metadata BLOB x5c leaf keyUsage extension is malformed", e);
32513
+ }
32514
+ if (!ku.bytes.length || (ku.bytes[0] & 128) === 0) {
32515
+ throw _err("webauthn/bad-att-cert", "the metadata BLOB x5c leaf keyUsage does not assert digitalSignature, so it may not sign the BLOB (RFC 5280 sec. 4.2.1.3)");
32516
+ }
32517
+ return;
32518
+ }
32519
+ }
32520
+ function _isAnchorItself(cert, anchor) {
32521
+ return guard.name.dnEqual(cert.subject, anchor.subject) && cert.subjectPublicKeyInfo.bytes.equals(anchor.subjectPublicKeyInfo.bytes);
32522
+ }
32523
+ function _asCert(v, label) {
32524
+ if (v && typeof v === "object" && !Buffer.isBuffer(v) && !(v instanceof Uint8Array) && v.subject && v.subjectPublicKeyInfo && Buffer.isBuffer(v.subjectPublicKeyInfo.bytes) && v.signatureAlgorithm && typeof v.signatureAlgorithm.oid === "string" && // `validity` is what separates a certificate from the other signed structures that carry a
32525
+ // subject, a public key and a signature algorithm: a parsed certification request has all
32526
+ // three and would otherwise be installed as a trust anchor.
32527
+ v.validity && v.validity.notBefore !== void 0) {
32528
+ return v;
32529
+ }
32530
+ try {
32531
+ return x509.parse(v);
32532
+ } catch (e) {
32533
+ throw _err("webauthn/bad-input", label + " is not a decodable certificate", e);
32534
+ }
32535
+ }
32536
+ function verifyMetadataBlob(blob, opts) {
32537
+ return Promise.resolve().then(function() {
32538
+ return _verifyMetadataBlob(blob, opts);
32539
+ });
32540
+ }
32541
+ function _verifyMetadataBlob(blob, opts) {
32542
+ opts = opts || {};
32543
+ if (!_isPlainObject(opts)) throw _err("webauthn/bad-input", "opts must be an object");
32544
+ guard.identifier.assertKnownKeys(opts, _BLOB_OPTS, _err, "webauthn/bad-input", "opts has an unknown key ");
32545
+ var roots = opts.rootCertificates;
32546
+ if (!Array.isArray(roots) || roots.length === 0) {
32547
+ throw _err("webauthn/metadata-no-root", "verifying a metadata BLOB requires opts.rootCertificates -- the FIDO root(s) to anchor it to; this library bundles none");
32548
+ }
32549
+ if (opts.time !== void 0) guard.time.assertValid(opts.time, _err, "webauthn/bad-input", "opts.time");
32550
+ var at = opts.time === void 0 ? /* @__PURE__ */ new Date() : opts.time;
32551
+ if (opts.previousNo !== void 0 && (!Number.isSafeInteger(opts.previousNo) || opts.previousNo < 0)) {
32552
+ throw _err("webauthn/bad-input", "opts.previousNo must be a non-negative safe integer");
32553
+ }
32554
+ ["requireRollbackCheck", "allowStale", "rejectUnknownStatus"].forEach(function(k) {
32555
+ if (opts[k] !== void 0 && typeof opts[k] !== "boolean") {
32556
+ throw _err("webauthn/bad-input", "opts." + k + " must be a boolean");
32557
+ }
32558
+ });
32559
+ if (opts.statusPolicy !== void 0 && typeof opts.statusPolicy !== "function" && opts.statusPolicy !== "any" && opts.statusPolicy !== "latest-by-date") {
32560
+ throw _err("webauthn/bad-input", 'opts.statusPolicy must be "any", "latest-by-date", or a function');
32561
+ }
32562
+ if (opts.requireRollbackCheck === true && opts.previousNo === void 0) {
32563
+ throw _err("webauthn/metadata-no-baseline", "opts.requireRollbackCheck was set without opts.previousNo, so there is no baseline to compare against");
32564
+ }
32565
+ var anchors = roots.map(function(r, i) {
32566
+ return _asCert(r, "opts.rootCertificates[" + i + "]");
32567
+ });
32568
+ var raw = Buffer.isBuffer(blob) || blob instanceof Uint8Array ? guard.bytes.view(blob, WebauthnError, "webauthn/bad-input", "the metadata BLOB") : null;
32569
+ var declaredLength = raw ? raw.length : typeof blob === "string" ? Buffer.byteLength(blob, "utf8") : null;
32570
+ if (declaredLength !== null && declaredLength > C.MDS_BLOB_MAX_BYTES) {
32571
+ throw _err("webauthn/too-large", "the metadata BLOB is " + declaredLength + " bytes, above the " + C.MDS_BLOB_MAX_BYTES + "-byte ceiling");
32572
+ }
32573
+ if (!raw && typeof blob !== "string") {
32574
+ throw _err("webauthn/bad-input", "the metadata BLOB must be bytes or a string");
32575
+ }
32576
+ var bytes = raw || Buffer.from(blob, "utf8");
32577
+ if (bytes.length > C.MDS_BLOB_MAX_BYTES) {
32578
+ throw _err("webauthn/too-large", "the metadata BLOB is " + bytes.length + " bytes, above the " + C.MDS_BLOB_MAX_BYTES + "-byte ceiling");
32579
+ }
32580
+ var segs = bytes.toString("utf8").split(".");
32581
+ if (segs.length !== 3) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB is not a three-part JWS compact serialization (RFC 7515 sec. 3.1)");
32582
+ if (segs[0].length > Math.ceil(C.MDS_BLOB_HEADER_MAX_BYTES / 3) * 4) {
32583
+ throw _err("webauthn/too-large", "the metadata BLOB protected header is above the " + C.MDS_BLOB_HEADER_MAX_BYTES + "-byte ceiling");
32584
+ }
32585
+ if (segs[2].length > Math.ceil(C.MDS_BLOB_SIG_MAX_BYTES / 3) * 4) {
32586
+ throw _err("webauthn/too-large", "the metadata BLOB signature is above the " + C.MDS_BLOB_SIG_MAX_BYTES + "-byte ceiling");
32587
+ }
32588
+ var header, sig;
32589
+ try {
32590
+ header = guard.json.parse(Buffer.from(jose.base64url.decode(segs[0])), _err, {
32591
+ // The header is read BEFORE anything is authenticated, so its ceiling is the header's own,
32592
+ // not the whole BLOB's: a JWS protected header is a few hundred bytes, and giving this reader
32593
+ // the 32 MiB envelope cap would let unauthenticated bytes buy an unbounded multiple of that
32594
+ // in heap ahead of the signature check. The payload's reader keeps the envelope cap, which is
32595
+ // sound because nothing reaches it until the signature and chain hold.
32596
+ maxBytes: C.MDS_BLOB_HEADER_MAX_BYTES,
32597
+ maxDepth: C.JSON_MAX_DEPTH,
32598
+ tooLarge: "webauthn/too-large",
32599
+ badJson: "webauthn/bad-metadata-blob",
32600
+ // Every code the guard can raise is named. An omitted one falls back to the framework default
32601
+ // and the module's own defences -- duplicate-member smuggling, the depth cap -- surface under
32602
+ // a generic code no webauthn/* consumer can switch on.
32603
+ tooDeep: "webauthn/bad-metadata-blob",
32604
+ duplicateMember: "webauthn/bad-metadata-blob",
32605
+ badInput: "webauthn/bad-metadata-blob",
32606
+ label: "the metadata BLOB header"
32607
+ });
32608
+ sig = Buffer.from(jose.base64url.decode(segs[2]));
32609
+ } catch (e) {
32610
+ if (e instanceof WebauthnError) throw e;
32611
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header or signature is not decodable", e);
32612
+ }
32613
+ if (!_isPlainObject(header)) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header must be a JSON object");
32614
+ if (header.x5u !== void 0) {
32615
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header carries x5u, which names a chain to fetch; supply a BLOB with an inline x5c instead");
32616
+ }
32617
+ if (Object.prototype.hasOwnProperty.call(header, "crit")) {
32618
+ var crit = header.crit;
32619
+ if (!Array.isArray(crit) || crit.length === 0) {
32620
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header crit must be a non-empty array (RFC 7515 sec. 4.1.11)");
32621
+ }
32622
+ var critSeen = /* @__PURE__ */ Object.create(null);
32623
+ for (var ci = 0; ci < crit.length; ci++) {
32624
+ var critName = crit[ci];
32625
+ if (typeof critName !== "string") throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header crit entries must be strings");
32626
+ if (critSeen[critName]) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header crit repeats " + JSON.stringify(critName));
32627
+ critSeen[critName] = 1;
32628
+ if (UNDERSTOOD_HEADER[critName]) {
32629
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header crit must not name the standard header parameter " + JSON.stringify(critName) + " (RFC 7515 sec. 4.1.11)");
32630
+ }
32631
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header names critical header parameter " + JSON.stringify(critName) + ", which this reader does not process");
32632
+ }
32633
+ }
32634
+ var algRow = typeof header.alg === "string" ? BLOB_ALGS[header.alg] : void 0;
32635
+ if (!algRow) throw _err("webauthn/unsupported-algorithm", "the metadata BLOB alg " + JSON.stringify(header.alg) + " is not a supported JWS signature algorithm");
32636
+ if (!Array.isArray(header.x5c) || header.x5c.length === 0) {
32637
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB header carries no x5c certificate chain (RFC 7515 sec. 4.1.6)");
32638
+ }
32639
+ if (header.x5c.length > C.WEBAUTHN_X5C_MAX_CERTS) {
32640
+ throw _err("webauthn/too-large", "the metadata BLOB x5c carries " + header.x5c.length + " certificates, above the " + C.WEBAUTHN_X5C_MAX_CERTS + " this library will parse");
32641
+ }
32642
+ var chain = header.x5c.map(function(entry, i) {
32643
+ if (typeof entry !== "string") throw _err("webauthn/bad-metadata-blob", "the metadata BLOB x5c entry " + i + " is not a string");
32644
+ var der;
32645
+ try {
32646
+ der = guard.encoding.base64(entry, C.MDS_BLOB_MAX_BYTES, _err, "webauthn/bad-metadata-blob", "a metadata BLOB x5c entry");
32647
+ } catch (e) {
32648
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB x5c entry " + i + " is not canonical base64", e);
32649
+ }
32650
+ try {
32651
+ return x509.parse(der);
32652
+ } catch (e) {
32653
+ throw _err("webauthn/bad-att-cert", "the metadata BLOB x5c entry " + i + " is not a decodable certificate", e);
32654
+ }
32655
+ });
32656
+ var leaf = chain[0];
32657
+ _assertLeafSigns(leaf);
32658
+ var leafAlg = (leaf.subjectPublicKeyInfo.algorithm || {}).name;
32659
+ var leafFamily = leafAlg === "ecPublicKey" ? "EC" : leafAlg === "rsaEncryption" ? "RSA" : null;
32660
+ if (leafFamily !== algRow.family) {
32661
+ throw _err("webauthn/unsupported-algorithm", "the metadata BLOB alg " + header.alg + " does not match the x5c leaf key type " + JSON.stringify(leafAlg));
32662
+ }
32663
+ var signingInput = Buffer.from(segs[0] + "." + segs[1], "ascii");
32664
+ return webcrypto.webcrypto.subtle.importKey("spki", leaf.subjectPublicKeyInfo.bytes, algRow.imp, false, ["verify"]).then(
32665
+ function(key) {
32666
+ return webcrypto.webcrypto.subtle.verify(algRow.ver, key, sig, signingInput);
32667
+ },
32668
+ function(e) {
32669
+ throw _err("webauthn/unsupported-algorithm", "the metadata BLOB x5c leaf key could not be imported for " + header.alg, e);
32670
+ }
32671
+ ).then(function(ok) {
32672
+ if (!ok) throw _err("webauthn/verify-failed", "the metadata BLOB signature does not verify under its x5c leaf key");
32673
+ return _chainToAnchor(chain, anchors, at);
32674
+ }).then(function() {
32675
+ return _parsePayload(segs[1], at, opts);
32676
+ });
32677
+ }
32678
+ function _chainToAnchor(chain, anchors, at, what) {
32679
+ var subject = what || "metadata BLOB certificate chain";
32680
+ var ordered = chain.slice().reverse();
32681
+ var lastFault = null;
32682
+ return anchors.reduce(function(p, anchor) {
32683
+ return p.then(function(done) {
32684
+ if (done) return true;
32685
+ var path = ordered.slice();
32686
+ var strippedAnchor = false;
32687
+ if (path.length && _isAnchorItself(path[0], anchor)) {
32688
+ path = path.slice(1);
32689
+ strippedAnchor = true;
32690
+ }
32691
+ if (path.length === 0) return strippedAnchor;
32692
+ return pathValidate.validate(path, {
32693
+ time: at,
32694
+ // The anchor tuple names the anchor's own KEY -- its SubjectPublicKeyInfo algorithm and that
32695
+ // algorithm's parameters -- not the algorithm its issuer used to sign it. The validator
32696
+ // carries these forward as the working public key, and a certificate below the anchor may
32697
+ // inherit its key parameters from them (the DSA-style parameter-inheritance case), so
32698
+ // supplying the signature OID leaves such a key unreconstructable and refuses a valid chain.
32699
+ trustAnchor: {
32700
+ name: anchor.subject,
32701
+ publicKey: anchor.subjectPublicKeyInfo.bytes,
32702
+ algorithm: anchor.subjectPublicKeyInfo.algorithm.oid,
32703
+ parameters: anchor.subjectPublicKeyInfo.algorithm.parameters
32704
+ }
32705
+ }).then(function(r) {
32706
+ return !!(r && r.valid);
32707
+ }, function(e) {
32708
+ lastFault = e;
32709
+ return false;
32710
+ });
32711
+ });
32712
+ }, Promise.resolve(false)).then(function(trusted) {
32713
+ if (!trusted) {
32714
+ throw _err("webauthn/metadata-untrusted", "the " + subject + " does not validate to any of the roots it must reach", lastFault);
32715
+ }
32716
+ });
32717
+ }
32718
+ function _staleAfter(nextUpdate) {
32719
+ var d = rfc3339.parseDate(
32720
+ nextUpdate,
32721
+ function(c, m) {
32722
+ return _err("webauthn/bad-metadata-blob", m);
32723
+ },
32724
+ "webauthn/bad-metadata-blob",
32725
+ "the metadata BLOB nextUpdate"
32726
+ );
32727
+ return d.getTime() + constants.TIME.days(1);
32728
+ }
32729
+ function assertFresh(metadata, at, label) {
32730
+ if (!metadata || metadata.allowStale === true || typeof metadata.nextUpdate !== "string") return;
32731
+ var atMs = at instanceof Date ? at.getTime() : NaN;
32732
+ var limit = _staleAfter(metadata.nextUpdate);
32733
+ if (!isFinite(atMs) || !isFinite(limit)) return;
32734
+ if (atMs >= limit) {
32735
+ throw _err("webauthn/metadata-stale", (label || "the metadata") + " expired after " + metadata.nextUpdate + "; re-verify a current BLOB, or pass opts.allowStale when verifying it");
32736
+ }
32737
+ }
32738
+ function _parsePayload(seg, at, opts) {
32739
+ var payload;
32740
+ try {
32741
+ payload = guard.json.parse(Buffer.from(jose.base64url.decode(seg)), _err, {
32742
+ maxBytes: C.MDS_BLOB_MAX_BYTES,
32743
+ maxDepth: C.JSON_MAX_DEPTH,
32744
+ tooLarge: "webauthn/too-large",
32745
+ badJson: "webauthn/bad-metadata-blob",
32746
+ tooDeep: "webauthn/bad-metadata-blob",
32747
+ duplicateMember: "webauthn/bad-metadata-blob",
32748
+ badInput: "webauthn/bad-metadata-blob",
32749
+ label: "the metadata BLOB payload"
32750
+ });
32751
+ } catch (e) {
32752
+ if (e instanceof WebauthnError) throw e;
32753
+ throw _err("webauthn/bad-metadata-blob", "the metadata BLOB payload is not decodable JSON", e);
32754
+ }
32755
+ if (!_isPlainObject(payload)) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB payload must be a JSON object");
32756
+ if (typeof payload.legalHeader !== "string") throw _err("webauthn/bad-metadata-blob", "the metadata BLOB payload must carry a string legalHeader");
32757
+ if (!Number.isSafeInteger(payload.no) || payload.no < 0) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB payload must carry a non-negative integer no");
32758
+ if (opts.previousNo !== void 0 && payload.no <= opts.previousNo) {
32759
+ throw _err("webauthn/metadata-rollback", "the metadata BLOB no " + payload.no + " does not exceed the previously held " + opts.previousNo);
32760
+ }
32761
+ var staleAfter = _staleAfter(payload.nextUpdate);
32762
+ var atMs = at.getTime();
32763
+ if (!isFinite(atMs) || !isFinite(staleAfter)) {
32764
+ throw _err("webauthn/bad-input", "the metadata freshness comparison has no usable instant");
32765
+ }
32766
+ var stale = atMs >= staleAfter;
32767
+ if (stale && opts.allowStale !== true) {
32768
+ throw _err("webauthn/metadata-stale", "the metadata BLOB expired after " + payload.nextUpdate + "; pass opts.allowStale to accept it anyway");
32769
+ }
32770
+ if (!Array.isArray(payload.entries)) throw _err("webauthn/bad-metadata-blob", "the metadata BLOB payload must carry an entries array");
32771
+ if (payload.entries.length > C.MDS_MAX_ENTRIES) {
32772
+ throw _err("webauthn/too-large", "the metadata BLOB declares " + payload.entries.length + " entries, above the " + C.MDS_MAX_ENTRIES + " ceiling");
32773
+ }
32774
+ var byAaguid = /* @__PURE__ */ Object.create(null);
32775
+ var byKeyIdentifier = /* @__PURE__ */ Object.create(null);
32776
+ var entries = payload.entries.map(function(e, i) {
32777
+ if (!_isPlainObject(e)) throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " is not an object");
32778
+ if (!Array.isArray(e.statusReports) || e.statusReports.length === 0) {
32779
+ throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " must carry a non-empty statusReports array");
32780
+ }
32781
+ if (e.statusReports.length > C.MDS_MAX_STATUS_REPORTS_PER_ENTRY) {
32782
+ throw _err("webauthn/too-large", "metadata entry " + i + " declares " + e.statusReports.length + " status reports, above the " + C.MDS_MAX_STATUS_REPORTS_PER_ENTRY + " ceiling");
32783
+ }
32784
+ e.statusReports.forEach(function(r, ri) {
32785
+ if (!_isPlainObject(r)) throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " status report " + ri + " is not an object");
32786
+ if (typeof r.status !== "string" || !r.status) {
32787
+ throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " status report " + ri + " has no status (MDS v3.0 sec. 3.1.3 requires one)");
32788
+ }
32789
+ });
32790
+ var aaguid = null;
32791
+ if (e.aaguid !== void 0) {
32792
+ if (typeof e.aaguid !== "string" || !AAGUID_RE.test(e.aaguid.toLowerCase())) {
32793
+ throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " has a malformed aaguid");
32794
+ }
32795
+ aaguid = e.aaguid.toLowerCase();
32796
+ }
32797
+ var st = e.metadataStatement;
32798
+ var keyIds = [];
32799
+ var seenKeyId = /* @__PURE__ */ Object.create(null);
32800
+ [[e.attestationCertificateKeyIdentifiers, "entry"], [st && st.attestationCertificateKeyIdentifiers, "metadataStatement"]].forEach(function(pair) {
32801
+ var list = pair[0];
32802
+ if (list === void 0) return;
32803
+ if (!Array.isArray(list)) {
32804
+ throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " " + pair[1] + " attestationCertificateKeyIdentifiers is not an array");
32805
+ }
32806
+ if (list.length > C.MDS_MAX_KEY_IDS_PER_ENTRY) {
32807
+ throw _err("webauthn/too-large", "metadata entry " + i + " declares " + list.length + " attestation certificate key identifiers, above the " + C.MDS_MAX_KEY_IDS_PER_ENTRY + " ceiling");
32808
+ }
32809
+ list.forEach(function(k) {
32810
+ if (typeof k !== "string" || !/^[0-9a-fA-F]{40}$/.test(k)) {
32811
+ throw _err("webauthn/bad-metadata-blob", "metadata entry " + i + " has a malformed attestation certificate key identifier");
32812
+ }
32813
+ var lower = k.toLowerCase();
32814
+ if (!seenKeyId[lower]) {
32815
+ seenKeyId[lower] = 1;
32816
+ keyIds.push(lower);
32817
+ }
32818
+ });
32819
+ });
32820
+ var out = {
32821
+ index: i,
32822
+ aaguid,
32823
+ keyIdentifiers: keyIds,
32824
+ statusReports: e.statusReports,
32825
+ metadataStatement: st || null,
32826
+ timeOfLastStatusChange: e.timeOfLastStatusChange || null
32827
+ };
32828
+ if (aaguid) {
32829
+ if (byAaguid[aaguid]) throw _err("webauthn/duplicate-metadata-entry", "two metadata entries claim aaguid " + aaguid);
32830
+ byAaguid[aaguid] = out;
32831
+ }
32832
+ keyIds.forEach(function(k) {
32833
+ if (byKeyIdentifier[k]) throw _err("webauthn/duplicate-metadata-entry", "two metadata entries claim attestation certificate key identifier " + k);
32834
+ byKeyIdentifier[k] = out;
32835
+ });
32836
+ return out;
32837
+ });
32838
+ var result = {
32839
+ no: payload.no,
32840
+ legalHeader: payload.legalHeader,
32841
+ nextUpdate: payload.nextUpdate,
32842
+ stale,
32843
+ allowStale: opts.allowStale === true,
32844
+ entries,
32845
+ byAaguid,
32846
+ byKeyIdentifier,
32847
+ statusPolicy: opts.statusPolicy || "any",
32848
+ rejectUnknownStatus: opts.rejectUnknownStatus === true
32849
+ };
32850
+ _deepFreeze(result, 0);
32851
+ _verifiedResults.add(result);
32852
+ return result;
32853
+ }
32854
+ function metadataFor(metadata, identifier) {
32855
+ if (!isVerifiedResult(metadata)) throw _err("webauthn/bad-input", "metadataFor expects a verifyMetadataBlob result -- an object that merely resembles one, such as a catalogue restored from a cache, has not been through the signature and chain checks");
32856
+ if (typeof identifier !== "string") return null;
32857
+ var key = identifier.toLowerCase();
32858
+ if (AAGUID_RE.test(key)) {
32859
+ if (key === ZERO_AAGUID) return null;
32860
+ return metadata.byAaguid[key] || null;
32861
+ }
32862
+ if (/^[0-9a-f]{40}$/.test(key)) return metadataForKeyIdentifier(metadata, key);
32863
+ return null;
32864
+ }
32865
+ function metadataAnchors(entry) {
32866
+ if (!entry || typeof entry !== "object") throw _err("webauthn/bad-input", "metadataAnchors expects a metadata entry");
32867
+ var st = entry.metadataStatement;
32868
+ var list = st && Array.isArray(st.attestationRootCertificates) ? st.attestationRootCertificates : [];
32869
+ if (list.length > C.MDS_MAX_ANCHORS_PER_ENTRY) {
32870
+ throw _err("webauthn/too-large", "metadata entry " + entry.index + " declares " + list.length + " attestation roots, above the " + C.MDS_MAX_ANCHORS_PER_ENTRY + " ceiling");
32871
+ }
32872
+ return list.map(function(b64, i) {
32873
+ var der;
32874
+ try {
32875
+ der = guard.encoding.base64(b64, C.MDS_BLOB_MAX_BYTES, _err, "webauthn/bad-metadata-entry", "an attestation root certificate");
32876
+ } catch (e) {
32877
+ throw _err("webauthn/bad-metadata-entry", "metadata entry " + entry.index + " attestation root " + i + " is not canonical base64", e);
32878
+ }
32879
+ try {
32880
+ return x509.parse(der);
32881
+ } catch (e) {
32882
+ throw _err("webauthn/bad-metadata-entry", "metadata entry " + entry.index + " attestation root " + i + " is not a decodable certificate", e);
32883
+ }
32884
+ });
32885
+ }
32886
+ function _reportNamesOtherCert(report, leaf) {
32887
+ if (typeof report.certificate !== "string" || !report.certificate) return false;
32888
+ if (!leaf) return false;
32889
+ var named;
32890
+ try {
32891
+ named = x509.parse(guard.encoding.base64(report.certificate, C.MDS_BLOB_MAX_BYTES, _err, "webauthn/bad-metadata-entry", "a status report certificate"));
32892
+ } catch (_e) {
32893
+ return false;
32894
+ }
32895
+ try {
32896
+ return certKeyIdentifier(named) !== certKeyIdentifier(leaf);
32897
+ } catch (_e) {
32898
+ return false;
32899
+ }
32900
+ }
32901
+ function _reportInForceAt(report, atMs) {
32902
+ var d = rfc3339.parseDate(
32903
+ report.effectiveDate,
32904
+ function(c, m) {
32905
+ return _err("webauthn/bad-metadata-blob", m);
32906
+ },
32907
+ "webauthn/bad-metadata-blob",
32908
+ "a status report effectiveDate"
32909
+ );
32910
+ return d.getTime() <= atMs;
32911
+ }
32912
+ function statusDenied(entry, metadata, leaf, at) {
32913
+ var policy = metadata && metadata.statusPolicy || "any";
32914
+ var reports = entry.statusReports || [];
32915
+ if (typeof policy === "function") return policy(reports) === true;
32916
+ reports = reports.filter(function(r) {
32917
+ return !(r && typeof r.status === "string" && CERT_SCOPED_STATUS[r.status] && _reportNamesOtherCert(r, leaf));
32918
+ });
32919
+ var isDated = function(r) {
32920
+ return r && typeof r.effectiveDate === "string" && rfc3339.isValidDate(r.effectiveDate);
32921
+ };
32922
+ var atMs = at instanceof Date && isFinite(at.getTime()) ? at.getTime() : null;
32923
+ if (atMs !== null) {
32924
+ reports = reports.filter(function(r) {
32925
+ return !isDated(r) || _reportInForceAt(r, atMs);
32926
+ });
32927
+ }
32928
+ var considered = reports;
32929
+ if (policy === "latest-by-date") {
32930
+ var dated = reports.filter(isDated);
32931
+ if (dated.length) {
32932
+ var newest = dated.reduce(function(a, b) {
32933
+ return a.effectiveDate >= b.effectiveDate ? a : b;
32934
+ }).effectiveDate;
32935
+ considered = dated.filter(function(r) {
32936
+ return r.effectiveDate === newest;
32937
+ }).concat(reports.filter(function(r) {
32938
+ return !isDated(r);
32939
+ }));
32940
+ }
32941
+ }
32942
+ var rejectUnknown = !!(metadata && metadata.rejectUnknownStatus);
32943
+ return considered.some(function(r) {
32944
+ var s = r && typeof r.status === "string" ? r.status : null;
32945
+ if (s === null) return false;
32946
+ if (DISQUALIFYING[s]) return true;
32947
+ return rejectUnknown && !_KNOWN_STATUS[s];
32948
+ });
32949
+ }
32950
+ var _KNOWN_STATUS = Object.assign(/* @__PURE__ */ Object.create(null), {
32951
+ NOT_FIDO_CERTIFIED: 1,
32952
+ SELF_ASSERTION_SUBMITTED: 1,
32953
+ FIDO_CERTIFIED: 1,
32954
+ FIDO_CERTIFIED_L1: 1,
32955
+ FIDO_CERTIFIED_L1plus: 1,
32956
+ FIDO_CERTIFIED_L2: 1,
32957
+ FIDO_CERTIFIED_L2plus: 1,
32958
+ FIDO_CERTIFIED_L3: 1,
32959
+ FIDO_CERTIFIED_L3plus: 1,
32960
+ UPDATE_AVAILABLE: 1
32961
+ });
32962
+ function aaguidToString(buf) {
32963
+ if (!Buffer.isBuffer(buf) || buf.length !== 16) return null;
32964
+ var h = buf.toString("hex");
32965
+ return h.slice(0, 8) + "-" + h.slice(8, 12) + "-" + h.slice(12, 16) + "-" + h.slice(16, 20) + "-" + h.slice(20);
32966
+ }
32967
+ function certKeyIdentifier(cert) {
32968
+ var pk = cert && cert.subjectPublicKeyInfo && cert.subjectPublicKeyInfo.publicKey;
32969
+ if (!pk || !Buffer.isBuffer(pk.bytes)) {
32970
+ throw _err("webauthn/bad-input", "certKeyIdentifier expects a parsed certificate carrying a subject public key");
32971
+ }
32972
+ return nodeCrypto.createHash("sha1").update(pk.bytes).digest("hex");
32973
+ }
32974
+ function metadataForKeyIdentifier(metadata, keyId) {
32975
+ if (!isVerifiedResult(metadata)) throw _err("webauthn/bad-input", "metadataForKeyIdentifier expects a verifyMetadataBlob result -- an object that merely resembles one has not been through the signature and chain checks");
32976
+ if (typeof keyId !== "string") return null;
32977
+ return metadata.byKeyIdentifier[keyId.toLowerCase()] || null;
32978
+ }
32979
+ module2.exports = {
32980
+ verifyMetadataBlob,
32981
+ metadataFor,
32982
+ metadataForKeyIdentifier,
32983
+ metadataAnchors,
32984
+ chainToAnchor: _chainToAnchor,
32985
+ assertFresh,
32986
+ isVerifiedResult,
32987
+ statusDenied,
32988
+ aaguidToString,
32989
+ ZERO_AAGUID,
32990
+ certKeyIdentifier,
32991
+ DISQUALIFYING
32992
+ };
32993
+ }
32994
+ });
32995
+
31455
32996
  // node_modules/@blamejs/pki/lib/webauthn.js
31456
32997
  var require_webauthn = __commonJS({
31457
32998
  "node_modules/@blamejs/pki/lib/webauthn.js"(exports2, module2) {
@@ -31466,6 +33007,10 @@ var require_webauthn = __commonJS({
31466
33007
  var constants = require_constants();
31467
33008
  var validator = require_validator_all();
31468
33009
  var edwardsPoint = require_edwards_point();
33010
+ var guard = require_guard_all();
33011
+ var jose = require_jose();
33012
+ var pathValidate = require_path_validate();
33013
+ var mds = require_webauthn_mds();
31469
33014
  var nodeCrypto = require("crypto");
31470
33015
  var WebauthnError = frameworkError.WebauthnError;
31471
33016
  function _err(code, message, cause) {
@@ -31696,7 +33241,11 @@ var require_webauthn = __commonJS({
31696
33241
  var fmtN = cbor.read.mapGet(root, "fmt"), attStmtN = cbor.read.mapGet(root, "attStmt"), authDataN = cbor.read.mapGet(root, "authData");
31697
33242
  if (root.children.length !== 3 || !fmtN || !attStmtN || !authDataN) throw _err("webauthn/bad-attestation-object", "the attestation object must be exactly { fmt, attStmt, authData }");
31698
33243
  if (fmtN.majorType !== 3) throw _err("webauthn/bad-attestation-object", "attestation object 'fmt' must be a text string");
31699
- if (attStmtN.majorType !== 5) throw _err("webauthn/bad-attestation-object", "attestation object 'attStmt' must be a CBOR map");
33244
+ var wantMajor = ATT_STMT_MAJOR[cbor.read.textString(fmtN)];
33245
+ if (wantMajor === void 0) wantMajor = 5;
33246
+ if (attStmtN.majorType !== wantMajor) {
33247
+ throw _err("webauthn/bad-attestation-object", "attestation object 'attStmt' must be a CBOR " + (wantMajor === 4 ? "array" : "map") + " for format " + JSON.stringify(cbor.read.textString(fmtN)));
33248
+ }
31700
33249
  if (authDataN.majorType !== 2) throw _err("webauthn/bad-attestation-object", "attestation object 'authData' must be a byte string");
31701
33250
  var authDataBytes = cbor.read.byteString(authDataN);
31702
33251
  return {
@@ -31738,9 +33287,28 @@ var require_webauthn = __commonJS({
31738
33287
  if (!have[k]) throw _err("webauthn/bad-att-stmt", "the attestation statement is missing the '" + k + "' field");
31739
33288
  });
31740
33289
  }
33290
+ var ATT_STMT_MAJOR = { compound: 4 };
33291
+ var _AAGUID_SIGNED_BY_FMT = Object.assign(/* @__PURE__ */ Object.create(null), { "fido-u2f": false });
33292
+ function _aaguidIsSigned(fmt) {
33293
+ return _AAGUID_SIGNED_BY_FMT[fmt] !== false;
33294
+ }
33295
+ var _VERIFY_OPTS = Object.assign(/* @__PURE__ */ Object.create(null), {
33296
+ time: 1,
33297
+ metadata: 1,
33298
+ tpmPolicy: 1,
33299
+ safetyNetRoots: 1,
33300
+ verifySafetyNetJws: 1,
33301
+ requireCtsProfileMatch: 1
33302
+ });
33303
+ function _requireX5cCount(n) {
33304
+ if (n > constants.LIMITS.WEBAUTHN_X5C_MAX_CERTS) {
33305
+ throw _err("webauthn/bad-att-stmt", "an attestation certificate chain carries " + n + " certificates, above the " + constants.LIMITS.WEBAUTHN_X5C_MAX_CERTS + " this toolkit will parse");
33306
+ }
33307
+ }
31741
33308
  function _readX5c(attStmt) {
31742
33309
  var x5cN = cbor.read.mapGet(attStmt, "x5c");
31743
33310
  if (!x5cN || x5cN.majorType !== 4 || !x5cN.children || !x5cN.children.length) throw _err("webauthn/bad-att-stmt", "x5c must be a non-empty array of certificates");
33311
+ _requireX5cCount(x5cN.children.length);
31744
33312
  return x5cN.children.map(function(c) {
31745
33313
  var der;
31746
33314
  try {
@@ -31841,7 +33409,8 @@ var require_webauthn = __commonJS({
31841
33409
  },
31842
33410
  // tpm (WebAuthn 8.3): decode certInfo/pubArea, enforce magic/type/extraData/Name,
31843
33411
  // bind pubArea to the credential key, and verify sig over certInfo with the AIK.
31844
- tpm: function(att, clientDataHash) {
33412
+ tpm: function(att, clientDataHash, opts) {
33413
+ var tpmPolicy = validator.tpm.normalizeObjectAttributePolicy((opts || {}).tpmPolicy, WebauthnError, "webauthn/bad-input");
31845
33414
  _requireAttShape(att.attStmt, ["ver", "alg", "sig", "certInfo", "pubArea", "x5c"], ["ver", "alg", "sig", "certInfo", "pubArea", "x5c"]);
31846
33415
  var verN = cbor.read.mapGet(att.attStmt, "ver");
31847
33416
  if (!verN || verN.majorType !== 3 || cbor.read.textString(verN) !== "2.0") throw _err("webauthn/bad-att-stmt", `tpm attestation 'ver' MUST be "2.0" (WebAuthn 8.3)`);
@@ -31862,7 +33431,150 @@ var require_webauthn = __commonJS({
31862
33431
  if (!ok) throw _err("webauthn/verify-failed", "the tpm attestation signature does not verify over certInfo under the AIK");
31863
33432
  _checkAikCert(aik);
31864
33433
  _checkAaguidExt(aik, att.authData.aaguid);
31865
- return _result("tpm", "AttCA", chain, att);
33434
+ validator.tpm.assertObjectAttributePolicy(pub, tpmPolicy, WebauthnError, "webauthn/tpm-policy", "webauthn/bad-tpm");
33435
+ var tpmRes = _result("tpm", "AttCA", chain, att);
33436
+ tpmRes.tpm = { objectAttributes: pub.objectAttributes, attributes: pub.attributes, authPolicy: pub.authPolicy };
33437
+ return tpmRes;
33438
+ });
33439
+ },
33440
+ // android-safetynet (WebAuthn 8.5): the attStmt carries a SafetyNet JWS ("response") whose payload
33441
+ // binds a nonce to this registration and whose x5c header chains to a Google root.
33442
+ //
33443
+ // OFF BY DEFAULT, and anchored only by the caller. Google retired the SafetyNet Attestation API, so
33444
+ // nothing mints these any more -- the surviving use is a relying party re-checking attestations it
33445
+ // stored years ago. Enabling a format whose producer is gone, against a root this library chose,
33446
+ // would widen what every caller trusts for no live benefit; so the caller opts in AND supplies the
33447
+ // root. With the opt off the verdict is byte-identical to the one this format had before the arm
33448
+ // existed. There is no bundled root and no trust-on-first-use.
33449
+ "android-safetynet": function(att, clientDataHash, opts) {
33450
+ opts = opts || {};
33451
+ if (opts.verifySafetyNetJws !== true) {
33452
+ if (opts.verifySafetyNetJws !== void 0 && typeof opts.verifySafetyNetJws !== "boolean") {
33453
+ throw _err("webauthn/bad-input", "opts.verifySafetyNetJws must be a boolean");
33454
+ }
33455
+ throw _err("webauthn/unsupported-format", "attestation statement format 'android-safetynet' is not supported");
33456
+ }
33457
+ var roots = opts.safetyNetRoots;
33458
+ if (!Array.isArray(roots) || roots.length === 0) {
33459
+ throw _err("webauthn/safetynet-no-root", "verifying an android-safetynet attestation requires opts.safetyNetRoots -- the Google root(s) to anchor the x5c chain to; this library bundles none (WebAuthn 8.5)");
33460
+ }
33461
+ if (opts.time !== void 0) guard.time.assertValid(opts.time, _err, "webauthn/bad-input", "opts.time");
33462
+ _requireAttShape(att.attStmt, ["ver", "response"], ["ver", "response"]);
33463
+ _attRead(att.attStmt, "ver", cbor.read.textString, "a text string");
33464
+ var responseBytes = _attRead(att.attStmt, "response", cbor.read.byteString, "a byte string");
33465
+ if (!responseBytes.length) throw _err("webauthn/bad-att-stmt", "the android-safetynet response is empty");
33466
+ var segs = guard.text.decode(responseBytes, constants.LIMITS.SAFETYNET_JWS_MAX_BYTES, WebauthnError, "webauthn/bad-att-stmt", "the android-safetynet response").split(".");
33467
+ if (segs.length !== 3) throw _err("webauthn/bad-att-stmt", "the android-safetynet response is not a three-part JWS compact serialization (RFC 7515 sec. 3.1)");
33468
+ var header, payload, sigBytes;
33469
+ try {
33470
+ header = jose.parseJson(jose.base64url.decode(segs[0]));
33471
+ payload = jose.parseJson(jose.base64url.decode(segs[1]));
33472
+ sigBytes = Buffer.from(jose.base64url.decode(segs[2]));
33473
+ } catch (e) {
33474
+ throw _err("webauthn/bad-att-stmt", "the android-safetynet response is not a decodable JWS", e);
33475
+ }
33476
+ if (!_isPlainObject(header) || !_isPlainObject(payload)) {
33477
+ throw _err("webauthn/bad-att-stmt", "the android-safetynet JWS header and payload must each be a JSON object");
33478
+ }
33479
+ if (header.alg !== "RS256") throw _err("webauthn/unsupported-algorithm", "the android-safetynet JWS alg must be RS256, got " + JSON.stringify(header.alg));
33480
+ if (!Array.isArray(header.x5c) || header.x5c.length === 0) {
33481
+ throw _err("webauthn/bad-att-stmt", "the android-safetynet JWS header carries no x5c certificate chain (RFC 7515 sec. 4.1.6)");
33482
+ }
33483
+ _requireX5cCount(header.x5c.length);
33484
+ var chain = header.x5c.map(function(entry, i) {
33485
+ if (typeof entry !== "string") throw _err("webauthn/bad-att-stmt", "the android-safetynet x5c entry " + i + " is not a string");
33486
+ var der;
33487
+ try {
33488
+ der = guard.encoding.base64(entry, constants.LIMITS.SAFETYNET_CERT_MAX_BYTES, WebauthnError, "webauthn/bad-att-stmt", "an android-safetynet x5c entry");
33489
+ } catch (e) {
33490
+ throw _err("webauthn/bad-att-stmt", "the android-safetynet x5c entry " + i + " is not canonical base64", e);
33491
+ }
33492
+ try {
33493
+ return x509.parse(der);
33494
+ } catch (e) {
33495
+ throw _err("webauthn/bad-att-cert", "the android-safetynet x5c entry " + i + " is not a decodable certificate", e);
33496
+ }
33497
+ });
33498
+ var leaf = chain[0];
33499
+ var wantNonce = _sha("sha256", Buffer.concat([att.authDataBytes, clientDataHash])).toString("base64");
33500
+ if (typeof payload.nonce !== "string" || !guard.crypto.constantTimeEqual(Buffer.from(payload.nonce, "utf8"), Buffer.from(wantNonce, "utf8"))) {
33501
+ throw _err("webauthn/safetynet-nonce-mismatch", "the android-safetynet nonce does not bind this authenticatorData and clientDataHash (WebAuthn 8.5)");
33502
+ }
33503
+ if (!_safetyNetHostnameOk(leaf)) {
33504
+ throw _err("webauthn/safetynet-bad-hostname", "the android-safetynet x5c leaf is not issued to attest.android.com (WebAuthn 8.5)");
33505
+ }
33506
+ var chainAt;
33507
+ var signals = {
33508
+ ctsProfileMatch: payload.ctsProfileMatch,
33509
+ basicIntegrity: payload.basicIntegrity,
33510
+ timestampMs: payload.timestampMs,
33511
+ apkPackageName: payload.apkPackageName,
33512
+ apkCertificateDigestSha256: payload.apkCertificateDigestSha256,
33513
+ advice: payload.advice
33514
+ };
33515
+ if (opts.requireCtsProfileMatch === true && signals.ctsProfileMatch !== true) {
33516
+ throw _err("webauthn/safetynet-cts-profile", "the android-safetynet response reports ctsProfileMatch " + JSON.stringify(signals.ctsProfileMatch) + ", and opts.requireCtsProfileMatch demands true");
33517
+ }
33518
+ if (opts.requireCtsProfileMatch !== void 0 && typeof opts.requireCtsProfileMatch !== "boolean") {
33519
+ throw _err("webauthn/bad-input", "opts.requireCtsProfileMatch must be a boolean");
33520
+ }
33521
+ return _verifySig(
33522
+ -257,
33523
+ sigBytes,
33524
+ leaf.subjectPublicKeyInfo.bytes,
33525
+ Buffer.from(segs[0] + "." + segs[1], "ascii"),
33526
+ _err
33527
+ ).then(function(ok) {
33528
+ if (!ok) throw _err("webauthn/verify-failed", "the android-safetynet JWS signature does not verify under the x5c leaf key");
33529
+ chainAt = opts.time !== void 0 ? opts.time : typeof payload.timestampMs === "number" && isFinite(payload.timestampMs) && payload.timestampMs > 0 ? new Date(payload.timestampMs) : void 0;
33530
+ return _safetyNetChainTrusted(chain, roots, chainAt);
33531
+ }).then(function() {
33532
+ var res = _result("android-safetynet", "Basic", chain, att);
33533
+ res.safetyNet = signals;
33534
+ if (chainAt !== void 0) res.chainValidatedAt = chainAt;
33535
+ return res;
33536
+ });
33537
+ },
33538
+ // compound (WebAuthn 8.9): the attStmt is an ARRAY of nested attestation statements, each
33539
+ // verified over the SAME authenticatorData and clientDataHash as the outer object. sec. 8.9
33540
+ // leaves the acceptance threshold to relying-party policy ("if validation fails for one or more
33541
+ // subStmt, decide the appropriate result based on RP policy"); this toolkit's policy is
33542
+ // fail-closed -- EVERY element must verify, because accepting a compound whose strong element
33543
+ // failed and whose `none` element passed would let a wrapper launder a failed attestation.
33544
+ compound: function(att, clientDataHash, opts) {
33545
+ var kids = att.attStmt.children || [];
33546
+ if (kids.length < 2) throw _err("webauthn/bad-att-stmt", "a compound attestation statement must carry at least two nested statements (WebAuthn 8.9)");
33547
+ if (kids.length > constants.LIMITS.WEBAUTHN_COMPOUND_MAX_STATEMENTS) {
33548
+ throw _err("webauthn/bad-att-stmt", "a compound attestation statement carries " + kids.length + " nested statements, above the " + constants.LIMITS.WEBAUTHN_COMPOUND_MAX_STATEMENTS + " this toolkit will verify");
33549
+ }
33550
+ var elements = kids.map(function(el, i) {
33551
+ if (!el || el.majorType !== 5) throw _err("webauthn/bad-att-stmt", "compound element " + i + " must be a CBOR map { fmt, attStmt } (WebAuthn 8.9)");
33552
+ var fN = cbor.read.mapGet(el, "fmt"), sN = cbor.read.mapGet(el, "attStmt");
33553
+ if (el.children.length !== 2 || !fN || !sN) throw _err("webauthn/bad-att-stmt", "compound element " + i + " must be exactly { fmt, attStmt } (WebAuthn 8.9)");
33554
+ if (fN.majorType !== 3) throw _err("webauthn/bad-att-stmt", "compound element " + i + " 'fmt' must be a text string");
33555
+ var f = cbor.read.textString(fN);
33556
+ if (f === "compound") throw _err("webauthn/bad-att-stmt", "a compound attestation statement must not nest another compound (WebAuthn 8.9)");
33557
+ var v = VERIFIERS[f];
33558
+ if (!v) throw _err("webauthn/unsupported-format", "compound element " + i + " uses unsupported attestation statement format '" + f + "'");
33559
+ var wantMajor = ATT_STMT_MAJOR[f] === void 0 ? 5 : ATT_STMT_MAJOR[f];
33560
+ if (sN.majorType !== wantMajor) throw _err("webauthn/bad-att-stmt", "compound element " + i + " 'attStmt' has the wrong CBOR shape for format '" + f + "'");
33561
+ return { fmt: f, index: i, att: { fmt: f, attStmt: sN, authData: att.authData, authDataBytes: att.authDataBytes } };
33562
+ });
33563
+ var out = [];
33564
+ return elements.reduce(function(p, e) {
33565
+ return p.then(function() {
33566
+ return Promise.resolve().then(function() {
33567
+ return VERIFIERS[e.fmt](e.att, clientDataHash, opts);
33568
+ }).then(function(r) {
33569
+ out.push(r);
33570
+ }, function(err) {
33571
+ throw _err("webauthn/compound-element-failed", "compound element " + e.index + " (format '" + e.fmt + "') did not verify", err);
33572
+ });
33573
+ });
33574
+ }, Promise.resolve()).then(function() {
33575
+ var res = _result("compound", "Compound", [], att);
33576
+ res.compound = out;
33577
+ return res;
31866
33578
  });
31867
33579
  },
31868
33580
  // none (WebAuthn 8.7): the authenticator provides no attestation. attStmt MUST be
@@ -31875,6 +33587,69 @@ var require_webauthn = __commonJS({
31875
33587
  return Promise.resolve(_result("none", "None", [], att));
31876
33588
  }
31877
33589
  };
33590
+ function _isPlainObject(v) {
33591
+ return !!v && typeof v === "object" && !Array.isArray(v);
33592
+ }
33593
+ function _safetyNetHostnameOk(leaf) {
33594
+ var want = "attest.android.com";
33595
+ var san = _decodeExt(leaf, "subjectAltName");
33596
+ var entries = san && Array.isArray(san.value) ? san.value : [];
33597
+ var dns = entries.filter(function(gn) {
33598
+ return gn && gn.type === "dNSName" && typeof gn.value === "string";
33599
+ });
33600
+ if (dns.length) return dns.some(function(gn) {
33601
+ return gn.value.toLowerCase() === want;
33602
+ });
33603
+ return leaf.subject.rdns.some(function(rdn) {
33604
+ return rdn.some(function(atv) {
33605
+ return atv.name === "commonName" && typeof atv.value === "string" && atv.value.toLowerCase() === want;
33606
+ });
33607
+ });
33608
+ }
33609
+ function _safetyNetChainTrusted(chain, roots, time) {
33610
+ var ordered = chain.slice().reverse();
33611
+ var when = time === void 0 ? /* @__PURE__ */ new Date() : time;
33612
+ var attempts = roots.map(function(root, i) {
33613
+ return function() {
33614
+ var anchorCert;
33615
+ try {
33616
+ anchorCert = Buffer.isBuffer(root) || typeof root === "string" ? x509.parse(root) : root;
33617
+ } catch (e) {
33618
+ throw _err("webauthn/bad-input", "opts.safetyNetRoots[" + i + "] is not a decodable certificate", e);
33619
+ }
33620
+ if (!anchorCert || !anchorCert.subject || !anchorCert.subjectPublicKeyInfo) {
33621
+ throw _err("webauthn/bad-input", "opts.safetyNetRoots[" + i + "] is not a certificate");
33622
+ }
33623
+ var path = ordered.slice();
33624
+ if (path.length > 1 && guard.name.dnEqual(path[0].subject, anchorCert.subject) && guard.name.dnEqual(path[0].issuer, path[0].subject)) {
33625
+ path = path.slice(1);
33626
+ }
33627
+ return pathValidate.validate(path, {
33628
+ time: when,
33629
+ // The anchor's own KEY algorithm and its parameters, not the algorithm its issuer signed it
33630
+ // with: the validator carries these forward as the working public key, and a certificate
33631
+ // below the anchor may inherit its key parameters from them.
33632
+ trustAnchor: {
33633
+ name: anchorCert.subject,
33634
+ publicKey: anchorCert.subjectPublicKeyInfo.bytes,
33635
+ algorithm: anchorCert.subjectPublicKeyInfo.algorithm.oid,
33636
+ parameters: anchorCert.subjectPublicKeyInfo.algorithm.parameters
33637
+ }
33638
+ }).then(function(r) {
33639
+ return !!(r && r.valid);
33640
+ }, function() {
33641
+ return false;
33642
+ });
33643
+ };
33644
+ });
33645
+ return attempts.reduce(function(p, next) {
33646
+ return p.then(function(done) {
33647
+ return done ? true : next();
33648
+ });
33649
+ }, Promise.resolve(false)).then(function(trusted) {
33650
+ if (!trusted) throw _err("webauthn/safetynet-cert-untrusted", "the android-safetynet x5c chain does not validate to any supplied root (opts.safetyNetRoots)");
33651
+ });
33652
+ }
31878
33653
  function _result(fmt, attestationType, chain, att) {
31879
33654
  return { verified: true, fmt, attestationType, trustPath: (chain || []).slice().reverse(), aaguid: att.authData.aaguid, credentialPublicKey: att.authData.credentialPublicKey };
31880
33655
  }
@@ -31900,6 +33675,13 @@ var require_webauthn = __commonJS({
31900
33675
  }
31901
33676
  function verify(attestationObject, clientDataHash, opts) {
31902
33677
  opts = opts || {};
33678
+ try {
33679
+ if (!_isPlainObject(opts)) throw _err("webauthn/bad-input", "opts must be an object");
33680
+ guard.identifier.assertKnownKeys(opts, _VERIFY_OPTS, _err, "webauthn/bad-input", "opts has an unknown key ");
33681
+ if (opts.time !== void 0) guard.time.assertValid(opts.time, _err, "webauthn/bad-input", "opts.time");
33682
+ } catch (e) {
33683
+ return Promise.reject(e);
33684
+ }
31903
33685
  if (!Buffer.isBuffer(clientDataHash) || clientDataHash.length !== 32) {
31904
33686
  return Promise.reject(_err("webauthn/bad-input", "clientDataHash must be a 32-byte SHA-256 digest"));
31905
33687
  }
@@ -31914,13 +33696,93 @@ var require_webauthn = __commonJS({
31914
33696
  }
31915
33697
  var verifier = VERIFIERS[att.fmt];
31916
33698
  if (!verifier) return Promise.reject(_err("webauthn/unsupported-format", "attestation statement format '" + att.fmt + "' is not supported"));
33699
+ if (opts.tpmPolicy !== void 0 && !_formatCanSatisfyTpmPolicy(att)) {
33700
+ return Promise.reject(_err("webauthn/tpm-policy", "opts.tpmPolicy requires a TPM attestation, but this attestation is format '" + att.fmt + "', which carries no TPM public area"));
33701
+ }
31917
33702
  return Promise.resolve().then(function() {
31918
33703
  return verifier(att, clientDataHash, opts);
33704
+ }).then(function(res) {
33705
+ return opts.metadata === void 0 ? res : _applyMetadata(res, att, opts);
33706
+ });
33707
+ }
33708
+ function _applyMetadata(res, att, opts) {
33709
+ var md = opts.metadata;
33710
+ if (!mds.isVerifiedResult(md)) {
33711
+ throw _err("webauthn/bad-input", "opts.metadata must be a pki.webauthn.verifyMetadataBlob result, not a raw BLOB");
33712
+ }
33713
+ var paths = res.fmt === "compound" && Array.isArray(res.compound) ? res.compound.filter(function(el) {
33714
+ return el.trustPath && el.trustPath.length;
33715
+ }).map(function(el) {
33716
+ return { tp: el.trustPath, fmt: el.fmt, at: el.chainValidatedAt };
33717
+ }) : res.trustPath && res.trustPath.length ? [{ tp: res.trustPath, fmt: res.fmt, at: res.chainValidatedAt }] : [];
33718
+ if (!paths.length) {
33719
+ throw _err("webauthn/metadata-not-applicable", "opts.metadata was supplied, but this attestation carries no trust path to anchor (format '" + res.fmt + "')");
33720
+ }
33721
+ var aaguid = mds.aaguidToString(att.authData.aaguid);
33722
+ var applied = [];
33723
+ function govern(info) {
33724
+ var tp = info.tp;
33725
+ var declared = _aaguidIsSigned(info.fmt) && aaguid && aaguid !== mds.ZERO_AAGUID;
33726
+ var entry, identifier;
33727
+ if (declared) {
33728
+ entry = mds.metadataFor(md, aaguid);
33729
+ identifier = "aaguid " + aaguid;
33730
+ } else {
33731
+ var keyId = mds.certKeyIdentifier(tp[tp.length - 1]);
33732
+ entry = mds.metadataForKeyIdentifier(md, keyId);
33733
+ identifier = "attestation certificate key identifier " + keyId;
33734
+ }
33735
+ if (!entry) throw _err("webauthn/metadata-not-found", "no metadata entry matches this authenticator (" + identifier + ")");
33736
+ if (mds.statusDenied(entry, md, tp[tp.length - 1], at)) {
33737
+ throw _err("webauthn/metadata-status", "the metadata entry for " + identifier + " carries a disqualifying status report");
33738
+ }
33739
+ var anchors = mds.metadataAnchors(entry);
33740
+ if (!anchors.length) throw _err("webauthn/metadata-no-anchor", "the metadata entry for " + identifier + " supplies no attestation root certificate");
33741
+ applied.push({ entry, anchors, identifier });
33742
+ return { anchors, identifier };
33743
+ }
33744
+ var at = opts.time !== void 0 ? opts.time : /* @__PURE__ */ new Date();
33745
+ mds.assertFresh(md, at, "the metadata supplied as opts.metadata");
33746
+ return paths.reduce(function(p, info) {
33747
+ return p.then(function() {
33748
+ var g = govern(info);
33749
+ var pathAt = opts.time !== void 0 ? opts.time : info.at || at;
33750
+ return mds.chainToAnchor(
33751
+ info.tp.slice().reverse(),
33752
+ g.anchors,
33753
+ pathAt,
33754
+ "attestation trust path for " + g.identifier + " (against the roots its metadata entry registers)"
33755
+ );
33756
+ });
33757
+ }, Promise.resolve()).then(function() {
33758
+ var primary = applied[0];
33759
+ res.metadata = {
33760
+ aaguid: primary.entry.aaguid,
33761
+ keyIdentifiers: primary.entry.keyIdentifiers || [],
33762
+ entry: primary.entry,
33763
+ entries: applied.map(function(a) {
33764
+ return a.entry;
33765
+ }),
33766
+ anchors: primary.anchors.length
33767
+ };
33768
+ return res;
33769
+ });
33770
+ }
33771
+ function _formatCanSatisfyTpmPolicy(att) {
33772
+ if (att.fmt === "tpm") return true;
33773
+ if (att.fmt !== "compound") return false;
33774
+ return (att.attStmt.children || []).some(function(el) {
33775
+ if (!el || el.majorType !== 5) return false;
33776
+ var fN = cbor.read.mapGet(el, "fmt");
33777
+ return !!fN && fN.majorType === 3 && cbor.read.textString(fN) === "tpm";
31919
33778
  });
31920
33779
  }
31921
33780
  module2.exports = {
31922
33781
  parseAttestationObject,
31923
- verify
33782
+ verify,
33783
+ verifyMetadataBlob: mds.verifyMetadataBlob,
33784
+ metadataFor: mds.metadataFor,
33785
+ metadataAnchors: mds.metadataAnchors
31924
33786
  };
31925
33787
  }
31926
33788
  });