hsmd: separate revoke_commitment_tx

ChangeLog-Added: Added hsmd_revoke_commitment_tx to ensure synchronization of local state with remote signers.
This commit is contained in:
Devrandom 2024-01-22 17:35:43 +01:00 committed by Rusty Russell
parent 019169fc9a
commit e6c7b58a8a
5 changed files with 66 additions and 10 deletions

View File

@ -60,6 +60,7 @@ CHANNELD_COMMON_OBJS := \
common/status_wiregen.o \
common/gossip_store.o \
common/hmac.o \
common/hsm_capable.o \
common/interactivetx.o \
common/htlc_state.o \
common/htlc_trim.o \

View File

@ -20,7 +20,8 @@
* v4 with renaming of channel_ready to setup_channel: 60b92a0930b631cc77df564cb9235e6cb220f4337a2bb00e5153145e0bf8c80e
* v4 with buried outpoint check: f44fae666895cab0347b3de7c245267c71cc7de834827b83e286e86318c08aec
* v4 with forget_channel: d87c6934ea188f92785d38d7cd0b13ed7f76aa7417f3200baf0c7b5aa832fe29
* v5 with hsmd_revoke_commitment_tx: 5742538f87ef5d5bf55b66dc19e52c8683cfeb1b887d3e64ba530ba9a4d8e638
*/
#define HSM_MIN_VERSION 3
#define HSM_MAX_VERSION 4
#define HSM_MAX_VERSION 5
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */

View File

@ -650,6 +650,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMD_FORGET_CHANNEL:
case WIRE_HSMD_SIGN_COMMITMENT_TX:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
case WIRE_HSMD_REVOKE_COMMITMENT_TX:
case WIRE_HSMD_VALIDATE_REVOCATION:
case WIRE_HSMD_SIGN_PENALTY_TO_US:
case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX:
@ -705,6 +706,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_REVOKE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
case WIRE_HSMD_SIGN_TX_REPLY:
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:

View File

@ -210,6 +210,14 @@ msgtype,hsmd_validate_commitment_tx_reply,135
msgdata,hsmd_validate_commitment_tx_reply,old_commitment_secret,?secret,
msgdata,hsmd_validate_commitment_tx_reply,next_per_commitment_point,pubkey,
# Revoke our local commitment, returns the revocation secret and next point
msgtype,hsmd_revoke_commitment_tx,40
msgdata,hsmd_revoke_commitment_tx,commit_num,u64,
msgtype,hsmd_revoke_commitment_tx_reply,140
msgdata,hsmd_revoke_commitment_tx_reply,old_commitment_secret,secret,
msgdata,hsmd_revoke_commitment_tx_reply,next_per_commitment_point,pubkey,
# Vaidate the counterparty's revocation secret
msgtype,hsmd_validate_revocation,36
msgdata,hsmd_validate_revocation,revoke_num,u64,

1 # Clients should not give a bad request but not the HSM's decision to crash.
210 msgdata,hsmd_sign_remote_commitment_tx,remote_funding_key,pubkey, msgdata,hsmd_sign_local_htlc_tx,wscript,u8,wscript_len
211 msgdata,hsmd_sign_remote_commitment_tx,remote_per_commit,pubkey, msgdata,hsmd_sign_local_htlc_tx,option_anchor_outputs,bool,
212 msgdata,hsmd_sign_remote_commitment_tx,option_static_remotekey,bool, # Openingd/channeld asks HSM to sign the other sides' commitment tx.
213 #include <common/htlc_wire.h>
214 msgtype,hsmd_sign_remote_commitment_tx,19
215 msgdata,hsmd_sign_remote_commitment_tx,tx,bitcoin_tx,
216 msgdata,hsmd_sign_remote_commitment_tx,remote_funding_key,pubkey,
217 msgdata,hsmd_sign_remote_commitment_tx,remote_per_commit,pubkey,
218 msgdata,hsmd_sign_remote_commitment_tx,option_static_remotekey,bool,
219 msgdata,hsmd_sign_remote_commitment_tx,commit_num,u64,
220 msgdata,hsmd_sign_remote_commitment_tx,num_htlcs,u16,
221 msgdata,hsmd_sign_remote_commitment_tx,commit_num,u64, msgdata,hsmd_sign_remote_commitment_tx,htlcs,simple_htlc,num_htlcs
222 msgdata,hsmd_sign_remote_commitment_tx,num_htlcs,u16, msgdata,hsmd_sign_remote_commitment_tx,feerate,u32,
223 msgdata,hsmd_sign_remote_commitment_tx,htlcs,simple_htlc,num_htlcs # channeld asks HSM to sign remote HTLC tx.

