Skip to content

Commit f1f398f

Browse files
committed
Fixed tests about decryption and starting the node with a mnemonic secret
1 parent a20abff commit f1f398f

File tree

3 files changed

+119
-151
lines changed

3 files changed

+119
-151
lines changed

hsmd/hsmd.c

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -279,31 +279,43 @@ static void create_hsm(int fd, const char *passphrase)
279279

280280
/* Always create a mnemonic-based hsm_secret */
281281
u8 entropy[BIP39_ENTROPY_LEN_128];
282-
char *mnemonic;
282+
char *mnemonic = NULL;
283283
struct sha256 seed_hash;
284284

285+
status_debug("HSM: Starting create_hsm with passphrase=%s", passphrase ? "provided" : "none");
286+
287+
/* Initialize wally tal context for libwally operations */
288+
tal_wally_start();
289+
status_debug("HSM: Initialized wally tal context");
290+
285291
/* Generate random entropy for new mnemonic */
286292
randombytes_buf(entropy, sizeof(entropy));
293+
status_debug("HSM: Generated random entropy");
287294

288295
/* Generate mnemonic from entropy */
289296
if (bip39_mnemonic_from_bytes(NULL, entropy, sizeof(entropy), &mnemonic) != WALLY_OK) {
297+
tal_wally_end(tmpctx);
290298
unlink_noerr("hsm_secret");
291299
status_failed(STATUS_FAIL_INTERNAL_ERROR,
292300
"Failed to generate mnemonic from entropy");
293301
}
302+
status_debug("HSM: Generated mnemonic from entropy");
294303

295304
if (!mnemonic) {
305+
tal_wally_end(tmpctx);
296306
unlink_noerr("hsm_secret");
297307
status_failed(STATUS_FAIL_INTERNAL_ERROR,
298308
"Failed to get generated mnemonic");
299309
}
300310

301311
/* Derive seed hash from mnemonic + passphrase (or zero if no passphrase) */
302312
if (!derive_seed_hash(mnemonic, passphrase, &seed_hash)) {
313+
tal_wally_end(tmpctx);
303314
unlink_noerr("hsm_secret");
304315
status_failed(STATUS_FAIL_INTERNAL_ERROR,
305316
"Failed to derive seed hash from mnemonic");
306317
}
318+
status_debug("HSM: Derived seed hash from mnemonic");
307319

308320
/* Create hsm_secret format: seed_hash (32 bytes) + mnemonic */
309321
hsm_secret_len = PASSPHRASE_HASH_LEN + strlen(mnemonic);
@@ -313,29 +325,34 @@ static void create_hsm(int fd, const char *passphrase)
313325
memcpy(hsm_secret_data, &seed_hash, PASSPHRASE_HASH_LEN);
314326
/* Copy mnemonic after seed hash */
315327
memcpy(hsm_secret_data + PASSPHRASE_HASH_LEN, mnemonic, strlen(mnemonic));
328+
status_debug("HSM: Created hsm_secret data structure");
316329

317330
/* Derive the actual secret from mnemonic + passphrase for our global hsm_secret */
318331
u8 bip32_seed[BIP39_SEED_LEN_512];
319332
size_t bip32_seed_len;
320333

321334
if (bip39_mnemonic_to_seed(mnemonic, passphrase, bip32_seed, sizeof(bip32_seed), &bip32_seed_len) != WALLY_OK) {
335+
tal_wally_end(tmpctx);
322336
unlink_noerr("hsm_secret");
323337
status_failed(STATUS_FAIL_INTERNAL_ERROR,
324338
"Failed to derive seed from mnemonic");
325339
}
340+
status_debug("HSM: Derived BIP32 seed from mnemonic");
326341

327342
/* Use first 32 bytes for hsm_secret */
328343
memcpy(&hsm_secret.secret, bip32_seed, sizeof(hsm_secret.secret));
329344

330-
/* Clean up the mnemonic */
331-
wally_free_string(mnemonic);
332-
345+
/* Clean up wally allocations */
346+
tal_wally_end(tmpctx);
347+
status_debug("HSM: Cleaned up wally allocations");
348+
333349
/* Write the hsm_secret data to file */
334350
if (!write_all(fd, hsm_secret_data, hsm_secret_len)) {
335351
unlink_noerr("hsm_secret");
336352
status_failed(STATUS_FAIL_INTERNAL_ERROR,
337353
"writing: %s", strerror(errno));
338354
}
355+
status_debug("HSM: Successfully wrote hsm_secret to file");
339356
}
340357

341358
/*~ We store our root secret in a "hsm_secret" file (like all of Core Lightning,
@@ -351,12 +368,16 @@ static void maybe_create_new_hsm(const char *passphrase)
351368
int fd = open("hsm_secret", O_CREAT|O_EXCL|O_WRONLY, 0400);
352369
if (fd < 0) {
353370
/* If this is not the first time we've run, it will exist. */
354-
if (errno == EEXIST)
371+
if (errno == EEXIST) {
372+
status_debug("HSM: hsm_secret file already exists, skipping creation");
355373
return;
374+
}
356375
status_failed(STATUS_FAIL_INTERNAL_ERROR,
357376
"creating: %s", strerror(errno));
358377
}
359378

379+
status_debug("HSM: Creating new hsm_secret file");
380+
360381
/*~ Store the seed in clear. New hsm_secret files will use mnemonic format
361382
* with passphrases, not encrypted 32-byte secrets. */
362383
create_hsm(fd, passphrase);
@@ -403,26 +424,44 @@ static void load_hsm(const char *passphrase)
403424
struct hsm_secret *hsms;
404425
enum hsm_secret_error err;
405426

