hsmd: new version, which tells us the HSM version, and capabilities.

Importantly, adds the version number at the *front* to help future
parsing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


Header from folded patch 'fix-hsm-check-pubkey.patch':

fixup! hsmd: capability addition: ability to check pubkeys.
This commit is contained in:
Rusty Russell
2023-03-21 14:28:09 +10:30
parent 21a1b4e6aa
commit e02f5f5bb8
8 changed files with 72 additions and 7 deletions

View File

@@ -10,7 +10,8 @@
* v2: dd89bf9323dff42200003fb864abb6608f3aa645b636fdae3ec81d804ac05196
* v3: edd3d288fc88a5470adc2f99abcbfe4d4af29fae0c7a80b4226f28810a815524
* v3 without v1: 3f813898f7de490e9126ab817e1c9a29af79c0413d5e37068acedce3ea7b5429
* v4: 41a730986c51b930e2d8d12b3169d24966c2004e08d424bdda310edbbde5ba70
*/
#define HSM_MIN_VERSION 3
#define HSM_MAX_VERSION 3
#define HSM_MAX_VERSION 4
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */

View File

@@ -695,6 +695,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:
case WIRE_HSMD_INIT_REPLY_V2:
case WIRE_HSMD_INIT_REPLY_V4:
case WIRE_HSMD_DERIVE_SECRET_REPLY:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:

View File

@@ -19,11 +19,25 @@ msgdata,hsmd_init,hsm_wire_min_version,u32,
msgdata,hsmd_init,hsm_wire_max_version,u32,
#include <common/bip32.h>
# DEPRECATED after 23.05, remove in two versions!
msgtype,hsmd_init_reply_v2,113
msgdata,hsmd_init_reply_v2,node_id,node_id,
msgdata,hsmd_init_reply_v2,bip32,ext_key,
msgdata,hsmd_init_reply_v2,bolt12,pubkey,
# Sorry: I should have put version in v2 :(
msgtype,hsmd_init_reply_v4,114
# This gets upgraded when the wire protocol changes in incompatible
# ways:
msgdata,hsmd_init_reply_v4,hsm_version,u32,
# Capabilities, by convention are message numbers, indicating
# that the HSM supports you sending this message.
msgdata,hsmd_init_reply_v4,num_hsm_capabilities,u16,
msgdata,hsmd_init_reply_v4,hsm_capabilities,u32,num_hsm_capabilities
msgdata,hsmd_init_reply_v4,node_id,node_id,
msgdata,hsmd_init_reply_v4,bip32,ext_key,
msgdata,hsmd_init_reply_v4,bolt12,pubkey,
# Declare a new channel.
msgtype,hsmd_new_channel,30
msgdata,hsmd_new_channel,id,node_id,
1 # Clients should not give a bad request but not the HSM's decision to crash.
19 #include <common/bip32.h>
20 msgtype,hsmd_init_reply_v2,113 # DEPRECATED after 23.05, remove in two versions!
21 msgdata,hsmd_init_reply_v2,node_id,node_id, msgtype,hsmd_init_reply_v2,113
22 msgdata,hsmd_init_reply_v2,node_id,node_id,
23 msgdata,hsmd_init_reply_v2,bip32,ext_key,
24 msgdata,hsmd_init_reply_v2,bolt12,pubkey,
25 # Declare a new channel. # Sorry: I should have put version in v2 :(
26 msgtype,hsmd_new_channel,30 msgtype,hsmd_init_reply_v4,114
27 msgdata,hsmd_new_channel,id,node_id, # This gets upgraded when the wire protocol changes in incompatible
28 # ways:
29 msgdata,hsmd_init_reply_v4,hsm_version,u32,
30 # Capabilities, by convention are message numbers, indicating
31 # that the HSM supports you sending this message.
32 msgdata,hsmd_init_reply_v4,num_hsm_capabilities,u16,
33 msgdata,hsmd_init_reply_v4,hsm_capabilities,u32,num_hsm_capabilities
34 msgdata,hsmd_init_reply_v4,node_id,node_id,
35 msgdata,hsmd_init_reply_v4,bip32,ext_key,
36 msgdata,hsmd_init_reply_v4,bolt12,pubkey,
37 # Declare a new channel.
38 msgtype,hsmd_new_channel,30
39 msgdata,hsmd_new_channel,id,node_id,
40 msgdata,hsmd_new_channel,dbid,u64,
41 msgdata,hsmd_new_channel,dbid,u64, # No value returned.
42 # No value returned. msgtype,hsmd_new_channel_reply,130
43 msgtype,hsmd_new_channel_reply,130 # Get a new HSM FD, with the specified capabilities

