@blamejs/core 0.18.53 → 0.18.54

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 (43) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/NOTICE +1 -1
  3. package/README.md +3 -3
  4. package/lib/ai-adverse-decision.js +18 -2
  5. package/lib/codepoint-class.js +72 -0
  6. package/lib/cookies.js +7 -10
  7. package/lib/credential-hash.js +8 -1
  8. package/lib/crypto.js +7 -5
  9. package/lib/guard-auth.js +34 -11
  10. package/lib/guard-filename.js +33 -32
  11. package/lib/guard-managesieve-command.js +49 -9
  12. package/lib/guard-regex.js +3 -5
  13. package/lib/guard-yaml.js +60 -15
  14. package/lib/mail-agent.js +23 -9
  15. package/lib/mail-arc-sign.js +40 -7
  16. package/lib/mail-auth.js +75 -20
  17. package/lib/mail-crypto-pgp.js +1 -1
  18. package/lib/mail-dkim.js +80 -11
  19. package/lib/mail-helo.js +10 -0
  20. package/lib/mail-rbl.js +10 -3
  21. package/lib/mail-send-deliver.js +151 -32
  22. package/lib/mail-server-imap.js +121 -55
  23. package/lib/mail-server-jmap.js +31 -4
  24. package/lib/mail-server-managesieve.js +168 -25
  25. package/lib/mail-server-mx.js +76 -4
  26. package/lib/mail-server-net.js +126 -0
  27. package/lib/mail-server-pop3.js +73 -22
  28. package/lib/mail-server-submission.js +21 -2
  29. package/lib/mail-store.js +33 -11
  30. package/lib/mail.js +355 -17
  31. package/lib/middleware/bearer-auth.js +6 -1
  32. package/lib/middleware/fetch-metadata.js +5 -1
  33. package/lib/middleware/headers.js +7 -10
  34. package/lib/network-dns-resolver.js +71 -8
  35. package/lib/network-dns.js +26 -0
  36. package/lib/network-smtp-policy.js +42 -10
  37. package/lib/redact.js +13 -3
  38. package/lib/retention.js +22 -2
  39. package/lib/vendor/MANIFEST.json +12 -12
  40. package/lib/vendor/blamejs-pki.cjs +278 -40
  41. package/lib/yaml-lex.js +55 -1
  42. package/package.json +1 -1
  43. package/sbom.cdx.json +6 -6
