i2pseeds 2026.8.31 → 2026.9.7
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/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "./shared/chunk-
|
|
3
|
+
SIG_TYPES2,
|
|
4
|
+
parseSu3Header2,
|
|
5
|
+
verifySu3Signature2,
|
|
6
|
+
createSu32,
|
|
7
|
+
extractNetDb2,
|
|
8
|
+
refreshSeeds2
|
|
9
|
+
} from "./shared/chunk-xmhnyzkb.js";
|
|
10
10
|
|
|
11
11
|
// src/cli.ts
|
|
12
12
|
import fs from "node:fs/promises";
|
|
@@ -48,12 +48,12 @@ async function main() {
|
|
|
48
48
|
process.exit(1);
|
|
49
49
|
}
|
|
50
50
|
const buf = await fs.readFile(filePath);
|
|
51
|
-
const header =
|
|
51
|
+
const header = parseSu3Header2(buf);
|
|
52
52
|
if (!header) {
|
|
53
53
|
console.error("Invalid SU3 file: Magic header not found");
|
|
54
54
|
process.exit(1);
|
|
55
55
|
}
|
|
56
|
-
const sigDetails =
|
|
56
|
+
const sigDetails = SIG_TYPES2[header.sigType];
|
|
57
57
|
console.log("SU3 Header Details:");
|
|
58
58
|
console.log(` Signer ID: ${header.signerId}`);
|
|
59
59
|
console.log(` Version: ${header.version}`);
|
|
@@ -74,7 +74,7 @@ async function main() {
|
|
|
74
74
|
}
|
|
75
75
|
const buf = await fs.readFile(filePath);
|
|
76
76
|
const certPem = await fs.readFile(certPath, "utf8");
|
|
77
|
-
const isValid =
|
|
77
|
+
const isValid = verifySu3Signature2(buf, certPem);
|
|
78
78
|
if (isValid) {
|
|
79
79
|
console.log("Signature is VALID");
|
|
80
80
|
process.exit(0);
|
|
@@ -92,7 +92,7 @@ async function main() {
|
|
|
92
92
|
process.exit(1);
|
|
93
93
|
}
|
|
94
94
|
const buf = await fs.readFile(filePath);
|
|
95
|
-
const header =
|
|
95
|
+
const header = parseSu3Header2(buf);
|
|
96
96
|
if (!header) {
|
|
97
97
|
console.error("Invalid SU3 file: Magic header not found");
|
|
98
98
|
process.exit(1);
|
|
@@ -157,7 +157,7 @@ async function main() {
|
|
|
157
157
|
}
|
|
158
158
|
const privateKeyPem = await fs.readFile(privateKeyPath, "utf8");
|
|
159
159
|
console.log(`Packaging & signing SU3 file (signer: ${signerId}, sigType: ${sigType})...`);
|
|
160
|
-
const su3Buf =
|
|
160
|
+
const su3Buf = createSu32({
|
|
161
161
|
content,
|
|
162
162
|
version,
|
|
163
163
|
signerId,
|
|
@@ -191,7 +191,7 @@ async function main() {
|
|
|
191
191
|
if (doRefresh) {
|
|
192
192
|
seedsDir = await fs.mkdtemp(path.join(os.tmpdir(), "su3-refresh-"));
|
|
193
193
|
console.log("Downloading fresh seeds from reseed servers...");
|
|
194
|
-
const saved = await
|
|
194
|
+
const saved = await refreshSeeds2(servers, seedsDir);
|
|
195
195
|
if (saved.length === 0) {
|
|
196
196
|
console.error("Could not download any fresh seeds. Falling back to bundled seeds.");
|
|
197
197
|
seedsDir = bundledSeedsDir;
|
|
@@ -208,7 +208,7 @@ async function main() {
|
|
|
208
208
|
} catch {
|
|
209
209
|
crtDir = path.join(__dirname2, "../src/crt");
|
|
210
210
|
}
|
|
211
|
-
const result = await
|
|
211
|
+
const result = await extractNetDb2(seedsDir, targetDir, crtDir, servers);
|
|
212
212
|
console.log(`Successfully extracted ${result.count} router entries into ./netdb`);
|
|
213
213
|
} catch (error) {
|
|
214
214
|
if (error.code === "ENOENT") {
|
|
Binary file
|
|
Binary file
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "./shared/chunk-
|
|
2
|
+
ZIP_MAGIC2,
|
|
3
|
+
SIG_TYPES2,
|
|
4
|
+
parseSu3Header2,
|
|
5
|
+
signerIdToCertFile2,
|
|
6
|
+
verifySu3Signature2,
|
|
7
|
+
createSu32,
|
|
8
|
+
extractZipFromSu32,
|
|
9
|
+
extractNetDb2,
|
|
10
|
+
refreshSeeds2
|
|
11
|
+
} from "./shared/chunk-xmhnyzkb.js";
|
|
12
12
|
export {
|
|
13
|
-
SIG_TYPES,
|
|
14
|
-
ZIP_MAGIC,
|
|
15
|
-
createSu3,
|
|
16
|
-
extractNetDb,
|
|
17
|
-
extractZipFromSu3,
|
|
18
|
-
parseSu3Header,
|
|
19
|
-
refreshSeeds,
|
|
20
|
-
signerIdToCertFile,
|
|
21
|
-
verifySu3Signature
|
|
13
|
+
SIG_TYPES2 as SIG_TYPES,
|
|
14
|
+
ZIP_MAGIC2 as ZIP_MAGIC,
|
|
15
|
+
createSu32 as createSu3,
|
|
16
|
+
extractNetDb2 as extractNetDb,
|
|
17
|
+
extractZipFromSu32 as extractZipFromSu3,
|
|
18
|
+
parseSu3Header2 as parseSu3Header,
|
|
19
|
+
refreshSeeds2 as refreshSeeds,
|
|
20
|
+
signerIdToCertFile2 as signerIdToCertFile,
|
|
21
|
+
verifySu3Signature2 as verifySu3Signature
|
|
22
22
|
};
|
|
@@ -3,8 +3,8 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import AdmZip from "adm-zip";
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var ZIP_MAGIC2 = Buffer.from([80, 75, 3, 4]);
|
|
7
|
+
var SIG_TYPES2 = {
|
|
8
8
|
0: {
|
|
9
9
|
name: "DSA-SHA1",
|
|
10
10
|
hash: "SHA1",
|
|
@@ -34,7 +34,7 @@ var SIG_TYPES = {
|
|
|
34
34
|
6: { name: "RSA-SHA512-4096", hash: "SHA512", sigLength: 512 },
|
|
35
35
|
8: { name: "EdDSA-SHA512-Ed25519ph", hash: null, sigLength: 64 }
|
|
36
36
|
};
|
|
37
|
-
function
|
|
37
|
+
function parseSu3Header2(buf) {
|
|
38
38
|
if (buf.length < 40)
|
|
39
39
|
return null;
|
|
40
40
|
const magic = buf.subarray(0, 6).toString("ascii");
|
|
@@ -62,14 +62,14 @@ function parseSu3Header(buf) {
|
|
|
62
62
|
signerId
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
-
function
|
|
65
|
+
function signerIdToCertFile2(signerId) {
|
|
66
66
|
return `${signerId.replace("@", "_at_")}.crt`;
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
const header =
|
|
68
|
+
function verifySu3Signature2(su3Buffer, certPem) {
|
|
69
|
+
const header = parseSu3Header2(su3Buffer);
|
|
70
70
|
if (!header)
|
|
71
71
|
return false;
|
|
72
|
-
const sigTypeDetails =
|
|
72
|
+
const sigTypeDetails = SIG_TYPES2[header.sigType];
|
|
73
73
|
if (!sigTypeDetails) {
|
|
74
74
|
console.error(`Unknown SU3 signature type: ${header.sigType}`);
|
|
75
75
|
return false;
|
|
@@ -94,8 +94,8 @@ function verifySu3Signature(su3Buffer, certPem) {
|
|
|
94
94
|
return false;
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
function
|
|
98
|
-
const sigTypeDetails =
|
|
97
|
+
function createSu32(params) {
|
|
98
|
+
const sigTypeDetails = SIG_TYPES2[params.sigType];
|
|
99
99
|
if (!sigTypeDetails) {
|
|
100
100
|
throw new Error(`Unsupported signature type: ${params.sigType}`);
|
|
101
101
|
}
|
|
@@ -148,13 +148,13 @@ function createSu3(params) {
|
|
|
148
148
|
}
|
|
149
149
|
return Buffer.concat([signedData, signature]);
|
|
150
150
|
}
|
|
151
|
-
function
|
|
152
|
-
const idx = su3Buffer.indexOf(
|
|
151
|
+
function extractZipFromSu32(su3Buffer) {
|
|
152
|
+
const idx = su3Buffer.indexOf(ZIP_MAGIC2);
|
|
153
153
|
if (idx === -1)
|
|
154
154
|
return null;
|
|
155
155
|
return su3Buffer.subarray(idx);
|
|
156
156
|
}
|
|
157
|
-
async function
|
|
157
|
+
async function extractNetDb2(seedsDir, targetDir, crtDir, servers) {
|
|
158
158
|
const dirEntries = await fs.readdir(seedsDir);
|
|
159
159
|
const su3Files = dirEntries.filter((f) => f.endsWith(".su3"));
|
|
160
160
|
if (su3Files.length === 0) {
|
|
@@ -165,7 +165,7 @@ async function extractNetDb(seedsDir, targetDir, crtDir, servers) {
|
|
|
165
165
|
for (const su3File of su3Files) {
|
|
166
166
|
const raw = await fs.readFile(path.join(seedsDir, su3File));
|
|
167
167
|
if (crtDir && servers) {
|
|
168
|
-
const header =
|
|
168
|
+
const header = parseSu3Header2(raw);
|
|
169
169
|
if (!header) {
|
|
170
170
|
console.error(`Skipping ${su3File}: invalid SU3 header`);
|
|
171
171
|
continue;
|
|
@@ -185,7 +185,7 @@ async function extractNetDb(seedsDir, targetDir, crtDir, servers) {
|
|
|
185
185
|
certFileName = `${certFileName}.crt`;
|
|
186
186
|
}
|
|
187
187
|
} else {
|
|
188
|
-
certFileName =
|
|
188
|
+
certFileName = signerIdToCertFile2(header.signerId);
|
|
189
189
|
}
|
|
190
190
|
let certPem;
|
|
191
191
|
try {
|
|
@@ -194,14 +194,14 @@ async function extractNetDb(seedsDir, targetDir, crtDir, servers) {
|
|
|
194
194
|
console.error(`Skipping ${su3File}: cert not found (${certFileName})`);
|
|
195
195
|
continue;
|
|
196
196
|
}
|
|
197
|
-
const sigValid =
|
|
197
|
+
const sigValid = verifySu3Signature2(raw, certPem);
|
|
198
198
|
if (sigValid) {
|
|
199
199
|
console.log(`✓ ${su3File} verified (signer: ${header.signerId})`);
|
|
200
200
|
} else {
|
|
201
201
|
console.warn(`⚠ ${su3File}: signature mismatch (signer: ${header.signerId}) — cert may have rotated, proceeding`);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
const zipPayload =
|
|
204
|
+
const zipPayload = extractZipFromSu32(raw);
|
|
205
205
|
if (!zipPayload) {
|
|
206
206
|
console.error(`Skipping ${su3File}: no ZIP payload found`);
|
|
207
207
|
continue;
|
|
@@ -222,7 +222,7 @@ async function extractNetDb(seedsDir, targetDir, crtDir, servers) {
|
|
|
222
222
|
}
|
|
223
223
|
return { count: written.length, files: written };
|
|
224
224
|
}
|
|
225
|
-
async function
|
|
225
|
+
async function refreshSeeds2(servers, outputDir, timeoutMs = 1e4) {
|
|
226
226
|
await fs.mkdir(outputDir, { recursive: true });
|
|
227
227
|
const saved = [];
|
|
228
228
|
for (const { url } of servers) {
|
|
@@ -255,4 +255,4 @@ async function refreshSeeds(servers, outputDir, timeoutMs = 1e4) {
|
|
|
255
255
|
return saved;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
export {
|
|
258
|
+
export { ZIP_MAGIC2, SIG_TYPES2, parseSu3Header2, signerIdToCertFile2, verifySu3Signature2, createSu32, extractZipFromSu32, extractNetDb2, refreshSeeds2 };
|
package/package.json
CHANGED