mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
hsmtool: makerune command.
You still need to actually make a rune when lightningd starts, as commando (for safety) won't work unless you actually generate a rune (that it knows of!). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: hsmtool: `makerune` command to make a master rune for a node.
This commit is contained in:
parent
441b38c9ea
commit
62d9ecb6d3
@ -68,6 +68,11 @@ We need the path to the hsm\_secret containing the wallet seed, and an optional
|
||||
To generate descriptors using testnet master keys, you may specify *testnet* as
|
||||
the last parameter. By default, mainnet-encoded keys are generated.
|
||||
|
||||
**makerune** *hsm\_secret*
|
||||
Make a master rune for this node (with `uniqueid` 0)
|
||||
This produces the same results as lightning-commando-rune(7) on a fresh node.
|
||||
You will still need to create a rune once the node starts, if you want commando to work (as it is only activated once it has generated one).
|
||||
|
||||
BUGS
|
||||
----
|
||||
|
||||
|
@ -1667,3 +1667,34 @@ def test_upgradewallet(node_factory, bitcoind):
|
||||
sync_blockheight(l1.bitcoin, [l1])
|
||||
upgrade = l1.rpc.upgradewallet(feerate="urgent", reservedok=True)
|
||||
assert upgrade['upgraded_outs'] == 0
|
||||
|
||||
|
||||
def test_hsmtool_makerune(node_factory):
|
||||
"""Test we can make a valid rune before the node really exists"""
|
||||
l1 = node_factory.get_node(start=False)
|
||||
|
||||
# get_node() creates a secret, but in usual case we generate one.
|
||||
hsm_path = os.path.join(l1.daemon.lightning_dir, TEST_NETWORK, "hsm_secret")
|
||||
os.remove(hsm_path)
|
||||
|
||||
hsmtool = HsmTool(node_factory.directory, "generatehsm", hsm_path)
|
||||
master_fd, slave_fd = os.openpty()
|
||||
hsmtool.start(stdin=slave_fd)
|
||||
hsmtool.wait_for_log(r"Select your language:")
|
||||
write_all(master_fd, "0\n".encode("utf-8"))
|
||||
hsmtool.wait_for_log(r"Introduce your BIP39 word list")
|
||||
write_all(master_fd, "ritual idle hat sunny universe pluck key alpha wing "
|
||||
"cake have wedding\n".encode("utf-8"))
|
||||
hsmtool.wait_for_log(r"Enter your passphrase:")
|
||||
write_all(master_fd, "This is actually not a passphrase\n".encode("utf-8"))
|
||||
assert hsmtool.proc.wait(WAIT_TIMEOUT) == 0
|
||||
hsmtool.is_in_log(r"New hsm_secret file created")
|
||||
|
||||
cmd_line = ["tools/hsmtool", "makerune", hsm_path]
|
||||
out = subprocess.check_output(cmd_line).decode("utf8").split("\n")[0]
|
||||
|
||||
l1.start()
|
||||
|
||||
# We have to generate a rune now, for commando to even start processing!
|
||||
rune = l1.rpc.commando_rune()['rune']
|
||||
assert rune == out
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/noerr/noerr.h>
|
||||
#include <ccan/read_write_all/read_write_all.h>
|
||||
#include <ccan/rune/rune.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/tal/path/path.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
@ -42,6 +43,7 @@ static void show_usage(const char *progname)
|
||||
printf(" - generatehsm <path/to/new/hsm_secret>\n");
|
||||
printf(" - checkhsm <path/to/new/hsm_secret>\n");
|
||||
printf(" - dumponchaindescriptors <path/to/hsm_secret> [network]\n");
|
||||
printf(" - makerune <path/to/hsm_secret>\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -611,6 +613,33 @@ static int check_hsm(const char *hsm_secret_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_rune(const char *hsm_secret_path)
|
||||
{
|
||||
struct secret hsm_secret, derived_secret, rune_secret;
|
||||
struct rune *master_rune, *rune;
|
||||
|
||||
/* Get hsm_secret */
|
||||
get_hsm_secret(&hsm_secret, hsm_secret_path);
|
||||
|
||||
/* HSM derives a root secret for `makesecret` */
|
||||
hkdf_sha256(&derived_secret, sizeof(struct secret), NULL, 0,
|
||||
&hsm_secret, sizeof(hsm_secret),
|
||||
"derived secrets", strlen("derived secrets"));
|
||||
|
||||
/* Commando derives secret using makesecret "commando" */
|
||||
hkdf_sha256(&rune_secret, sizeof(struct secret), NULL, 0,
|
||||
&derived_secret, sizeof(derived_secret),
|
||||
"commando", strlen("commando"));
|
||||
|
||||
master_rune = rune_new(tmpctx,
|
||||
rune_secret.data,
|
||||
ARRAY_SIZE(rune_secret.data),
|
||||
NULL);
|
||||
rune = rune_derive_start(tmpctx, master_rune, "0");
|
||||
printf("%s\n", rune_to_base64(tmpctx, rune));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *method;
|
||||
@ -703,5 +732,11 @@ int main(int argc, char *argv[])
|
||||
return check_hsm(argv[2]);
|
||||
}
|
||||
|
||||
if (streq(method, "makerune")) {
|
||||
if (argc < 3)
|
||||
show_usage(argv[0]);
|
||||
return make_rune(argv[2]);
|
||||
}
|
||||
|
||||
show_usage(argv[0]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user