@@ -1,4 +1,4 @@
1
- // @blamejs/pki v0.5.28 — vendored (Apache-2.0). Zero-dep pure CJS.
1
+ // @blamejs/pki v0.5.30 — 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;
@@ -141,7 +141,7 @@ var require_package = __commonJS({
141
141
  "node_modules/@blamejs/pki/package.json"(exports2, module2) {
142
142
  module2.exports = {
143
143
  name: "@blamejs/pki",
144
- version: "0.5.28",
144
+ version: "0.5.30",
145
145
  description: "Pure-JavaScript PKI toolkit that owns its stack \u2014 X.509, ASN.1/DER, CMS, PQC-first.",
146
146
  license: "Apache-2.0",
147
147
  author: "blamejs contributors",
@@ -1957,6 +1957,41 @@ var require_oid = __commonJS({
1957
1957
  // The arc is RSA-dedicated, so a consumer can classify the whole family by its prefix; one member is
1958
1958
  // registered here so that prefix can be derived from the registry rather than a dotted-decimal literal.
1959
1959
  teletrustRsaSig: { base: [1, 3, 36, 3, 3, 1], of: { "rsaSignatureWithripemd160": 2 } },
1960
+ // TeleTrusT (BSI) signatureScheme arc (1.3.36.3.4) -- the ISO/IEC 9796-2 RSA signatures giving message
1961
+ // recovery (schemes 1/2/3: two deterministic, one randomized). ISO/IEC 9796-2 is titled "integer
1962
+ // factorization based mechanisms", so EVERY scheme it defines is RSA and the standard has no non-RSA
1963
+ // member; each node is registered so a consumer can name it -- e.g. the CMP keySpec RSA exclusion, which
1964
+ // must recognize RSA wherever it is standardized. ISO/IEC 9796-2 assigns no algorithm OIDs of its own;
1965
+ // this registrant tree is the de-facto registry. The .2 (deterministic) and .3 (randomized) sub-arcs are
1966
+ // RSA-dedicated in full -- every descendant is RSA -- so a consumer prefix-matches each to catch a hash
1967
+ // variant added later; the per-hash leaves are registered for readability. The `...Withrsa-even-exp`
1968
+ // nodes (.2.1 / .3.1) are the even-public-exponent RSA variants the registrant marks "not used"; they are
1969
+ // RSA (the registrant names them `sigS_ISO9796-2Withrsa_even-exp`), so the sub-arc prefix classifies them
1970
+ // correctly, not wrongly. .1 is ISO/IEC 9796-1, also RSA, on the same arc. The PARENT node (.4) is generic
1971
+ // "signatureScheme" and the sibling authentication arc (.5) is mixed (its .5.3 children are ECC), so
1972
+ // neither is RSA-dedicated -- a consumer must not prefix-match the parent or .5.
1973
+ teletrustSigScheme: { base: [1, 3, 36, 3, 4], of: {
1974
+ "sigS-ISO9796-1": 1,
1975
+ "sigS-ISO9796-1-DFUE": [1, 1],
1976
+ "sigS-ISO9796-2": 2,
1977
+ "sigS-ISO9796-2Withrsa-even-exp": [2, 1],
1978
+ "sigS-ISO9796-2Withrsa": [2, 2],
1979
+ "sigS-ISO9796-2Withrsa-sha1": [2, 2, 1],
1980
+ "sigS-ISO9796-2Withrsa-ripemd160": [2, 2, 2],
1981
+ "sigS-ISO9796-2Withrsa-sha224": [2, 2, 3],
1982
+ "sigS-ISO9796-2Withrsa-sha256": [2, 2, 4],
1983
+ "sigS-ISO9796-2Withrsa-sha384": [2, 2, 5],
1984
+ "sigS-ISO9796-2Withrsa-sha512": [2, 2, 6],
1985
+ "sigS-ISO9796-2rnd": 3,
1986
+ "sigS-ISO9796-2rndWithrsa-even-exp": [3, 1],
1987
+ "sigS-ISO9796-2rndWithrsa": [3, 2],
1988
+ "sigS-ISO9796-2rndWithrsa-sha1": [3, 2, 1],
1989
+ "sigS-ISO9796-2rndWithrsa-ripemd160": [3, 2, 2],
1990
+ "sigS-ISO9796-2rndWithrsa-sha224": [3, 2, 3],
1991
+ "sigS-ISO9796-2rndWithrsa-sha256": [3, 2, 4],
1992
+ "sigS-ISO9796-2rndWithrsa-sha384": [3, 2, 5],
1993
+ "sigS-ISO9796-2rndWithrsa-sha512": [3, 2, 6]
1994
+ } },
1960
1995
  // X.509 directory encryptionAlgorithm arc (2.5.8.1). id-ea-rsa (.1) is the X.509 `rsa` public-key
1961
1996
  // identifier, distinct from PKCS#1 rsaEncryption. Registered so a consumer can name it -- e.g. the
1962
1997
  // CMP keySpec RSA exclusion, which must recognize RSA wherever it is standardized.
@@ -24151,7 +24186,14 @@ var require_cmp_session = __commonJS({
24151
24186
  crlUpdate: { name: "crlUpdate", requestOid: "crlStatusList", responseOid: "crls", value: "crlStatus", read: "readCrls" }
24152
24187
  });
24153
24188
  var KNOWN_REVOKE_KEYS = { certificate: 1, certDetails: 1, reason: 1 };
24154
- var RSA_ARCS = ["rsaEncryption", "rsaSignatureWithripemd160", "id-TA-RSA-v1-5-SHA-256"].map(function(n) {
24189
+ var RSA_ARCS = [
24190
+ "rsaEncryption",
24191
+ "rsaSignatureWithripemd160",
24192
+ "id-TA-RSA-v1-5-SHA-256",
24193
+ "sigS-ISO9796-1-DFUE",
24194
+ "sigS-ISO9796-2Withrsa",
24195
+ "sigS-ISO9796-2rndWithrsa"
24196
+ ].map(function(n) {
24155
24197
  return oid.toArcs(oid.byName(n)).slice(0, -1);
24156
24198
  });
24157
24199
  var RSA_OFF_ARC = /* @__PURE__ */ Object.create(null);
@@ -24179,8 +24221,13 @@ var require_cmp_session = __commonJS({
24179
24221
  "sqMod-nWithRSA",
24180
24222
  "mdc2WithRSA",
24181
24223
  // the X.500 directory signatureAlgorithm RSA OIDs (2.5.8.3.1, 2.5.8.3.100)
24182
- "sm3WithRSAEncryption"
24224
+ "sm3WithRSAEncryption",
24183
24225
  // the Chinese GM/T RSA-with-SM3 signature (1.2.156.10197.1.504)
24226
+ // The TeleTrusT signatureScheme (ISO/IEC 9796-2) sub-arcs are prefix-matched in RSA_ARCS, but the strict-
24227
+ // descendant match skips each arc NODE itself, so the three bare nodes are named here (1.3.36.3.4.1/.2/.3).
24228
+ "sigS-ISO9796-1",
24229
+ "sigS-ISO9796-2",
24230
+ "sigS-ISO9796-2rnd"
24184
24231
  ].forEach(function(n) {
24185
24232
  var d = oid.byName(n);
24186
24233
  if (d) RSA_OFF_ARC[d] = 1;
@@ -25298,6 +25345,7 @@ var require_path_validate = __commonJS({
25298
25345
  }
25299
25346
  var NS = pkix.makeNS("path", PathError, oid);
25300
25347
  var EXT_DECODERS = pkix.certExtensionDecoders(NS).byOid;
25348
+ var ANCHOR_SPKI_SCHEMA = pkix.spki(NS);
25301
25349
  var subtle = webcrypto.webcrypto.subtle;
25302
25350
  var OID = {
25303
25351
  basicConstraints: oid.byName("basicConstraints"),
@@ -25781,7 +25829,7 @@ var require_path_validate = __commonJS({
25781
25829
  return { tag: st.tag, base: st.base };
25782
25830
  });
25783
25831
  }
25784
- function initialize(certs, params, seeds) {
25832
+ function initialize(certs, params, seeds, anchor) {
25785
25833
  var n = certs.length;
25786
25834
  return {
25787
25835
  validPolicyTree: rootNode(),
@@ -25794,10 +25842,10 @@ var require_path_validate = __commonJS({
25794
25842
  explicitPolicy: params.initialExplicitPolicy ? 0 : n + 1,
25795
25843
  inhibitAnyPolicy: params.initialAnyPolicyInhibit ? 0 : n + 1,
25796
25844
  policyMapping: params.initialPolicyMappingInhibit ? 0 : n + 1,
25797
- workingPublicKeyAlgorithm: params.trustAnchor.algorithm,
25798
- workingPublicKey: params.trustAnchor.publicKey,
25799
- workingPublicKeyParameters: params.trustAnchor.parameters || null,
25800
- workingIssuerName: params.trustAnchor.name,
25845
+ workingPublicKeyAlgorithm: anchor.algorithm,
25846
+ workingPublicKey: anchor.publicKey,
25847
+ workingPublicKeyParameters: anchor.parameters || null,
25848
+ workingIssuerName: anchor.name,
25801
25849
  maxPathLength: n,
25802
25850
  userInitialPolicySet: params.userInitialPolicySet || [OID.anyPolicy],
25803
25851
  results: []
@@ -26110,6 +26158,7 @@ var require_path_validate = __commonJS({
26110
26158
  var n = certs.length;
26111
26159
  if (n < 1) throw E("path/empty-path", "validate: the certification path is empty");
26112
26160
  if (!opts.trustAnchor) throw E("path/bad-input", "validate: a trustAnchor is required");
26161
+ var anchor = toAnchor(opts.trustAnchor, "validate");
26113
26162
  guard.time.assertValid(opts.time, E, "path/bad-input", "validate: opts.time (the always-on validity-window check date)");
26114
26163
  guard.limits.cap(opts.maxPolicyNodes, "validate: opts.maxPolicyNodes", void 0, { E, code: "path/bad-input", min: 1 });
26115
26164
  if (opts.userInitialPolicySet !== void 0) {
@@ -26128,7 +26177,7 @@ var require_path_validate = __commonJS({
26128
26177
  var purposeOpts = resolvePurposeOpts(opts);
26129
26178
  var requiredEku = purposeOpts.requiredEku;
26130
26179
  var checkPurpose = purposeOpts.checkPurpose;
26131
- var state = initialize(certs, opts, seeds);
26180
+ var state = initialize(certs, opts, seeds, anchor);
26132
26181
  state._n = n;
26133
26182
  state.requiredEku = requiredEku;
26134
26183
  var verifier = opts.verifier || null;
@@ -26138,7 +26187,7 @@ var require_path_validate = __commonJS({
26138
26187
  var failed = false;
26139
26188
  var revocationRan = false, revocationWaived = false, revocationUndetermined = false;
26140
26189
  var anchorDistrustApplied = false, anchorPurposeApplied = false;
26141
- if (!checkPurpose && opts.trustAnchor && _hasPurposeScopedMetadata(opts.trustAnchor)) {
26190
+ if (!checkPurpose && _hasPurposeScopedMetadata(anchor)) {
26142
26191
  throw E("path/bad-input", "validate: the trust anchor carries purpose-scoped metadata (distrustAfter / purposes), which is keyed by key purpose -- supply opts.checkPurpose to say which purpose this validation is for, or the constraint cannot be applied");
26143
26192
  }
26144
26193
  for (var idx = 0; idx < n; idx++) {
@@ -26295,7 +26344,7 @@ var require_path_validate = __commonJS({
26295
26344
  }
26296
26345
  if (requireCriticalExt(liap, "inhibitAnyPolicy", checks)) failed = true;
26297
26346
  if (requiredEku && ekuPurposeFails(cert, requiredEku, checks)) failed = true;
26298
- var ta = opts.trustAnchor;
26347
+ var ta = anchor;
26299
26348
  var distrustDate = assertAnchorConstraints(ta, checkPurpose);
26300
26349
  if (distrustDate != null) {
26301
26350
  anchorDistrustApplied = true;
@@ -26936,11 +26985,13 @@ var require_path_validate = __commonJS({
26936
26985
  if (!ta || typeof ta !== "object") return false;
26937
26986
  return guard.list.anyMatches(["distrustAfter", "purposes"], function(k) {
26938
26987
  var m = ta[k];
26939
- return !!m && typeof m === "object" && Object.keys(m).length > 0;
26988
+ return !!m && typeof m === "object" && intrinsic.getOwnPropertyNames(m).length > 0;
26940
26989
  });
26941
26990
  }
26942
26991
  function assertAnchorConstraints(ta, checkPurpose) {
26943
- var d = checkPurpose && ta && ta.distrustAfter && intrinsic.hasOwn(ta.distrustAfter, checkPurpose) ? ta.distrustAfter[checkPurpose] : null;
26992
+ if (!checkPurpose || !ta) return null;
26993
+ var da = ta.distrustAfter;
26994
+ var d = da && intrinsic.hasOwn(da, checkPurpose) ? da[checkPurpose] : null;
26944
26995
  if (d == null) return null;
26945
26996
  return guard.time.assertValid(d, E, "path/bad-input", "trustAnchor.distrustAfter." + checkPurpose);
26946
26997
  }
@@ -26973,22 +27024,191 @@ var require_path_validate = __commonJS({
26973
27024
  }
26974
27025
  return { requiredEku, checkPurpose };
26975
27026
  }
26976
- function toAnchor(entry) {
26977
- if (entry && typeof entry === "object" && !Buffer.isBuffer(entry) && entry.name && entry.publicKey && entry.algorithm) {
26978
- if (!intrinsic.isArray(entry.name.rdns) || !Buffer.isBuffer(entry.publicKey) || typeof entry.algorithm !== "string") {
26979
- throw E("path/bad-input", "build: a trustAnchor tuple must be { name: { rdns: [...] }, publicKey: Buffer, algorithm: OID string }");
27027
+ function _snapshotConstraintMap(m, E2, code, who) {
27028
+ var out = {};
27029
+ var proto = intrinsic.getPrototypeOf(m);
27030
+ if (proto !== null && proto !== intrinsic.ObjectProto) throw E2(code, who + ": a trustAnchor constraint map must be a plain object (its own entries only), not one with a custom or cross-realm prototype");
27031
+ var keys = intrinsic.getOwnPropertyNames(m);
27032
+ if (intrinsic.ownKeys(m).length !== keys.length) throw E2(code, who + ": a trustAnchor constraint map must not have symbol-keyed entries");
27033
+ for (var i = 0; i < keys.length; i++) {
27034
+ if (keys[i] === "__proto__") throw E2(code, who + ": a trustAnchor constraint map must not have an own __proto__ entry");
27035
+ var d = intrinsic.getOwnPropertyDescriptor(m, keys[i]);
27036
+ if (!d || !intrinsic.hasOwn(d, "value")) throw E2(code, who + ": a trustAnchor constraint-map entry must be a data property, not an accessor");
27037
+ var v = d.value;
27038
+ if (intrinsic.types.isDate(v)) v = new intrinsic.Date(guard.time.instantOf(v));
27039
+ intrinsic.defineProperty(out, keys[i], { value: v, enumerable: true, configurable: true, writable: true });
27040
+ }
27041
+ return out;
27042
+ }
27043
+ function _normalizeConstraintField(v, E2, code, who) {
27044
+ if (v === null || v === void 0) return v;
27045
+ if (typeof v !== "object" || intrinsic.isBuffer(v)) throw E2(code, who + ": a trustAnchor constraint map must be a plain object");
27046
+ return _snapshotConstraintMap(v, E2, code, who);
27047
+ }
27048
+ function _captureConstraintMap(entry, key, E2, code, who) {
27049
+ var d = intrinsic.getOwnPropertyDescriptor(entry, key);
27050
+ if (d === void 0) {
27051
+ if (key in entry) throw E2(code, who + ": a trustAnchor " + key + " must be an own data property, not inherited");
27052
+ return void 0;
27053
+ }
27054
+ if (!intrinsic.hasOwn(d, "value")) throw E2(code, who + ": a trustAnchor " + key + " must be a data property, not an accessor");
27055
+ if (intrinsic.types.isProxy(d.value)) throw E2(code, who + ": a trustAnchor " + key + " map must not be a Proxy");
27056
+ return d.value;
27057
+ }
27058
+ function _captureOwnData(entry, key) {
27059
+ var d = intrinsic.getOwnPropertyDescriptor(entry, key);
27060
+ return d && intrinsic.hasOwn(d, "value") ? d.value : void 0;
27061
+ }
27062
+ function _copyAtv(atv) {
27063
+ var out = {};
27064
+ var t = atv.type;
27065
+ if (t !== void 0) intrinsic.defineProperty(out, "type", { value: t, enumerable: true, configurable: true, writable: true });
27066
+ var v = atv.value;
27067
+ if (v !== void 0) intrinsic.defineProperty(out, "value", { value: v, enumerable: true, configurable: true, writable: true });
27068
+ var nm = atv.name;
27069
+ if (nm !== void 0) intrinsic.defineProperty(out, "name", { value: nm, enumerable: true, configurable: true, writable: true });
27070
+ return out;
27071
+ }
27072
+ function _copyRdnsDeep(rdns) {
27073
+ if (!intrinsic.isArray(rdns)) return rdns;
27074
+ var out = [];
27075
+ out.length = rdns.length;
27076
+ for (var i = 0; i < rdns.length; i++) {
27077
+ if (!intrinsic.hasOwn(rdns, i)) continue;
27078
+ var rdn = rdns[i], val;
27079
+ if (intrinsic.isArray(rdn)) {
27080
+ var rdnOut = [];
27081
+ rdnOut.length = rdn.length;
27082
+ for (var j = 0; j < rdn.length; j++) {
27083
+ if (!intrinsic.hasOwn(rdn, j)) continue;
27084
+ var atv = rdn[j] !== null && typeof rdn[j] === "object" ? _copyAtv(rdn[j]) : rdn[j];
27085
+ intrinsic.defineProperty(rdnOut, j, { value: atv, enumerable: true, configurable: true, writable: true });
27086
+ }
27087
+ val = rdnOut;
27088
+ } else {
27089
+ val = rdn;
27090
+ }
27091
+ intrinsic.defineProperty(out, i, { value: val, enumerable: true, configurable: true, writable: true });
27092
+ }
27093
+ return out;
27094
+ }
27095
+ function toAnchor(entry, verb) {
27096
+ var who = verb || "build";
27097
+ var isTuple = false, alg = null, pubRaw = null, nameRaw = null, pk = null, purposesSnap, distrustSnap;
27098
+ var subjectDerRaw, labelRaw, mozRaw;
27099
+ if (intrinsic.types.isProxy(entry)) {
27100
+ throw E("path/bad-input", who + ": a trustAnchor must not be a Proxy");
27101
+ }
27102
+ if (entry !== null && typeof entry === "object") {
27103
+ var proto = intrinsic.getPrototypeOf(entry);
27104
+ while (proto !== null) {
27105
+ if (intrinsic.types.isProxy(proto)) throw E("path/bad-input", who + ": a trustAnchor must not inherit from a Proxy");
27106
+ proto = intrinsic.getPrototypeOf(proto);
27107
+ }
27108
+ }
27109
+ try {
27110
+ if (entry && typeof entry === "object" && !Buffer.isBuffer(entry) && !guard.parsed.isRecorded(entry)) {
27111
+ var pRaw = _captureConstraintMap(entry, "purposes", E, "path/bad-input", who);
27112
+ purposesSnap = _normalizeConstraintField(pRaw, E, "path/bad-input", who);
27113
+ var dRaw = _captureConstraintMap(entry, "distrustAfter", E, "path/bad-input", who);
27114
+ distrustSnap = _normalizeConstraintField(dRaw, E, "path/bad-input", who);
27115
+ subjectDerRaw = _captureOwnData(entry, "subjectDer");
27116
+ labelRaw = _captureOwnData(entry, "label");
27117
+ mozRaw = _captureOwnData(entry, "mozillaCaPolicy");
27118
+ pubRaw = entry.publicKey;
27119
+ if (guard.bytes.isByteSource(pubRaw)) {
27120
+ pk = guard.bytes.snapshot(pubRaw, PathError, "path/bad-input", who + ": trustAnchor publicKey");
27121
+ }
27122
+ nameRaw = entry.name;
27123
+ alg = entry.algorithm;
27124
+ isTuple = !!(nameRaw && pubRaw && alg);
26980
27125
  }
26981
- return entry;
27126
+ } catch (e) {
27127
+ throw E("path/bad-input", who + ": a trustAnchor accessor threw", e);
27128
+ }
27129
+ if (isTuple) {
27130
+ var algStr;
27131
+ try {
27132
+ if (typeof alg === "string") {
27133
+ algStr = alg;
27134
+ } else if (alg !== null && typeof alg === "object") {
27135
+ if (intrinsic.types.isProxy(alg)) throw E("path/bad-input", who + ": a trustAnchor algorithm must not be a Proxy");
27136
+ var algOidD = intrinsic.getOwnPropertyDescriptor(alg, "oid");
27137
+ if (algOidD && !intrinsic.hasOwn(algOidD, "value")) throw E("path/bad-input", who + ": a trustAnchor algorithm.oid must be a data property, not an accessor");
27138
+ var algOid = algOidD ? algOidD.value : void 0;
27139
+ algStr = typeof algOid === "string" ? algOid : null;
27140
+ } else {
27141
+ algStr = null;
27142
+ }
27143
+ } catch (e) {
27144
+ throw E("path/bad-input", who + ": a trustAnchor algorithm.oid accessor threw", e);
27145
+ }
27146
+ var nameOut = {};
27147
+ try {
27148
+ var nsrc = nameRaw !== null && typeof nameRaw === "object" ? nameRaw : null;
27149
+ if (nsrc !== null && intrinsic.types.isProxy(nsrc)) throw E("path/bad-input", who + ": a trustAnchor name must not be a Proxy");
27150
+ var rdnsD = nsrc ? intrinsic.getOwnPropertyDescriptor(nsrc, "rdns") : void 0;
27151
+ if (rdnsD && !intrinsic.hasOwn(rdnsD, "value")) throw E("path/bad-input", who + ": a trustAnchor name.rdns must be a data property, not an accessor");
27152
+ var rdnsVal = rdnsD ? rdnsD.value : void 0;
27153
+ if (rdnsVal !== void 0) {
27154
+ intrinsic.defineProperty(nameOut, "rdns", { value: _copyRdnsDeep(rdnsVal), enumerable: true, configurable: true, writable: true });
27155
+ }
27156
+ var bytesD = nsrc ? intrinsic.getOwnPropertyDescriptor(nsrc, "bytes") : void 0;
27157
+ if (bytesD && !intrinsic.hasOwn(bytesD, "value")) throw E("path/bad-input", who + ": a trustAnchor name.bytes must be a data property, not an accessor");
27158
+ var nBytes = bytesD ? bytesD.value : void 0;
27159
+ if (nBytes !== void 0) {
27160
+ intrinsic.defineProperty(nameOut, "bytes", { value: nBytes, enumerable: true, configurable: true, writable: true });
27161
+ }
27162
+ var dnD = nsrc ? intrinsic.getOwnPropertyDescriptor(nsrc, "dn") : void 0;
27163
+ if (dnD && !intrinsic.hasOwn(dnD, "value")) throw E("path/bad-input", who + ": a trustAnchor name.dn must be a data property, not an accessor");
27164
+ var nDn = dnD ? dnD.value : void 0;
27165
+ if (typeof nDn === "string") {
27166
+ intrinsic.defineProperty(nameOut, "dn", { value: nDn, enumerable: true, configurable: true, writable: true });
27167
+ }
27168
+ } catch (e) {
27169
+ throw E("path/bad-input", who + ": trustAnchor name could not be materialized", e);
27170
+ }
27171
+ var nameHasRdns = intrinsic.hasOwn(nameOut, "rdns") && intrinsic.isArray(nameOut.rdns);
27172
+ if (!nameHasRdns || !Buffer.isBuffer(pubRaw) || algStr === null) {
27173
+ throw E("path/bad-input", who + ": a trustAnchor tuple must be { name: { rdns: [...] }, publicKey: Buffer, algorithm: an OID string or a SubjectPublicKeyInfo algorithm carrying an oid }");
27174
+ }
27175
+ guard.identifier.assertCanonicalOid(algStr, E, "path/bad-input", who + ": trustAnchor algorithm " + algStr);
27176
+ var spkiAlg;
27177
+ try {
27178
+ spkiAlg = schema.walk(ANCHOR_SPKI_SCHEMA, asn1.decode(pk), NS).result.algorithm;
27179
+ } catch (e) {
27180
+ throw E("path/bad-input", who + ": trustAnchor publicKey is not a valid SubjectPublicKeyInfo", e);
27181
+ }
27182
+ if (spkiAlg.oid !== algStr) {
27183
+ throw E("path/bad-input", who + ": trustAnchor algorithm " + algStr + " does not match its publicKey key algorithm " + spkiAlg.oid);
27184
+ }
27185
+ var flat = {};
27186
+ intrinsic.defineProperty(flat, "name", { value: nameOut, enumerable: true, configurable: true, writable: true });
27187
+ if (purposesSnap !== void 0) intrinsic.defineProperty(flat, "purposes", { value: purposesSnap, enumerable: true, configurable: true, writable: true });
27188
+ if (distrustSnap !== void 0) intrinsic.defineProperty(flat, "distrustAfter", { value: distrustSnap, enumerable: true, configurable: true, writable: true });
27189
+ if (subjectDerRaw !== void 0) intrinsic.defineProperty(flat, "subjectDer", { value: subjectDerRaw, enumerable: true, configurable: true, writable: true });
27190
+ if (labelRaw !== void 0) intrinsic.defineProperty(flat, "label", { value: labelRaw, enumerable: true, configurable: true, writable: true });
27191
+ if (mozRaw !== void 0) intrinsic.defineProperty(flat, "mozillaCaPolicy", { value: mozRaw, enumerable: true, configurable: true, writable: true });
27192
+ intrinsic.defineProperty(flat, "publicKey", { value: pk, enumerable: true, configurable: true, writable: true });
27193
+ intrinsic.defineProperty(flat, "algorithm", { value: spkiAlg.oid, enumerable: true, configurable: true, writable: true });
27194
+ intrinsic.defineProperty(flat, "parameters", { value: spkiAlg.parameters, enumerable: true, configurable: true, writable: true });
27195
+ return flat;
27196
+ }
27197
+ if (entry && typeof entry === "object" && ("purposes" in entry || "distrustAfter" in entry)) {
27198
+ throw E("path/bad-input", who + ": a trustAnchor certificate must not carry purposes / distrustAfter -- put per-purpose constraints on a { name, publicKey, algorithm, purposes, distrustAfter } tuple (or a pki.trust anchor), not on a parsed certificate");
26982
27199
  }
26983
27200
  var cert;
26984
27201
  try {
26985
27202
  cert = coerceCert(entry);
26986
27203
  } catch (e) {
26987
- throw E("path/bad-input", "build: a trustAnchor entry must be a { name, publicKey, algorithm } tuple or a certificate", e);
27204
+ throw E("path/bad-input", who + ": a trustAnchor entry must be a { name, publicKey, algorithm } tuple or a certificate", e);
26988
27205
  }
26989
27206
  var spki = cert.subjectPublicKeyInfo;
26990
27207
  return { name: cert.subject, publicKey: spki.bytes, algorithm: spki.algorithm.oid, parameters: spki.algorithm.parameters, subjectDer: cert.subject.bytes };
26991
27208
  }
27209
+ function anchorFromCert(cert) {
27210
+ return toAnchor(cert, "anchorFromCert");
27211
+ }
26992
27212
  function identityKey(cert) {
26993
27213
  var san = findExt(cert, OID.subjectAltName);
26994
27214
  return cert.subject.bytes.toString("hex") + "|" + (san ? san.value.toString("hex") : "") + "|" + cert.subjectPublicKeyInfo.bytes.toString("hex");
@@ -27170,7 +27390,9 @@ var require_path_validate = __commonJS({
27170
27390
  var poolDerKeys = /* @__PURE__ */ new Set();
27171
27391
  for (var pdk = 0; pdk < pool.length; pdk++) intrinsic.setAdd(poolDerKeys, certDerKey(pool[pdk]));
27172
27392
  if (!intrinsic.isArray(opts.trustAnchors) || opts.trustAnchors.length === 0) throw E("path/bad-input", "build: opts.trustAnchors must be a non-empty array of anchor tuples or root certificates");
27173
- var anchors = opts.trustAnchors.map(toAnchor);
27393
+ var anchors = opts.trustAnchors.map(function(a) {
27394
+ return toAnchor(a, "build");
27395
+ });
27174
27396
  guard.time.assertValid(opts.time, E, "path/bad-input", "build: opts.time (the validity-window check date, forwarded to validate)");
27175
27397
  var effectiveMaxCerts = guard.limits.cap(opts.maxPathCerts, "build: opts.maxPathCerts", constants.LIMITS.PATH_MAX_CERTS, { E, code: "path/bad-input", min: 1 });
27176
27398
  var depthCeiling = effectiveMaxCerts - 1;
@@ -27325,6 +27547,7 @@ var require_path_validate = __commonJS({
27325
27547
  module2.exports = {
27326
27548
  validate,
27327
27549
  build,
27550
+ anchorFromCert,
27328
27551
  crlChecker,
27329
27552
  ocspChecker,
27330
27553
  verifyOcspResponse,
@@ -37384,6 +37607,19 @@ var require_acme = __commonJS({
37384
37607
  sleep: 1,
37385
37608
  clock: 1
37386
37609
  };
37610
+ var _METHOD_OPTS = {
37611
+ finalize: { csr: 1, identifiers: 1 },
37612
+ poll: { maxPolls: 1, maxTotalWait: 1, onRetryAfter: 1 },
37613
+ download: { expectedSpki: 1, identifiers: 1, requireBinding: 1, selectChain: 1, maxAlternates: 1 },
37614
+ revoke: { certAlg: 1, certJwk: 1, certKey: 1, certificate: 1, reason: 1 },
37615
+ keyChange: { newAlg: 1, newJwk: 1, newKey: 1 },
37616
+ renewalWindow: { random: 1, clock: 1, replaced: 1, previous: 1 }
37617
+ };
37618
+ function _gateOpts(bag, whitelist, name) {
37619
+ bag = guard.identifier.optionsObject(bag, E, "acme/bad-input", "pki.acme " + name + " options");
37620
+ guard.identifier.assertKnownKeys(bag, whitelist, E, "acme/bad-input", "unknown " + name + " option ");
37621
+ return bag;
37622
+ }
37387
37623
  function client(directoryUrl, opts) {
37388
37624
  opts = guard.identifier.optionsObject(opts, E, "acme/bad-input", "pki.acme.client options");
37389
37625
  guard.identifier.assertKnownKeys(opts, _CLIENT_OPTS, E, "acme/bad-input", "unknown pki.acme.client option ");
@@ -37638,7 +37874,7 @@ var require_acme = __commonJS({
37638
37874
  });
37639
37875
  }
37640
37876
  function _finalizeBody(order, o) {
37641
- o = o || {};
37877
+ o = _gateOpts(o, _METHOD_OPTS.finalize, "finalize");
37642
37878
  if (!_isObject(order) || !_isString(order.finalize)) throw E("acme/bad-input", "finalize requires the order object with its finalize URL");
37643
37879
  if (!Array.isArray(order.identifiers)) throw E("acme/bad-input", "finalize requires the order's identifiers to enforce the RFC 8555 sec. 7.4 CSR-set match");
37644
37880
  return _post(_clientUrl(order.finalize), finalize, { csr: o.csr, identifiers: order.identifiers, accountJwk }, "kid").then(function(res) {
@@ -37646,9 +37882,9 @@ var require_acme = __commonJS({
37646
37882
  });
37647
37883
  }
37648
37884
  function _poll(kind, url, budget) {
37649
- budget = budget || {};
37650
37885
  var capPolls, capWait;
37651
37886
  try {
37887
+ budget = _gateOpts(budget, _METHOD_OPTS.poll, "poll");
37652
37888
  capPolls = budget.maxPolls != null ? guard.limits.cap(budget.maxPolls, "maxPolls", maxPolls, { E, code: "acme/bad-input", min: 1, max: 1e3 }) : maxPolls;
37653
37889
  capWait = budget.maxTotalWait != null ? guard.limits.cap(budget.maxTotalWait, "maxTotalWait", maxTotalWait, { E, code: "acme/bad-input", min: 0, max: retryAfter.MAX_RETRY_AFTER_SECONDS }) : maxTotalWait;
37654
37890
  url = _clientUrl(url);
@@ -37747,8 +37983,8 @@ var require_acme = __commonJS({
37747
37983
  }
37748
37984
  }
37749
37985
  function _downloadCertificate(url, opts2) {
37750
- opts2 = opts2 || {};
37751
37986
  return Promise.resolve().then(function() {
37987
+ opts2 = _gateOpts(opts2, _METHOD_OPTS.download, "downloadCertificate");
37752
37988
  var select = opts2.selectChain;
37753
37989
  if (select !== void 0 && typeof select !== "function") throw E("acme/bad-input", "downloadCertificate opts.selectChain must be a function");
37754
37990
  var maxAlt = guard.limits.cap(opts2.maxAlternates, "maxAlternates", DEFAULT_MAX_ALTERNATES, { E, code: "acme/bad-input", min: 0, max: 64 });
@@ -37797,22 +38033,24 @@ var require_acme = __commonJS({
37797
38033
  });
37798
38034
  }
37799
38035
  function _revokeCert(o) {
37800
- o = o || {};
37801
- if (!Buffer.isBuffer(o.certificate)) return Promise.reject(E("acme/bad-input", "revokeCert requires a DER certificate Buffer (opts.certificate)"));
37802
- var certKeyMode = o.certKey != null || _isObject(o.certJwk) || o.certAlg != null;
37803
- if (certKeyMode && !(o.certKey != null && _isObject(o.certJwk) && _isString(o.certAlg))) return Promise.reject(E("acme/bad-input", "revokeCert certificate-key mode requires certKey, certJwk, AND certAlg together, or none (RFC 8555 sec. 7.6)"));
37804
- var extra = { certificate: o.certificate };
37805
- if (o.reason !== void 0) extra.reason = o.reason;
37806
- return _resource("revokeCert").then(function(url) {
37807
- if (certKeyMode) {
37808
- return _postJws(url, function(nonce) {
37809
- return revokeCert(Object.assign({}, extra, { key: o.certKey, alg: o.certAlg, nonce, url, jwk: o.certJwk }));
37810
- }).then(function() {
38036
+ return _promised(function() {
38037
+ o = _gateOpts(o, _METHOD_OPTS.revoke, "revokeCert");
38038
+ if (!Buffer.isBuffer(o.certificate)) throw E("acme/bad-input", "revokeCert requires a DER certificate Buffer (opts.certificate)");
38039
+ var certKeyMode = o.certKey != null || _isObject(o.certJwk) || o.certAlg != null;
38040
+ if (certKeyMode && !(o.certKey != null && _isObject(o.certJwk) && _isString(o.certAlg))) throw E("acme/bad-input", "revokeCert certificate-key mode requires certKey, certJwk, AND certAlg together, or none (RFC 8555 sec. 7.6)");
38041
+ var extra = { certificate: o.certificate };
38042
+ if (o.reason !== void 0) extra.reason = o.reason;
38043
+ return _resource("revokeCert").then(function(url) {
38044
+ if (certKeyMode) {
38045
+ return _postJws(url, function(nonce) {
38046
+ return revokeCert(Object.assign({}, extra, { key: o.certKey, alg: o.certAlg, nonce, url, jwk: o.certJwk }));
38047
+ }).then(function() {
38048
+ return true;
38049
+ });
38050
+ }
38051
+ return _post(url, revokeCert, extra, "kid").then(function() {
37811
38052
  return true;
37812
38053
  });
37813
- }
37814
- return _post(url, revokeCert, extra, "kid").then(function() {
37815
- return true;
37816
38054
  });
37817
38055
  });
37818
38056
  }
@@ -37836,7 +38074,7 @@ var require_acme = __commonJS({
37836
38074
  });
37837
38075
  }
37838
38076
  function _keyChangeBody(o) {
37839
- o = o || {};
38077
+ o = _gateOpts(o, _METHOD_OPTS.keyChange, "keyChange");
37840
38078
  if (!o.newKey || !_isObject(o.newJwk) || !_isString(o.newAlg)) throw E("acme/bad-input", "keyChange requires newKey, newJwk, and newAlg");
37841
38079
  var account = _requireKid();
37842
38080
  return _resource("keyChange").then(function(url) {
@@ -37895,8 +38133,8 @@ var require_acme = __commonJS({
37895
38133
  });
37896
38134
  }
37897
38135
  function _renewalWindow(certDer, o) {
37898
- o = o || {};
37899
38136
  return Promise.resolve().then(function() {
38137
+ o = _gateOpts(o, _METHOD_OPTS.renewalWindow, "renewalWindow");
37900
38138
  if (!Buffer.isBuffer(certDer)) throw E("acme/bad-input", "renewalWindow requires a DER certificate Buffer");
37901
38139
  if (o.random !== void 0 && typeof o.random !== "function") throw E("acme/bad-input", "renewalWindow opts.random must be a function returning a number in [0, 1]");
37902
38140
  if (o.clock !== void 0 && typeof o.clock !== "function") throw E("acme/bad-input", "renewalWindow opts.clock must be a function returning epoch milliseconds");
package/lib/yaml-lex.js CHANGED
@@ -96,7 +96,44 @@ function _isVerbatimLine(line, indent) {
96
96
  return false;
97
97
  }
98
98
 
99
+ // maskNonStructural(text) → the mask alone, which is what most callers want.
99
100
  function maskNonStructural(text) {
101
+ return lexLines(text).masked;
102
+ }
103
+
104
+ // lexLines(text) → { masked, nodeStarts }.
105
+ //
106
+ // `nodeStarts` is a byte per source character, 1 where a NODE may begin: the
107
+ // first content character of a key, a value, or a flow-collection item. It
108
+ // answers the question the mask cannot, because the mask blanks a key's own text
109
+ // along with a comment's, and a screen that deliberately reports shapes which
110
+ // are not valid structure needs them apart.
111
+ //
112
+ // A byte array rather than a sparse one keyed by offset. Sparse indices this
113
+ // large put V8's array into dictionary mode, which measured ~200 bytes for each
114
+ // node in the document: a 1.7 MB file of short keys allocated 71 MB, a 40x
115
+ // amplification an attacker picks by choosing the shape of the input. A byte per
116
+ // character is 1x, flat, and known before the scan starts.
117
+ //
118
+ // The merge-key screen is that kind of screen. `<<:*d` with no space after the
119
+ // colon is not a mapping entry, and is reported anyway, because a parser variant
120
+ // may read it as a merge and that is the shape being smuggled. So its test
121
+ // cannot be "is this well-formed structure?" — it has to be "could a node begin
122
+ // here at all?", which is false inside a comment, a quoted body, a block
123
+ // scalar's body, and a plain scalar's continuation line, and true for both
124
+ // `<<: *b` and `<<:*b`.
125
+ //
126
+ // Enumerating those regions instead was tried and is the wrong shape: a first
127
+ // version excluded block-scalar bodies and quoted bodies and still reported a
128
+ // merge key written in a comment, on a plain scalar's continuation line, and
129
+ // after a document marker. There are more ways to be inside literal text than
130
+ // anyone lists from memory, and the lexer is already tracking the one property
131
+ // that separates them.
132
+ //
133
+ // Both come out of ONE pass. A second function walking the same grammar is how
134
+ // two answers to one question start disagreeing, which is the defect this
135
+ // module was written to end.
136
+ function lexLines(text) {
100
137
  var src = String(text == null ? "" : text);
101
138
  // Split on the newline ALONE, keeping any `\r` with the line it terminates.
102
139
  // `codepointClass.splitLines` strips it, and rejoining those with "\n" drops
@@ -106,6 +143,13 @@ function maskNonStructural(text) {
106
143
  // mask, because the locations it reports are confidently wrong.
107
144
  var lines = src.split("\n");
108
145
  var out = [];
146
+ var nodeStarts = new Uint8Array(src.length);
147
+ // The absolute offset line `li` begins at. Derived at the TOP of each
148
+ // iteration from the PREVIOUS line's raw length, rather than advanced at the
149
+ // bottom, because the loop body leaves by a dozen different `continue`s and
150
+ // any one of them forgetting to advance would silently shift every offset
151
+ // after it.
152
+ var lineBase = 0;
109
153
  // A block scalar's body indentation is DETECTED from its first content line,
110
154
  // which is what YAML specifies and the only thing that works. Two fixed
111
155
  // columns were tried and each failed the other's case: measuring from the
@@ -149,6 +193,7 @@ function maskNonStructural(text) {
149
193
  var plainFromDash = false;
150
194
 
151
195
  for (var li = 0; li < lines.length; li += 1) {
196
+ if (li > 0) lineBase += lines[li - 1].length + 1; // + the "\n" that ended it
152
197
  var raw = lines[li];
153
198
  // The carriage return of a CRLF pair is a line TERMINATOR, not content, so
154
199
  // it is held aside and put back verbatim. Letting it into the scan would
@@ -283,6 +328,14 @@ function maskNonStructural(text) {
283
328
  var jsonKeyBefore = prevWasJsonKey;
284
329
  prevWasJsonKey = false;
285
330
 
331
+ // The first content character of a node position. Whitespace carries the
332
+ // flag rather than clearing it, so this lands on the character that
333
+ // actually starts the node, and a `#` here opens a comment instead — no
334
+ // node begins inside one.
335
+ if (atNodeStart && !_isPlainSpace(ch) && ch !== "#") {
336
+ nodeStarts[lineBase + i] = 1;
337
+ }
338
+
286
339
  // A comment opens on `#` at the start of the content or after whitespace,
287
340
  // and runs to the end of the line. Its text is not YAML, whatever it
288
341
  // says: `x: 1 # note !bang` names no tag.
@@ -478,7 +531,7 @@ function maskNonStructural(text) {
478
531
  }
479
532
  out.push(masked + (cr ? "\r" : ""));
480
533
  }
481
- return out.join("\n");
534
+ return { masked: out.join("\n"), nodeStarts: nodeStarts };
482
535
  }
483
536
 
484
537
  // A line kept for its structure, with any comment on it masked. Used for the
@@ -530,4 +583,5 @@ function _blanked(s) {
530
583
 
531
584
  module.exports = {
532
585
  maskNonStructural: maskNonStructural,
586
+ lexLines: lexLines,
533
587
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.18.53",
3
+ "version": "0.18.54",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:f52f2ee6-253b-4bf4-9915-22d453a4407a",
5
+ "serialNumber": "urn:uuid:df56ad31-5a1c-4fe3-91c9-28416a675962",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-08-24T12:08:00.505Z",
8
+ "timestamp": "2026-08-25T01:22:53.297Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.18.53",
22
+ "bom-ref": "@blamejs/core@0.18.54",
23
23
  "type": "application",
24
24
  "name": "blamejs",
25
- "version": "0.18.53",
25
+ "version": "0.18.54",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.18.53",
29
+ "purl": "pkg:npm/%40blamejs/core@0.18.54",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.18.53",
57
+ "ref": "@blamejs/core@0.18.54",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]