Skip to content

Commit 6dd899d

Browse files
committed
Modifications to c-lightning for validating lightning signer
1 parent c4313b9 commit 6dd899d

File tree

14 files changed

+185
-8
lines changed

14 files changed

+185
-8
lines changed

channeld/channeld.c

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,17 @@ static u8 *make_revocation_msg(const struct peer *peer, u64 revoke_index,
14421442
point);
14431443
}
14441444

1445+
static u8 *make_revocation_msg_from_secret(const struct peer *peer,
1446+
u64 revoke_index,
1447+
struct pubkey *point,
1448+
const struct secret *old_commit_secret,
1449+
const struct pubkey *next_point)
1450+
{
1451+
*point = *next_point;
1452+
return towire_revoke_and_ack(peer, &peer->channel_id,
1453+
old_commit_secret, next_point);
1454+
}
1455+
14451456
/* Convert changed htlcs into parts which lightningd expects. */
14461457
static void marshall_htlc_info(const tal_t *ctx,
14471458
const struct htlc **changed_htlcs,
@@ -1501,7 +1512,9 @@ static void send_revocation(struct peer *peer,
15011512
const struct bitcoin_signature *commit_sig,
15021513
const struct bitcoin_signature *htlc_sigs,
15031514
const struct htlc **changed_htlcs,
1504-
const struct bitcoin_tx *committx)
1515+
const struct bitcoin_tx *committx,
1516+
const struct secret *old_secret,
1517+
const struct pubkey *next_point)
15051518
{
15061519
struct changed_htlc *changed;
15071520
struct fulfilled_htlc *fulfilled;
@@ -1519,8 +1532,9 @@ static void send_revocation(struct peer *peer,
15191532
&added);
15201533

15211534
/* Revoke previous commit, get new point. */
1522-
u8 *msg = make_revocation_msg(peer, peer->next_index[LOCAL]-1,
1523-
&peer->next_local_per_commit);
1535+
u8 *msg = make_revocation_msg_from_secret(peer, peer->next_index[LOCAL]-1,
1536+
&peer->next_local_per_commit,
1537+
old_secret, next_point);
15241538

15251539
/* From now on we apply changes to the next commitment */
15261540
peer->next_index[LOCAL]++;
@@ -1685,8 +1699,48 @@ static void handle_peer_commit_sig(struct peer *peer, const u8 *msg)
16851699
status_debug("Received commit_sig with %zu htlc sigs",
16861700
tal_count(htlc_sigs));
16871701

1688-
send_revocation(peer,
1689-
&commit_sig, htlc_sigs, changed_htlcs, txs[0]);
1702+
// Collect the htlcs for call to hsmd validate.
1703+
//
1704+
// We use the simple_htlc to_wire routines, it's unfortunate that
1705+
// we have to send a dummy onion_routing_packet ...
1706+
//
1707+
struct simple_htlc **htlcs = tal_arr(NULL, struct simple_htlc *, 0);
1708+
size_t num_entries = tal_count(htlc_map);
1709+
for (size_t ndx = 0; ndx < num_entries; ++ndx) {
1710+
struct htlc const *hh = htlc_map[ndx];
1711+
if (hh) {
1712+
status_debug("HTLC[%lu]=%" PRIu64 ", %s",
1713+
ndx, hh->id, htlc_state_name(hh->state));
1714+
struct simple_htlc *simple =
1715+
new_simple_htlc(NULL,
1716+
htlc_state_owner(hh->state),
1717+
hh->amount,
1718+
&hh->rhash,
1719+
hh->expiry.locktime);
1720+
tal_arr_expand(&htlcs, tal_steal(htlcs, simple));
1721+
}
1722+
}
1723+
1724+
// Validate the counterparty's signatures, returns old_secret.
1725+
const u8 * msg2 =
1726+
towire_hsmd_validate_commitment_tx(NULL,
1727+
txs[0],
1728+
(const struct simple_htlc **) htlcs,
1729+
peer->next_index[LOCAL],
1730+
channel_feerate(peer->channel, LOCAL),
1731+
&commit_sig,
1732+
htlc_sigs);
1733+
tal_free(htlcs);
1734+
msg2 = hsm_req(tmpctx, take(msg2));
1735+
struct secret *old_secret;
1736+
struct pubkey next_point;
1737+
if (!fromwire_hsmd_validate_commitment_tx_reply(tmpctx, msg2, &old_secret, &next_point))
1738+
status_failed(STATUS_FAIL_HSM_IO,
1739+
"Reading validate_commitment_tx reply: %s",
1740+
tal_hex(tmpctx, msg2));
1741+
1742+
send_revocation(peer, &commit_sig, htlc_sigs, changed_htlcs, txs[0],
1743+
old_secret, &next_point);
16901744

16911745
/* We may now be quiescent on our side. */
16921746
maybe_send_stfu(peer);

common/psbt_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
#define LIGHTNING_COMMON_PSBT_INTERNAL_H
33

44
#include "config.h"
5+
#include <ccan/short_types/short_types.h>
56
#include <ccan/tal/tal.h>
67
#include <common/tx_roles.h>
78

9+
struct bitcoin_tx;
10+
struct ext_key;
11+
struct wally_map;
812
struct wally_psbt;
913
struct wally_psbt_input;
1014
struct witness_element;

common/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,6 @@ extern const tal_t *wally_tal_ctx;
143143

144144
/* Like mkstemp but resolves template relative to $TMPDIR (or /tmp if unset).
145145
* Returns created temporary path name at *created if successful. */
146-
int tmpdir_mkstemp(const tal_t *ctx, const char *template TAKES, char **created);
146+
int tmpdir_mkstemp(const tal_t *ctx, const char *tmplt TAKES, char **created);
147147

148148
#endif /* LIGHTNING_COMMON_UTILS_H */

contrib/remote_hsmd/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ RMTHSMD_COMMON_OBJS := \
3535
hsmd/hsmd_wiregen.o \
3636
common/amount.o \
3737
common/autodata.o \
38+
common/base32.o \
3839
common/bigsize.o \
3940
common/bip32.o \
4041
common/channel_id.o \
@@ -63,7 +64,8 @@ RMTHSMD_COMMON_OBJS := \
6364
common/type_to_string.o \
6465
common/utils.o \
6566
common/utxo.o \
66-
common/version.o
67+
common/version.o \
68+
common/wireaddr.o
6769

6870
# For checking
6971
LIGHTNINGD_RMTHSM_ALLSRC_NOGEN := $(filter-out contrib/remote_hsmd/remotesigner.%, $(LIGHTNINGD_RMTHSM_SRC) $(LIGHTNINGD_RMTHSM_SRC))

hsmd/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ HSMD_COMMON_OBJS := \
3131
common/daemon.o \
3232
common/daemon_conn.o \
3333
common/derive_basepoints.o \
34-
common/status_wiregen.o \
3534
common/hash_u5.o \
3635
common/hsm_encryption.o \
3736
common/htlc_wire.o \
@@ -47,6 +46,7 @@ HSMD_COMMON_OBJS := \
4746
common/setup.o \
4847
common/status.o \
4948
common/status_wire.o \
49+
common/status_wiregen.o \
5050
common/subdaemon.o \
5151
common/type_to_string.o \
5252
common/utils.o \

hsmd/hsmd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
644644
case WIRE_HSMD_NEW_CHANNEL:
645645
case WIRE_HSMD_READY_CHANNEL:
646646
case WIRE_HSMD_SIGN_COMMITMENT_TX:
647+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
647648
case WIRE_HSMD_VALIDATE_REVOCATION:
648649
case WIRE_HSMD_SIGN_PENALTY_TO_US:
649650
case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX:
@@ -682,6 +683,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
682683
case WIRE_HSMD_INIT_REPLY:
683684
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
684685
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
686+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
685687
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
686688
case WIRE_HSMD_SIGN_TX_REPLY:
687689
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:

hsmd/hsmd_wire.csv

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,22 @@ msgdata,hsmd_sign_commitment_tx,commit_num,u64,
138138
msgtype,hsmd_sign_commitment_tx_reply,105
139139
msgdata,hsmd_sign_commitment_tx_reply,sig,bitcoin_signature,
140140

141+
# Validate the counterparty's commitment signatures.
142+
#include <common/htlc_wire.h>
143+
msgtype,hsmd_validate_commitment_tx,35
144+
msgdata,hsmd_validate_commitment_tx,tx,bitcoin_tx,
145+
msgdata,hsmd_validate_commitment_tx,num_htlcs,u16,
146+
msgdata,hsmd_validate_commitment_tx,htlcs,simple_htlc,num_htlcs
147+
msgdata,hsmd_validate_commitment_tx,commit_num,u64,
148+
msgdata,hsmd_validate_commitment_tx,feerate,u32,
149+
msgdata,hsmd_validate_commitment_tx,sig,bitcoin_signature,
150+
msgdata,hsmd_validate_commitment_tx,num_htlc_sigs,u16,
151+
msgdata,hsmd_validate_commitment_tx,htlc_sigs,bitcoin_signature,num_htlc_sigs
152+
153+
msgtype,hsmd_validate_commitment_tx_reply,135
154+
msgdata,hsmd_validate_commitment_tx_reply,old_commitment_secret,?secret,
155+
msgdata,hsmd_validate_commitment_tx_reply,next_per_commitment_point,pubkey,
156+
141157
# Vaidate the counterparty's revocation secret
142158
msgtype,hsmd_validate_revocation,36
143159
msgdata,hsmd_validate_revocation,revoke_num,u64,

hsmd/libhsmd.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
9696

9797
case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX:
9898
case WIRE_HSMD_SIGN_REMOTE_HTLC_TX:
99+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
99100
case WIRE_HSMD_VALIDATE_REVOCATION:
100101
return (client->capabilities & HSM_CAP_SIGN_REMOTE_TX) != 0;
101102

@@ -133,6 +134,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
133134
case WIRE_HSMD_INIT_REPLY:
134135
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
135136
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
137+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
136138
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
137139
case WIRE_HSMD_SIGN_TX_REPLY:
138140
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:
@@ -1339,6 +1341,51 @@ static u8 *handle_sign_commitment_tx(struct hsmd_client *c, const u8 *msg_in)
13391341
return towire_hsmd_sign_commitment_tx_reply(NULL, &sig);
13401342
}
13411343

