diff --git a/common/Makefile b/common/Makefile index b48f993f2..acadda6f6 100644 --- a/common/Makefile +++ b/common/Makefile @@ -98,6 +98,7 @@ COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) \ common/ecdh.h \ common/errcode.h \ common/gossip_constants.h \ + common/hsm_version.h \ common/htlc.h \ common/json_command.h \ common/jsonrpc_errors.h \ diff --git a/common/hsm_version.h b/common/hsm_version.h new file mode 100644 index 000000000..3fd2135e0 --- /dev/null +++ b/common/hsm_version.h @@ -0,0 +1,9 @@ +#ifndef LIGHTNING_COMMON_HSM_VERSION_H +#define LIGHTNING_COMMON_HSM_VERSION_H +#include "config.h" + +/* We give a maximum and minimum compatibility version to HSM, to allow + * some API adaptation. */ +#define HSM_MIN_VERSION 1 +#define HSM_MAX_VERSION 1 +#endif /* LIGHTNING_COMMON_HSM_VERSION_H */ diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 9e3991c4e..3c4b56192 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -443,6 +443,8 @@ static struct io_plan *init_hsm(struct io_conn *conn, struct sha256 *shaseed; struct secret *hsm_encryption_key; struct bip32_key_version bip32_key_version; + u32 minversion, maxversion; + const u32 our_minversion = 1, our_maxversion = 1; /* This must be lightningd. */ assert(is_lightningd(c)); @@ -452,9 +454,19 @@ static struct io_plan *init_hsm(struct io_conn *conn, * an extension of the simple comma-separated format output by the * BOLT tools/extract-formats.py tool. */ if (!fromwire_hsmd_init(NULL, msg_in, &bip32_key_version, &chainparams, - &hsm_encryption_key, &privkey, &seed, &secrets, &shaseed)) + &hsm_encryption_key, &privkey, &seed, &secrets, &shaseed, + &minversion, &maxversion)) return bad_req(conn, c, msg_in); + /*~ Usually we don't worry about API breakage between internal daemons, + * but there are other implementations of the HSM daemon now, so we + * do at least the simplest, clearest thing. */ + if (our_minversion > maxversion || our_maxversion < minversion) + return bad_req_fmt(conn, c, msg_in, + "Version %u-%u not valid: we need %u-%u", + minversion, maxversion, + our_minversion, our_maxversion); + /*~ The memory is actually copied in towire(), so lock the `hsm_secret` * encryption key (new) memory again here. */ if (hsm_encryption_key && sodium_mlock(hsm_encryption_key, diff --git a/hsmd/hsmd_wire.csv b/hsmd/hsmd_wire.csv index ba29d2b86..37ff13806 100644 --- a/hsmd/hsmd_wire.csv +++ b/hsmd/hsmd_wire.csv @@ -15,6 +15,8 @@ msgdata,hsmd_init,dev_force_privkey,?privkey, msgdata,hsmd_init,dev_force_bip32_seed,?secret, msgdata,hsmd_init,dev_force_channel_secrets,?secrets, msgdata,hsmd_init,dev_force_channel_secrets_shaseed,?sha256, +msgdata,hsmd_init,hsm_wire_min_version,u32, +msgdata,hsmd_init,hsm_wire_max_version,u32, #include msgtype,hsmd_init_reply,111 diff --git a/lightningd/hsm_control.c b/lightningd/hsm_control.c index f360d813a..b1b46db51 100644 --- a/lightningd/hsm_control.c +++ b/lightningd/hsm_control.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -109,7 +110,9 @@ struct ext_key *hsm_init(struct lightningd *ld) IFDEV(ld->dev_force_privkey, NULL), IFDEV(ld->dev_force_bip32_seed, NULL), IFDEV(ld->dev_force_channel_secrets, NULL), - IFDEV(ld->dev_force_channel_secrets_shaseed, NULL)))) + IFDEV(ld->dev_force_channel_secrets_shaseed, NULL), + HSM_MIN_VERSION, + HSM_MAX_VERSION))) err(EXITCODE_HSM_GENERIC_ERROR, "Writing init msg to hsm"); bip32_base = tal(ld, struct ext_key);