@interop/did-cli 0.8.0 → 0.9.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +195 -1
  3. package/dist/commands/did.d.ts.map +1 -1
  4. package/dist/commands/did.js +25 -6
  5. package/dist/commands/did.js.map +1 -1
  6. package/dist/commands/edv.d.ts +63 -0
  7. package/dist/commands/edv.d.ts.map +1 -0
  8. package/dist/commands/edv.js +627 -0
  9. package/dist/commands/edv.js.map +1 -0
  10. package/dist/commands/key.d.ts.map +1 -1
  11. package/dist/commands/key.js +44 -8
  12. package/dist/commands/key.js.map +1 -1
  13. package/dist/edv/core.d.ts +60 -0
  14. package/dist/edv/core.d.ts.map +1 -0
  15. package/dist/edv/core.js +75 -0
  16. package/dist/edv/core.js.map +1 -0
  17. package/dist/edv/document.d.ts +25 -0
  18. package/dist/edv/document.d.ts.map +1 -0
  19. package/dist/edv/document.js +19 -0
  20. package/dist/edv/document.js.map +1 -0
  21. package/dist/edv/hmac.d.ts +26 -0
  22. package/dist/edv/hmac.d.ts.map +1 -0
  23. package/dist/edv/hmac.js +67 -0
  24. package/dist/edv/hmac.js.map +1 -0
  25. package/dist/edv/recipients.d.ts +65 -0
  26. package/dist/edv/recipients.d.ts.map +1 -0
  27. package/dist/edv/recipients.js +253 -0
  28. package/dist/edv/recipients.js.map +1 -0
  29. package/dist/edv/stream.d.ts +69 -0
  30. package/dist/edv/stream.d.ts.map +1 -0
  31. package/dist/edv/stream.js +169 -0
  32. package/dist/edv/stream.js.map +1 -0
  33. package/dist/index.js +2 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/meta.d.ts +1 -0
  36. package/dist/meta.d.ts.map +1 -1
  37. package/dist/meta.js +1 -1
  38. package/dist/meta.js.map +1 -1
  39. package/dist/storage.d.ts +6 -4
  40. package/dist/storage.d.ts.map +1 -1
  41. package/dist/storage.js +6 -5
  42. package/dist/storage.js.map +1 -1
  43. package/dist/was/io.d.ts +14 -0
  44. package/dist/was/io.d.ts.map +1 -1
  45. package/dist/was/io.js +20 -7
  46. package/dist/was/io.js.map +1 -1
  47. package/package.json +6 -4
