@did-btcr2/cli 0.15.0 → 0.16.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 +47 -6
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +563 -117
- package/dist/esm/src/cli.js +7 -4
- package/dist/esm/src/cli.js.map +1 -1
- package/dist/esm/src/commands/config.js +11 -15
- package/dist/esm/src/commands/config.js.map +1 -1
- package/dist/esm/src/commands/create.js +4 -1
- package/dist/esm/src/commands/create.js.map +1 -1
- package/dist/esm/src/commands/deactivate.js +3 -1
- package/dist/esm/src/commands/deactivate.js.map +1 -1
- package/dist/esm/src/commands/index.js +2 -0
- package/dist/esm/src/commands/index.js.map +1 -1
- package/dist/esm/src/commands/init.js +63 -0
- package/dist/esm/src/commands/init.js.map +1 -0
- package/dist/esm/src/commands/keystore.js +81 -0
- package/dist/esm/src/commands/keystore.js.map +1 -0
- package/dist/esm/src/commands/profile.js +1 -1
- package/dist/esm/src/commands/profile.js.map +1 -1
- package/dist/esm/src/commands/update.js +3 -1
- package/dist/esm/src/commands/update.js.map +1 -1
- package/dist/esm/src/config.js +85 -28
- package/dist/esm/src/config.js.map +1 -1
- package/dist/esm/src/keystore/file-key-store.js +340 -32
- package/dist/esm/src/keystore/file-key-store.js.map +1 -1
- package/dist/esm/src/keystore/passphrase.js +40 -10
- package/dist/esm/src/keystore/passphrase.js.map +1 -1
- package/dist/esm/src/keystore/paths.js +6 -18
- package/dist/esm/src/keystore/paths.js.map +1 -1
- package/dist/esm/src/paths.js +59 -0
- package/dist/esm/src/paths.js.map +1 -0
- package/dist/esm/src/types.js.map +1 -1
- package/dist/types/src/cli.d.ts.map +1 -1
- package/dist/types/src/commands/config.d.ts.map +1 -1
- package/dist/types/src/commands/create.d.ts.map +1 -1
- package/dist/types/src/commands/deactivate.d.ts.map +1 -1
- package/dist/types/src/commands/index.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts.map +1 -1
- package/dist/types/src/commands/init.d.ts +13 -0
- package/dist/types/src/commands/init.d.ts.map +1 -0
- package/dist/types/src/commands/keystore.d.ts +10 -0
- package/dist/types/src/commands/keystore.d.ts.map +1 -0
- package/dist/types/src/commands/update.d.ts.map +1 -1
- package/dist/types/src/config.d.ts +38 -14
- package/dist/types/src/config.d.ts.map +1 -1
- package/dist/types/src/keystore/file-key-store.d.ts +86 -10
- package/dist/types/src/keystore/file-key-store.d.ts.map +1 -1
- package/dist/types/src/keystore/passphrase.d.ts +16 -1
- package/dist/types/src/keystore/passphrase.d.ts.map +1 -1
- package/dist/types/src/keystore/paths.d.ts +6 -10
- package/dist/types/src/keystore/paths.d.ts.map +1 -1
- package/dist/types/src/paths.d.ts +54 -0
- package/dist/types/src/paths.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +38 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/cli.ts +8 -3
- package/src/commands/config.ts +12 -14
- package/src/commands/create.ts +4 -1
- package/src/commands/deactivate.ts +3 -1
- package/src/commands/index.ts +2 -0
- package/src/commands/init.ts +74 -0
- package/src/commands/keystore.ts +98 -0
- package/src/commands/profile.ts +1 -1
- package/src/commands/update.ts +3 -1
- package/src/config.ts +93 -32
- package/src/keystore/file-key-store.ts +455 -43
- package/src/keystore/passphrase.ts +48 -8
- package/src/keystore/paths.ts +6 -19
- package/src/paths.ts +79 -0
- package/src/types.ts +13 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
|
+
import { utf8ToBytes } from '@noble/hashes/utils.js';
|
|
3
4
|
import { base64urlnopad } from '@scure/base';
|
|
4
5
|
import { assertSecurePerms, ensureDir, writeFileAtomic } from './atomic.js';
|
|
5
6
|
import { DEFAULT_ARGON_PARAMS, decryptSecret, encryptSecret } from './envelope.js';
|
|
@@ -9,19 +10,44 @@ import { defaultKeystorePath } from './paths.js';
|
|
|
9
10
|
/** Current on-disk keystore file format version. */
|
|
10
11
|
export const KEYSTORE_VERSION = 1;
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* Fixed sentinel sealed under the keystore passphrase and stored as the file's
|
|
14
|
+
* `verifier`. Decrypting it checks a candidate passphrase before any real secret
|
|
15
|
+
* is sealed or opened, so a typo fails loudly instead of corrupting the store.
|
|
16
|
+
*/
|
|
17
|
+
const VERIFIER_PLAINTEXT = utf8ToBytes('did-btcr2-keystore-verifier-v1');
|
|
18
|
+
/** Constant-length-independent byte compare for the verifier sentinel. */
|
|
19
|
+
function bytesEqual(a, b) {
|
|
20
|
+
if (a.length !== b.length)
|
|
21
|
+
return false;
|
|
22
|
+
let diff = 0;
|
|
23
|
+
for (let i = 0; i < a.length; i++)
|
|
24
|
+
diff |= a[i] ^ b[i];
|
|
25
|
+
return diff === 0;
|
|
26
|
+
}
|
|
27
|
+
/** Whether two secret envelopes are byte-identical (structural JSON compare). */
|
|
28
|
+
function sameEnvelope(a, b) {
|
|
29
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A Node-only, file-backed {@link KeyValueStore} that protects secret keys at
|
|
13
33
|
* rest. It satisfies the synchronous store contract by caching the parsed file
|
|
14
34
|
* in memory at construction and flushing the whole file atomically on every
|
|
15
35
|
* mutation.
|
|
16
36
|
*
|
|
37
|
+
* Encrypted keystores seal each secret in its own argon2id + XChaCha20-Poly1305
|
|
38
|
+
* envelope under one shared passphrase, and store a `verifier` sentinel so a
|
|
39
|
+
* candidate passphrase is checked before it is used (ADR 080): the first
|
|
40
|
+
* passphrase is established with a confirm prompt, and every later use is
|
|
41
|
+
* verified, so a typo is a loud failure rather than a key sealed under an
|
|
42
|
+
* unknown or divergent passphrase. Dev keystores (`protection: 'none'`) store
|
|
43
|
+
* secrets as plaintext and never prompt; they are refused for mainnet by the
|
|
44
|
+
* command layer.
|
|
45
|
+
*
|
|
17
46
|
* Every mutation runs under an exclusive cross-process lock and, inside that
|
|
18
|
-
* lock, reloads the file from disk before applying its change and flushing
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* merges any change the other made, so concurrent invocations compose instead of
|
|
23
|
-
* clobbering. Reads stay lock-free: an atomic rename means a concurrent reader
|
|
24
|
-
* always sees a complete file, old or new.
|
|
47
|
+
* lock, reloads the file from disk before applying its change and flushing, so
|
|
48
|
+
* concurrent `btcr2` invocations compose instead of clobbering. Reads stay
|
|
49
|
+
* lock-free: an atomic rename means a concurrent reader always sees a complete
|
|
50
|
+
* file, old or new.
|
|
25
51
|
*
|
|
26
52
|
* Secrets are materialized only through {@link FileKeyStore.get}. The
|
|
27
53
|
* {@link FileKeyStore.list} and {@link FileKeyStore.entries} projections omit
|
|
@@ -36,12 +62,17 @@ export class FileKeyStore {
|
|
|
36
62
|
#argonParams;
|
|
37
63
|
#cache = new Map();
|
|
38
64
|
#active;
|
|
65
|
+
#protection;
|
|
66
|
+
#verifier;
|
|
39
67
|
constructor(options) {
|
|
40
68
|
this.#path = options.path ?? defaultKeystorePath();
|
|
41
69
|
this.#lockPath = `${this.#path}.lock`;
|
|
42
70
|
this.#lockOptions = options.lock ?? {};
|
|
43
71
|
this.#getPassphrase = options.getPassphrase;
|
|
44
72
|
this.#argonParams = options.argonParams ?? DEFAULT_ARGON_PARAMS;
|
|
73
|
+
// The requested mode applies only when establishing a fresh keystore; an
|
|
74
|
+
// existing file's on-disk protection overrides it in #loadFromDisk.
|
|
75
|
+
this.#protection = options.protection ?? 'passphrase';
|
|
45
76
|
ensureDir(dirname(this.#path), 0o700);
|
|
46
77
|
this.#loadFromDisk();
|
|
47
78
|
}
|
|
@@ -59,7 +90,24 @@ export class FileKeyStore {
|
|
|
59
90
|
if (parsed.v !== KEYSTORE_VERSION) {
|
|
60
91
|
throw new KeyStoreError(`Unsupported keystore version: ${String(parsed.v)}.`, 'KEYSTORE_VERSION_ERROR', { version: parsed.v });
|
|
61
92
|
}
|
|
93
|
+
// Every keystore this CLI writes carries a recognized protection header. A
|
|
94
|
+
// file without one was not written by this CLI (there is no pre-header
|
|
95
|
+
// format to accommodate); refuse it rather than guess how its secrets are
|
|
96
|
+
// protected.
|
|
97
|
+
if (parsed.protection !== 'none' && parsed.protection !== 'passphrase') {
|
|
98
|
+
throw new KeyStoreError(`Keystore at ${this.#path} has no recognized protection header; it was not written by this CLI.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path });
|
|
99
|
+
}
|
|
100
|
+
this.#protection = parsed.protection;
|
|
101
|
+
this.#verifier = parsed.verifier;
|
|
62
102
|
this.#active = parsed.active;
|
|
103
|
+
// An encrypted keystore that holds sealed keys must carry the verifier that
|
|
104
|
+
// established its passphrase. Without it, the verify-or-establish decision in
|
|
105
|
+
// #sealPassphrase could take the establish path over existing sealed keys and
|
|
106
|
+
// seal a new key under a divergent passphrase; refuse the file instead.
|
|
107
|
+
const sealedPresent = Object.values(parsed.keys ?? {}).some(k => k && typeof k === 'object' && k.secret !== undefined);
|
|
108
|
+
if (this.#protection === 'passphrase' && sealedPresent && this.#verifier === undefined) {
|
|
109
|
+
throw new KeyStoreError(`Keystore at ${this.#path} holds sealed keys but no passphrase verifier; it is corrupt or was tampered with.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path });
|
|
110
|
+
}
|
|
63
111
|
for (const [id, stored] of Object.entries(parsed.keys ?? {})) {
|
|
64
112
|
let publicKey;
|
|
65
113
|
try {
|
|
@@ -73,24 +121,61 @@ export class FileKeyStore {
|
|
|
73
121
|
if (publicKey.length !== 33) {
|
|
74
122
|
throw new KeyStoreError(`Keystore entry ${id} has a ${publicKey.length}-byte public key; expected 33.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path, keyId: id });
|
|
75
123
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
124
|
+
const entry = { publicKey, ...(stored.tags && { tags: stored.tags }) };
|
|
125
|
+
// A secret's storage form must match the keystore's protection mode: a dev
|
|
126
|
+
// keystore holds plaintext, an encrypted keystore holds sealed envelopes. A
|
|
127
|
+
// mismatch is a tampered or foreign file, not something to open blindly.
|
|
128
|
+
if (stored.plainSecret !== undefined) {
|
|
129
|
+
if (this.#protection !== 'none') {
|
|
130
|
+
throw new KeyStoreError(`Keystore entry ${id} holds a plaintext secret in an encrypted keystore at ${this.#path}.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path, keyId: id });
|
|
131
|
+
}
|
|
132
|
+
entry.plaintext = true;
|
|
133
|
+
entry.decrypted = this.#decodePlainSecret(stored.plainSecret, id);
|
|
134
|
+
}
|
|
135
|
+
else if (stored.secret) {
|
|
136
|
+
if (this.#protection !== 'passphrase') {
|
|
137
|
+
throw new KeyStoreError(`Keystore entry ${id} holds a sealed secret in a dev keystore at ${this.#path}.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path, keyId: id });
|
|
138
|
+
}
|
|
139
|
+
entry.secret = stored.secret;
|
|
140
|
+
}
|
|
141
|
+
this.#cache.set(id, entry);
|
|
81
142
|
}
|
|
82
143
|
}
|
|
144
|
+
/** Decodes and length-checks a dev-keystore plaintext secret. */
|
|
145
|
+
#decodePlainSecret(encoded, id) {
|
|
146
|
+
let secret;
|
|
147
|
+
try {
|
|
148
|
+
secret = base64urlnopad.decode(encoded);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
throw new KeyStoreError(`Keystore entry ${id} has a malformed plaintext secret.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path, keyId: id });
|
|
152
|
+
}
|
|
153
|
+
if (secret.length !== 32) {
|
|
154
|
+
throw new KeyStoreError(`Keystore entry ${id} has a ${secret.length}-byte secret; expected 32.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path, keyId: id });
|
|
155
|
+
}
|
|
156
|
+
return secret;
|
|
157
|
+
}
|
|
83
158
|
#flush() {
|
|
84
159
|
const keys = {};
|
|
85
160
|
for (const [id, entry] of this.#cache) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
161
|
+
const stored = { publicKey: base64urlnopad.encode(entry.publicKey) };
|
|
162
|
+
if (entry.tags)
|
|
163
|
+
stored.tags = entry.tags;
|
|
164
|
+
if (entry.plaintext && entry.decrypted) {
|
|
165
|
+
stored.plainSecret = base64urlnopad.encode(entry.decrypted);
|
|
166
|
+
}
|
|
167
|
+
else if (entry.secret) {
|
|
168
|
+
stored.secret = entry.secret;
|
|
169
|
+
}
|
|
170
|
+
keys[id] = stored;
|
|
91
171
|
}
|
|
172
|
+
// Every keystore this CLI writes self-describes: the protection header is
|
|
173
|
+
// always present (`passphrase` for encrypted, `none` for dev), so a file is
|
|
174
|
+
// never ambiguous about how its secrets are protected.
|
|
92
175
|
const file = {
|
|
93
176
|
v: KEYSTORE_VERSION,
|
|
177
|
+
protection: this.#protection,
|
|
178
|
+
...(this.#verifier && { verifier: this.#verifier }),
|
|
94
179
|
...(this.#active && { active: this.#active }),
|
|
95
180
|
keys,
|
|
96
181
|
};
|
|
@@ -101,7 +186,8 @@ export class FileKeyStore {
|
|
|
101
186
|
* mutation applies on top of whatever other processes have written. Secrets
|
|
102
187
|
* already decrypted this session are carried over for entries whose sealed
|
|
103
188
|
* envelope is byte-identical on disk, so a mid-session write does not force a
|
|
104
|
-
* re-prompt for keys it did not touch.
|
|
189
|
+
* re-prompt for keys it did not touch. (Dev-keystore plaintext secrets are
|
|
190
|
+
* reloaded from disk, so they need no carry.)
|
|
105
191
|
*/
|
|
106
192
|
#reload() {
|
|
107
193
|
const carried = new Map();
|
|
@@ -133,6 +219,47 @@ export class FileKeyStore {
|
|
|
133
219
|
this.#flush();
|
|
134
220
|
}, this.#lockOptions);
|
|
135
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Verifies a candidate passphrase against the keystore verifier, throwing when
|
|
224
|
+
* it does not open the sentinel. A no-op only on a fresh keystore whose
|
|
225
|
+
* passphrase has not been established yet (no verifier to check against).
|
|
226
|
+
*/
|
|
227
|
+
#assertPassphrase(passphrase) {
|
|
228
|
+
if (!this.#verifier)
|
|
229
|
+
return;
|
|
230
|
+
let plain;
|
|
231
|
+
try {
|
|
232
|
+
plain = decryptSecret(this.#verifier, passphrase);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
throw new KeyStoreError(`Incorrect passphrase for the keystore at ${this.#path}.`, 'DECRYPT_ERROR', { path: this.#path });
|
|
236
|
+
}
|
|
237
|
+
if (!bytesEqual(plain, VERIFIER_PLAINTEXT)) {
|
|
238
|
+
throw new KeyStoreError(`Keystore verifier at ${this.#path} did not match; the file may be corrupt.`, 'KEYSTORE_CORRUPT_ERROR', { path: this.#path });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/** Passphrase for opening an existing secret: verified when a verifier exists. */
|
|
242
|
+
#openPassphrase() {
|
|
243
|
+
const passphrase = this.#getPassphrase();
|
|
244
|
+
this.#assertPassphrase(passphrase);
|
|
245
|
+
return passphrase;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Passphrase for sealing a secret. When the keystore's passphrase is already
|
|
249
|
+
* established (a verifier exists), prompt once and verify it. Otherwise this is
|
|
250
|
+
* establishment on a fresh keystore: prompt with confirm and mint a verifier for
|
|
251
|
+
* the caller to persist alongside the first sealed key.
|
|
252
|
+
*/
|
|
253
|
+
#sealPassphrase() {
|
|
254
|
+
if (this.#verifier) {
|
|
255
|
+
const passphrase = this.#getPassphrase();
|
|
256
|
+
this.#assertPassphrase(passphrase);
|
|
257
|
+
return { passphrase };
|
|
258
|
+
}
|
|
259
|
+
const passphrase = this.#getPassphrase({ confirm: true });
|
|
260
|
+
const newVerifier = encryptSecret(VERIFIER_PLAINTEXT, passphrase, this.#argonParams);
|
|
261
|
+
return { passphrase, newVerifier };
|
|
262
|
+
}
|
|
136
263
|
get(id) {
|
|
137
264
|
const entry = this.#cache.get(id);
|
|
138
265
|
if (!entry)
|
|
@@ -141,18 +268,26 @@ export class FileKeyStore {
|
|
|
141
268
|
publicKey: entry.publicKey,
|
|
142
269
|
...(entry.tags && { tags: entry.tags }),
|
|
143
270
|
};
|
|
144
|
-
if (entry.
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
271
|
+
if (entry.plaintext && entry.decrypted) {
|
|
272
|
+
// Dev keystore: plaintext already materialized; expose without a prompt.
|
|
273
|
+
const secret = entry.decrypted;
|
|
274
|
+
Object.defineProperty(result, 'secretKey', {
|
|
275
|
+
configurable: true,
|
|
276
|
+
enumerable: false,
|
|
277
|
+
get: () => secret,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
else if (entry.secret) {
|
|
281
|
+
// Materialize the sealed secret lazily, only when it is actually accessed,
|
|
282
|
+
// so reads that need just public material never trigger a passphrase
|
|
283
|
+
// prompt. The property is non-enumerable so spreading or serializing the
|
|
284
|
+
// entry cannot silently decrypt the secret.
|
|
150
285
|
const sealed = entry.secret;
|
|
151
286
|
Object.defineProperty(result, 'secretKey', {
|
|
152
287
|
configurable: true,
|
|
153
288
|
enumerable: false,
|
|
154
289
|
get: () => {
|
|
155
|
-
entry.decrypted ??= decryptSecret(sealed, this.#
|
|
290
|
+
entry.decrypted ??= decryptSecret(sealed, this.#openPassphrase());
|
|
156
291
|
return entry.decrypted;
|
|
157
292
|
},
|
|
158
293
|
});
|
|
@@ -163,16 +298,55 @@ export class FileKeyStore {
|
|
|
163
298
|
return this.#cache.has(id);
|
|
164
299
|
}
|
|
165
300
|
set(id, value) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
301
|
+
if (this.#protection === 'none') {
|
|
302
|
+
// Dev keystore: store the secret in the clear, never prompt.
|
|
303
|
+
this.#mutate(() => {
|
|
304
|
+
this.#cache.set(id, {
|
|
305
|
+
publicKey: value.publicKey,
|
|
306
|
+
...(value.tags && { tags: value.tags }),
|
|
307
|
+
...(value.secretKey && { plaintext: true, decrypted: value.secretKey }),
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
// Encrypted keystore. Resolve (and, if establishing, confirm) the passphrase
|
|
313
|
+
// and seal the secret before taking the lock: argon2id is deliberately slow
|
|
314
|
+
// and must not extend the critical section that blocks other processes.
|
|
315
|
+
const verifierAtSeal = this.#verifier;
|
|
316
|
+
let sealed;
|
|
317
|
+
let newVerifier;
|
|
318
|
+
let passphrase;
|
|
319
|
+
if (value.secretKey) {
|
|
320
|
+
const resolved = this.#sealPassphrase();
|
|
321
|
+
passphrase = resolved.passphrase;
|
|
322
|
+
newVerifier = resolved.newVerifier;
|
|
323
|
+
sealed = encryptSecret(value.secretKey, passphrase, this.#argonParams);
|
|
324
|
+
}
|
|
171
325
|
this.#mutate(() => {
|
|
326
|
+
// A secret sealed outside the lock must never be persisted under a
|
|
327
|
+
// passphrase that diverges from the keystore verifier (the key-loss class
|
|
328
|
+
// ADR 080 exists to prevent). Reconcile our seal-time view with whatever the
|
|
329
|
+
// reload sees before committing.
|
|
330
|
+
if (value.secretKey) {
|
|
331
|
+
if (this.#verifier === undefined && newVerifier !== undefined) {
|
|
332
|
+
// Establishing, and no concurrent writer beat us to it: record our verifier.
|
|
333
|
+
this.#verifier = newVerifier;
|
|
334
|
+
}
|
|
335
|
+
else if (this.#verifier !== undefined && passphrase !== undefined) {
|
|
336
|
+
// A verifier exists: it pre-existed, was established concurrently while we
|
|
337
|
+
// sealed, or was rotated by a concurrent change-passphrase. If it was
|
|
338
|
+
// rotated out from under our seal, abort with a clear message; otherwise
|
|
339
|
+
// assert our passphrase still opens it before persisting the key.
|
|
340
|
+
if (verifierAtSeal !== undefined && !sameEnvelope(this.#verifier, verifierAtSeal)) {
|
|
341
|
+
throw new KeyStoreError(`The keystore passphrase at ${this.#path} changed concurrently; re-run the command.`, 'KEYSTORE_CONCURRENT_CHANGE_ERROR', { path: this.#path });
|
|
342
|
+
}
|
|
343
|
+
this.#assertPassphrase(passphrase);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
172
346
|
this.#cache.set(id, {
|
|
173
347
|
publicKey: value.publicKey,
|
|
174
348
|
...(value.tags && { tags: value.tags }),
|
|
175
|
-
...(
|
|
349
|
+
...(sealed && { secret: sealed }),
|
|
176
350
|
...(value.secretKey && { decrypted: value.secretKey }),
|
|
177
351
|
});
|
|
178
352
|
});
|
|
@@ -240,5 +414,139 @@ export class FileKeyStore {
|
|
|
240
414
|
this.#active = id;
|
|
241
415
|
});
|
|
242
416
|
}
|
|
417
|
+
/** The keystore's protection mode. */
|
|
418
|
+
get protection() {
|
|
419
|
+
return this.#protection;
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Re-seals every sealed secret and the verifier under a new passphrase (ADR
|
|
423
|
+
* 080), returning the number of secrets re-sealed. Verifies the current
|
|
424
|
+
* passphrase against the verifier first. Refused on a dev keystore, which has
|
|
425
|
+
* no passphrase.
|
|
426
|
+
*/
|
|
427
|
+
changePassphrase(oldPassphrase, newPassphrase) {
|
|
428
|
+
if (this.#protection === 'none') {
|
|
429
|
+
throw new KeyStoreError(`The keystore at ${this.#path} is an unencrypted dev keystore; it has no passphrase to change.`, 'KEYSTORE_PROTECTION_ERROR', { path: this.#path });
|
|
430
|
+
}
|
|
431
|
+
// Fail a wrong current passphrase up front (when a verifier exists) so a typo
|
|
432
|
+
// does not pay for a full re-seal before failing.
|
|
433
|
+
if (this.#verifier)
|
|
434
|
+
this.#assertPassphrase(oldPassphrase);
|
|
435
|
+
// Precompute every re-seal and the new verifier BEFORE taking the lock:
|
|
436
|
+
// argon2id is deliberately slow, and holding the exclusive lock across many
|
|
437
|
+
// derivations could exceed the lock's stale threshold and let a concurrent
|
|
438
|
+
// process break a still-live lock. Each re-seal records the source envelope
|
|
439
|
+
// it derived from, so the locked section can abort on any concurrent change
|
|
440
|
+
// instead of corrupting. This follows the same do-expensive-work-before-the-
|
|
441
|
+
// lock contract as set().
|
|
442
|
+
const resealed = new Map();
|
|
443
|
+
for (const [id, entry] of this.#cache) {
|
|
444
|
+
if (!entry.secret)
|
|
445
|
+
continue;
|
|
446
|
+
let plain;
|
|
447
|
+
try {
|
|
448
|
+
plain = decryptSecret(entry.secret, oldPassphrase);
|
|
449
|
+
}
|
|
450
|
+
catch {
|
|
451
|
+
throw new KeyStoreError(`Incorrect current passphrase for the keystore at ${this.#path}.`, 'DECRYPT_ERROR', { path: this.#path });
|
|
452
|
+
}
|
|
453
|
+
resealed.set(id, { from: entry.secret, to: encryptSecret(plain, newPassphrase, this.#argonParams), plain });
|
|
454
|
+
}
|
|
455
|
+
const newVerifier = encryptSecret(VERIFIER_PLAINTEXT, newPassphrase, this.#argonParams);
|
|
456
|
+
let rekeyed = 0;
|
|
457
|
+
this.#mutate(() => {
|
|
458
|
+
// The reload reflects any concurrent writer. Apply a precomputed re-seal
|
|
459
|
+
// only where the on-disk envelope still matches what it was derived from;
|
|
460
|
+
// abort if any sealed key changed or a new sealed key appeared that was not
|
|
461
|
+
// re-sealed, rather than leave a key under the old passphrase.
|
|
462
|
+
for (const [id, entry] of this.#cache) {
|
|
463
|
+
if (!entry.secret)
|
|
464
|
+
continue;
|
|
465
|
+
const pre = resealed.get(id);
|
|
466
|
+
if (!pre || !sameEnvelope(pre.from, entry.secret)) {
|
|
467
|
+
throw new KeyStoreError(`The keystore at ${this.#path} changed while its passphrase was being changed; re-run the command.`, 'KEYSTORE_CONCURRENT_CHANGE_ERROR', { path: this.#path });
|
|
468
|
+
}
|
|
469
|
+
entry.secret = pre.to;
|
|
470
|
+
entry.decrypted = pre.plain;
|
|
471
|
+
rekeyed++;
|
|
472
|
+
}
|
|
473
|
+
this.#verifier = newVerifier;
|
|
474
|
+
});
|
|
475
|
+
return rekeyed;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Summarizes a keystore file by structure alone: protection mode, whether a
|
|
480
|
+
* passphrase is established, key count, and active key. Never decrypts, never
|
|
481
|
+
* prompts, and never throws (a missing or unreadable file reports `absent`), so
|
|
482
|
+
* it is safe for `keystore status`, `config path`, and the mainnet dev-keystore
|
|
483
|
+
* guard.
|
|
484
|
+
*/
|
|
485
|
+
export function keystoreSummary(path) {
|
|
486
|
+
const absent = { protection: 'absent', established: false, keyCount: 0, active: undefined };
|
|
487
|
+
if (!existsSync(path))
|
|
488
|
+
return absent;
|
|
489
|
+
let parsed;
|
|
490
|
+
try {
|
|
491
|
+
parsed = JSON.parse(readFileSync(path, 'utf-8'));
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
return absent;
|
|
495
|
+
}
|
|
496
|
+
const keys = (parsed.keys && typeof parsed.keys === 'object') ? parsed.keys : {};
|
|
497
|
+
const keyCount = Object.keys(keys).length;
|
|
498
|
+
const active = typeof parsed.active === 'string' ? parsed.active : undefined;
|
|
499
|
+
if (parsed.protection === 'none') {
|
|
500
|
+
return { protection: 'dev', established: true, keyCount, active };
|
|
501
|
+
}
|
|
502
|
+
if (parsed.protection === 'passphrase') {
|
|
503
|
+
// An encrypted keystore is "established" once its passphrase verifier exists
|
|
504
|
+
// (written by `init` or the first key-seal). Without it the passphrase has not
|
|
505
|
+
// been set yet: a freshly-created, still-empty encrypted keystore.
|
|
506
|
+
return { protection: 'encrypted', established: parsed.verifier !== undefined, keyCount, active };
|
|
507
|
+
}
|
|
508
|
+
// No recognized protection header: not a keystore this CLI wrote. Report absent
|
|
509
|
+
// (never throw) so `keystore status` stays a safe, no-decrypt introspection; an
|
|
510
|
+
// actual open of such a file is refused by FileKeyStore.
|
|
511
|
+
return absent;
|
|
512
|
+
}
|
|
513
|
+
/** The protection label of a keystore file, without decrypting or prompting. */
|
|
514
|
+
export function keystoreProtection(path) {
|
|
515
|
+
return keystoreSummary(path).protection;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Establishes a fresh keystore file (ADR 080). An encrypted keystore prompts
|
|
519
|
+
* (with confirm) for the passphrase and writes the verifier; a dev keystore
|
|
520
|
+
* writes a plaintext-mode header with no passphrase. The caller is responsible
|
|
521
|
+
* for refusing to overwrite an existing keystore; this always writes the file.
|
|
522
|
+
*/
|
|
523
|
+
export function initKeystore(path, options) {
|
|
524
|
+
ensureDir(dirname(path), 0o700);
|
|
525
|
+
let file;
|
|
526
|
+
if (options.protection === 'none') {
|
|
527
|
+
file = { v: KEYSTORE_VERSION, protection: 'none', keys: {} };
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
const passphrase = options.getPassphrase({ confirm: true });
|
|
531
|
+
const verifier = encryptSecret(VERIFIER_PLAINTEXT, passphrase, options.argonParams ?? DEFAULT_ARGON_PARAMS);
|
|
532
|
+
file = { v: KEYSTORE_VERSION, protection: 'passphrase', verifier, keys: {} };
|
|
533
|
+
}
|
|
534
|
+
writeFileAtomic(path, `${JSON.stringify(file, null, 2)}\n`, 0o600);
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Re-seals every secret in an encrypted keystore under a new passphrase (ADR
|
|
538
|
+
* 080), returning the count re-sealed. The old and new passphrases are supplied
|
|
539
|
+
* explicitly, so the store's own passphrase provider is never invoked (a wrong
|
|
540
|
+
* current passphrase is caught by the verifier). Refused on a dev keystore.
|
|
541
|
+
*/
|
|
542
|
+
export function changeKeystorePassphrase(path, oldPassphrase, newPassphrase, argonParams) {
|
|
543
|
+
const store = new FileKeyStore({
|
|
544
|
+
path,
|
|
545
|
+
...(argonParams && { argonParams }),
|
|
546
|
+
getPassphrase: () => {
|
|
547
|
+
throw new KeyStoreError(`Unexpected passphrase prompt while changing the passphrase for ${path}.`, 'KEYSTORE_INTERNAL_ERROR', { path });
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
return store.changePassphrase(oldPassphrase, newPassphrase);
|
|
243
551
|
}
|
|
244
552
|
//# sourceMappingURL=file-key-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-key-store.js","sourceRoot":"","sources":["../../../../src/keystore/file-key-store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-key-store.js","sourceRoot":"","sources":["../../../../src/keystore/file-key-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,16 +7,19 @@ export const ENV_KEYSTORE_PASSPHRASE = 'BTCR2_KEYSTORE_PASSPHRASE';
|
|
|
7
7
|
* (which would leak into process listings and shell history). Resolution order:
|
|
8
8
|
* the {@link ENV_KEYSTORE_PASSPHRASE} environment variable, a passphrase file,
|
|
9
9
|
* then a non-echoing terminal prompt. Throws if none is available and standard
|
|
10
|
-
* input is not a terminal.
|
|
10
|
+
* input is not a terminal. When `forcePrompt` is set, the env var and file are
|
|
11
|
+
* skipped and a terminal entry is required.
|
|
11
12
|
*/
|
|
12
13
|
export function acquirePassphrase(options = {}) {
|
|
13
14
|
// All sources are normalized identically (at most one trailing newline
|
|
14
15
|
// removed) so the KDF input is source-independent.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if (!options.forcePrompt) {
|
|
17
|
+
const fromEnv = process.env[ENV_KEYSTORE_PASSPHRASE];
|
|
18
|
+
if (fromEnv)
|
|
19
|
+
return assertNonEmpty(fromEnv.replace(/\r?\n$/, ''));
|
|
20
|
+
if (options.passphraseFile) {
|
|
21
|
+
return assertNonEmpty(readFileSync(options.passphraseFile, 'utf-8').replace(/\r?\n$/, ''));
|
|
22
|
+
}
|
|
20
23
|
}
|
|
21
24
|
if (!process.stdin.isTTY) {
|
|
22
25
|
throw new KeyStoreError(`No passphrase available. Set ${ENV_KEYSTORE_PASSPHRASE}, pass --passphrase-file, or run in a terminal.`, 'PASSPHRASE_REQUIRED_ERROR');
|
|
@@ -37,9 +40,32 @@ function assertNonEmpty(passphrase) {
|
|
|
37
40
|
}
|
|
38
41
|
return passphrase;
|
|
39
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* A 4-byte shared buffer used only as an {@link Atomics.wait} target. It lets
|
|
45
|
+
* {@link promptHidden} block briefly on an empty non-blocking TTY instead of
|
|
46
|
+
* busy-spinning. It is never written to, so the wait always times out.
|
|
47
|
+
*/
|
|
48
|
+
const IDLE_WAIT = new Int32Array(new SharedArrayBuffer(4));
|
|
49
|
+
/**
|
|
50
|
+
* Milliseconds to block on each empty read. Imperceptible to a typist yet long
|
|
51
|
+
* enough that an open prompt sits idle rather than pegging a CPU core.
|
|
52
|
+
*/
|
|
53
|
+
const IDLE_POLL_MS = 20;
|
|
54
|
+
/**
|
|
55
|
+
* Removes the last whole UTF-8 character from an accumulating byte array in
|
|
56
|
+
* place: pops any trailing continuation bytes (0b10xxxxxx) then the leading
|
|
57
|
+
* byte. Exported for testing; a backspace mid-entry must not strand a fragment
|
|
58
|
+
* that later decodes to U+FFFD.
|
|
59
|
+
*/
|
|
60
|
+
export function dropLastUtf8Char(bytes) {
|
|
61
|
+
while (bytes.length > 0 && (bytes[bytes.length - 1] & 0xc0) === 0x80)
|
|
62
|
+
bytes.pop();
|
|
63
|
+
bytes.pop();
|
|
64
|
+
}
|
|
40
65
|
/**
|
|
41
66
|
* Reads a line from the terminal synchronously without echoing keystrokes.
|
|
42
|
-
* Bytes are accumulated and decoded as UTF-8 so multibyte passphrases survive
|
|
67
|
+
* Bytes are accumulated and decoded as UTF-8 so multibyte passphrases survive,
|
|
68
|
+
* including a backspace that spans a whole multibyte character.
|
|
43
69
|
* This path runs only when standard input is a terminal.
|
|
44
70
|
*/
|
|
45
71
|
function promptHidden(label) {
|
|
@@ -57,8 +83,12 @@ function promptHidden(label) {
|
|
|
57
83
|
}
|
|
58
84
|
catch (error) {
|
|
59
85
|
const code = error.code;
|
|
60
|
-
if (code === 'EAGAIN')
|
|
61
|
-
|
|
86
|
+
if (code === 'EAGAIN') {
|
|
87
|
+
// No byte ready yet on a non-blocking TTY. Block briefly instead of
|
|
88
|
+
// spinning so an open prompt does not peg a CPU core while it waits.
|
|
89
|
+
Atomics.wait(IDLE_WAIT, 0, 0, IDLE_POLL_MS);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
62
92
|
if (code === 'EOF')
|
|
63
93
|
break;
|
|
64
94
|
throw error;
|
|
@@ -72,7 +102,7 @@ function promptHidden(label) {
|
|
|
72
102
|
throw new KeyStoreError('Passphrase entry aborted.', 'PASSPHRASE_REQUIRED_ERROR');
|
|
73
103
|
}
|
|
74
104
|
if (ch === 0x7f || ch === 0x08) { // DEL or backspace
|
|
75
|
-
bytes
|
|
105
|
+
dropLastUtf8Char(bytes);
|
|
76
106
|
continue;
|
|
77
107
|
}
|
|
78
108
|
bytes.push(ch);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../../../../src/keystore/passphrase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,qFAAqF;AACrF,MAAM,CAAC,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../../../../src/keystore/passphrase.ts"],"names":[],"mappings":"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"}
|