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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-07-23 11:53:02 +09:30 committed by Christian Decker
parent 14d6fc4a31
commit 2575dbf493
3 changed files with 66 additions and 0 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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