| 486 | } |
| 487 | |
| 488 | static int generate_hsm(const char *hsm_secret_path) |
| 489 | { |
| 490 | char mnemonic[BIP39_WORDLIST_LEN]; |
| 491 | char *passphrase, *err; |
| 492 | int exit_code = 0; |
| 493 | |
| 494 | read_mnemonic(mnemonic); |
| 495 | printf("Warning: remember that different passphrases yield different " |
| 496 | "bitcoin wallets.\n"); |
| 497 | printf("If left empty, no password is used (echo is disabled).\n"); |
| 498 | printf("Enter your passphrase: \n"); |
| 499 | fflush(stdout); |
| 500 | passphrase = read_stdin_pass_with_exit_code(&err, &exit_code); |
| 501 | if (!passphrase) |
| 502 | errx(exit_code, "%s", err); |
| 503 | if (strlen(passphrase) == 0) { |
| 504 | free(passphrase); |
| 505 | passphrase = NULL; |
| 506 | } |
| 507 | |
| 508 | u8 bip32_seed[BIP39_SEED_LEN_512]; |
| 509 | size_t bip32_seed_len; |
| 510 | |
| 511 | if (bip39_mnemonic_to_seed(mnemonic, passphrase, bip32_seed, sizeof(bip32_seed), &bip32_seed_len) != WALLY_OK) |
| 512 | errx(ERROR_LIBWALLY, "Unable to derive BIP32 seed from BIP39 mnemonic"); |
| 513 | |
| 514 | int fd = open(hsm_secret_path, O_CREAT|O_EXCL|O_WRONLY, 0400); |
| 515 | if (fd < 0) { |
| 516 | errx(ERROR_USAGE, "Unable to create hsm_secret file"); |
| 517 | } |
| 518 | /* Write only the first 32 bytes, length of the (plaintext) seed in the |
| 519 | * hsm_secret. */ |
| 520 | if (!write_all(fd, bip32_seed, 32)) |
| 521 | errx(ERROR_USAGE, "Error writing secret to hsm_secret file"); |
| 522 | |
| 523 | if (fsync(fd) != 0) |
| 524 | errx(ERROR_USAGE, "Error fsyncing hsm_secret file"); |
| 525 | |
| 526 | /* This should never fail if fsync succeeded. But paranoia is good, and bugs exist */ |
| 527 | if (close(fd) != 0) |
| 528 | errx(ERROR_USAGE, "Error closing hsm_secret file"); |
| 529 | |
| 530 | printf("New hsm_secret file created at %s\n", hsm_secret_path); |
| 531 | printf("Use the `encrypt` command to encrypt the BIP32 seed if needed\n"); |
| 532 | |
| 533 | free(passphrase); |
| 534 | return 0; |
| 535 | } |
| 536 | |
| 537 | static int dumponchaindescriptors(const char *hsm_secret_path, const char *old_passwd UNUSED, |
| 538 | const bool is_testnet) |
no test coverage detected