View File

@@ -137,6 +137,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:
case WIRE_HSMD_INIT_REPLY_V2:
case WIRE_HSMD_INIT_REPLY_V4:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
@@ -1662,6 +1663,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:
case WIRE_HSMD_INIT_REPLY_V2:
case WIRE_HSMD_INIT_REPLY_V4:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
@@ -1815,8 +1817,11 @@ u8 *hsmd_init(struct secret hsm_secret,
/*~ Note: marshalling a bip32 tree only marshals the public side,
* not the secrets! So we're not actually handing them out here!
*
* And version is 4: we offer limited compatibility (or at least,
* incompatibility detection) with alternate implementations.
*/
return take(towire_hsmd_init_reply_v2(
NULL, &node_id, &secretstuff.bip32,
&bolt12));
return take(towire_hsmd_init_reply_v4(
NULL, 4, NULL, &node_id, &secretstuff.bip32,
&bolt12));
}

View File

@@ -77,11 +77,23 @@ static unsigned int hsm_msg(struct subd *hsmd,
return 0;
}
/* Is this capability supported by the HSM? (So far, always a message
* number) */
bool hsm_capable(struct lightningd *ld, u32 msgtype)
{
for (size_t i = 0; i < tal_count(ld->hsm_capabilities); i++) {
if (ld->hsm_capabilities[i] == msgtype)
return true;
}
return false;
}
struct ext_key *hsm_init(struct lightningd *ld)
{
u8 *msg;
int fds[2];
struct ext_key *bip32_base;
u32 hsm_version;
/* We actually send requests synchronously: only status is async. */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
@@ -118,14 +130,39 @@ struct ext_key *hsm_init(struct lightningd *ld)
bip32_base = tal(ld, struct ext_key);
msg = wire_sync_read(tmpctx, ld->hsm_fd);
if (!fromwire_hsmd_init_reply_v2(msg,
&ld->id, bip32_base,
&ld->bolt12_base)) {
if (fromwire_hsmd_init_reply_v4(ld, msg,
&hsm_version,
&ld->hsm_capabilities,
&ld->id, bip32_base,
&ld->bolt12_base)) {
/* nothing to do. */
} else if (fromwire_hsmd_init_reply_v2(msg,
&ld->id, bip32_base,
&ld->bolt12_base)) {
/* implicit version */
hsm_version = 3;
ld->hsm_capabilities = NULL;
} else {
if (ld->config.keypass)
errx(EXITCODE_HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret.");
errx(EXITCODE_HSM_GENERIC_ERROR, "HSM did not give init reply");
}
if (hsm_version < HSM_MIN_VERSION)
errx(EXITCODE_HSM_GENERIC_ERROR,
"HSM version %u below minimum %u",
hsm_version, HSM_MIN_VERSION);
if (hsm_version > HSM_MAX_VERSION)
errx(EXITCODE_HSM_GENERIC_ERROR,
"HSM version %u above maximum %u",
hsm_version, HSM_MAX_VERSION);
/* Debugging help */
for (size_t i = 0; i < tal_count(ld->hsm_capabilities); i++) {
log_debug(ld->hsm->log, "capability +%s",
hsmd_wire_name(ld->hsm_capabilities[i]));
}
/* This is equivalent to makesecret("bolt12-invoice-base") */
msg = towire_hsmd_derive_secret(NULL, tal_dup_arr(tmpctx, u8,
(const u8 *)INVOICE_PATH_BASE_STRING,

View File

@@ -16,5 +16,9 @@ int hsm_get_client_fd(struct lightningd *ld,
/* Ask HSM for an fd for a global subdaemon to use (gossipd, connectd) */
int hsm_get_global_fd(struct lightningd *ld, int capabilities);
/* Is this capability supported by the HSM? (So far, always a message
* number) */
bool hsm_capable(struct lightningd *ld, u32 msgtype);
struct ext_key *hsm_init(struct lightningd *ld);
#endif /* LIGHTNING_LIGHTNINGD_HSM_CONTROL_H */

View File

@@ -319,6 +319,8 @@ struct lightningd {
char *wallet_dsn;
bool encrypted_hsm;
/* What (additional) messages the HSM accepts */
u32 *hsm_capabilities;
mode_t initial_umask;

View File

@@ -1951,6 +1951,7 @@ int main(int argc, const char *argv[])
ld = tal(tmpctx, struct lightningd);
ld->config = test_config;
ld->hsm_capabilities = NULL;
/* Only elements in ld we should access */
ld->peers = tal(ld, struct peer_node_id_map);