@@ -0,0 +1,627 @@
1
+ /**
2
+ * `edv` command -- encrypt to and decrypt from X25519 recipients using the
3
+ * EDV / minimal-cipher serialization.
4
+ *
5
+ * Public-key (key-agreement) encryption only: recipients are one or more X25519
6
+ * public keys, given as a raw `publicKeyMultibase`, a wallet key
7
+ * fingerprint/handle, a DID / DID URL, or a key-document JSON file. Three output
8
+ * shapes:
9
+ * - default -- a single raw JWE (the `jwe` field of an EDV Document), to stdout
10
+ * or an `-o` file (convention `*.jwe.json`); Layer 1.
11
+ * - `--document` -- a full EDV Document envelope `{ id, sequence, indexed, jwe }`
12
+ * (convention `*.edvdoc.json`), encrypting the input as the document
13
+ * `content`; Layer 2, Phase 1.
14
+ * - `--stream` -- a bundle directory (convention `*.edvdoc/`) whose
15
+ * `document.json` carries a `stream: { sequence, chunks }` descriptor and
16
+ * whose `chunks/<index>.jwe.json` hold the input encrypted as fixed-size
17
+ * chunks; Layer 2, Phase 2.
18
+ * In `--document`/`--stream` mode, `--index` blinds indexable attributes into
19
+ * the envelope's `indexed` array with a wallet HMAC key (Layer 2, Phase 3).
20
+ *
21
+ * The EDV Document envelope (and its blinded `indexed` array) is assembled and
22
+ * unwrapped by `@interop/edv-client`'s `EdvClientCore` via `../edv/core.ts`.
23
+ *
24
+ * Data goes to stdout, diagnostics to stderr. Exit codes: 0 success, 1
25
+ * decryption failure (wrong key / not a recipient), 2 input error (no
26
+ * recipient, unresolvable recipient/key, malformed input).
27
+ */
28
+ import { stat } from 'node:fs/promises';
29
+ import { Command, InvalidArgumentError } from 'commander';
30
+ import { Cipher } from '@interop/minimal-cipher';
31
+ import { readInputBytes, writeBytesOutput, writeJsonOutput } from '../was/io.js';
32
+ import { runAndExit } from './was/shared.js';
33
+ import { autoSelectKeyAgreementKey, loadKeyAgreementKey, resolveRecipient, resolveRecipientFile } from '../edv/recipients.js';
34
+ import { isEncryptedDocument } from '../edv/document.js';
35
+ import { decryptDocument, encryptDocument } from '../edv/core.js';
36
+ import { resolveHmac } from '../edv/hmac.js';
37
+ import { decryptChunks, encryptToChunks, readDocumentBundle, writeDocumentBundle } from '../edv/stream.js';
38
+ /**
39
+ * Collect a repeatable option value into an array (commander reducer).
40
+ *
41
+ * @param value {string}
42
+ * @param previous {string[]}
43
+ * @returns {string[]}
44
+ */
45
+ function collect(value, previous) {
46
+ return previous.concat(value);
47
+ }
48
+ /**
49
+ * Parse and validate the `--chunk-size` option (a positive integer of bytes).
50
+ *
51
+ * @param value {string}
52
+ * @returns {number}
53
+ */
54
+ function parseChunkSize(value) {
55
+ const bytes = Number(value);
56
+ if (!Number.isInteger(bytes) || bytes <= 0) {
57
+ throw new InvalidArgumentError('--chunk-size must be a positive integer.');
58
+ }
59
+ return bytes;
60
+ }
61
+ /**
62
+ * Decode bytes as UTF-8 JSON. Returns `undefined` (rather than throwing) when
63
+ * the input is not valid JSON, so callers can emit a context-specific message.
64
+ *
65
+ * @param bytes {Uint8Array}
66
+ * @returns {unknown}
67
+ */
68
+ function parseJson(bytes) {
69
+ try {
70
+ return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ }
76
+ /**
77
+ * Recover the recipient reference to re-resolve a prior recipient from its
78
+ * `kid`. An X25519 `did:key` kid (`did:key:z6LS…#z6LS…`) embeds the public key
79
+ * multibase as its fragment -- resolve that directly, since the DID resolver
80
+ * does not resolve a `did:key` whose base is an X25519 (`z6LS`) key. Any other
81
+ * kid (e.g. a `did:web` URL) is left for `resolveRecipient`'s DID path.
82
+ *
83
+ * @param kid {string}
84
+ * @returns {string}
85
+ */
86
+ function recipientRefFromKid(kid) {
87
+ const fragment = kid.includes('#') ? kid.slice(kid.indexOf('#') + 1) : '';
88
+ if (kid.startsWith('did:key:') && fragment.startsWith('z6LS')) {
89
+ return fragment;
90
+ }
91
+ return kid;
92
+ }
93
+ /**
94
+ * Merge the recipients of an existing document into the freshly resolved keys
95
+ * for an `--update`, re-resolving each prior recipient from its `kid` and
96
+ * skipping any already covered. This lets an update add a recipient without
97
+ * re-specifying the existing ones; the merged set is passed to the core so its
98
+ * key resolver covers every recipient of the resulting JWE.
99
+ *
100
+ * @param options {object}
101
+ * @param options.keys {KeyAgreementKey[]} Keys resolved from `--recipient(s)`.
102
+ * @param options.existing {IEncryptedDocument} The document being updated.
103
+ * @returns {Promise<KeyAgreementKey[]>}
104
+ */
105
+ async function mergeUpdateRecipients({ keys, existing }) {
106
+ const seen = new Set(keys.map(key => key.id));
107
+ const merged = [...keys];
108
+ for (const recipient of existing.jwe.recipients ?? []) {
109
+ const kid = recipient?.header?.kid;
110
+ if (!kid || seen.has(kid)) {
111
+ continue;
112
+ }
113
+ merged.push(await resolveRecipient({ ref: recipientRefFromKid(kid) }));
114
+ seen.add(kid);
115
+ }
116
+ return merged;
117
+ }
118
+ /**
119
+ * True when a path exists and is a directory (an EDV Document bundle).
120
+ *
121
+ * @param path {string}
122
+ * @returns {Promise<boolean>}
123
+ */
124
+ async function isDirectory(path) {
125
+ return (await stat(path).catch(() => undefined))?.isDirectory() ?? false;
126
+ }
127
+ /**
128
+ * Load an existing EDV Document to update, from either a single `.edvdoc.json`
129
+ * file or a bundle directory (`document.json` inside it). Returns `undefined`
130
+ * when the source is neither.
131
+ *
132
+ * @param options {object}
133
+ * @param options.path {string}
134
+ * @returns {Promise<IEncryptedDocument | undefined>}
135
+ */
136
+ async function loadEnvelope({ path }) {
137
+ if (await isDirectory(path)) {
138
+ return (await readDocumentBundle({ dir: path })).document;
139
+ }
140
+ const parsed = parseJson(await readInputBytes({ file: path }));
141
+ return isEncryptedDocument(parsed) ? parsed : undefined;
142
+ }
143
+ /**
144
+ * Parse a JSON-object command option, throwing a clear error when the value is
145
+ * not valid JSON or not an object.
146
+ *
147
+ * @param options {object}
148
+ * @param options.value {string}
149
+ * @param options.label {string} The option name, for the error message.
150
+ * @returns {Record<string, unknown>}
151
+ */
152
+ function parseJsonObjectOption({ value, label }) {
153
+ let parsed;
154
+ try {
155
+ parsed = JSON.parse(value);
156
+ }
157
+ catch {
158
+ throw new Error(`${label} is not valid JSON.`);
159
+ }
160
+ if (parsed === null || typeof parsed !== 'object') {
161
+ throw new Error(`${label} must be a JSON object.`);
162
+ }
163
+ return parsed;
164
+ }
165
+ /**
166
+ * Resolve the encrypt-time context for an envelope (document/stream) write:
167
+ * parse `--meta`, build the `--index`/`--unique` declarations and resolve the
168
+ * blinding `--hmac` key when indexing, and -- for `--update` -- load the prior
169
+ * document for its id/sequence/`indexed` and merge its recipients.
170
+ *
171
+ * @param options {object}
172
+ * @param options.keys {KeyAgreementKey[]} Keys resolved from `--recipient(s)`.
173
+ * @param [options.meta] {string}
174
+ * @param [options.update] {string}
175
+ * @param options.index {string[]} Indexable attribute paths.
176
+ * @param [options.unique] {boolean} Mark every `--index` attribute unique.
177
+ * @param [options.hmac] {string} Blinding-key ref; auto-selected when omitted.
178
+ * @returns {Promise<EncryptContext>}
179
+ */
180
+ async function resolveEncryptContext({ keys, meta, update, index, unique, hmac }) {
181
+ const metaObject = meta !== undefined
182
+ ? parseJsonObjectOption({ value: meta, label: '--meta' })
183
+ : undefined;
184
+ const indexes = index.length > 0
185
+ ? index.map(attribute => ({ attribute, unique: Boolean(unique) }))
186
+ : undefined;
187
+ const hmacKey = indexes ? await resolveHmac({ ref: hmac }) : undefined;
188
+ if (update === undefined) {
189
+ return { metaObject, hmac: hmacKey, indexes, encryptKeys: keys };
190
+ }
191
+ const existing = await loadEnvelope({ path: update });
192
+ if (!existing) {
193
+ throw new Error(`--update target "${update}" is not an EDV Document.`);
194
+ }
195
+ return {
196
+ metaObject,
197
+ hmac: hmacKey,
198
+ indexes,
199
+ base: {
200
+ id: existing.id,
201
+ sequence: existing.sequence,
202
+ indexed: existing.indexed ?? []
203
+ },
204
+ encryptKeys: await mergeUpdateRecipients({ keys, existing })
205
+ };
206
+ }
207
+ /**
208
+ * Encrypt stdin or a file to one or more X25519 recipients. By default emits a
209
+ * raw JWE (Layer 1); `--document` wraps the JWE in an EDV Document envelope
210
+ * `{ id, sequence, indexed, jwe }` (input encrypted as `content`); `--stream`
211
+ * writes a bundle directory whose chunks hold the input as a chunked stream.
212
+ *
213
+ * @param options {object}
214
+ * @param [options.file] {string} Input file; stdin when omitted.
215
+ * @param options.recipient {string[]} Recipient refs (`--recipient`).
216
+ * @param options.recipientFile {string[]} Key-document files.
217
+ * @param [options.json] {boolean} Parse input as JSON (`encryptObject`).
218
+ * @param [options.document] {boolean} Emit a full EDV Document envelope.
219
+ * @param [options.stream] {boolean} Emit a chunked-stream bundle directory.
220
+ * @param [options.chunkSize] {number} Bytes per chunk for `--stream`.
221
+ * @param [options.meta] {string} JSON `meta` object for the document.
222
+ * @param options.index {string[]} Indexable attribute paths (`--index`).
223
+ * @param [options.unique] {boolean} Mark every `--index` attribute unique.
224
+ * @param [options.hmac] {string} Blinding-key ref for `--index`.
225
+ * @param [options.update] {string} Existing document (file or bundle) to
226
+ * update: reuse its `id`, increment `sequence`, and merge its recipients.
227
+ * @param [options.out] {string} Output file/bundle; stdout when omitted.
228
+ * @returns {Promise<number>}
229
+ */
230
+ export async function runEncrypt({ file, recipient, recipientFile, json, document, stream, chunkSize, meta, index, unique, hmac, update, out }) {
231
+ const envelopeMode = Boolean(document) || Boolean(stream);
232
+ if (!envelopeMode && (meta !== undefined || update !== undefined)) {
233
+ console.error('--meta and --update require --document or --stream.');
234
+ return 2;
235
+ }
236
+ if (!envelopeMode && index.length > 0) {
237
+ console.error('--index requires --document or --stream.');
238
+ return 2;
239
+ }
240
+ if (hmac !== undefined && index.length === 0) {
241
+ console.error('--hmac requires --index.');
242
+ return 2;
243
+ }
244
+ const keys = [];
245
+ try {
246
+ for (const ref of recipient) {
247
+ keys.push(await resolveRecipient({ ref }));
248
+ }
249
+ for (const path of recipientFile) {
250
+ keys.push(await resolveRecipientFile({ path }));
251
+ }
252
+ }
253
+ catch (err) {
254
+ console.error(err.message);
255
+ return 2;
256
+ }
257
+ if (keys.length === 0) {
258
+ console.error('At least one --recipient or --recipient-file is required.');
259
+ return 2;
260
+ }
261
+ const bytes = await readInputBytes({ file });
262
+ const cipher = new Cipher();
263
+ if (stream) {
264
+ return runEncryptStream({
265
+ bytes,
266
+ keys,
267
+ meta,
268
+ index,
269
+ unique,
270
+ hmac,
271
+ update,
272
+ chunkSize,
273
+ out,
274
+ cipher
275
+ });
276
+ }
277
+ if (document) {
278
+ return runEncryptDocument({
279
+ bytes,
280
+ keys,
281
+ meta,
282
+ index,
283
+ unique,
284
+ hmac,
285
+ update,
286
+ out
287
+ });
288
+ }
289
+ const { recipients, keyResolver } = cipher.createRecipients({ keys });
290
+ let jwe;
291
+ if (json) {
292
+ const obj = parseJson(bytes);
293
+ if (obj === null || typeof obj !== 'object') {
294
+ console.error('--json was given but the input is not valid JSON.');
295
+ return 2;
296
+ }
297
+ jwe = await cipher.encryptObject({ obj, recipients, keyResolver });
298
+ }
299
+ else {
300
+ jwe = await cipher.encrypt({ data: bytes, recipients, keyResolver });
301
+ }
302
+ await writeJsonOutput({ value: jwe, output: out });
303
+ return 0;
304
+ }
305
+ /**
306
+ * The `--document` branch of `runEncrypt`: parse the input as the document's
307
+ * `content`, attach optional `--meta` and blinded `--index` entries, mint or
308
+ * carry over the envelope id/sequence, and emit the encrypted envelope.
309
+ *
310
+ * @param options {object}
311
+ * @param options.bytes {Uint8Array}
312
+ * @param options.keys {KeyAgreementKey[]}
313
+ * @param [options.meta] {string}
314
+ * @param options.index {string[]}
315
+ * @param [options.unique] {boolean}
316
+ * @param [options.hmac] {string}
317
+ * @param [options.update] {string}
318
+ * @param [options.out] {string}
319
+ * @returns {Promise<number>}
320
+ */
321
+ async function runEncryptDocument({ bytes, keys, meta, index, unique, hmac, update, out }) {
322
+ const content = parseJson(bytes);
323
+ if (content === null || typeof content !== 'object') {
324
+ console.error('--document requires the input to be a JSON object.');
325
+ return 2;
326
+ }
327
+ let context;
328
+ try {
329
+ context = await resolveEncryptContext({
330
+ keys,
331
+ meta,
332
+ update,
333
+ index,
334
+ unique,
335
+ hmac
336
+ });
337
+ }
338
+ catch (err) {
339
+ console.error(err.message);
340
+ return 2;
341
+ }
342
+ const doc = { content: content };
343
+ if (context.metaObject) {
344
+ doc.meta = context.metaObject;
345
+ }
346
+ const envelope = await encryptDocument({
347
+ doc,
348
+ keys: context.encryptKeys,
349
+ hmac: context.hmac,
350
+ indexes: context.indexes,
351
+ base: context.base
352
+ });
353
+ await writeJsonOutput({ value: envelope, output: out });
354
+ return 0;
355
+ }
356
+ /**
357
+ * The `--stream` branch of `runEncrypt`: encrypt the input as a chunked stream
358
+ * and write a bundle directory whose `document.json` carries a
359
+ * `stream: { sequence, chunks }` descriptor (its `content` is `{}`; the bytes
360
+ * live in the chunk JWEs). Requires `-o/--out` (the bundle directory).
361
+ *
362
+ * @param options {object}
363
+ * @param options.bytes {Uint8Array}
364
+ * @param options.keys {KeyAgreementKey[]}
365
+ * @param [options.meta] {string}
366
+ * @param options.index {string[]}
367
+ * @param [options.unique] {boolean}
368
+ * @param [options.hmac] {string}
369
+ * @param [options.update] {string}
370
+ * @param [options.chunkSize] {number}
371
+ * @param [options.out] {string}
372
+ * @param options.cipher {Cipher}
373
+ * @returns {Promise<number>}
374
+ */
375
+ async function runEncryptStream({ bytes, keys, meta, index, unique, hmac, update, chunkSize, out, cipher }) {
376
+ if (!out) {
377
+ console.error('--stream requires -o/--out (the bundle directory to write).');
378
+ return 2;
379
+ }
380
+ let context;
381
+ try {
382
+ context = await resolveEncryptContext({
383
+ keys,
384
+ meta,
385
+ update,
386
+ index,
387
+ unique,
388
+ hmac
389
+ });
390
+ }
391
+ catch (err) {
392
+ console.error(err.message);
393
+ return 2;
394
+ }
395
+ // The chunk `sequence` must equal the document's final sequence; the core
396
+ // sets a new document to 0 and increments an updated one, so compute the same
397
+ // value here to stamp the chunks (which are encrypted before the envelope).
398
+ const sequence = context.base ? context.base.sequence + 1 : 0;
399
+ // The stream's encrypt transformer mutates its recipients array (it injects
400
+ // an ephemeral key), so build a recipients set just for the chunks; the core
401
+ // builds its own for the document jwe.
402
+ const forChunks = cipher.createRecipients({ keys: context.encryptKeys });
403
+ const chunks = await encryptToChunks({
404
+ cipher,
405
+ data: bytes,
406
+ recipients: forChunks.recipients,
407
+ keyResolver: forChunks.keyResolver,
408
+ chunkSize,
409
+ sequence
410
+ });
411
+ const doc = {
412
+ content: {},
413
+ stream: { sequence, chunks: chunks.length }
414
+ };
415
+ if (context.metaObject) {
416
+ doc.meta = context.metaObject;
417
+ }
418
+ const envelope = await encryptDocument({
419
+ doc,
420
+ keys: context.encryptKeys,
421
+ hmac: context.hmac,
422
+ indexes: context.indexes,
423
+ base: context.base
424
+ });
425
+ await writeDocumentBundle({ dir: out, document: envelope, chunks });
426
+ console.error(`Wrote bundle ${out} (${chunks.length} chunk${chunks.length === 1 ? '' : 's'})`);
427
+ return 0;
428
+ }
429
+ /**
430
+ * Decrypt a JWE or EDV Document from stdin or a file with a stored X25519 key.
431
+ * An EDV Document envelope (`{ id, jwe, … }`) is detected automatically and its
432
+ * `content` is emitted; `--document` forces that expectation (erroring on a bare
433
+ * JWE), and a bare JWE is decrypted directly.
434
+ *
435
+ * @param options {object}
436
+ * @param [options.file] {string} Input `.jwe.json`/`.edvdoc.json` file; stdin
437
+ * when omitted.
438
+ * @param [options.key] {string} Secret-key ref; auto-selected when omitted.
439
+ * @param [options.json] {boolean} Parse plaintext as JSON (`decryptObject`).
440
+ * @param [options.document] {boolean} Require an EDV Document envelope.
441
+ * @param [options.out] {string} Output plaintext file; stdout when omitted.
442
+ * @returns {Promise<number>}
443
+ */
444
+ export async function runDecrypt({ file, key, json, document, out }) {
445
+ // A bundle directory is a streamed EDV Document; reassemble its chunks.
446
+ if (file && (await isDirectory(file))) {
447
+ return runDecryptBundle({ dir: file, key, out });
448
+ }
449
+ const bytes = await readInputBytes({ file });
450
+ const parsed = parseJson(bytes);
451
+ if (parsed === null || typeof parsed !== 'object') {
452
+ console.error('The input is not a valid JWE or EDV Document.');
453
+ return 2;
454
+ }
455
+ const envelope = isEncryptedDocument(parsed) ? parsed : undefined;
456
+ if (document && !envelope) {
457
+ console.error('--document was given but the input is not an EDV Document.');
458
+ return 2;
459
+ }
460
+ const jwe = (envelope ? envelope.jwe : parsed);
461
+ let keyAgreementKey;
462
+ try {
463
+ keyAgreementKey = await selectKeyAgreementKey({ key, jwe });
464
+ }
465
+ catch (err) {
466
+ console.error(err.message);
467
+ return 2;
468
+ }
469
+ // An EDV Document envelope is unwrapped through the core (its payload is
470
+ // always the `{ content, meta }` object); a bare JWE honors `--json`.
471
+ if (envelope) {
472
+ let payload;
473
+ try {
474
+ payload = await decryptDocument({
475
+ encryptedDoc: envelope,
476
+ keyAgreementKey
477
+ });
478
+ }
479
+ catch {
480
+ console.error('Decryption failed: the key does not match any recipient of this ' +
481
+ 'document.');
482
+ return 1;
483
+ }
484
+ reportDocumentSidecars({ payload });
485
+ await writeJsonOutput({ value: payload.content, output: out });
486
+ return 0;
487
+ }
488
+ const cipher = new Cipher();
489
+ // A mismatched key throws ("no matching recipient"); a matched key whose
490
+ // unwrap/decrypt fails returns null. Both are decryption failures, not
491
+ // crashes, so report either as a clean non-zero exit.
492
+ let result;
493
+ try {
494
+ result = json
495
+ ? await cipher.decryptObject({ jwe, keyAgreementKey })
496
+ : await cipher.decrypt({ jwe, keyAgreementKey });
497
+ }
498
+ catch {
499
+ result = null;
500
+ }
501
+ if (result === null) {
502
+ console.error('Decryption failed: the key does not match any recipient of this JWE.');
503
+ return 1;
504
+ }
505
+ if (json) {
506
+ await writeJsonOutput({ value: result, output: out });
507
+ }
508
+ else {
509
+ await writeBytesOutput({ bytes: result, output: out });
510
+ }
511
+ return 0;
512
+ }
513
+ /**
514
+ * Load the decryption key: the `-k/--key` ref when given, otherwise the stored
515
+ * key whose id matches a recipient of `jwe`.
516
+ *
517
+ * @param options {object}
518
+ * @param [options.key] {string}
519
+ * @param options.jwe {IJWE}
520
+ * @returns {Promise<KeyAgreementKey>}
521
+ */
522
+ async function selectKeyAgreementKey({ key, jwe }) {
523
+ return key
524
+ ? loadKeyAgreementKey({ ref: key })
525
+ : autoSelectKeyAgreementKey({ jwe });
526
+ }
527
+ /**
528
+ * Report a decrypted document's `meta` / `stream` on stderr (diagnostics that
529
+ * accompany the `content` written to stdout).
530
+ *
531
+ * @param options {object}
532
+ * @param options.payload {DocumentPayload}
533
+ * @returns {void}
534
+ */
535
+ function reportDocumentSidecars({ payload }) {
536
+ if (payload.meta !== undefined) {
537
+ console.error(`meta: ${JSON.stringify(payload.meta)}`);
538
+ }
539
+ if (payload.stream !== undefined) {
540
+ console.error(`stream: ${JSON.stringify(payload.stream)}`);
541
+ }
542
+ }
543
+ /**
544
+ * Decrypt a streamed EDV Document bundle directory: decrypt the document jwe for
545
+ * its `content`/`meta`/`stream` (reported on stderr), then reassemble the chunk
546
+ * JWEs into the original bytes, written to `-o`/stdout.
547
+ *
548
+ * @param options {object}
549
+ * @param options.dir {string} The bundle directory.
550
+ * @param [options.key] {string}
551
+ * @param [options.out] {string}
552
+ * @returns {Promise<number>}
553
+ */
554
+ async function runDecryptBundle({ dir, key, out }) {
555
+ let document;
556
+ let chunks;
557
+ try {
558
+ ;
559
+ ({ document, chunks } = await readDocumentBundle({ dir }));
560
+ }
561
+ catch (err) {
562
+ console.error(err.message);
563
+ return 2;
564
+ }
565
+ let keyAgreementKey;
566
+ try {
567
+ keyAgreementKey = await selectKeyAgreementKey({ key, jwe: document.jwe });
568
+ }
569
+ catch (err) {
570
+ console.error(err.message);
571
+ return 2;
572
+ }
573
+ const cipher = new Cipher();
574
+ let bytes;
575
+ try {
576
+ const payload = await decryptDocument({
577
+ encryptedDoc: document,
578
+ keyAgreementKey
579
+ });
580
+ reportDocumentSidecars({ payload });
581
+ bytes = await decryptChunks({ cipher, chunks, keyAgreementKey });
582
+ }
583
+ catch {
584
+ console.error('Decryption failed: the key does not match any recipient of this bundle.');
585
+ return 1;
586
+ }
587
+ await writeBytesOutput({ bytes, output: out });
588
+ return 0;
589
+ }
590
+ export function makeEdvCommand() {
591
+ const edv = new Command('edv').description('Encrypt and decrypt objects and files to X25519 recipients (raw JWE)');
592
+ edv
593
+ .command('encrypt [file]')
594
+ .description('Encrypt stdin or a file to one or more X25519 recipients')
595
+ .option('-r, --recipient <ref>', 'an X25519 recipient: a publicKeyMultibase, a wallet key ' +
596
+ 'fingerprint/handle, or a DID / DID URL (repeatable)', collect, [])
597
+ .option('--recipient-file <path>', 'a key-document JSON file holding an X25519 public key (repeatable)', collect, [])
598
+ .option('--json', 'parse the input as JSON and encrypt it as an object')
599
+ .option('-d, --document', 'emit a full EDV Document envelope { id, sequence, indexed, jwe }, ' +
600
+ 'encrypting the input as the document content')
601
+ .option('-s, --stream', 'emit a chunked-stream bundle directory (requires -o); the input is ' +
602
+ 'encrypted as fixed-size chunks')
603
+ .option('--chunk-size <bytes>', 'bytes per chunk for --stream (default 1 MiB)', parseChunkSize)
604
+ .option('--meta <json>', 'a JSON meta object to store in the document (requires --document/--stream)')
605
+ .option('--index <attribute>', 'an indexable attribute path (e.g. content.type) to HMAC-blind into the ' +
606
+ 'document indexed array; requires --document/--stream (repeatable)', collect, [])
607
+ .option('--unique', 'mark every --index attribute as unique')
608
+ .option('--hmac <ref>', 'the wallet HMAC key (id or handle) to blind --index attributes with; ' +
609
+ 'auto-selected when the wallet has exactly one')
610
+ .option('--update <path>', 'an existing EDV Document (file or bundle) to update: reuse its id, ' +
611
+ 'increment its sequence, and merge its recipients')
612
+ .option('-o, --out <path>', 'write the JWE/EDV Document to a file, or the --stream bundle to a ' +
613
+ 'directory (default: stdout)')
614
+ .action(async (file, options) => runAndExit(runEncrypt({ file, ...options })));
615
+ edv
616
+ .command('decrypt [file]')
617
+ .description('Decrypt a JWE or EDV Document from stdin or a file with a stored ' +
618
+ 'X25519 key')
619
+ .option('-k, --key <ref>', 'the X25519 secret key to decrypt with (fingerprint or handle); ' +
620
+ 'auto-selected from the wallet when omitted')
621
+ .option('--json', 'parse the decrypted plaintext as JSON and pretty-print it')
622
+ .option('-d, --document', 'require an EDV Document envelope and emit its decrypted content')
623
+ .option('-o, --out <file>', 'write the plaintext to a file (default: stdout)')
624
+ .action(async (file, options) => runAndExit(runDecrypt({ file, ...options })));
625
+ return edv;
626
+ }
627
+ //# sourceMappingURL=edv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edv.js","sourceRoot":"","sources":["../../src/commands/edv.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/commands/key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoGnC,wBAAgB,cAAc,IAAI,OAAO,CAigBxC"}
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/commands/key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAqGnC,wBAAgB,cAAc,IAAI,OAAO,CA4iBxC"}