diff --git a/channeld/channeld.c b/channeld/channeld.c index 3730a6838..c56735cdc 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -534,9 +534,12 @@ static struct secret *get_shared_secret(const tal_t *ctx, struct onionpacket *op; struct secret *secret = tal(ctx, struct secret); const u8 *msg; + /* FIXME: Use this! */ + enum onion_type why_bad; /* We unwrap the onion now. */ - op = parse_onionpacket(tmpctx, htlc->routing, TOTAL_PACKET_SIZE); + op = parse_onionpacket(tmpctx, htlc->routing, TOTAL_PACKET_SIZE, + &why_bad); if (!op) return tal_free(secret); diff --git a/common/sphinx.c b/common/sphinx.c index 7bbc4fa4a..95db48663 100644 --- a/common/sphinx.c +++ b/common/sphinx.c @@ -75,30 +75,31 @@ u8 *serialize_onionpacket( return dst; } -struct onionpacket *parse_onionpacket( - const tal_t *ctx, - const void *src, - const size_t srclen - ) +struct onionpacket *parse_onionpacket(const tal_t *ctx, + const void *src, + const size_t srclen, + enum onion_type *why_bad) { struct onionpacket *m; int p = 0; u8 rawEphemeralkey[33]; - if (srclen != TOTAL_PACKET_SIZE) - return NULL; + assert(srclen == TOTAL_PACKET_SIZE); m = talz(ctx, struct onionpacket); read_buffer(&m->version, src, 1, &p); if (m->version != 0x00) { // FIXME add logging + *why_bad = WIRE_INVALID_ONION_VERSION; return tal_free(m); } read_buffer(rawEphemeralkey, src, 33, &p); - if (secp256k1_ec_pubkey_parse(secp256k1_ctx, &m->ephemeralkey, rawEphemeralkey, 33) != 1) + if (secp256k1_ec_pubkey_parse(secp256k1_ctx, &m->ephemeralkey, rawEphemeralkey, 33) != 1) { + *why_bad = WIRE_INVALID_ONION_KEY; return tal_free(m); + } read_buffer(&m->routinginfo, src, ROUTING_INFO_SIZE, &p); read_buffer(&m->mac, src, SECURITY_PARAMETER, &p); diff --git a/common/sphinx.h b/common/sphinx.h index 03fdd9350..8a167f06f 100644 --- a/common/sphinx.h +++ b/common/sphinx.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #define SECURITY_PARAMETER 32 @@ -148,13 +149,13 @@ u8 *serialize_onionpacket( * * @ctx: tal context to allocate from * @src: buffer to read the packet from - * @srclen: length of the @src + * @srclen: length of the @src (must be TOTAL_PACKET_SIZE) + * @why_bad: if NULL return, this is what was wrong with the packet. */ -struct onionpacket *parse_onionpacket( - const tal_t *ctx, - const void *src, - const size_t srclen - ); +struct onionpacket *parse_onionpacket(const tal_t *ctx, + const void *src, + const size_t srclen, + enum onion_type *why_bad); struct onionreply { /* Node index in the path that is replying */ diff --git a/devtools/Makefile b/devtools/Makefile index e70db606b..4ea586a75 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -14,7 +14,8 @@ DEVTOOLS_COMMON_OBJS := \ common/type_to_string.o \ common/utils.o \ common/version.o \ - common/wireaddr.o + common/wireaddr.o \ + wire/gen_onion_wire.o devtools-all: $(DEVTOOLS) diff --git a/devtools/onion.c b/devtools/onion.c index 1237a11d0..33f9e0ed0 100644 --- a/devtools/onion.c +++ b/devtools/onion.c @@ -66,6 +66,7 @@ static void do_decode(int argc, char **argv) memset(hextemp, 0, sizeof(hextemp)); u8 shared_secret[32]; u8 assocdata[32]; + enum onion_type why_bad; memset(&assocdata, 'B', sizeof(assocdata)); @@ -82,10 +83,10 @@ static void do_decode(int argc, char **argv) errx(1, "Invalid onion hex '%s'", hextemp); } - msg = parse_onionpacket(ctx, serialized, sizeof(serialized)); + msg = parse_onionpacket(ctx, serialized, sizeof(serialized), &why_bad); if (!msg) - errx(1, "Error parsing message."); + errx(1, "Error parsing message: %s", onion_type_name(why_bad)); if (!onion_shared_secret(shared_secret, msg, &seckey)) errx(1, "Error creating shared secret."); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 300d3a517..7a9cfac5c 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -648,7 +648,8 @@ static bool peer_accepted_htlc(struct channel *channel, /* channeld tests this, so it should pass. */ op = parse_onionpacket(tmpctx, hin->onion_routing_packet, - sizeof(hin->onion_routing_packet)); + sizeof(hin->onion_routing_packet), + failcode); if (!op) { channel_internal_error(channel, "bad onion in got_revoke: %s", diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 063532b9d..b00f65f12 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -367,11 +367,10 @@ struct command_result *param_tok(struct command *cmd UNNEEDED, const char *name const jsmntok_t **out UNNEEDED) { fprintf(stderr, "param_tok called!\n"); abort(); } /* Generated stub for parse_onionpacket */ -struct onionpacket *parse_onionpacket( - const tal_t *ctx UNNEEDED, - const void *src UNNEEDED, - const size_t srclen - ) +struct onionpacket *parse_onionpacket(const tal_t *ctx UNNEEDED, + const void *src UNNEEDED, + const size_t srclen UNNEEDED, + enum onion_type *why_bad UNNEEDED) { fprintf(stderr, "parse_onionpacket called!\n"); abort(); } /* Generated stub for payment_failed */ void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout UNNEEDED,