Skip to content

Commit

Permalink
developer: add --dev-force-privkey to allow setting a specific node key.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and niftynei committed Jul 17, 2019
1 parent fb6870c commit 07adb7e
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 2 deletions.
1 change: 1 addition & 0 deletions hsmd/hsm_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ hsmstatus_client_bad_request,,msg,len*u8
# Start the HSM.
hsm_init,11
hsm_init,,bip32_key_version,struct bip32_key_version
hsm_init,,dev_force_privkey,?struct privkey

#include <common/bip32.h>
hsm_init_reply,111
Expand Down
24 changes: 23 additions & 1 deletion hsmd/hsmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ static struct {
* so set it static.*/
static struct bip32_key_version bip32_key_version;

#if DEVELOPER
/* If they specify --dev-force-privkey it ends up in here. */
static struct privkey *dev_force_privkey;
#endif

/*~ We keep track of clients, but there's not much to keep. */
struct client {
/* The ccan/io async io connection for this client: it closes, we die. */
Expand Down Expand Up @@ -314,6 +319,17 @@ static void node_key(struct privkey *node_privkey, struct pubkey *node_id)
salt++;
} while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey,
node_privkey->secret.data));

#if DEVELOPER
/* In DEVELOPER mode, we can override with --dev-force-privkey */
if (dev_force_privkey) {
*node_privkey = *dev_force_privkey;
if (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey,
node_privkey->secret.data))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Failed to derive pubkey for dev_force_privkey");
}
#endif
}

/*~ This secret is the basis for all per-channel secrets: the per-channel seeds
Expand Down Expand Up @@ -540,6 +556,7 @@ static struct io_plan *init_hsm(struct io_conn *conn,
{
struct node_id node_id;
struct pubkey key;
struct privkey *privkey;

/* This must be lightningd. */
assert(is_lightningd(c));
Expand All @@ -548,9 +565,12 @@ static struct io_plan *init_hsm(struct io_conn *conn,
* definitions in hsm_client_wire.csv. The format of those files is
* an extension of the simple comma-separated format output by the
* BOLT tools/extract-formats.py tool. */
if (!fromwire_hsm_init(msg_in, &bip32_key_version))
if (!fromwire_hsm_init(NULL, msg_in, &bip32_key_version, &privkey))
return bad_req(conn, c, msg_in);

#if DEVELOPER
dev_force_privkey = privkey;
#endif
maybe_create_new_hsm();
load_hsm();

Expand Down Expand Up @@ -1601,6 +1621,8 @@ static struct io_plan *handle_memleak(struct io_conn *conn,
memleak_remove_uintmap(memtable, &clients);
memleak_scan_region(memtable, status_conn, tal_bytelen(status_conn));

memleak_scan_region(memtable, dev_force_privkey, 0);

found_leak = dump_memleak(memtable);
reply = towire_hsm_dev_memleak_reply(NULL, found_leak);
return req_reply(conn, c, take(reply));
Expand Down
8 changes: 7 additions & 1 deletion lightningd/hsm_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,13 @@ void hsm_init(struct lightningd *ld)

ld->hsm_fd = fds[0];
if (!wire_sync_write(ld->hsm_fd, towire_hsm_init(tmpctx,
&ld->topology->bitcoind->chainparams->bip32_key_version)))
&ld->topology->bitcoind->chainparams->bip32_key_version,
#if DEVELOPER
ld->dev_force_privkey
#else
NULL
#endif
)))
err(1, "Writing init msg to hsm");

ld->wallet->bip32_base = tal(ld->wallet, struct ext_key);
Expand Down
1 change: 1 addition & 0 deletions lightningd/lightningd.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->dev_subdaemon_fail = false;
ld->dev_allow_localhost = false;
ld->dev_gossip_time = 0;
ld->dev_force_privkey = NULL;
#endif

/*~ These are CCAN lists: an embedded double-linked list. It's not
Expand Down
3 changes: 3 additions & 0 deletions lightningd/lightningd.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ struct lightningd {

/* Things we've marked as not leaking. */
const void **notleaks;

/* This is the forced private key for the node. */
struct privkey *dev_force_privkey;
#endif /* DEVELOPER */

/* tor support */
Expand Down
13 changes: 13 additions & 0 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <ccan/opt/private.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/short_types/short_types.h>
#include <ccan/str/hex/hex.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h>
Expand Down Expand Up @@ -438,6 +439,16 @@ static char *opt_subprocess_debug(const char *optarg, struct lightningd *ld)
return NULL;
}

static char *opt_force_privkey(const char *optarg, struct lightningd *ld)
{
tal_free(ld->dev_force_privkey);
ld->dev_force_privkey = tal(ld, struct privkey);
if (!hex_decode(optarg, strlen(optarg),
ld->dev_force_privkey, sizeof(*ld->dev_force_privkey)))
return tal_fmt(NULL, "Unable to parse privkey '%s'", optarg);
return NULL;
}

static void dev_register_opts(struct lightningd *ld)
{
opt_register_noarg("--dev-no-reconnect", opt_set_invbool,
Expand Down Expand Up @@ -474,6 +485,8 @@ static void dev_register_opts(struct lightningd *ld)
opt_register_arg("--dev-gossip-time", opt_set_u32, opt_show_u32,
&ld->dev_gossip_time,
"UNIX time to override gossipd to use.");
opt_register_arg("--dev-force-privkey", opt_force_privkey, NULL, ld,
"Force HSM to use this as node private key");
}
#endif

Expand Down

0 comments on commit 07adb7e

Please sign in to comment.