1344+
/* Validate the peer's signatures for our commitment and htlc txs. */
1345+
static u8 *handle_validate_commitment_tx(struct hsmd_client *c, const u8 *msg_in)
1346+
{
1347+
struct bitcoin_tx *tx;
1348+
struct simple_htlc **htlc;
1349+
u64 commit_num;
1350+
u32 feerate;
1351+
struct bitcoin_signature sig;
1352+
struct bitcoin_signature *htlc_sigs;
1353+
struct secret channel_seed;
1354+
struct sha256 shaseed;
1355+
struct secret *old_secret;
1356+
struct pubkey next_per_commitment_point;
1357+
1358+
if (!fromwire_hsmd_validate_commitment_tx(tmpctx, msg_in,
1359+
&tx, &htlc,
1360+
&commit_num, &feerate,
1361+
&sig, &htlc_sigs))
1362+
return hsmd_status_malformed_request(c, msg_in);
1363+
1364+
// FIXME - Not actually validating the commitment and htlc tx
1365+
// signatures here ...
1366+
1367+
get_channel_seed(&c->id, c->dbid, &channel_seed);
1368+
if (!derive_shaseed(&channel_seed, &shaseed))
1369+
return hsmd_status_bad_request(c, msg_in, "bad derive_shaseed");
1370+
1371+
if (!per_commit_point(&shaseed, &next_per_commitment_point, commit_num + 1))
1372+
return hsmd_status_bad_request_fmt(
1373+
c, msg_in, "bad per_commit_point %" PRIu64, commit_num + 1);
1374+
1375+
if (commit_num >= 1) {
1376+
old_secret = tal(tmpctx, struct secret);
1377+
if (!per_commit_secret(&shaseed, old_secret, commit_num - 1)) {
1378+
return hsmd_status_bad_request_fmt(
1379+
c, msg_in, "Cannot derive secret %" PRIu64, commit_num - 1);
1380+
}
1381+
} else {
1382+
old_secret = NULL;
1383+
}
1384+
1385+
return towire_hsmd_validate_commitment_tx_reply(
1386+
NULL, old_secret, &next_per_commitment_point);
1387+
}
1388+
13421389
/* This stub implementation is overriden by fully validating signers
13431390
* that need to independently verify that the latest state is
13441391
* commited. */
@@ -1533,6 +1580,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
15331580
return handle_sign_penalty_to_us(client, msg);
15341581
case WIRE_HSMD_SIGN_COMMITMENT_TX:
15351582
return handle_sign_commitment_tx(client, msg);
1583+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
1584+
return handle_validate_commitment_tx(client, msg);
15361585
case WIRE_HSMD_VALIDATE_REVOCATION:
15371586
return handle_validate_revocation(client, msg);
15381587
case WIRE_HSMD_SIGN_REMOTE_HTLC_TO_US:
@@ -1553,6 +1602,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
15531602
case WIRE_HSMD_INIT_REPLY:
15541603
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
15551604
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
1605+
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
15561606
case WIRE_HSMD_VALIDATE_REVOCATION_REPLY:
15571607
case WIRE_HSMD_SIGN_TX_REPLY:
15581608
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:

