From 2575dbf4937460eb9bbe47ed396bbd7bdd7d9d35 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 23 Jul 2018 11:53:02 +0930 Subject: [PATCH] hsmd: provide routine to get the per-commitment point. This will be used by onchaind for now, but also for openingd and channeld in future, so it returns the old revocation secret as well. Of course, the HSM should refuse to sign a commitment transaction if it has handed out the revocation secret previously! Signed-off-by: Rusty Russell --- hsmd/capabilities.h | 1 + hsmd/hsm.c | 57 ++++++++++++++++++++++++++++++++++++++++ hsmd/hsm_client_wire_csv | 8 ++++++ 3 files changed, 66 insertions(+) diff --git a/hsmd/capabilities.h b/hsmd/capabilities.h index 629fbff36..aebd607be 100644 --- a/hsmd/capabilities.h +++ b/hsmd/capabilities.h @@ -4,6 +4,7 @@ #define HSM_CAP_ECDH 1 #define HSM_CAP_SIGN_GOSSIP 2 #define HSM_CAP_SIGN_ONCHAIN_TX 4 +#define HSM_CAP_COMMITMENT_POINT 8 #define HSM_CAP_MASTER 1024 #endif /* LIGHTNING_HSMD_CAPABILITIES_H */ diff --git a/hsmd/hsm.c b/hsmd/hsm.c index 07e8328fa..d3a53a87b 100644 --- a/hsmd/hsm.c +++ b/hsmd/hsm.c @@ -538,6 +538,55 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn, return daemon_conn_read_next(conn, &c->dc); } +static struct io_plan * +handle_get_per_commitment_point(struct io_conn *conn, struct client *c) +{ + struct daemon_conn *dc = &c->dc; + struct secret channel_seed; + struct sha256 shaseed; + struct pubkey per_commitment_point; + u64 n; + struct secret *old_secret; + + if (!fromwire_hsm_get_per_commitment_point(dc->msg_in, &n)) { + status_broken("bad get_per_commitment_point for client %s", + type_to_string(tmpctx, struct pubkey, &c->id)); + goto fail; + } + + get_channel_seed(&c->id, c->dbid, &channel_seed); + if (!derive_shaseed(&channel_seed, &shaseed)) { + status_broken("bad derive_shaseed for client %s", + type_to_string(tmpctx, struct pubkey, &c->id)); + goto fail; + } + + if (!per_commit_point(&shaseed, &per_commitment_point, n)) { + status_broken("bad per_commit_point %"PRIu64" for client %s", + n, type_to_string(tmpctx, struct pubkey, &c->id)); + goto fail; + } + + if (n >= 2) { + old_secret = tal(tmpctx, struct secret); + per_commit_secret(&shaseed, old_secret, n - 2); + } else + old_secret = NULL; + + daemon_conn_send(&c->dc, + take(towire_hsm_get_per_commitment_point_reply(NULL, + &per_commitment_point, + old_secret))); + return daemon_conn_read_next(conn, &c->dc); + +fail: + daemon_conn_send(c->master, + take(towire_hsmstatus_client_bad_request(NULL, + &c->id, + c->dc.msg_in))); + return io_close(conn); +} + static bool check_client_capabilities(struct client *client, enum hsm_client_wire_type t) { @@ -556,6 +605,9 @@ static bool check_client_capabilities(struct client *client, case WIRE_HSM_SIGN_LOCAL_HTLC_TX: return (client->capabilities & HSM_CAP_SIGN_ONCHAIN_TX) != 0; + case WIRE_HSM_GET_PER_COMMITMENT_POINT: + return (client->capabilities & HSM_CAP_COMMITMENT_POINT) != 0; + case WIRE_HSM_INIT: case WIRE_HSM_CLIENT_HSMFD: case WIRE_HSM_SIGN_FUNDING: @@ -577,6 +629,7 @@ static bool check_client_capabilities(struct client *client, case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSM_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSM_SIGN_TX_REPLY: + case WIRE_HSM_GET_PER_COMMITMENT_POINT_REPLY: break; } return false; @@ -650,6 +703,9 @@ static struct io_plan *handle_client(struct io_conn *conn, case WIRE_HSM_SIGN_LOCAL_HTLC_TX: return handle_sign_local_htlc_tx(conn, c); + case WIRE_HSM_GET_PER_COMMITMENT_POINT: + return handle_get_per_commitment_point(conn, c); + case WIRE_HSM_ECDH_RESP: case WIRE_HSM_CANNOUNCEMENT_SIG_REPLY: case WIRE_HSM_CUPDATE_SIG_REPLY: @@ -662,6 +718,7 @@ static struct io_plan *handle_client(struct io_conn *conn, case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSM_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSM_SIGN_TX_REPLY: + case WIRE_HSM_GET_PER_COMMITMENT_POINT_REPLY: break; } diff --git a/hsmd/hsm_client_wire_csv b/hsmd/hsm_client_wire_csv index 4df759080..5a0350f7e 100644 --- a/hsmd/hsm_client_wire_csv +++ b/hsmd/hsm_client_wire_csv @@ -139,3 +139,11 @@ hsm_sign_local_htlc_tx,,input_amount,u64 hsm_sign_tx_reply,112 hsm_sign_tx_reply,,sig,secp256k1_ecdsa_signature +# Openingd/channeld/onchaind asks for Nth per_commitment_point, if > 2, gets N-2 secret. +hsm_get_per_commitment_point,18 +hsm_get_per_commitment_point,,n,u64 + +hsm_get_per_commitment_point_reply,118 +hsm_get_per_commitment_point_reply,,per_commitment_point,struct pubkey +hsm_get_per_commitment_point_reply,,old_commitment_secret,?struct secret +