@drop2p/cli 0.1.0
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/README.md +94 -0
- package/dist/cli.js +1248 -0
- package/dist/wasm/drop2p_crypto_wasm.cjs +326 -0
- package/dist/wasm/drop2p_crypto_wasm_bg.wasm +0 -0
- package/package.json +36 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/* @ts-self-types="./drop2p_crypto_wasm.d.ts" */
|
|
2
|
+
|
|
3
|
+
//#region exports
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One side of a SPAKE2 exchange.
|
|
7
|
+
*/
|
|
8
|
+
class Spake2Session {
|
|
9
|
+
__destroy_into_raw() {
|
|
10
|
+
const ptr = this.__wbg_ptr;
|
|
11
|
+
this.__wbg_ptr = 0;
|
|
12
|
+
Spake2SessionFinalization.unregister(this);
|
|
13
|
+
return ptr;
|
|
14
|
+
}
|
|
15
|
+
free() {
|
|
16
|
+
const ptr = this.__destroy_into_raw();
|
|
17
|
+
wasm.__wbg_spake2session_free(ptr, 0);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Complete the exchange using the peer's message, returning the shared key.
|
|
21
|
+
* A mismatched password yields a *different* key (not an error) — detection
|
|
22
|
+
* happens later when the first AEAD frame fails to authenticate.
|
|
23
|
+
* @param {Uint8Array} inbound
|
|
24
|
+
* @returns {Uint8Array}
|
|
25
|
+
*/
|
|
26
|
+
finish(inbound) {
|
|
27
|
+
if (this.__wbg_ptr == 0) throw new Error('Attempt to use a moved value');
|
|
28
|
+
_assertNum(this.__wbg_ptr);
|
|
29
|
+
const ptr0 = passArray8ToWasm0(inbound, wasm.__wbindgen_malloc);
|
|
30
|
+
const len0 = WASM_VECTOR_LEN;
|
|
31
|
+
const ret = wasm.spake2session_finish(this.__wbg_ptr, ptr0, len0);
|
|
32
|
+
if (ret[3]) {
|
|
33
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
34
|
+
}
|
|
35
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
36
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
37
|
+
return v2;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Begin a symmetric SPAKE2 exchange. Both peers call this with the same
|
|
41
|
+
* `password` (the code secret) and the same `identity` (binds the channel,
|
|
42
|
+
* e.g. `"DSTP/1:<channel>"`).
|
|
43
|
+
* @param {Uint8Array} password
|
|
44
|
+
* @param {Uint8Array} identity
|
|
45
|
+
*/
|
|
46
|
+
constructor(password, identity) {
|
|
47
|
+
const ptr0 = passArray8ToWasm0(password, wasm.__wbindgen_malloc);
|
|
48
|
+
const len0 = WASM_VECTOR_LEN;
|
|
49
|
+
const ptr1 = passArray8ToWasm0(identity, wasm.__wbindgen_malloc);
|
|
50
|
+
const len1 = WASM_VECTOR_LEN;
|
|
51
|
+
const ret = wasm.spake2session_new(ptr0, len0, ptr1, len1);
|
|
52
|
+
this.__wbg_ptr = ret;
|
|
53
|
+
Spake2SessionFinalization.register(this, this.__wbg_ptr, this);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The message to send to the peer over the (already DTLS-encrypted) channel.
|
|
58
|
+
* @returns {Uint8Array}
|
|
59
|
+
*/
|
|
60
|
+
outboundMessage() {
|
|
61
|
+
if (this.__wbg_ptr == 0) throw new Error('Attempt to use a moved value');
|
|
62
|
+
_assertNum(this.__wbg_ptr);
|
|
63
|
+
const ret = wasm.spake2session_outboundMessage(this.__wbg_ptr);
|
|
64
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
65
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
66
|
+
return v1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (Symbol.dispose) Spake2Session.prototype[Symbol.dispose] = Spake2Session.prototype.free;
|
|
70
|
+
exports.Spake2Session = Spake2Session;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Derive a 32-byte key from a passphrase using Argon2id (the Ultimate
|
|
74
|
+
* "double encryption" layer). Parameters follow the OWASP baseline
|
|
75
|
+
* (m = 19 MiB, t = 2, p = 1); the caller supplies a random per-transfer salt
|
|
76
|
+
* and feeds the result into AES-256-GCM on the JS side, layered *inside* the
|
|
77
|
+
* code-derived DSTP key so the file is encrypted with two independent secrets.
|
|
78
|
+
* @param {Uint8Array} passphrase
|
|
79
|
+
* @param {Uint8Array} salt
|
|
80
|
+
* @returns {Uint8Array}
|
|
81
|
+
*/
|
|
82
|
+
function argon2idDerive(passphrase, salt) {
|
|
83
|
+
const ptr0 = passArray8ToWasm0(passphrase, wasm.__wbindgen_malloc);
|
|
84
|
+
const len0 = WASM_VECTOR_LEN;
|
|
85
|
+
const ptr1 = passArray8ToWasm0(salt, wasm.__wbindgen_malloc);
|
|
86
|
+
const len1 = WASM_VECTOR_LEN;
|
|
87
|
+
const ret = wasm.argon2idDerive(ptr0, len0, ptr1, len1);
|
|
88
|
+
if (ret[3]) {
|
|
89
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
90
|
+
}
|
|
91
|
+
var v3 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
92
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
93
|
+
return v3;
|
|
94
|
+
}
|
|
95
|
+
exports.argon2idDerive = argon2idDerive;
|
|
96
|
+
|
|
97
|
+
//#endregion
|
|
98
|
+
|
|
99
|
+
//#region wasm imports
|
|
100
|
+
function __wbg_get_imports() {
|
|
101
|
+
const import0 = {
|
|
102
|
+
__proto__: null,
|
|
103
|
+
__wbg_Error_92b29b0548f8b746: function() { return logError(function (arg0, arg1) {
|
|
104
|
+
const ret = Error(getStringFromWasm0(arg0, arg1));
|
|
105
|
+
return ret;
|
|
106
|
+
}, arguments); },
|
|
107
|
+
__wbg___wbindgen_is_function_1ff95bcc5517c252: function(arg0) {
|
|
108
|
+
const ret = typeof(arg0) === 'function';
|
|
109
|
+
_assertBoolean(ret);
|
|
110
|
+
return ret;
|
|
111
|
+
},
|
|
112
|
+
__wbg___wbindgen_is_object_a27215656b807791: function(arg0) {
|
|
113
|
+
const val = arg0;
|
|
114
|
+
const ret = typeof(val) === 'object' && val !== null;
|
|
115
|
+
_assertBoolean(ret);
|
|
116
|
+
return ret;
|
|
117
|
+
},
|
|
118
|
+
__wbg___wbindgen_is_string_ea5e6cc2e4141dfe: function(arg0) {
|
|
119
|
+
const ret = typeof(arg0) === 'string';
|
|
120
|
+
_assertBoolean(ret);
|
|
121
|
+
return ret;
|
|
122
|
+
},
|
|
123
|
+
__wbg___wbindgen_is_undefined_c05833b95a3cf397: function(arg0) {
|
|
124
|
+
const ret = arg0 === undefined;
|
|
125
|
+
_assertBoolean(ret);
|
|
126
|
+
return ret;
|
|
127
|
+
},
|
|
128
|
+
__wbg___wbindgen_throw_344f42d3211c4765: function(arg0, arg1) {
|
|
129
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
130
|
+
},
|
|
131
|
+
__wbg_call_a6e5c5dce5018821: function() { return handleError(function (arg0, arg1, arg2) {
|
|
132
|
+
const ret = arg0.call(arg1, arg2);
|
|
133
|
+
return ret;
|
|
134
|
+
}, arguments); },
|
|
135
|
+
__wbg_crypto_38df2bab126b63dc: function() { return logError(function (arg0) {
|
|
136
|
+
const ret = arg0.crypto;
|
|
137
|
+
return ret;
|
|
138
|
+
}, arguments); },
|
|
139
|
+
__wbg_getRandomValues_c44a50d8cfdaebeb: function() { return handleError(function (arg0, arg1) {
|
|
140
|
+
arg0.getRandomValues(arg1);
|
|
141
|
+
}, arguments); },
|
|
142
|
+
__wbg_length_1f0964f4a5e2c6d8: function() { return logError(function (arg0) {
|
|
143
|
+
const ret = arg0.length;
|
|
144
|
+
_assertNum(ret);
|
|
145
|
+
return ret;
|
|
146
|
+
}, arguments); },
|
|
147
|
+
__wbg_msCrypto_bd5a034af96bcba6: function() { return logError(function (arg0) {
|
|
148
|
+
const ret = arg0.msCrypto;
|
|
149
|
+
return ret;
|
|
150
|
+
}, arguments); },
|
|
151
|
+
__wbg_new_with_length_e6785c33c8e4cce8: function() { return logError(function (arg0) {
|
|
152
|
+
const ret = new Uint8Array(arg0 >>> 0);
|
|
153
|
+
return ret;
|
|
154
|
+
}, arguments); },
|
|
155
|
+
__wbg_node_84ea875411254db1: function() { return logError(function (arg0) {
|
|
156
|
+
const ret = arg0.node;
|
|
157
|
+
return ret;
|
|
158
|
+
}, arguments); },
|
|
159
|
+
__wbg_process_44c7a14e11e9f69e: function() { return logError(function (arg0) {
|
|
160
|
+
const ret = arg0.process;
|
|
161
|
+
return ret;
|
|
162
|
+
}, arguments); },
|
|
163
|
+
__wbg_prototypesetcall_4770620bbe4688a0: function() { return logError(function (arg0, arg1, arg2) {
|
|
164
|
+
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
165
|
+
}, arguments); },
|
|
166
|
+
__wbg_randomFillSync_6c25eac9869eb53c: function() { return handleError(function (arg0, arg1) {
|
|
167
|
+
arg0.randomFillSync(arg1);
|
|
168
|
+
}, arguments); },
|
|
169
|
+
__wbg_require_b4edbdcf3e2a1ef0: function() { return handleError(function () {
|
|
170
|
+
const ret = module.require;
|
|
171
|
+
return ret;
|
|
172
|
+
}, arguments); },
|
|
173
|
+
__wbg_static_accessor_GLOBAL_4ef717fb391d88b7: function() { return logError(function () {
|
|
174
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
175
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
176
|
+
}, arguments); },
|
|
177
|
+
__wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4: function() { return logError(function () {
|
|
178
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
179
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
180
|
+
}, arguments); },
|
|
181
|
+
__wbg_static_accessor_SELF_146583524fe1469b: function() { return logError(function () {
|
|
182
|
+
const ret = typeof self === 'undefined' ? null : self;
|
|
183
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
184
|
+
}, arguments); },
|
|
185
|
+
__wbg_static_accessor_WINDOW_f2829a2234d7819e: function() { return logError(function () {
|
|
186
|
+
const ret = typeof window === 'undefined' ? null : window;
|
|
187
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
188
|
+
}, arguments); },
|
|
189
|
+
__wbg_subarray_3ed232c8a6baee09: function() { return logError(function (arg0, arg1, arg2) {
|
|
190
|
+
const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
|
|
191
|
+
return ret;
|
|
192
|
+
}, arguments); },
|
|
193
|
+
__wbg_versions_276b2795b1c6a219: function() { return logError(function (arg0) {
|
|
194
|
+
const ret = arg0.versions;
|
|
195
|
+
return ret;
|
|
196
|
+
}, arguments); },
|
|
197
|
+
__wbindgen_cast_0000000000000001: function() { return logError(function (arg0, arg1) {
|
|
198
|
+
// Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
|
|
199
|
+
const ret = getArrayU8FromWasm0(arg0, arg1);
|
|
200
|
+
return ret;
|
|
201
|
+
}, arguments); },
|
|
202
|
+
__wbindgen_cast_0000000000000002: function() { return logError(function (arg0, arg1) {
|
|
203
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
204
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
205
|
+
return ret;
|
|
206
|
+
}, arguments); },
|
|
207
|
+
__wbindgen_init_externref_table: function() {
|
|
208
|
+
const table = wasm.__wbindgen_externrefs;
|
|
209
|
+
const offset = table.grow(4);
|
|
210
|
+
table.set(0, undefined);
|
|
211
|
+
table.set(offset + 0, undefined);
|
|
212
|
+
table.set(offset + 1, null);
|
|
213
|
+
table.set(offset + 2, true);
|
|
214
|
+
table.set(offset + 3, false);
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
return {
|
|
218
|
+
__proto__: null,
|
|
219
|
+
"./drop2p_crypto_wasm_bg.js": import0,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
const Spake2SessionFinalization = (typeof FinalizationRegistry === 'undefined')
|
|
226
|
+
? { register: () => {}, unregister: () => {} }
|
|
227
|
+
: new FinalizationRegistry(ptr => wasm.__wbg_spake2session_free(ptr, 1));
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
//#region intrinsics
|
|
231
|
+
function addToExternrefTable0(obj) {
|
|
232
|
+
const idx = wasm.__externref_table_alloc();
|
|
233
|
+
wasm.__wbindgen_externrefs.set(idx, obj);
|
|
234
|
+
return idx;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function _assertBoolean(n) {
|
|
238
|
+
if (typeof(n) !== 'boolean') {
|
|
239
|
+
throw new Error(`expected a boolean argument, found ${typeof(n)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function _assertNum(n) {
|
|
244
|
+
if (typeof(n) !== 'number') throw new Error(`expected a number argument, found ${typeof(n)}`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
248
|
+
ptr = ptr >>> 0;
|
|
249
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function getStringFromWasm0(ptr, len) {
|
|
253
|
+
return decodeText(ptr >>> 0, len);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
let cachedUint8ArrayMemory0 = null;
|
|
257
|
+
function getUint8ArrayMemory0() {
|
|
258
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
259
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
260
|
+
}
|
|
261
|
+
return cachedUint8ArrayMemory0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function handleError(f, args) {
|
|
265
|
+
try {
|
|
266
|
+
return f.apply(this, args);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
const idx = addToExternrefTable0(e);
|
|
269
|
+
wasm.__wbindgen_exn_store(idx);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function isLikeNone(x) {
|
|
274
|
+
return x === undefined || x === null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function logError(f, args) {
|
|
278
|
+
try {
|
|
279
|
+
return f.apply(this, args);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
let error = (function () {
|
|
282
|
+
try {
|
|
283
|
+
return e instanceof Error ? `${e.message}\n\nStack:\n${e.stack}` : e.toString();
|
|
284
|
+
} catch(_) {
|
|
285
|
+
return "<failed to stringify thrown value>";
|
|
286
|
+
}
|
|
287
|
+
}());
|
|
288
|
+
console.error("wasm-bindgen: imported JS function that was not marked as `catch` threw an error:", error);
|
|
289
|
+
throw e;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
294
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
295
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
296
|
+
WASM_VECTOR_LEN = arg.length;
|
|
297
|
+
return ptr;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function takeFromExternrefTable0(idx) {
|
|
301
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
302
|
+
wasm.__externref_table_dealloc(idx);
|
|
303
|
+
return value;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
307
|
+
cachedTextDecoder.decode();
|
|
308
|
+
function decodeText(ptr, len) {
|
|
309
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
let WASM_VECTOR_LEN = 0;
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
//#endregion
|
|
316
|
+
|
|
317
|
+
//#region wasm loading
|
|
318
|
+
const wasmPath = `${__dirname}/drop2p_crypto_wasm_bg.wasm`;
|
|
319
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
320
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
321
|
+
let wasmInstance = new WebAssembly.Instance(wasmModule, __wbg_get_imports());
|
|
322
|
+
let wasm = wasmInstance.exports;
|
|
323
|
+
wasm.__wbindgen_start();
|
|
324
|
+
|
|
325
|
+
//#endregion
|
|
326
|
+
exports.__wasm = wasm;
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drop2p/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Drop2p CLI — a zero-storage, end-to-end-encrypted file transfer peer for the terminal.",
|
|
6
|
+
"bin": {
|
|
7
|
+
"drop2p": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "tsx src/cli.ts",
|
|
18
|
+
"build": "node build.mjs",
|
|
19
|
+
"prepack": "node build.mjs",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"node-datachannel": "^0.32.3",
|
|
24
|
+
"qrcode-terminal": "^0.12.0",
|
|
25
|
+
"ws": "^8.18.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@drop2p/protocol": "workspace:*",
|
|
29
|
+
"@drop2p/transfer-core": "workspace:*",
|
|
30
|
+
"@types/node": "^22.10.2",
|
|
31
|
+
"@types/ws": "^8.5.13",
|
|
32
|
+
"esbuild": "^0.24.0",
|
|
33
|
+
"tsx": "^4.19.2",
|
|
34
|
+
"typescript": "^5.7.2"
|
|
35
|
+
}
|
|
36
|
+
}
|