Browse Source

lightningd: '--encrypted-hsm', a new startup option

Add a new startup option which will, if set, prompt the user for a
password to derive a key from. This key will later be used to encrypt
and/or decrypt `hsm_secret`.

This was made a noarg option even if it would have been preferable to
let the user the choice of how to specify the password. Since we have
to chose, better to not let the password in the commands history.
travis-debug
darosior 5 years ago
committed by neil saitug
parent
commit
a698395bf0
  1. 9
      doc/lightningd-config.5
  2. 5
      doc/lightningd-config.5.md
  3. 5
      lightningd/lightningd.c
  4. 4
      lightningd/lightningd.h
  5. 60
      lightningd/options.c

9
doc/lightningd-config.5

@ -155,6 +155,12 @@ Identify the location of the wallet\. This is a fully qualified data source
name, including a scheme such as \fBsqlite3\fR or \fBpostgres\fR followed by the
connection parameters\.
\fBencrypted-hsm\fR
If set, you will be prompted to enter a password used to encrypt the \fBhsm_secret\fR\.
Note that once you encrypt the \fBhsm_secret\fR this option will be mandatory for
\fBlightningd\fR to start\.
.SH Lightning node customization options
\fBalias\fR=\fIRRGGBB\fR
@ -374,12 +380,15 @@ Always use the \fBproxy\fR, even to connect to normal IP addresses (you
can still connect to Unix domain sockets manually)\. This also disables
all DNS lookups, to avoid leaking information\.
\fBdisable-dns\fR
Disable the DNS bootstrapping mechanism to find a node by its node ID\.
\fBenable-autotor-v2-mode\fR
Try to get a v2 onion address from the Tor service call, default is v3\.
\fBtor-service-password\fR=\fIPASSWORD\fR
Set a Tor control password, which may be needed for \fIautotor:\fR to
authenticate to the Tor control port\.

5
doc/lightningd-config.5.md

@ -133,6 +133,11 @@ Identify the location of the wallet. This is a fully qualified data source
name, including a scheme such as `sqlite3` or `postgres` followed by the
connection parameters.
**encrypted-hsm**
If set, you will be prompted to enter a password used to encrypt the `hsm_secret`.
Note that once you encrypt the `hsm_secret` this option will be mandatory for
`lightningd` to start.
### Lightning node customization options
**alias**=*RRGGBB*

5
lightningd/lightningd.c

@ -234,6 +234,11 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
/*~ This is set when a JSON RPC command comes in to shut us down. */
ld->stop_conn = NULL;
/*~ This is used to signal that `hsm_secret` is encrypted, and will
* be set to `true` if the `--encrypted` option is passed at startup.
*/
ld->encrypted_hsm = false;
return ld;
}

4
lightningd/lightningd.h

@ -71,6 +71,8 @@ struct config {
/* Allow to define the default behavior of tot services calls*/
bool use_v3_autotor;
/* This is the key we use to encrypt `hsm_secret`. */
struct secret *keypass;
};
struct lightningd {
@ -235,6 +237,8 @@ struct lightningd {
struct plugins *plugins;
char *wallet_dsn;
bool encrypted_hsm;
};
/* Turning this on allows a tal allocation to return NULL, rather than aborting.

60
lightningd/options.c

@ -32,12 +32,14 @@
#include <lightningd/options.h>
#include <lightningd/plugin.h>
#include <lightningd/subd.h>
#include <sodium.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <wire/wire.h>
@ -366,6 +368,58 @@ static char *opt_clear_plugins(struct lightningd *ld)
return NULL;
}
/* Prompt the user to enter a password, from which will be derived the key used
* for `hsm_secret` encryption.
* The algorithm used to derive the key is Argon2(id), to which libsodium
* defaults. However argon2id-specific constants are used in case someone runs it
* with a libsodium version which default constants differs (typically <1.0.9).
*/
static char *opt_set_hsm_password(struct lightningd *ld)
{
struct termios current_term, temp_term;
char *passwd = NULL;
size_t passwd_size = 0;
u8 salt[11] = "c-lightning";
ld->encrypted_hsm = true;
ld->config.keypass = tal(NULL, struct secret);
/* Don't swap the encryption key ! */
if (sodium_mlock(ld->config.keypass->data,
sizeof(ld->config.keypass->data)) != 0)
return "Could not lock hsm_secret encryption key memory.";
/* Get the password from stdin, but don't echo it. */
if (tcgetattr(fileno(stdin), &current_term) != 0)
return "Could not get current terminal options.";
temp_term = current_term;
temp_term.c_lflag &= ~ECHO;
if (tcsetattr(fileno(stdin), TCSAFLUSH, &temp_term) != 0)
return "Could not disable password echoing.";
printf("Enter hsm_secret password : ");
if (getline(&passwd, &passwd_size, stdin) < 0)
return "Could not read password from stdin.";
if (tcsetattr(fileno(stdin), TCSAFLUSH, &current_term) != 0)
return "Could not restore terminal options.";
printf("\n");
/* Derive the key from the password. */
if (strlen(passwd) < crypto_pwhash_argon2id_PASSWD_MIN)
return "Password too short to be able to derive a key from it.";
if (strlen(passwd) > crypto_pwhash_argon2id_PASSWD_MAX)
return "Password too long to be able to derive a key from it.";
if (crypto_pwhash(ld->config.keypass->data, sizeof(ld->config.keypass->data),
passwd, strlen(passwd), salt,
/* INTERACTIVE needs 64 MiB of RAM, MODERATE needs 256,
* 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.";
free(passwd);
return NULL;
}
#if DEVELOPER
static char *opt_subprocess_debug(const char *optarg, struct lightningd *ld)
{
@ -1029,6 +1083,10 @@ static void register_opts(struct lightningd *ld)
opt_register_noarg("--enable-autotor-v2-mode", opt_set_invbool, &ld->config.use_v3_autotor,
"Try to get a v2 onion address from the Tor service call, default is v3");
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.");
opt_register_logging(ld);
opt_register_version();
@ -1215,6 +1273,8 @@ static void add_config(struct lightningd *ld,
answer = tal_fmt(name0, "%s",
ld->daemon_parent_fd == -1
? "false" : "true");
} else if (opt->cb == (void *)opt_set_hsm_password) {
json_add_bool(response, "encrypted-hsm", ld->encrypted_hsm);
} else {
/* Insert more decodes here! */
assert(!"A noarg option was added but was not handled");

Loading…
Cancel
Save