Browse Source

lightningd: get HSM to sign the last commitment tx for us.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
93b8217eb0
  1. 44
      hsmd/hsm.c
  2. 14
      hsmd/hsm_client_wire_csv
  3. 31
      lightningd/peer_control.c
  4. 12
      wallet/test/run-wallet.c

44
hsmd/hsm.c

@ -277,6 +277,44 @@ static struct io_plan *handle_channel_update_sig(struct io_conn *conn,
return daemon_conn_read_next(conn, dc);
}
/* FIXME: Ensure HSM never does this twice for same dbid! */
static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn,
struct daemon_conn *dc)
{
struct pubkey peer_id, remote_funding_pubkey, local_funding_pubkey;
u64 dbid, funding_amount;
struct secret channel_seed;
struct bitcoin_tx *tx;
secp256k1_ecdsa_signature sig;
struct secrets secrets;
const u8 *funding_wscript;
if (!fromwire_hsm_sign_commitment_tx(tmpctx, dc->msg_in,
&peer_id, &dbid,
&tx,
&remote_funding_pubkey,
&funding_amount))
master_badmsg(WIRE_HSM_SIGN_COMMITMENT_TX, dc->msg_in);
get_channel_seed(&peer_id, dbid, &channel_seed);
derive_basepoints(&channel_seed,
&local_funding_pubkey, NULL, &secrets, NULL);
funding_wscript = bitcoin_redeem_2of2(tmpctx,
&local_funding_pubkey,
&remote_funding_pubkey);
/* Need input amount for signing */
tx->input[0].amount = tal_dup(tx->input, u64, &funding_amount);
sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&local_funding_pubkey,
&sig);
daemon_conn_send(dc,
take(towire_hsm_sign_commitment_tx_reply(NULL, &sig)));
return daemon_conn_read_next(conn, dc);
}
static bool check_client_capabilities(struct client *client,
enum hsm_client_wire_type t)
{
@ -294,6 +332,7 @@ static bool check_client_capabilities(struct client *client,
case WIRE_HSM_SIGN_FUNDING:
case WIRE_HSM_SIGN_WITHDRAWAL:
case WIRE_HSM_SIGN_INVOICE:
case WIRE_HSM_SIGN_COMMITMENT_TX:
return (client->capabilities & HSM_CAP_MASTER) != 0;
/* These are messages sent by the HSM so we should never receive them */
@ -307,6 +346,7 @@ static bool check_client_capabilities(struct client *client,
case WIRE_HSM_SIGN_INVOICE_REPLY:
case WIRE_HSM_INIT_REPLY:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSM_SIGN_COMMITMENT_TX_REPLY:
break;
}
return false;
@ -365,6 +405,9 @@ static struct io_plan *handle_client(struct io_conn *conn,
sign_withdrawal_tx(dc, dc->msg_in);
return daemon_conn_read_next(conn, dc);
case WIRE_HSM_SIGN_COMMITMENT_TX:
return handle_sign_commitment_tx(conn, dc);
case WIRE_HSM_ECDH_RESP:
case WIRE_HSM_CANNOUNCEMENT_SIG_REPLY:
case WIRE_HSM_CUPDATE_SIG_REPLY:
@ -375,6 +418,7 @@ static struct io_plan *handle_client(struct io_conn *conn,
case WIRE_HSM_SIGN_INVOICE_REPLY:
case WIRE_HSM_INIT_REPLY:
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
case WIRE_HSM_SIGN_COMMITMENT_TX_REPLY:
break;
}

14
hsmd/hsm_client_wire_csv

@ -23,6 +23,7 @@ hsm_client_hsmfd,,capabilities,u64
# No content, just an fd.
hsm_client_hsmfd_reply,109
# Return signature for a funding tx.
#include <common/utxo.h>
# FIXME: This should also take their commit sig & details, to verify.
@ -90,3 +91,16 @@ hsm_cupdate_sig_req,,cu,culen*u8
hsm_cupdate_sig_reply,103
hsm_cupdate_sig_reply,,culen,u16
hsm_cupdate_sig_reply,,cu,culen*u8
# Master asks HSM to sign a commitment transaction.
hsm_sign_commitment_tx,5
hsm_sign_commitment_tx,,peer_id,struct pubkey
hsm_sign_commitment_tx,,channel_dbid,u64
hsm_sign_commitment_tx,,tx,struct bitcoin_tx
hsm_sign_commitment_tx,,remote_funding_key,struct pubkey
hsm_sign_commitment_tx,,funding_amount,u64
hsm_sign_commitment_tx_reply,105
hsm_sign_commitment_tx_reply,,sig,secp256k1_ecdsa_signature

31
lightningd/peer_control.c

@ -44,6 +44,7 @@
#include <unistd.h>
#include <wally_bip32.h>
#include <wire/gen_onion_wire.h>
#include <wire/wire_sync.h>
struct close_command {
/* Inside struct lightningd close_commands. */
@ -197,24 +198,27 @@ u32 feerate_max(struct lightningd *ld)
static void sign_last_tx(struct channel *channel)
{
u8 *funding_wscript;
struct secrets secrets;
struct lightningd *ld = channel->peer->ld;
secp256k1_ecdsa_signature sig;
u8 *msg;
assert(!channel->last_tx->input[0].witness);
derive_basepoints(&channel->seed, NULL, NULL, &secrets, NULL);
msg = towire_hsm_sign_commitment_tx(tmpctx,
&channel->peer->id,
channel->dbid,
channel->last_tx,
&channel->channel_info
.remote_fundingkey,
channel->funding_satoshi);
if (!wire_sync_write(ld->hsm_fd, take(msg)))
fatal("Could not write to HSM: %s", strerror(errno));
funding_wscript = bitcoin_redeem_2of2(tmpctx,
&channel->local_funding_pubkey,
&channel->channel_info.remote_fundingkey);
/* Need input amount for signing */
channel->last_tx->input[0].amount = tal_dup(channel->last_tx->input, u64,
&channel->funding_satoshi);
sign_tx_input(channel->last_tx, 0, NULL, funding_wscript,
&secrets.funding_privkey,
&channel->local_funding_pubkey,
&sig);
msg = wire_sync_read(tmpctx, ld->hsm_fd);
if (!fromwire_hsm_sign_commitment_tx_reply(msg, &sig))
fatal("HSM gave bad sign_commitment_tx_reply %s",
tal_hex(tmpctx, msg));
channel->last_tx->input[0].witness
= bitcoin_witness_2of2(channel->last_tx->input,
@ -226,7 +230,6 @@ static void sign_last_tx(struct channel *channel)
static void remove_sig(struct bitcoin_tx *signed_tx)
{
signed_tx->input[0].amount = tal_free(signed_tx->input[0].amount);
signed_tx->input[0].witness = tal_free(signed_tx->input[0].witness);
}

12
wallet/test/run-wallet.c

@ -77,6 +77,9 @@ bool fromwire_gossip_getpeers_reply(const tal_t *ctx UNNEEDED, const void *p UNN
/* Generated stub for fromwire_gossip_peer_connected */
bool fromwire_gossip_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_hsm_sign_commitment_tx_reply */
bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); }
/* Generated stub for get_feerate */
u32 get_feerate(const struct chain_topology *topo UNNEEDED, enum feerate feerate UNNEEDED)
{ fprintf(stderr, "get_feerate called!\n"); abort(); }
@ -384,6 +387,9 @@ u8 *towire_gossipctl_peer_important(const tal_t *ctx UNNEEDED, const struct pubk
/* Generated stub for towire_gossip_getpeers_request */
u8 *towire_gossip_getpeers_request(const tal_t *ctx UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "towire_gossip_getpeers_request called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }
/* Generated stub for watch_txid */
struct txwatch *watch_txid(const tal_t *ctx UNNEEDED,
struct chain_topology *topo UNNEEDED,
@ -404,6 +410,12 @@ struct txowatch *watch_txo(const tal_t *ctx UNNEEDED,
size_t input_num UNNEEDED,
const struct block *block))
{ fprintf(stderr, "watch_txo called!\n"); abort(); }
/* Generated stub for wire_sync_read */
u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
{ fprintf(stderr, "wire_sync_read called!\n"); abort(); }
/* Generated stub for wire_sync_write */
bool wire_sync_write(int fd UNNEEDED, const void *msg TAKES UNNEEDED)
{ fprintf(stderr, "wire_sync_write called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */
#if DEVELOPER

Loading…
Cancel
Save