View File

@ -100,6 +100,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX:
case WIRE_HSMD_SIGN_REMOTE_HTLC_TX:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
case WIRE_HSMD_REVOKE_COMMITMENT_TX:
case WIRE_HSMD_VALIDATE_REVOCATION:
return (client->capabilities & HSM_PERM_SIGN_REMOTE_TX) != 0;
@ -160,6 +161,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_REVOKE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
case WIRE_HSMD_SIGN_TX_REPLY:
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:
@ -1709,20 +1711,58 @@ static u8 *handle_validate_commitment_tx(struct hsmd_client *c, const u8 *msg_in
return hsmd_status_bad_request_fmt(
c, msg_in, "bad per_commit_point %" PRIu64, commit_num + 1);
if (commit_num >= 1) {
old_secret = tal(tmpctx, struct secret);
if (!per_commit_secret(&shaseed, old_secret, commit_num - 1)) {
return hsmd_status_bad_request_fmt(
c, msg_in, "Cannot derive secret %" PRIu64, commit_num - 1);
}
} else {
old_secret = NULL;
}
/* Don't ever return the old_secret here anymore. The node should
* call hsmd_revoke_commitment_tx to transactionally revoke the commitment
* and return the secret ...
*/
old_secret = NULL;
return towire_hsmd_validate_commitment_tx_reply(
NULL, old_secret, &next_per_commitment_point);
}
/* ~This stub implementation is overriden by fully validating signers
* that need to independently revoke the old local commitment tx and
* release it's secret.
* Revoke the old commitment tx by disclosing its secret and also return
* the next commitiment's per-commitment-point.
*/
static u8 *handle_revoke_commitment_tx(struct hsmd_client *c, const u8 *msg_in)
{
u64 commit_num;
struct secret channel_seed;
struct sha256 shaseed;
struct secret *old_secret;
struct pubkey next_per_commitment_point;
if (!fromwire_hsmd_revoke_commitment_tx(msg_in, &commit_num))
return hsmd_status_malformed_request(c, msg_in);
/* Stub implementation */
/* The signatures are not checked in this stub because they
* are already checked by the caller. However, the returned
* old_secret and next_per_commitment_point are used.
*/
get_channel_seed(&c->id, c->dbid, &channel_seed);
if (!derive_shaseed(&channel_seed, &shaseed))
return hsmd_status_bad_request(c, msg_in, "bad derive_shaseed");
if (!per_commit_point(&shaseed, &next_per_commitment_point, commit_num + 2))
return hsmd_status_bad_request_fmt(
c, msg_in, "bad per_commit_point %" PRIu64, commit_num + 2);
old_secret = tal(tmpctx, struct secret);
if (!per_commit_secret(&shaseed, old_secret, commit_num)) {
return hsmd_status_bad_request_fmt(
c, msg_in, "Cannot derive secret %" PRIu64, commit_num);
}
return towire_hsmd_revoke_commitment_tx_reply(
NULL, old_secret, &next_per_commitment_point);
}
/* This stub implementation is overriden by fully validating signers
* that need to independently verify that the latest state is
* commited. */
@ -2010,6 +2050,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
return handle_sign_commitment_tx(client, msg);
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
return handle_validate_commitment_tx(client, msg);
case WIRE_HSMD_REVOKE_COMMITMENT_TX:
return handle_revoke_commitment_tx(client, msg);
case WIRE_HSMD_VALIDATE_REVOCATION:
return handle_validate_revocation(client, msg);
case WIRE_HSMD_SIGN_REMOTE_HTLC_TO_US:
@ -2052,6 +2094,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_REVOKE_COMMITMENT_TX_REPLY:
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
case WIRE_HSMD_SIGN_TX_REPLY:
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:
@ -2088,6 +2131,7 @@ u8 *hsmd_init(struct secret hsm_secret,
WIRE_HSMD_SIGN_SPLICE_TX,
WIRE_HSMD_CHECK_OUTPOINT,
WIRE_HSMD_FORGET_CHANNEL,
WIRE_HSMD_REVOKE_COMMITMENT_TX,
};
/*~ Don't swap this. */