427+
status_debug("HSM: Starting load_hsm with passphrase=%s", passphrase ? "provided" : "none");
428+
429+
/* Initialize wally tal context for libwally operations */
430+
tal_wally_start();
431+
status_debug("HSM: Initialized wally tal context for load_hsm");
432+
406433
/* Read the hsm_secret file */
407434
hsm_secret_contents = grab_file(tmpctx, "hsm_secret");
408-
if (!hsm_secret_contents)
435+
if (!hsm_secret_contents) {
436+
tal_wally_end(tmpctx);
409437
status_failed(STATUS_FAIL_INTERNAL_ERROR,
410438
"Could not read hsm_secret: %s", strerror(errno));
439+
}
440+
status_debug("HSM: Successfully read hsm_secret file, size=%zu", tal_bytelen(hsm_secret_contents));
411441

412442
/* Remove the NUL terminator that grab_file adds */
413443
tal_resize(&hsm_secret_contents, tal_bytelen(hsm_secret_contents) - 1);
444+
status_debug("HSM: Removed NUL terminator, new size=%zu", tal_bytelen(hsm_secret_contents));
414445

415446
/* Extract the secret using the new hsm_secret module */
447+
status_debug("HSM: Calling extract_hsm_secret");
416448
hsms = extract_hsm_secret(tmpctx, hsm_secret_contents,
417449
tal_bytelen(hsm_secret_contents),
418450
passphrase, &err);
419451
if (!hsms) {
452+
tal_wally_end(tmpctx);
420453
status_failed(STATUS_FAIL_INTERNAL_ERROR,
421454
"Failed to load hsm_secret: %s", hsm_secret_error_str(err));
422455
}
456+
status_debug("HSM: Successfully extracted hsm_secret");
423457

424458
/* Copy the extracted secret to our global hsm_secret */
425459
memcpy(&hsm_secret, &hsms->secret, sizeof(hsm_secret));
460+
status_debug("HSM: Copied secret to global hsm_secret");
461+
462+
/* Clean up wally allocations */
463+
tal_wally_end(tmpctx);
464+
status_debug("HSM: Cleaned up wally allocations in load_hsm");
426465
}
427466

428467
/*~ We have a pre-init call in developer mode, to set dev flags */
@@ -462,6 +501,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
462501
u32 minversion, maxversion;
463502
const u32 our_minversion = 4, our_maxversion = 6;
464503

504+
status_debug("HSM: Starting init_hsm");
505+
465506
/* This must be lightningd. */
466507
assert(is_lightningd(c));
467508

@@ -479,6 +520,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
479520
&minversion, &maxversion, &tlvs))
480521
return bad_req(conn, c, msg_in);
481522

523+
status_debug("HSM: Successfully parsed init message");
524+
482525
/*~ Usually we don't worry about API breakage between internal daemons,
483526
* but there are other implementations of the HSM daemon now, so we
484527
* do at least the simplest, clearest thing. */
@@ -488,6 +531,8 @@ static struct io_plan *init_hsm(struct io_conn *conn,
488531
minversion, maxversion,
489532
our_minversion, our_maxversion);
490533

534+
status_debug("HSM: Version check passed");
535+
491536
/*~ Don't swap this. */
492537
sodium_mlock(hsm_secret.secret.data, sizeof(hsm_secret.secret.data));
493538

@@ -502,16 +547,23 @@ static struct io_plan *init_hsm(struct io_conn *conn,
502547
const char *hsm_passphrase = NULL;
503548
if (tlvs && tlvs->hsm_passphrase) {
504549
hsm_passphrase = (const char *)tlvs->hsm_passphrase;
550+
status_debug("HSM: Passphrase provided in TLV");
551+
} else {
552+
status_debug("HSM: No passphrase provided in TLV");
505553
}
506554

507555
/* Once we have read the init message we know which params the master
508556
* will use */
509557
c->chainparams = chainparams;
558+
status_debug("HSM: About to call maybe_create_new_hsm");
510559
maybe_create_new_hsm(hsm_passphrase);
560+
status_debug("HSM: About to call load_hsm");
511561
load_hsm(hsm_passphrase);
562+
status_debug("HSM: Successfully loaded hsm_secret");
512563

513564
/* Define the minimum common max version for the hsmd one */
514565
hsmd_mutual_version = maxversion < our_maxversion ? maxversion : our_maxversion;
566+
status_debug("HSM: Sending init reply");
515567
return req_reply(conn, c, hsmd_init(hsm_secret.secret, hsmd_mutual_version,
516568
bip32_key_version));
517569
}

lightningd/hsm_control.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,16 @@ static const char *read_hsm_passphrase_if_needed(struct lightningd *ld)
8888
if (!ld->hsm_passphrase_required)
8989
return NULL;
9090

91-
printf("The hsm_secret uses a mnemonic with a passphrase. In order to "
92-
"derive the seed and start the node you must provide the passphrase.\n");
93-
printf("Enter hsm_secret passphrase: ");
94-
fflush(stdout);
91+
log_info(ld->log, "The hsm_secret uses a mnemonic with a passphrase. In order to "
92+
"derive the seed and start the node you must provide the passphrase.");
93+
log_info(ld->log, "Enter hsm_secret passphrase: ");
9594

9695
enum hsm_secret_error err;
9796
const char *passphrase = read_stdin_pass(tmpctx, &err);
9897
if (err != HSM_SECRET_OK) {
9998
fatal("Failed to read passphrase: %s", hsm_secret_error_str(err));
10099
}
101100

102-
printf("\n");
103-
104101
return passphrase;
105102
}
106103

0 commit comments

Comments
 (0)