Browse Source

developer: add --dev-force-privkey to allow setting a specific node key.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
pull/2938/head
Rusty Russell 6 years ago
committed by neil saitug
parent
commit
07adb7efd6
  1. 1
      hsmd/hsm_wire.csv
  2. 24
      hsmd/hsmd.c
  3. 8
      lightningd/hsm_control.c
  4. 1
      lightningd/lightningd.c
  5. 3
      lightningd/lightningd.h
  6. 13
      lightningd/options.c

1
hsmd/hsm_wire.csv

@ -9,6 +9,7 @@ hsmstatus_client_bad_request,,msg,len*u8
# Start the HSM. # Start the HSM.
hsm_init,11 hsm_init,11
hsm_init,,bip32_key_version,struct bip32_key_version hsm_init,,bip32_key_version,struct bip32_key_version
hsm_init,,dev_force_privkey,?struct privkey
#include <common/bip32.h> #include <common/bip32.h>
hsm_init_reply,111 hsm_init_reply,111

Can't render this file because it has a wrong number of fields in line 2.

24
hsmd/hsmd.c

@ -72,6 +72,11 @@ static struct {
* so set it static.*/ * so set it static.*/
static struct bip32_key_version bip32_key_version; 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. */ /*~ We keep track of clients, but there's not much to keep. */
struct client { struct client {
/* The ccan/io async io connection for this client: it closes, we die. */ /* The ccan/io async io connection for this client: it closes, we die. */
@ -314,6 +319,17 @@ static void node_key(struct privkey *node_privkey, struct pubkey *node_id)
salt++; salt++;
} while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey, } while (!secp256k1_ec_pubkey_create(secp256k1_ctx, &node_id->pubkey,
node_privkey->secret.data)); 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 /*~ This secret is the basis for all per-channel secrets: the per-channel seeds
@ -540,6 +556,7 @@ static struct io_plan *init_hsm(struct io_conn *conn,
{ {
struct node_id node_id; struct node_id node_id;
struct pubkey key; struct pubkey key;
struct privkey *privkey;
/* This must be lightningd. */ /* This must be lightningd. */
assert(is_lightningd(c)); assert(is_lightningd(c));
@ -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 * definitions in hsm_client_wire.csv. The format of those files is
* an extension of the simple comma-separated format output by the * an extension of the simple comma-separated format output by the
* BOLT tools/extract-formats.py tool. */ * 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); return bad_req(conn, c, msg_in);
#if DEVELOPER
dev_force_privkey = privkey;
#endif
maybe_create_new_hsm(); maybe_create_new_hsm();
load_hsm(); load_hsm();
@ -1601,6 +1621,8 @@ static struct io_plan *handle_memleak(struct io_conn *conn,
memleak_remove_uintmap(memtable, &clients); memleak_remove_uintmap(memtable, &clients);
memleak_scan_region(memtable, status_conn, tal_bytelen(status_conn)); memleak_scan_region(memtable, status_conn, tal_bytelen(status_conn));
memleak_scan_region(memtable, dev_force_privkey, 0);
found_leak = dump_memleak(memtable); found_leak = dump_memleak(memtable);
reply = towire_hsm_dev_memleak_reply(NULL, found_leak); reply = towire_hsm_dev_memleak_reply(NULL, found_leak);
return req_reply(conn, c, take(reply)); return req_reply(conn, c, take(reply));

8
lightningd/hsm_control.c

@ -94,7 +94,13 @@ void hsm_init(struct lightningd *ld)
ld->hsm_fd = fds[0]; ld->hsm_fd = fds[0];
if (!wire_sync_write(ld->hsm_fd, towire_hsm_init(tmpctx, 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"); err(1, "Writing init msg to hsm");
ld->wallet->bip32_base = tal(ld->wallet, struct ext_key); ld->wallet->bip32_base = tal(ld->wallet, struct ext_key);

1
lightningd/lightningd.c

@ -118,6 +118,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->dev_subdaemon_fail = false; ld->dev_subdaemon_fail = false;
ld->dev_allow_localhost = false; ld->dev_allow_localhost = false;
ld->dev_gossip_time = 0; ld->dev_gossip_time = 0;
ld->dev_force_privkey = NULL;
#endif #endif
/*~ These are CCAN lists: an embedded double-linked list. It's not /*~ These are CCAN lists: an embedded double-linked list. It's not

3
lightningd/lightningd.h

@ -205,6 +205,9 @@ struct lightningd {
/* Things we've marked as not leaking. */ /* Things we've marked as not leaking. */
const void **notleaks; const void **notleaks;
/* This is the forced private key for the node. */
struct privkey *dev_force_privkey;
#endif /* DEVELOPER */ #endif /* DEVELOPER */
/* tor support */ /* tor support */

13
lightningd/options.c

@ -7,6 +7,7 @@
#include <ccan/opt/private.h> #include <ccan/opt/private.h>
#include <ccan/read_write_all/read_write_all.h> #include <ccan/read_write_all/read_write_all.h>
#include <ccan/short_types/short_types.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/grab_file/grab_file.h>
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
@ -438,6 +439,16 @@ static char *opt_subprocess_debug(const char *optarg, struct lightningd *ld)
return NULL; 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) static void dev_register_opts(struct lightningd *ld)
{ {
opt_register_noarg("--dev-no-reconnect", opt_set_invbool, opt_register_noarg("--dev-no-reconnect", opt_set_invbool,
@ -474,6 +485,8 @@ static void dev_register_opts(struct lightningd *ld)
opt_register_arg("--dev-gossip-time", opt_set_u32, opt_show_u32, opt_register_arg("--dev-gossip-time", opt_set_u32, opt_show_u32,
&ld->dev_gossip_time, &ld->dev_gossip_time,
"UNIX time to override gossipd to use."); "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 #endif

Loading…
Cancel
Save