channeld: process onion packet ourselves.

This covers all the cases where an onion can be malformed; this means
we know in advance that it's bad.  That allows us to distinguish two
cases: where lightningd rejects the onion as bad, and where the next
peer rejects the next onion as bad.  Both of those (will) set failcode
to one of the BADONION values.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-01-08 11:22:13 +10:30 committed by Christian Decker
parent 59febcb968
commit 554c3ec7e5
3 changed files with 27 additions and 8 deletions

View File

@ -528,18 +528,18 @@ static void handle_peer_announcement_signatures(struct peer *peer, const u8 *msg
}
static struct secret *get_shared_secret(const tal_t *ctx,
const struct htlc *htlc)
const struct htlc *htlc,
enum onion_type *why_bad)
{
struct pubkey ephemeral;
struct onionpacket *op;
struct secret *secret = tal(ctx, struct secret);
const u8 *msg;
/* FIXME: Use this! */
enum onion_type why_bad;
struct route_step *rs;
/* We unwrap the onion now. */
op = parse_onionpacket(tmpctx, htlc->routing, TOTAL_PACKET_SIZE,
&why_bad);
why_bad);
if (!op)
return tal_free(secret);
@ -549,6 +549,16 @@ static struct secret *get_shared_secret(const tal_t *ctx,
if (!fromwire_hsm_ecdh_resp(msg, secret))
status_failed(STATUS_FAIL_HSM_IO, "Reading ecdh response");
/* We make sure we can parse onion packet, so we know if shared secret
* is actually valid (this checks hmac). */
rs = process_onionpacket(tmpctx, op, secret->data,
htlc->rhash.u.u8,
sizeof(htlc->rhash));
if (!rs) {
*why_bad = WIRE_INVALID_ONION_HMAC;
return tal_free(secret);
}
return secret;
}
@ -581,7 +591,8 @@ static void handle_peer_add_htlc(struct peer *peer, const u8 *msg)
/* If this is wrong, we don't complain yet; when it's confirmed we'll
* send it to the master which handles all HTLC failures. */
htlc->shared_secret = get_shared_secret(htlc, htlc);
htlc->shared_secret = get_shared_secret(htlc, htlc,
&htlc->why_bad_onion);
}
static void handle_peer_feechange(struct peer *peer, const u8 *msg)
@ -2593,7 +2604,8 @@ static void init_shared_secrets(struct channel *channel,
continue;
htlc = channel_get_htlc(channel, REMOTE, htlcs[i].id);
htlc->shared_secret = get_shared_secret(htlc, htlc);
htlc->shared_secret = get_shared_secret(htlc, htlc,
&htlc->why_bad_onion);
}
}

View File

@ -23,6 +23,8 @@ struct htlc {
/* The routing shared secret (only for incoming) */
struct secret *shared_secret;
/* If incoming HTLC has shared_secret, this is which BADONION error */
enum onion_type why_bad_onion;
/* FIXME: We could union these together: */
/* Routing information sent with this HTLC. */

View File

@ -646,6 +646,8 @@ static bool peer_accepted_htlc(struct channel *channel,
goto out;
}
/* FIXME: Have channeld hand through just the route_step! */
/* channeld tests this, so it should pass. */
op = parse_onionpacket(tmpctx, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet),
@ -663,8 +665,11 @@ static bool peer_accepted_htlc(struct channel *channel,
hin->payment_hash.u.u8,
sizeof(hin->payment_hash));
if (!rs) {
*failcode = WIRE_INVALID_ONION_HMAC;
goto out;
channel_internal_error(channel,
"bad process_onionpacket in got_revoke: %s",
tal_hexstr(channel, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet)));
return false;
}
/* Unknown realm isn't a bad onion, it's a normal failure. */