openingd/common.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
#include <common/channel_config.h>
44
#include <common/features.h>
55
#include <common/initial_commit_tx.h>
6+
#include <common/status.h>
67
#include <common/type_to_string.h>
8+
#include <hsmd/hsmd_wiregen.h>
79
#include <openingd/common.h>
10+
#include <wire/wire_sync.h>
811

912
/*~ This is the key function that checks that their configuration is reasonable:
1013
* it applied for both the case where they're trying to open a channel, and when
@@ -225,3 +228,33 @@ u8 *no_upfront_shutdown_script(const tal_t *ctx,
225228

226229
return NULL;
227230
}
231+
232+
void validate_initial_commitment_signature(int hsm_fd,
233+
struct bitcoin_tx *tx,
234+
struct bitcoin_signature *sig)
235+
{
236+
// Validate the counterparty's signature.
237+
struct existing_htlc **htlcs = tal_arr(NULL, struct existing_htlc *, 0);
238+
struct bitcoin_signature *htlc_sigs = tal_arr(NULL, struct bitcoin_signature, 0);
239+
u32 feerate = 0; // unused since there are no htlcs
240+
u64 commit_num = 0;
241+
const u8 * msg =
242+
towire_hsmd_validate_commitment_tx(NULL,
243+
tx,
244+
(const struct simple_htlc **) htlcs,
245+
commit_num,
246+
feerate,
247+
sig,
248+
htlc_sigs);
249+
tal_free(htlc_sigs);
250+
tal_free(htlcs);
251+
wire_sync_write(hsm_fd, take(msg));
252+
msg = wire_sync_read(tmpctx, hsm_fd);
253+
struct secret *old_secret;
254+
struct pubkey next_point;
255+
if (!fromwire_hsmd_validate_commitment_tx_reply(tmpctx, msg, &old_secret, &next_point))
256+
status_failed(STATUS_FAIL_HSM_IO,
257+
"Reading validate_commitment_tx reply: %s",
258+
tal_hex(tmpctx, msg));
259+
}
260+

openingd/common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "config.h"
55

66
struct amount_sat;
7+
struct bitcoin_tx;
8+
struct bitcoin_signature;
79
struct channel_config;
810

911

@@ -21,4 +23,8 @@ bool check_config_bounds(const tal_t *ctx,
2123
u8 *no_upfront_shutdown_script(const tal_t *ctx,
2224
struct feature_set *our_features,
2325
const u8 *their_features);
26+
27+
void validate_initial_commitment_signature(int hsm_fd,
28+
struct bitcoin_tx *tx,
29+
struct bitcoin_signature *sig);
2430
#endif /* LIGHTNING_OPENINGD_COMMON_H */

