mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-19 05:44:12 +01:00
lightningd: support hsm error code
Suggested-by: Rusty Russell Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com> Changelog-Changed: Support hsm specific error error code in lightning-cli
This commit is contained in:
parent
9a85b02c6f
commit
43ff949ea7
@ -9,4 +9,10 @@ typedef s32 errcode_t;
|
||||
|
||||
#define PRIerrcode PRId32
|
||||
|
||||
// HSM errors code
|
||||
#define HSM_GENERIC_ERROR 20
|
||||
#define HSM_ERROR_IS_ENCRYPT 21
|
||||
#define HSM_BAD_PASSWORD 22
|
||||
#define HSM_PASSWORD_INPUT_ERR 23
|
||||
|
||||
#endif /* LIGHTNING_COMMON_ERRCODE_H */
|
||||
|
@ -1,21 +1,28 @@
|
||||
#include "config.h"
|
||||
#include <common/errcode.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *hsm_secret_encryption_key(const char *pass, struct secret *key)
|
||||
int hsm_secret_encryption_key_with_exitcode(const char *pass, struct secret *key,
|
||||
char **err_msg)
|
||||
{
|
||||
u8 salt[16] = "c-lightning\0\0\0\0\0";
|
||||
|
||||
/* Don't swap the encryption key ! */
|
||||
if (sodium_mlock(key->data, sizeof(key->data)) != 0)
|
||||
return "Could not lock hsm_secret encryption key memory.";
|
||||
if (sodium_mlock(key->data, sizeof(key->data)) != 0) {
|
||||
*err_msg = "Could not lock hsm_secret encryption key memory.";
|
||||
return HSM_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
/* Check bounds. */
|
||||
if (strlen(pass) < crypto_pwhash_argon2id_PASSWD_MIN)
|
||||
return "Password too short to be able to derive a key from it.";
|
||||
if (strlen(pass) > crypto_pwhash_argon2id_PASSWD_MAX)
|
||||
return "Password too long to be able to derive a key from it.";
|
||||
if (strlen(pass) < crypto_pwhash_argon2id_PASSWD_MIN) {
|
||||
*err_msg = "Password too short to be able to derive a key from it.";
|
||||
return HSM_BAD_PASSWORD;
|
||||
} else if (strlen(pass) > crypto_pwhash_argon2id_PASSWD_MAX) {
|
||||
*err_msg = "Password too long to be able to derive a key from it.";
|
||||
return HSM_BAD_PASSWORD;
|
||||
}
|
||||
|
||||
/* Now derive the key. */
|
||||
if (crypto_pwhash(key->data, sizeof(key->data), pass, strlen(pass), salt,
|
||||
@ -23,10 +30,12 @@ char *hsm_secret_encryption_key(const char *pass, struct secret *key)
|
||||
* and SENSITIVE needs 1024. */
|
||||
crypto_pwhash_argon2id_OPSLIMIT_MODERATE,
|
||||
crypto_pwhash_argon2id_MEMLIMIT_MODERATE,
|
||||
crypto_pwhash_ALG_ARGON2ID13) != 0)
|
||||
return "Could not derive a key from the password.";
|
||||
crypto_pwhash_ALG_ARGON2ID13) != 0) {
|
||||
*err_msg = "Could not derive a key from the password.";
|
||||
return HSM_BAD_PASSWORD;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool encrypt_hsm_secret(const struct secret *encryption_key,
|
||||
@ -90,7 +99,7 @@ static bool getline_stdin_pass(char **passwd, size_t *passwd_size)
|
||||
return true;
|
||||
}
|
||||
|
||||
char *read_stdin_pass(char **reason)
|
||||
char *read_stdin_pass_with_exit_code(char **reason, int *exit_code)
|
||||
{
|
||||
struct termios current_term, temp_term;
|
||||
char *passwd = NULL;
|
||||
@ -100,17 +109,20 @@ char *read_stdin_pass(char **reason)
|
||||
/* Set a temporary term, same as current but with ECHO disabled. */
|
||||
if (tcgetattr(fileno(stdin), ¤t_term) != 0) {
|
||||
*reason = "Could not get current terminal options.";
|
||||
*exit_code = HSM_PASSWORD_INPUT_ERR;
|
||||
return NULL;
|
||||
}
|
||||
temp_term = current_term;
|
||||
temp_term.c_lflag &= ~ECHO;
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, &temp_term) != 0) {
|
||||
*reason = "Could not disable pass echoing.";
|
||||
*exit_code = HSM_PASSWORD_INPUT_ERR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!getline_stdin_pass(&passwd, &passwd_size)) {
|
||||
*reason = "Could not read pass from stdin.";
|
||||
*exit_code = HSM_PASSWORD_INPUT_ERR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -118,12 +130,13 @@ char *read_stdin_pass(char **reason)
|
||||
if (tcsetattr(fileno(stdin), TCSANOW, ¤t_term) != 0) {
|
||||
*reason = "Could not restore terminal options.";
|
||||
free(passwd);
|
||||
*exit_code = HSM_PASSWORD_INPUT_ERR;
|
||||
return NULL;
|
||||
}
|
||||
} else if (!getline_stdin_pass(&passwd, &passwd_size)) {
|
||||
*reason = "Could not read pass from stdin.";
|
||||
*exit_code = HSM_PASSWORD_INPUT_ERR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return passwd;
|
||||
}
|
||||
|
@ -21,10 +21,12 @@ struct encrypted_hsm_secret {
|
||||
/** Derive the hsm_secret encryption key from a passphrase.
|
||||
* @pass: the passphrase string.
|
||||
* @encryption_key: the output key derived from the passphrase.
|
||||
* @err_msg: if not NULL the error message contains the reason of the failure.
|
||||
*
|
||||
* On success, NULL is returned. On error, a human-readable error is.
|
||||
* On success, 0 is returned, on error a value > 0 is returned and it can be used as exit code.
|
||||
*/
|
||||
char *hsm_secret_encryption_key(const char *pass, struct secret *encryption_key);
|
||||
int hsm_secret_encryption_key_with_exitcode(const char *pass, struct secret *key,
|
||||
char **err_msg);
|
||||
|
||||
/** Encrypt the hsm_secret using a previously derived encryption key.
|
||||
* @encryption_key: the key derived from the passphrase.
|
||||
@ -54,10 +56,11 @@ bool decrypt_hsm_secret(const struct secret *encryption_key,
|
||||
void discard_key(struct secret *key TAKES);
|
||||
|
||||
/** Read hsm_secret encryption pass from stdin, disabling echoing.
|
||||
* @reason: if NULL is returned, will point to the human-readable error.
|
||||
* @reason: if NULL is returned, will point to the human-readable error,
|
||||
* and the correct exit code is returned by the exit_code parameter.
|
||||
*
|
||||
* Caller must free the string as it does tal-reallocate getline's output.
|
||||
*/
|
||||
char *read_stdin_pass(char **reason);
|
||||
char *read_stdin_pass_with_exit_code(char **reason, int *exit_code);
|
||||
|
||||
#endif /* LIGHTNING_COMMON_HSM_ENCRYPTION_H */
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/fdpass/fdpass.h>
|
||||
#include <common/ecdh.h>
|
||||
#include <common/errcode.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/param.h>
|
||||
@ -82,14 +83,14 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
||||
|
||||
/* We actually send requests synchronously: only status is async. */
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
|
||||
err(1, "Could not create hsm socketpair");
|
||||
err(HSM_GENERIC_ERROR, "Could not create hsm socketpair");
|
||||
|
||||
ld->hsm = new_global_subd(ld, "lightning_hsmd",
|
||||
hsmd_wire_name,
|
||||
hsm_msg,
|
||||
take(&fds[1]), NULL);
|
||||
if (!ld->hsm)
|
||||
err(1, "Could not subd hsm");
|
||||
err(HSM_GENERIC_ERROR, "Could not subd hsm");
|
||||
|
||||
/* If hsm_secret is encrypted and the --encrypted-hsm startup option is
|
||||
* not passed, don't let hsmd use the first 32 bytes of the cypher as the
|
||||
@ -98,7 +99,7 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
||||
struct stat st;
|
||||
if (stat("hsm_secret", &st) == 0 &&
|
||||
st.st_size == ENCRYPTED_HSM_SECRET_LEN)
|
||||
errx(1, "hsm_secret is encrypted, you need to pass the "
|
||||
errx(HSM_ERROR_IS_ENCRYPT, "hsm_secret is encrypted, you need to pass the "
|
||||
"--encrypted-hsm startup option.");
|
||||
}
|
||||
|
||||
@ -111,7 +112,7 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
||||
IFDEV(ld->dev_force_bip32_seed, NULL),
|
||||
IFDEV(ld->dev_force_channel_secrets, NULL),
|
||||
IFDEV(ld->dev_force_channel_secrets_shaseed, NULL))))
|
||||
err(1, "Writing init msg to hsm");
|
||||
err(HSM_GENERIC_ERROR, "Writing init msg to hsm");
|
||||
|
||||
bip32_base = tal(ld, struct ext_key);
|
||||
msg = wire_sync_read(tmpctx, ld->hsm_fd);
|
||||
@ -120,8 +121,8 @@ struct ext_key *hsm_init(struct lightningd *ld)
|
||||
&ld->bolt12_base,
|
||||
&ld->onion_reply_secret)) {
|
||||
if (ld->config.keypass)
|
||||
errx(1, "Wrong password for encrypted hsm_secret.");
|
||||
errx(1, "HSM did not give init reply");
|
||||
errx(HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret.");
|
||||
errx(HSM_GENERIC_ERROR, "HSM did not give init reply");
|
||||
}
|
||||
|
||||
return bip32_base;
|
||||
|
@ -26,6 +26,20 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
/* Unless overridden, we exit with status 1 when option parsing fails */
|
||||
static int opt_exitcode = 1;
|
||||
|
||||
static void opt_log_stderr_exitcode(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
exit(opt_exitcode);
|
||||
}
|
||||
|
||||
/* Declare opt_add_addr here, because we we call opt_add_addr
|
||||
* and opt_announce_addr vice versa
|
||||
*/
|
||||
@ -461,7 +475,7 @@ static char *opt_important_plugin(const char *arg, struct lightningd *ld)
|
||||
*/
|
||||
static char *opt_set_hsm_password(struct lightningd *ld)
|
||||
{
|
||||
char *passwd, *passwd_confirmation, *err;
|
||||
char *passwd, *passwd_confirmation, *err_msg;
|
||||
|
||||
printf("The hsm_secret is encrypted with a password. In order to "
|
||||
"decrypt it and start the node you must provide the password.\n");
|
||||
@ -469,20 +483,23 @@ static char *opt_set_hsm_password(struct lightningd *ld)
|
||||
/* If we don't flush we might end up being buffered and we might seem
|
||||
* to hang while we wait for the password. */
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
|
||||
passwd = read_stdin_pass_with_exit_code(&err_msg, &opt_exitcode);
|
||||
if (!passwd)
|
||||
return err;
|
||||
return err_msg;
|
||||
printf("Confirm hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd_confirmation = read_stdin_pass(&err);
|
||||
passwd_confirmation = read_stdin_pass_with_exit_code(&err_msg, &opt_exitcode);
|
||||
if (!passwd_confirmation)
|
||||
return err;
|
||||
return err_msg;
|
||||
printf("\n");
|
||||
|
||||
ld->config.keypass = tal(NULL, struct secret);
|
||||
err = hsm_secret_encryption_key(passwd, ld->config.keypass);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
opt_exitcode = hsm_secret_encryption_key_with_exitcode(passwd, ld->config.keypass, &err_msg);
|
||||
if (opt_exitcode > 0)
|
||||
return err_msg;
|
||||
|
||||
ld->encrypted_hsm = true;
|
||||
free(passwd);
|
||||
free(passwd_confirmation);
|
||||
@ -1087,8 +1104,8 @@ static void register_opts(struct lightningd *ld)
|
||||
opt_hidden);
|
||||
|
||||
opt_register_noarg("--encrypted-hsm", opt_set_hsm_password, ld,
|
||||
"Set the password to encrypt hsm_secret with. If no password is passed through command line, "
|
||||
"you will be prompted to enter it.");
|
||||
"Set the password to encrypt hsm_secret with. If no password is passed through command line, "
|
||||
"you will be prompted to enter it.");
|
||||
|
||||
opt_register_arg("--rpc-file-mode", &opt_set_mode, &opt_show_mode,
|
||||
&ld->rpc_filemode,
|
||||
@ -1315,10 +1332,9 @@ void handle_opts(struct lightningd *ld, int argc, char *argv[])
|
||||
parse_config_files(ld->config_filename, ld->config_basedir, false);
|
||||
|
||||
/* Now parse cmdline, which overrides config. */
|
||||
opt_parse(&argc, argv, opt_log_stderr_exit);
|
||||
opt_parse(&argc, argv, opt_log_stderr_exitcode);
|
||||
if (argc != 1)
|
||||
errx(1, "no arguments accepted");
|
||||
|
||||
/* We keep a separate variable rather than overriding always_use_proxy,
|
||||
* so listconfigs shows the correct thing. */
|
||||
if (tal_count(ld->proposed_wireaddr) != 0
|
||||
|
@ -17,6 +17,11 @@ import unittest
|
||||
|
||||
WAIT_TIMEOUT = 60 # Wait timeout for processes
|
||||
|
||||
# Errors codes
|
||||
HSM_GENERIC_ERROR = 20
|
||||
HSM_ERROR_IS_ENCRYPT = 21
|
||||
HSM_BAD_PASSWORD = 22
|
||||
|
||||
|
||||
@unittest.skipIf(TEST_NETWORK != 'regtest', "Test relies on a number of example addresses valid only in regtest")
|
||||
def test_withdraw(node_factory, bitcoind):
|
||||
@ -1018,7 +1023,7 @@ def test_hsm_secret_encryption(node_factory):
|
||||
|
||||
# Test we cannot start the same wallet without specifying --encrypted-hsm
|
||||
l1.daemon.opts.pop("encrypted-hsm")
|
||||
with pytest.raises(subprocess.CalledProcessError, match=r'returned non-zero exit status 1'):
|
||||
with pytest.raises(subprocess.CalledProcessError, match=r'returned non-zero exit status {}'.format(HSM_ERROR_IS_ENCRYPT)):
|
||||
subprocess.check_call(l1.daemon.cmd_line)
|
||||
|
||||
# Test we cannot restore the same wallet with another password
|
||||
@ -1029,7 +1034,7 @@ def test_hsm_secret_encryption(node_factory):
|
||||
write_all(master_fd, password[2:].encode("utf-8"))
|
||||
l1.daemon.wait_for_log(r'Confirm hsm_secret password')
|
||||
write_all(master_fd, password[2:].encode("utf-8"))
|
||||
assert(l1.daemon.proc.wait(WAIT_TIMEOUT) == 1)
|
||||
assert(l1.daemon.proc.wait(WAIT_TIMEOUT) == HSM_BAD_PASSWORD)
|
||||
assert(l1.daemon.is_in_log("Wrong password for encrypted hsm_secret."))
|
||||
|
||||
# Test we can restore the same wallet with the same password
|
||||
@ -1097,6 +1102,7 @@ def test_hsmtool_secret_decryption(node_factory):
|
||||
hsmtool.wait_for_log(r"Enter hsm_secret password:")
|
||||
write_all(master_fd, password.encode("utf-8"))
|
||||
assert hsmtool.proc.wait(WAIT_TIMEOUT) == 0
|
||||
|
||||
# Then test we can now start it without password
|
||||
l1.daemon.opts.pop("encrypted-hsm")
|
||||
l1.daemon.start(stdin=slave_fd, wait_for_initialized=True)
|
||||
@ -1115,7 +1121,7 @@ def test_hsmtool_secret_decryption(node_factory):
|
||||
assert hsmtool.proc.wait(WAIT_TIMEOUT) == 0
|
||||
# Now we need to pass the encrypted-hsm startup option
|
||||
l1.stop()
|
||||
with pytest.raises(subprocess.CalledProcessError, match=r'returned non-zero exit status 1'):
|
||||
with pytest.raises(subprocess.CalledProcessError, match=r'returned non-zero exit status {}'.format(HSM_ERROR_IS_ENCRYPT)):
|
||||
subprocess.check_call(l1.daemon.cmd_line)
|
||||
|
||||
l1.daemon.opts.update({"encrypted-hsm": None})
|
||||
|
@ -90,6 +90,7 @@ static void get_encrypted_hsm_secret(struct secret *hsm_secret,
|
||||
struct secret key;
|
||||
struct encrypted_hsm_secret encrypted_secret;
|
||||
char *err;
|
||||
int exit_code = 0;
|
||||
|
||||
fd = open(hsm_secret_path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
@ -98,9 +99,9 @@ static void get_encrypted_hsm_secret(struct secret *hsm_secret,
|
||||
if (!read_all(fd, encrypted_secret.data, ENCRYPTED_HSM_SECRET_LEN))
|
||||
errx(ERROR_HSM_FILE, "Could not read encrypted hsm_secret");
|
||||
|
||||
err = hsm_secret_encryption_key(passwd, &key);
|
||||
if (err)
|
||||
errx(ERROR_LIBSODIUM, "%s", err);
|
||||
exit_code = hsm_secret_encryption_key_with_exitcode(passwd, &key, &err);
|
||||
if (exit_code > 0)
|
||||
errx(exit_code, "%s", err);
|
||||
if (!decrypt_hsm_secret(&key, &encrypted_secret, hsm_secret))
|
||||
errx(ERROR_LIBSODIUM, "Could not retrieve the seed. Wrong password ?");
|
||||
|
||||
@ -164,15 +165,15 @@ static int decrypt_hsm(const char *hsm_secret_path)
|
||||
struct secret hsm_secret;
|
||||
char *passwd, *err;
|
||||
const char *dir, *backup;
|
||||
|
||||
int exit_code = 0;
|
||||
/* This checks the file existence, too. */
|
||||
if (!hsm_secret_is_encrypted(hsm_secret_path))
|
||||
errx(ERROR_USAGE, "hsm_secret is not encrypted");
|
||||
printf("Enter hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
passwd = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
|
||||
if (sodium_init() == -1)
|
||||
errx(ERROR_LIBSODIUM,
|
||||
@ -221,6 +222,7 @@ static int encrypt_hsm(const char *hsm_secret_path)
|
||||
struct encrypted_hsm_secret encrypted_hsm_secret;
|
||||
char *passwd, *passwd_confirmation, *err;
|
||||
const char *dir, *backup;
|
||||
int exit_code = 0;
|
||||
|
||||
/* This checks the file existence, too. */
|
||||
if (hsm_secret_is_encrypted(hsm_secret_path))
|
||||
@ -228,14 +230,14 @@ static int encrypt_hsm(const char *hsm_secret_path)
|
||||
|
||||
printf("Enter hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
passwd = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
printf("Confirm hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd_confirmation = read_stdin_pass(&err);
|
||||
passwd_confirmation = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd_confirmation)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
if (!streq(passwd, passwd_confirmation))
|
||||
errx(ERROR_USAGE, "Passwords confirmation mismatch.");
|
||||
get_hsm_secret(&hsm_secret, hsm_secret_path);
|
||||
@ -249,9 +251,9 @@ static int encrypt_hsm(const char *hsm_secret_path)
|
||||
|
||||
/* Derive the encryption key from the password provided, and try to encrypt
|
||||
* the seed. */
|
||||
err = hsm_secret_encryption_key(passwd, &key);
|
||||
if (err)
|
||||
errx(ERROR_LIBSODIUM, "%s", err);
|
||||
exit_code = hsm_secret_encryption_key_with_exitcode(passwd, &key, &err);
|
||||
if (exit_code > 0)
|
||||
errx(exit_code, "%s", err);
|
||||
if (!encrypt_hsm_secret(&key, &hsm_secret, &encrypted_hsm_secret))
|
||||
errx(ERROR_LIBSODIUM, "Could not encrypt the hsm_secret seed.");
|
||||
|
||||
@ -295,6 +297,7 @@ static int dump_commitments_infos(struct node_id *node_id, u64 channel_id,
|
||||
struct secret hsm_secret, channel_seed, per_commitment_secret;
|
||||
struct pubkey per_commitment_point;
|
||||
char *passwd, *err;
|
||||
int exit_code = 0;
|
||||
|
||||
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||
| SECP256K1_CONTEXT_SIGN);
|
||||
@ -303,9 +306,9 @@ static int dump_commitments_infos(struct node_id *node_id, u64 channel_id,
|
||||
if (hsm_secret_is_encrypted(hsm_secret_path)) {
|
||||
printf("Enter hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
passwd = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd);
|
||||
free(passwd);
|
||||
} else
|
||||
@ -357,7 +360,7 @@ static int guess_to_remote(const char *address, struct node_id *node_id,
|
||||
u8 goal_pubkeyhash[20];
|
||||
/* See common/bech32.h for buffer size. */
|
||||
char hrp[strlen(address) - 6];
|
||||
int witver;
|
||||
int witver, exit_code = 0;
|
||||
size_t witlen;
|
||||
|
||||
/* Get the hrp to accept addresses from any network. */
|
||||
@ -373,9 +376,9 @@ static int guess_to_remote(const char *address, struct node_id *node_id,
|
||||
if (hsm_secret_is_encrypted(hsm_secret_path)) {
|
||||
printf("Enter hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
passwd = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd);
|
||||
free(passwd);
|
||||
} else
|
||||
@ -478,6 +481,7 @@ static int generate_hsm(const char *hsm_secret_path)
|
||||
{
|
||||
char mnemonic[BIP39_WORDLIST_LEN];
|
||||
char *passphrase, *err;
|
||||
int exit_code = 0;
|
||||
|
||||
read_mnemonic(mnemonic);
|
||||
printf("Warning: remember that different passphrases yield different "
|
||||
@ -485,9 +489,9 @@ static int generate_hsm(const char *hsm_secret_path)
|
||||
printf("If left empty, no password is used (echo is disabled).\n");
|
||||
printf("Enter your passphrase: \n");
|
||||
fflush(stdout);
|
||||
passphrase = read_stdin_pass(&err);
|
||||
passphrase = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passphrase)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
if (strlen(passphrase) == 0) {
|
||||
free(passphrase);
|
||||
passphrase = NULL;
|
||||
@ -534,14 +538,15 @@ static int dumponchaindescriptors(const char *hsm_secret_path, const char *old_p
|
||||
struct ext_key master_extkey;
|
||||
char *enc_xpub, *descriptor;
|
||||
struct descriptor_checksum checksum;
|
||||
int exit_code = 0;
|
||||
|
||||
/* This checks the file existence, too. */
|
||||
if (hsm_secret_is_encrypted(hsm_secret_path)) {
|
||||
printf("Enter hsm_secret password:\n");
|
||||
fflush(stdout);
|
||||
passwd = read_stdin_pass(&err);
|
||||
passwd = read_stdin_pass_with_exit_code(&err, &exit_code);
|
||||
if (!passwd)
|
||||
errx(ERROR_TERM, "%s", err);
|
||||
errx(exit_code, "%s", err);
|
||||
get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd);
|
||||
free(passwd);
|
||||
} else
|
||||
|
Loading…
Reference in New Issue
Block a user