From 6ba1bc5c934e64fa23bd70ab6d7a4196a6c27499 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Jan 2018 06:59:49 +1030 Subject: [PATCH] channeld: repopulate HTLC shared secrets on reinitialization. We could do this lazily, if HTLC errors out, but we do it as HTLCs come in in the normal case, so this is slightly simpler. Signed-off-by: Rusty Russell --- channeld/channel.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/channeld/channel.c b/channeld/channel.c index 192c605a6..ca0177fd6 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -538,7 +538,7 @@ static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg announce_channel(peer); } -static void get_shared_secret(const struct htlc *htlc, +static bool get_shared_secret(const struct htlc *htlc, struct secret *shared_secret) { tal_t *tmpctx = tal_tmpctx(htlc); @@ -552,7 +552,7 @@ static void get_shared_secret(const struct htlc *htlc, /* Return an invalid shared secret. */ memset(shared_secret, 0, sizeof(*shared_secret)); tal_free(tmpctx); - return; + return false; } /* Because wire takes struct pubkey. */ @@ -565,6 +565,8 @@ static void get_shared_secret(const struct htlc *htlc, if (!msg || !fromwire_hsm_ecdh_resp(msg, NULL, shared_secret)) status_failed(STATUS_FAIL_HSM_IO, "Reading ecdh response"); tal_free(tmpctx); + + return !memeqzero(shared_secret, sizeof(*shared_secret)); } static void handle_peer_add_htlc(struct peer *peer, const u8 *msg) @@ -2388,6 +2390,23 @@ static void req_in(struct peer *peer, const u8 *msg) master_badmsg(-1, msg); } +static void init_shared_secrets(struct channel *channel, + const struct added_htlc *htlcs, + const enum htlc_state *hstates) +{ + for (size_t i = 0; i < tal_count(htlcs); i++) { + struct htlc *htlc; + + /* We only derive this for HTLCs *they* added. */ + if (htlc_state_owner(hstates[i]) != REMOTE) + continue; + + htlc = channel_get_htlc(channel, REMOTE, htlcs[i].id); + htlc->shared_secret = tal(htlc, struct secret); + get_shared_secret(htlc, htlc->shared_secret); + } +} + /* We do this synchronously. */ static void init_channel(struct peer *peer) { @@ -2506,6 +2525,10 @@ static void init_channel(struct peer *peer) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Could not restore HTLCs"); + /* We derive shared secrets for each remote HTLC, so we can + * create error packet if necessary. */ + init_shared_secrets(peer->channel, htlcs, hstates); + peer->channel_direction = get_channel_direction( &peer->node_ids[LOCAL], &peer->node_ids[REMOTE]);