openingd/dualopend.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,8 @@ static u8 *accepter_commits(struct state *state,
18431843
return NULL;
18441844
}
18451845

1846+
validate_initial_commitment_signature(HSM_FD, local_commit, &remote_sig);
1847+
18461848
/* BOLT #2:
18471849
*
18481850
* The recipient:
@@ -2567,6 +2569,8 @@ static u8 *opener_commits(struct state *state,
25672569
return NULL;
25682570
}
25692571

2572+
validate_initial_commitment_signature(HSM_FD, local_commit, &remote_sig);
2573+
25702574
/* BOLT #2:
25712575
*
25722576
* The recipient:

openingd/openingd.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ static bool funder_finalize_channel_setup(struct state *state,
701701
goto fail;
702702
}
703703

704+
validate_initial_commitment_signature(HSM_FD, *tx, sig);
705+
704706
if (!check_tx_sig(*tx, 0, NULL, wscript, &state->their_funding_pubkey, sig)) {
705707
peer_failed_err(state->pps, &state->channel_id,
706708
"Bad signature %s on tx %s using key %s (channel_type=%s)",
@@ -1133,6 +1135,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
11331135
return NULL;
11341136
}
11351137

1138+
validate_initial_commitment_signature(HSM_FD, local_commit, &theirsig);
1139+
11361140
if (!check_tx_sig(local_commit, 0, NULL, wscript, &their_funding_pubkey,
11371141
&theirsig)) {
11381142
/* BOLT #1:

wallet/wallet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <common/blockheight_states.h>
88
#include <common/fee_states.h>
99
#include <common/onionreply.h>
10+
#include <common/psbt_internal.h>
1011
#include <common/type_to_string.h>
1112
#include <db/bindings.h>
1213
#include <db/common.h>

wallet/wallet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct node_id;
1919
struct oneshot;
2020
struct peer;
2121
struct timers;
22+
struct wally_map;
2223
enum channel_state;
2324
enum state_change;
2425

0 commit comments

Comments
 (0)