@blamejs/core 0.18.54 → 0.18.56
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.
- package/CHANGELOG.md +146 -0
- package/NOTICE +5 -5
- package/README.md +9 -9
- package/lib/agent-audit.js +27 -2
- package/lib/audit-sign.js +24 -5
- package/lib/audit.js +26 -24
- package/lib/auth/passkey.js +4 -1
- package/lib/chain-writer.js +17 -0
- package/lib/db-file-lifecycle.js +14 -3
- package/lib/db.js +505 -49
- package/lib/guard-filename.js +8 -1
- package/lib/guard-html.js +10 -2
- package/lib/guard-list-unsubscribe.js +6 -1
- package/lib/guard-managesieve-command.js +24 -3
- package/lib/guard-smtp-command.js +20 -4
- package/lib/guard-svg.js +6 -1
- package/lib/http-client.js +17 -3
- package/lib/mail-agent.js +6 -4
- package/lib/mail-auth.js +59 -2
- package/lib/mail-server-imap.js +65 -34
- package/lib/mail-server-managesieve.js +65 -42
- package/lib/mail-server-mx.js +313 -40
- package/lib/mail-server-net.js +155 -1
- package/lib/mail-server-pop3.js +16 -19
- package/lib/mail-server-rate-limit.js +104 -6
- package/lib/mail-server-submission.js +162 -33
- package/lib/mail-server-tls.js +71 -11
- package/lib/mcp.js +11 -3
- package/lib/middleware/csrf-protect.js +37 -20
- package/lib/middleware/require-mtls.js +8 -1
- package/lib/network-tls.js +18 -0
- package/lib/safe-mount-info.js +39 -6
- package/lib/safe-smtp.js +96 -1
- package/lib/safe-url.js +8 -2
- package/lib/self-update.js +4 -1
- package/lib/session-stores.js +6 -3
- package/lib/vendor/MANIFEST.json +34 -34
- package/lib/vendor/blamejs-pki.cjs +396 -37
- package/lib/vendor/browser/noble-ciphers.mjs +15 -1
- package/lib/vendor/browser/noble-hashes.mjs +12 -4
- package/lib/vendor/browser/noble-post-quantum.mjs +78 -37
- package/lib/vendor/noble-ciphers.cjs +15 -1
- package/lib/vendor/noble-curves.cjs +46 -21
- package/lib/vendor/noble-post-quantum.cjs +184 -75
- package/lib/watcher.js +31 -6
- package/lib/ws-client.js +17 -2
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @noble/post-quantum v0.7.
|
|
1
|
+
// @noble/post-quantum v0.7.1 — vendored from Paul Miller
|
|
2
2
|
// License: MIT — https://github.com/paulmillr/noble-post-quantum
|
|
3
3
|
// Bundled with esbuild. Exports: ml_kem512 / ml_kem768 / ml_kem1024 (FIPS 203 KEM),
|
|
4
4
|
// ml_dsa44 / ml_dsa65 / ml_dsa87 (FIPS 204 lattice signatures),
|
|
@@ -124,6 +124,14 @@ var aobject = (value, label) => {
|
|
|
124
124
|
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
125
125
|
throw new TypeError((label === "object" ? "" : `"${label}" `) + "expected object, got type=" + typeof value);
|
|
126
126
|
};
|
|
127
|
+
var aopts = (value, label) => {
|
|
128
|
+
aobject(value, label);
|
|
129
|
+
const proto = Object.getPrototypeOf(value);
|
|
130
|
+
if (proto !== Object.prototype && proto !== null)
|
|
131
|
+
throw new TypeError(`"${label}" expected plain object`);
|
|
132
|
+
if (Object.hasOwn(value, "__proto__"))
|
|
133
|
+
throw new TypeError(`"${label}.__proto__" is not allowed`);
|
|
134
|
+
};
|
|
127
135
|
function aexists(instance, checkFinished = true) {
|
|
128
136
|
if (instance.destroyed)
|
|
129
137
|
throw new Error("hash was destroyed");
|
|
@@ -224,10 +232,10 @@ function concatBytes(...arrays) {
|
|
|
224
232
|
return res;
|
|
225
233
|
}
|
|
226
234
|
function checkOpts(defaults, opts2, title = "opts") {
|
|
227
|
-
|
|
235
|
+
aopts(defaults, "defaults");
|
|
228
236
|
if (opts2 !== void 0)
|
|
229
|
-
|
|
230
|
-
const merged = Object.assign(defaults, opts2);
|
|
237
|
+
aopts(opts2, title);
|
|
238
|
+
const merged = Object.assign(/* @__PURE__ */ Object.create(null), defaults, opts2);
|
|
231
239
|
return merged;
|
|
232
240
|
}
|
|
233
241
|
function createHasher(hashCons, info = {}) {
|
|
@@ -686,22 +694,47 @@ function equalBytes(a, b) {
|
|
|
686
694
|
return diff === 0;
|
|
687
695
|
}
|
|
688
696
|
function copyBytes(bytes) {
|
|
689
|
-
return Uint8Array
|
|
697
|
+
return new Uint8Array(abytes(bytes));
|
|
690
698
|
}
|
|
691
699
|
function validateOpts(opts2) {
|
|
692
700
|
if (isBytes(opts2))
|
|
693
701
|
throw new TypeError('"opts" expected object, got Uint8Array');
|
|
694
702
|
aobject3(opts2, "opts");
|
|
703
|
+
const proto = Object.getPrototypeOf(opts2);
|
|
704
|
+
if (proto !== null && proto !== Object.prototype)
|
|
705
|
+
throw new TypeError('"opts" expected a plain object');
|
|
695
706
|
}
|
|
696
|
-
|
|
707
|
+
var VER_OPT_KEYS = /* @__PURE__ */ Object.freeze([
|
|
708
|
+
"context"
|
|
709
|
+
]);
|
|
710
|
+
var SIG_OPT_KEYS = /* @__PURE__ */ Object.freeze([
|
|
711
|
+
"context",
|
|
712
|
+
"extraEntropy"
|
|
713
|
+
]);
|
|
714
|
+
function checkOptKeys(opts2, allowed) {
|
|
697
715
|
validateOpts(opts2);
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
716
|
+
const normalized = Object.assign(/* @__PURE__ */ Object.create(null), opts2);
|
|
717
|
+
for (const [k, v] of Object.entries(normalized)) {
|
|
718
|
+
if (v === void 0)
|
|
719
|
+
continue;
|
|
720
|
+
if (!allowed.includes(k))
|
|
721
|
+
throw new TypeError('unexpected option "' + String(k) + '"; expected one of: ' + allowed.join(", "));
|
|
722
|
+
}
|
|
723
|
+
return Object.freeze(normalized);
|
|
724
|
+
}
|
|
725
|
+
function validateVerOpts(opts2, allowed = VER_OPT_KEYS) {
|
|
726
|
+
const normalized = checkOptKeys(opts2, allowed);
|
|
727
|
+
if (normalized.context !== void 0)
|
|
728
|
+
abytes(normalized.context, void 0, "opts.context");
|
|
729
|
+
return normalized;
|
|
730
|
+
}
|
|
731
|
+
function validateSigOpts(opts2, allowed = SIG_OPT_KEYS) {
|
|
732
|
+
const normalized = checkOptKeys(opts2, allowed);
|
|
733
|
+
if (normalized.context !== void 0)
|
|
734
|
+
abytes(normalized.context, void 0, "opts.context");
|
|
735
|
+
if (normalized.extraEntropy !== false && normalized.extraEntropy !== void 0)
|
|
736
|
+
abytes(normalized.extraEntropy, void 0, "opts.extraEntropy");
|
|
737
|
+
return normalized;
|
|
705
738
|
}
|
|
706
739
|
function splitCoder(label, ...lengths) {
|
|
707
740
|
const getLength = (c) => typeof c === "number" ? c : c.bytesLen;
|
|
@@ -786,6 +819,12 @@ function getMessage(msg, ctx = EMPTY) {
|
|
|
786
819
|
return concatBytes(new Uint8Array([0, ctx.length]), ctx, msg);
|
|
787
820
|
}
|
|
788
821
|
var oidNistP = /* @__PURE__ */ Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2]);
|
|
822
|
+
var XOF_OID_OUTPUT_LEN = /* @__PURE__ */ (() => ({
|
|
823
|
+
"060960864801650304020b": 32,
|
|
824
|
+
// id-shake128, SHAKE128(M, 256)
|
|
825
|
+
"060960864801650304020c": 64
|
|
826
|
+
// id-shake256, SHAKE256(M, 512)
|
|
827
|
+
}))();
|
|
789
828
|
function checkHash(hash, requiredStrength = 0) {
|
|
790
829
|
if (typeof hash !== "function" || typeof hash.create !== "function")
|
|
791
830
|
throw new TypeError('"hash" expected hash function, got type=' + typeof hash);
|
|
@@ -795,6 +834,10 @@ function checkHash(hash, requiredStrength = 0) {
|
|
|
795
834
|
abytes(oid, void 0, "hash.oid");
|
|
796
835
|
if (!equalBytes(oid.subarray(0, 10), oidNistP))
|
|
797
836
|
throw new Error('"hash.oid" is invalid: expected NIST hash');
|
|
837
|
+
const xofLen = XOF_OID_OUTPUT_LEN[bytesToHex(oid)];
|
|
838
|
+
if (xofLen !== void 0 && hash.outputLen !== xofLen) {
|
|
839
|
+
throw new Error("Pre-hash XOF output length must be " + xofLen + " bytes for this OID, got: " + hash.outputLen);
|
|
840
|
+
}
|
|
798
841
|
const collisionResistance = hash.outputLen * 8 / 2;
|
|
799
842
|
if (requiredStrength > collisionResistance) {
|
|
800
843
|
throw new Error("Pre-hash security strength too low: " + collisionResistance + ", required: " + requiredStrength);
|
|
@@ -1162,8 +1205,9 @@ var genKPKE = (opts_) => {
|
|
|
1162
1205
|
for (let i = 0; i < K; i++)
|
|
1163
1206
|
polyAdd(tmp, MultiplyNTTs(sk[i], crystals.NTT.encode(u[i])));
|
|
1164
1207
|
polySub(v, crystals.NTT.decode(tmp));
|
|
1165
|
-
|
|
1166
|
-
|
|
1208
|
+
const res = poly1.encode(v);
|
|
1209
|
+
cleanBytes(tmp, sk, u, v);
|
|
1210
|
+
return res;
|
|
1167
1211
|
}
|
|
1168
1212
|
};
|
|
1169
1213
|
};
|
|
@@ -1193,32 +1237,55 @@ function createKyber(opts2) {
|
|
|
1193
1237
|
return Object.freeze({
|
|
1194
1238
|
info: Object.freeze({ type: "ml-kem" }),
|
|
1195
1239
|
lengths: kemLengths,
|
|
1196
|
-
keygen: (seed
|
|
1197
|
-
|
|
1198
|
-
const
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1240
|
+
keygen: (seed) => {
|
|
1241
|
+
const ownSeed = seed === void 0;
|
|
1242
|
+
const s = ownSeed ? randomBytes2(seedLen) : seed;
|
|
1243
|
+
let sk;
|
|
1244
|
+
let publicKeyHash;
|
|
1245
|
+
try {
|
|
1246
|
+
abytesDoc(s, seedLen, "seed");
|
|
1247
|
+
const keys = KPKE.keygen(s.subarray(0, 32));
|
|
1248
|
+
const publicKey = keys.publicKey;
|
|
1249
|
+
sk = keys.secretKey;
|
|
1250
|
+
publicKeyHash = HASH256(publicKey);
|
|
1251
|
+
const secretKey = secretCoder.encode([sk, publicKey, publicKeyHash, s.subarray(32)]);
|
|
1252
|
+
return {
|
|
1253
|
+
publicKey,
|
|
1254
|
+
secretKey
|
|
1255
|
+
};
|
|
1256
|
+
} finally {
|
|
1257
|
+
if (sk !== void 0)
|
|
1258
|
+
cleanBytes(sk);
|
|
1259
|
+
if (publicKeyHash !== void 0)
|
|
1260
|
+
cleanBytes(publicKeyHash);
|
|
1261
|
+
if (ownSeed)
|
|
1262
|
+
cleanBytes(s);
|
|
1263
|
+
}
|
|
1206
1264
|
},
|
|
1207
1265
|
getPublicKey: (secretKey) => {
|
|
1208
1266
|
const [_sk, publicKey, _publicKeyHash, _z] = secretCoder.decode(secretKey);
|
|
1209
1267
|
return Uint8Array.from(publicKey);
|
|
1210
1268
|
},
|
|
1211
|
-
encapsulate: (publicKey, msg
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1269
|
+
encapsulate: (publicKey, msg) => {
|
|
1270
|
+
const ownMsg = msg === void 0;
|
|
1271
|
+
const m = ownMsg ? randomBytes2(msgLen) : msg;
|
|
1272
|
+
let kr;
|
|
1273
|
+
try {
|
|
1274
|
+
abytesDoc(publicKey, lengths.publicKey, "publicKey");
|
|
1275
|
+
abytesDoc(m, msgLen, "message");
|
|
1276
|
+
validateModulus(publicKey, "encapsulate");
|
|
1277
|
+
kr = HASH512.create().update(m).update(HASH256(publicKey)).digest();
|
|
1278
|
+
const cipherText = KPKE.encrypt(publicKey, m, kr.subarray(32, 64));
|
|
1279
|
+
return {
|
|
1280
|
+
cipherText,
|
|
1281
|
+
sharedSecret: kr.subarray(0, 32)
|
|
1282
|
+
};
|
|
1283
|
+
} finally {
|
|
1284
|
+
if (kr !== void 0)
|
|
1285
|
+
cleanBytes(kr.subarray(32));
|
|
1286
|
+
if (ownMsg)
|
|
1287
|
+
cleanBytes(m);
|
|
1288
|
+
}
|
|
1222
1289
|
},
|
|
1223
1290
|
decapsulate: (cipherText, secretKey) => {
|
|
1224
1291
|
abytesDoc(secretKey, secretCoder.bytesLen, "secretKey");
|
|
@@ -1251,15 +1318,24 @@ function createKyber(opts2) {
|
|
|
1251
1318
|
const cached = KPKE.prepare(ek);
|
|
1252
1319
|
return Object.freeze({
|
|
1253
1320
|
publicKey: ek,
|
|
1254
|
-
encapsulate: (msg
|
|
1255
|
-
|
|
1256
|
-
const
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1321
|
+
encapsulate: (msg) => {
|
|
1322
|
+
const ownMsg = msg === void 0;
|
|
1323
|
+
const m = ownMsg ? randomBytes2(msgLen) : msg;
|
|
1324
|
+
let kr;
|
|
1325
|
+
try {
|
|
1326
|
+
abytesDoc(m, msgLen, "message");
|
|
1327
|
+
kr = HASH512.create().update(m).update(publicKeyHash).digest();
|
|
1328
|
+
const cipherText = cached.encrypt(m, kr.subarray(32, 64));
|
|
1329
|
+
return {
|
|
1330
|
+
cipherText,
|
|
1331
|
+
sharedSecret: kr.subarray(0, 32)
|
|
1332
|
+
};
|
|
1333
|
+
} finally {
|
|
1334
|
+
if (kr !== void 0)
|
|
1335
|
+
cleanBytes(kr.subarray(32));
|
|
1336
|
+
if (ownMsg)
|
|
1337
|
+
cleanBytes(m);
|
|
1338
|
+
}
|
|
1263
1339
|
},
|
|
1264
1340
|
decapsulate: (cipherText, secretKey) => {
|
|
1265
1341
|
abytesDoc(secretKey, secretCoder.bytesLen, "secretKey");
|
|
@@ -1300,10 +1376,16 @@ var ml_kem768 = /* @__PURE__ */ (() => mk(PARAMS[768]))();
|
|
|
1300
1376
|
var ml_kem1024 = /* @__PURE__ */ (() => mk(PARAMS[1024]))();
|
|
1301
1377
|
|
|
1302
1378
|
// node_modules/@noble/post-quantum/ml-dsa.js
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1379
|
+
var INTERNAL_SIG_OPT_KEYS = /* @__PURE__ */ Object.freeze([
|
|
1380
|
+
"extraEntropy",
|
|
1381
|
+
"externalMu"
|
|
1382
|
+
]);
|
|
1383
|
+
var INTERNAL_VER_OPT_KEYS = /* @__PURE__ */ Object.freeze(["externalMu"]);
|
|
1384
|
+
function validateInternalOpts(opts2, allowed) {
|
|
1385
|
+
const normalized = checkOptKeys(opts2, allowed);
|
|
1386
|
+
if (normalized.externalMu !== void 0)
|
|
1387
|
+
abool2(normalized.externalMu, "opts.externalMu");
|
|
1388
|
+
return normalized;
|
|
1307
1389
|
}
|
|
1308
1390
|
var N2 = 256;
|
|
1309
1391
|
var Q2 = 8380417;
|
|
@@ -1646,8 +1728,8 @@ function getDilithium(opts_) {
|
|
|
1646
1728
|
},
|
|
1647
1729
|
// NOTE: random is optional.
|
|
1648
1730
|
sign: (msg, secretKey, opts3 = {}) => {
|
|
1649
|
-
validateSigOpts(opts3);
|
|
1650
|
-
validateInternalOpts(opts3);
|
|
1731
|
+
opts3 = validateSigOpts(opts3, INTERNAL_SIG_OPT_KEYS);
|
|
1732
|
+
opts3 = validateInternalOpts(opts3, INTERNAL_SIG_OPT_KEYS);
|
|
1651
1733
|
const { extraEntropy: random, externalMu = false } = opts3;
|
|
1652
1734
|
if (externalMu)
|
|
1653
1735
|
abytesDoc(msg, CRH_BYTES, "mu");
|
|
@@ -1708,26 +1790,34 @@ function getDilithium(opts_) {
|
|
|
1708
1790
|
const cs1 = s1.map((i) => MultiplyNTTs2(i, cHat));
|
|
1709
1791
|
for (let i = 0; i < L; i++) {
|
|
1710
1792
|
polyAdd2(crystals2.NTT.decode(cs1[i]), y[i]);
|
|
1711
|
-
if (polyChknorm(cs1[i], GAMMA1 - BETA))
|
|
1793
|
+
if (polyChknorm(cs1[i], GAMMA1 - BETA)) {
|
|
1794
|
+
cleanBytes(cTilde, cs1, cHat, w1, w, z, y);
|
|
1712
1795
|
continue main_loop;
|
|
1796
|
+
}
|
|
1713
1797
|
}
|
|
1714
1798
|
let cnt = 0;
|
|
1715
1799
|
const h = [];
|
|
1716
1800
|
for (let i = 0; i < K; i++) {
|
|
1717
1801
|
const cs2 = crystals2.NTT.decode(MultiplyNTTs2(s2[i], cHat));
|
|
1718
1802
|
const r0 = polySub2(w[i], cs2).map(LowBits);
|
|
1719
|
-
if (polyChknorm(r0, GAMMA2 - BETA))
|
|
1803
|
+
if (polyChknorm(r0, GAMMA2 - BETA)) {
|
|
1804
|
+
cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h, cs2, r0);
|
|
1720
1805
|
continue main_loop;
|
|
1806
|
+
}
|
|
1721
1807
|
const ct0 = crystals2.NTT.decode(MultiplyNTTs2(t0[i], cHat));
|
|
1722
|
-
if (polyChknorm(ct0, GAMMA2))
|
|
1808
|
+
if (polyChknorm(ct0, GAMMA2)) {
|
|
1809
|
+
cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h, cs2, r0, ct0);
|
|
1723
1810
|
continue main_loop;
|
|
1811
|
+
}
|
|
1724
1812
|
polyAdd2(r0, ct0);
|
|
1725
1813
|
const hint = polyMakeHint(r0, w1[i]);
|
|
1726
1814
|
h.push(hint.v);
|
|
1727
1815
|
cnt += hint.cnt;
|
|
1728
1816
|
}
|
|
1729
|
-
if (cnt > OMEGA)
|
|
1817
|
+
if (cnt > OMEGA) {
|
|
1818
|
+
cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h);
|
|
1730
1819
|
continue;
|
|
1820
|
+
}
|
|
1731
1821
|
x256.clean();
|
|
1732
1822
|
const res = sigCoder.encode([cTilde, cs1, h]);
|
|
1733
1823
|
cleanBytes(cTilde, cs1, h, cHat, w1, w, z, y, rhoprime, s1, s2, t0, ...A);
|
|
@@ -1738,7 +1828,7 @@ function getDilithium(opts_) {
|
|
|
1738
1828
|
throw new Error("Unreachable code path reached, report this error");
|
|
1739
1829
|
},
|
|
1740
1830
|
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
1741
|
-
validateInternalOpts(opts3);
|
|
1831
|
+
opts3 = validateInternalOpts(opts3, INTERNAL_VER_OPT_KEYS);
|
|
1742
1832
|
const { externalMu = false } = opts3;
|
|
1743
1833
|
if (externalMu)
|
|
1744
1834
|
abytesDoc(msg, CRH_BYTES, "mu");
|
|
@@ -1793,16 +1883,19 @@ function getDilithium(opts_) {
|
|
|
1793
1883
|
lengths: internal.lengths,
|
|
1794
1884
|
getPublicKey: internal.getPublicKey,
|
|
1795
1885
|
sign: (msg, secretKey, opts3 = {}) => {
|
|
1796
|
-
validateSigOpts(opts3);
|
|
1886
|
+
opts3 = validateSigOpts(opts3);
|
|
1797
1887
|
const M = getMessage(msg, opts3.context);
|
|
1798
|
-
const res = internal.sign(M, secretKey,
|
|
1888
|
+
const res = internal.sign(M, secretKey, {
|
|
1889
|
+
extraEntropy: opts3.extraEntropy,
|
|
1890
|
+
externalMu: false
|
|
1891
|
+
});
|
|
1799
1892
|
cleanBytes(M);
|
|
1800
1893
|
return res;
|
|
1801
1894
|
},
|
|
1802
1895
|
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
1803
|
-
validateVerOpts(opts3);
|
|
1896
|
+
opts3 = validateVerOpts(opts3);
|
|
1804
1897
|
abytesDoc(sig, void 0, "signature");
|
|
1805
|
-
return internal.verify(sig, getMessage(msg, opts3.context), publicKey);
|
|
1898
|
+
return internal.verify(sig, getMessage(msg, opts3.context), publicKey, { externalMu: false });
|
|
1806
1899
|
},
|
|
1807
1900
|
prehash: (hash) => {
|
|
1808
1901
|
checkHash(hash, securityLevel);
|
|
@@ -1814,16 +1907,21 @@ function getDilithium(opts_) {
|
|
|
1814
1907
|
keygen: internal.keygen,
|
|
1815
1908
|
getPublicKey: internal.getPublicKey,
|
|
1816
1909
|
sign: (msg, secretKey, opts3 = {}) => {
|
|
1817
|
-
validateSigOpts(opts3);
|
|
1910
|
+
opts3 = validateSigOpts(opts3);
|
|
1818
1911
|
const M = getMessagePrehash(rawHash, msg, opts3.context);
|
|
1819
|
-
const res = internal.sign(M, secretKey,
|
|
1912
|
+
const res = internal.sign(M, secretKey, {
|
|
1913
|
+
extraEntropy: opts3.extraEntropy,
|
|
1914
|
+
externalMu: false
|
|
1915
|
+
});
|
|
1820
1916
|
cleanBytes(M);
|
|
1821
1917
|
return res;
|
|
1822
1918
|
},
|
|
1823
1919
|
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
1824
|
-
validateVerOpts(opts3);
|
|
1920
|
+
opts3 = validateVerOpts(opts3);
|
|
1825
1921
|
abytesDoc(sig, void 0, "signature");
|
|
1826
|
-
return internal.verify(sig, getMessagePrehash(rawHash, msg, opts3.context), publicKey
|
|
1922
|
+
return internal.verify(sig, getMessagePrehash(rawHash, msg, opts3.context), publicKey, {
|
|
1923
|
+
externalMu: false
|
|
1924
|
+
});
|
|
1827
1925
|
}
|
|
1828
1926
|
});
|
|
1829
1927
|
}
|
|
@@ -2463,6 +2561,8 @@ var sha512 = /* @__PURE__ */ createHasher(
|
|
|
2463
2561
|
);
|
|
2464
2562
|
|
|
2465
2563
|
// node_modules/@noble/post-quantum/slh-dsa.js
|
|
2564
|
+
var INTERNAL_SIG_OPT_KEYS2 = /* @__PURE__ */ Object.freeze(["extraEntropy"]);
|
|
2565
|
+
var INTERNAL_VER_OPT_KEYS2 = /* @__PURE__ */ Object.freeze([]);
|
|
2466
2566
|
var PARAMS3 = /* @__PURE__ */ (() => Object.freeze({
|
|
2467
2567
|
"128f": Object.freeze({ W: 16, N: 16, H: 66, D: 22, K: 33, A: 6, securityLevel: 128 }),
|
|
2468
2568
|
"128s": Object.freeze({ W: 16, N: 16, H: 63, D: 7, K: 14, A: 12, securityLevel: 128 }),
|
|
@@ -2533,8 +2633,16 @@ function gen(opts2, hashOpts_) {
|
|
|
2533
2633
|
OFFSET_HASH_ADDR += 10;
|
|
2534
2634
|
}
|
|
2535
2635
|
const setAddr = (opts3, addr = new Uint8Array(ADDR_BYTES)) => {
|
|
2536
|
-
const
|
|
2537
|
-
const
|
|
2636
|
+
const type = Object.hasOwn(opts3, "type") ? opts3.type : void 0;
|
|
2637
|
+
const height = Object.hasOwn(opts3, "height") ? opts3.height : void 0;
|
|
2638
|
+
const tree = Object.hasOwn(opts3, "tree") ? opts3.tree : void 0;
|
|
2639
|
+
const layer = Object.hasOwn(opts3, "layer") ? opts3.layer : void 0;
|
|
2640
|
+
const index = Object.hasOwn(opts3, "index") ? opts3.index : void 0;
|
|
2641
|
+
const chain = Object.hasOwn(opts3, "chain") ? opts3.chain : void 0;
|
|
2642
|
+
const hash = Object.hasOwn(opts3, "hash") ? opts3.hash : void 0;
|
|
2643
|
+
const keypair = Object.hasOwn(opts3, "keypair") ? opts3.keypair : void 0;
|
|
2644
|
+
const subtreeAddr = Object.hasOwn(opts3, "subtreeAddr") ? opts3.subtreeAddr : void 0;
|
|
2645
|
+
const keypairAddr = Object.hasOwn(opts3, "keypairAddr") ? opts3.keypairAddr : void 0;
|
|
2538
2646
|
if (height !== void 0)
|
|
2539
2647
|
addr[OFFSET_CHAIN_ADDR] = height;
|
|
2540
2648
|
if (layer !== void 0)
|
|
@@ -2735,7 +2843,7 @@ function gen(opts2, hashOpts_) {
|
|
|
2735
2843
|
return Uint8Array.from(pk);
|
|
2736
2844
|
},
|
|
2737
2845
|
sign: (msg, sk, opts3 = {}) => {
|
|
2738
|
-
validateSigOpts(opts3);
|
|
2846
|
+
opts3 = validateSigOpts(opts3, INTERNAL_SIG_OPT_KEYS2);
|
|
2739
2847
|
let { extraEntropy: random } = opts3;
|
|
2740
2848
|
const [skSeed, skPRF, pk] = secretCoder.decode(sk);
|
|
2741
2849
|
const [pkSeed, _] = publicCoder.decode(pk);
|
|
@@ -2793,7 +2901,8 @@ function gen(opts2, hashOpts_) {
|
|
|
2793
2901
|
cleanBytes(R, random, treeAddr, wotsAddr, forsLeaf, forsTreeAddr, indices, roots);
|
|
2794
2902
|
return SIG;
|
|
2795
2903
|
},
|
|
2796
|
-
verify: (sig, msg, publicKey) => {
|
|
2904
|
+
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
2905
|
+
validateVerOpts(opts3, INTERNAL_VER_OPT_KEYS2);
|
|
2797
2906
|
const [pkSeed, pubRoot] = publicCoder.decode(publicKey);
|
|
2798
2907
|
const pk = publicKey;
|
|
2799
2908
|
abytesDoc(sig, void 0, "signature");
|
|
@@ -2860,14 +2969,14 @@ function gen(opts2, hashOpts_) {
|
|
|
2860
2969
|
keygen: internal.keygen,
|
|
2861
2970
|
getPublicKey: internal.getPublicKey,
|
|
2862
2971
|
sign: (msg, secretKey, opts3 = {}) => {
|
|
2863
|
-
validateSigOpts(opts3);
|
|
2972
|
+
opts3 = validateSigOpts(opts3);
|
|
2864
2973
|
const M = getMessage(msg, opts3.context);
|
|
2865
|
-
const res = internal.sign(M, secretKey, opts3);
|
|
2974
|
+
const res = internal.sign(M, secretKey, { extraEntropy: opts3.extraEntropy });
|
|
2866
2975
|
cleanBytes(M);
|
|
2867
2976
|
return res;
|
|
2868
2977
|
},
|
|
2869
2978
|
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
2870
|
-
validateVerOpts(opts3);
|
|
2979
|
+
opts3 = validateVerOpts(opts3);
|
|
2871
2980
|
return internal.verify(sig, getMessage(msg, opts3.context), publicKey);
|
|
2872
2981
|
},
|
|
2873
2982
|
prehash: (hash) => {
|
|
@@ -2879,14 +2988,14 @@ function gen(opts2, hashOpts_) {
|
|
|
2879
2988
|
keygen: internal.keygen,
|
|
2880
2989
|
getPublicKey: internal.getPublicKey,
|
|
2881
2990
|
sign: (msg, secretKey, opts3 = {}) => {
|
|
2882
|
-
validateSigOpts(opts3);
|
|
2991
|
+
opts3 = validateSigOpts(opts3);
|
|
2883
2992
|
const M = getMessagePrehash(rawHash, msg, opts3.context);
|
|
2884
|
-
const res = internal.sign(M, secretKey, opts3);
|
|
2993
|
+
const res = internal.sign(M, secretKey, { extraEntropy: opts3.extraEntropy });
|
|
2885
2994
|
cleanBytes(M);
|
|
2886
2995
|
return res;
|
|
2887
2996
|
},
|
|
2888
2997
|
verify: (sig, msg, publicKey, opts3 = {}) => {
|
|
2889
|
-
validateVerOpts(opts3);
|
|
2998
|
+
opts3 = validateVerOpts(opts3);
|
|
2890
2999
|
return internal.verify(sig, getMessagePrehash(rawHash, msg, opts3.context), publicKey);
|
|
2891
3000
|
}
|
|
2892
3001
|
});
|
|
@@ -2931,7 +3040,7 @@ var genShake2 = () => (opts2) => (pubSeed, skSeed) => {
|
|
|
2931
3040
|
}
|
|
2932
3041
|
};
|
|
2933
3042
|
};
|
|
2934
|
-
var SHAKE_SIMPLE = /* @__PURE__ */ (() => ({ getContext: genShake2() }))();
|
|
3043
|
+
var SHAKE_SIMPLE = /* @__PURE__ */ (() => ({ isCompressed: false, getContext: genShake2() }))();
|
|
2935
3044
|
var slh_dsa_shake_128f = /* @__PURE__ */ (() => gen(PARAMS3["128f"], SHAKE_SIMPLE))();
|
|
2936
3045
|
var slh_dsa_shake_192f = /* @__PURE__ */ (() => gen(PARAMS3["192f"], SHAKE_SIMPLE))();
|
|
2937
3046
|
var slh_dsa_shake_256f = /* @__PURE__ */ (() => gen(PARAMS3["256f"], SHAKE_SIMPLE))();
|
package/lib/watcher.js
CHANGED
|
@@ -231,7 +231,7 @@ var AUTO_PROBE_POLL_FSTYPES = new Set([
|
|
|
231
231
|
"vboxsf",
|
|
232
232
|
]);
|
|
233
233
|
|
|
234
|
-
function _detectAutoMode(rootPath) {
|
|
234
|
+
function _detectAutoMode(rootPath, probe) {
|
|
235
235
|
// Sync probe — looks at the kernel's view of the mount carrying the
|
|
236
236
|
// watcher's root and decides whether fs.watch will deliver events.
|
|
237
237
|
// Three signals contribute, in priority order:
|
|
@@ -246,7 +246,21 @@ function _detectAutoMode(rootPath) {
|
|
|
246
246
|
// 3. Otherwise — fs.
|
|
247
247
|
//
|
|
248
248
|
// Returns { mode, reason, fsType, inContainer }.
|
|
249
|
-
|
|
249
|
+
// Injectable so the branches that only exist on a restricted Linux can be
|
|
250
|
+
// driven from any host. A rule about what happens when mountinfo cannot be
|
|
251
|
+
// read is untestable while reaching it requires unmounting /proc.
|
|
252
|
+
var platform = (probe && probe.platform) || process.platform;
|
|
253
|
+
var readEntries = (probe && probe.readEntries) ||
|
|
254
|
+
function () { return safeMountInfo.read(); };
|
|
255
|
+
// Injected for the same reason as readEntries, and for one more: "/.dockerenv"
|
|
256
|
+
// is drive-relative on Windows, so a direct probe there asks about C:\.dockerenv
|
|
257
|
+
// rather than about being in a container. It is only reached below the
|
|
258
|
+
// non-Linux return, but reaching a POSIX path through the injected reader is
|
|
259
|
+
// what keeps that ordering from being the only thing holding it up.
|
|
260
|
+
var exists = (probe && probe.exists) ||
|
|
261
|
+
function (p) { return nodeFs.existsSync(p); };
|
|
262
|
+
|
|
263
|
+
if (platform !== "linux") {
|
|
250
264
|
// macOS + Windows fs.watch backends use FSEvents + ReadDirectoryChangesW
|
|
251
265
|
// respectively, which DO deliver recursive events natively for
|
|
252
266
|
// operator-owned local filesystems. Containerized Linux is the
|
|
@@ -255,7 +269,7 @@ function _detectAutoMode(rootPath) {
|
|
|
255
269
|
}
|
|
256
270
|
|
|
257
271
|
var inContainer = false;
|
|
258
|
-
try { inContainer =
|
|
272
|
+
try { inContainer = exists("/.dockerenv"); }
|
|
259
273
|
catch (_e) { inContainer = false; }
|
|
260
274
|
|
|
261
275
|
// Route through b.safeMountInfo — single canonical parser that
|
|
@@ -263,13 +277,23 @@ function _detectAutoMode(rootPath) {
|
|
|
263
277
|
// mount check below. Pre-v0.11.6 this parsed inline; centralizing
|
|
264
278
|
// it means future container-escape / sealed-store / sandbox call
|
|
265
279
|
// sites inherit the discipline.
|
|
266
|
-
var entries =
|
|
280
|
+
var entries = readEntries();
|
|
281
|
+
// Not knowing which filesystem this is resolves toward polling, not toward
|
|
282
|
+
// fs.watch. On Linux mountinfo is always there, so failing to read it means
|
|
283
|
+
// /proc is unmounted or restricted — which is the containerized case this
|
|
284
|
+
// probe exists for, and the one where inotify is least likely to deliver.
|
|
285
|
+
// The two answers are not symmetric: polling costs stat calls the operator
|
|
286
|
+
// can see, while fs.watch on a filesystem that does not chain inotify drops
|
|
287
|
+
// events silently and nothing downstream can tell that it did.
|
|
267
288
|
if (entries === null || entries.length === 0) {
|
|
268
|
-
return { mode: "
|
|
289
|
+
return { mode: "poll", reason: "no-mountinfo", fsType: null, inContainer: inContainer };
|
|
269
290
|
}
|
|
270
291
|
var bestMatch = safeMountInfo.bestMatch(entries, rootPath);
|
|
271
292
|
if (!bestMatch) {
|
|
272
|
-
|
|
293
|
+
// Same reasoning: "/" matches every path on a healthy Linux, so no match
|
|
294
|
+
// means the mount table did not describe this root and its fstype is
|
|
295
|
+
// unknown rather than known-good.
|
|
296
|
+
return { mode: "poll", reason: "no-mount-match", fsType: null, inContainer: inContainer };
|
|
273
297
|
}
|
|
274
298
|
if (AUTO_PROBE_POLL_FSTYPES.has(bestMatch.fstype)) {
|
|
275
299
|
return {
|
|
@@ -687,4 +711,5 @@ module.exports = {
|
|
|
687
711
|
// create() enforces, instead of pinning hand-copied mirror constants.
|
|
688
712
|
MAX_IGNORE_PATTERN_LEN: MAX_IGNORE_PATTERN_LEN,
|
|
689
713
|
MAX_IGNORE_STAR_COUNT: MAX_IGNORE_STAR_COUNT,
|
|
714
|
+
_detectAutoModeForTest: _detectAutoMode,
|
|
690
715
|
};
|
package/lib/ws-client.js
CHANGED
|
@@ -361,7 +361,12 @@ class WsClient extends EventEmitter {
|
|
|
361
361
|
allowInternal: opts.allowInternal,
|
|
362
362
|
errorClass: WsClientError,
|
|
363
363
|
});
|
|
364
|
-
|
|
364
|
+
// `null` when the gate produced no pin at all, the array when it did —
|
|
365
|
+
// including an EMPTY one. An empty pin means the gate admitted no address,
|
|
366
|
+
// so there is nothing to connect to; treating it as "no pin" would hand the
|
|
367
|
+
// connect back to the ordinary resolver and re-open the rebinding window
|
|
368
|
+
// the pin exists to close.
|
|
369
|
+
this._ssrfPinnedIps = probe && Array.isArray(probe.ips) ? probe.ips : null;
|
|
365
370
|
this._dialParsed = dialParsed;
|
|
366
371
|
this._dialTlsOpts = dialTlsOpts;
|
|
367
372
|
}
|
|
@@ -405,12 +410,22 @@ class WsClient extends EventEmitter {
|
|
|
405
410
|
// private one between the check and the connect.
|
|
406
411
|
var pinnedIps = self._ssrfPinnedIps || null;
|
|
407
412
|
var lookup = null;
|
|
408
|
-
if (pinnedIps
|
|
413
|
+
if (pinnedIps) {
|
|
409
414
|
lookup = function (h, lookupOpts, cb) {
|
|
410
415
|
// Node's lookup callback signatures:
|
|
411
416
|
// (err, address, family) for legacy { all: false } (default)
|
|
412
417
|
// (err, addresses) for { all: true }
|
|
413
418
|
if (typeof lookupOpts === "function") { cb = lookupOpts; lookupOpts = {}; }
|
|
419
|
+
// An empty pin admits no address, so there is nothing to connect to.
|
|
420
|
+
// Answer the lookup with an error, which fails the dial through the
|
|
421
|
+
// socket's ordinary error path — reading `pinnedIps[0].address` here
|
|
422
|
+
// would throw a TypeError out of a lookup callback instead, which is a
|
|
423
|
+
// crash rather than a refusal.
|
|
424
|
+
if (pinnedIps.length === 0) {
|
|
425
|
+
var noneErr = new Error("ws.connect: the SSRF gate admitted no address for " + h);
|
|
426
|
+
noneErr.code = "ENOTFOUND";
|
|
427
|
+
return cb(noneErr);
|
|
428
|
+
}
|
|
414
429
|
var first = pinnedIps[0];
|
|
415
430
|
if (lookupOpts && lookupOpts.all) {
|
|
416
431
|
return cb(null, pinnedIps.map(function (ip) {
|
package/package.json
CHANGED
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:
|
|
5
|
+
"serialNumber": "urn:uuid:e4edcf7d-70cf-4995-b5eb-587eff95c384",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-08-
|
|
8
|
+
"timestamp": "2026-08-28T06:45:48.742Z",
|
|
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.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.18.56",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.18.
|
|
25
|
+
"version": "0.18.56",
|
|
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.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.18.56",
|
|
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.
|
|
57
|
+
"ref": "@blamejs/core@0.18.56",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|