Browse Source

common/sphinx: add realm flag so we can avoid legacy parsing.

For messages, we use the onion but payload lengths 0 and 1 aren't special.
Create a flag to disable that logic.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
committed by Christian Decker
parent
commit
24984ec680
  1. 16
      common/onion.c
  2. 2
      common/onion.h
  3. 5
      common/sphinx.c
  4. 4
      common/sphinx.h
  5. 4
      devtools/onion.c
  6. 2
      lightningd/peer_htlcs.c
  7. 3
      wallet/test/run-wallet.c

16
common/onion.c

@ -143,6 +143,7 @@ u8 *onion_final_hop(const tal_t *ctx,
/* Returns true if valid, and fills in type. */ /* Returns true if valid, and fills in type. */
static bool pull_payload_length(const u8 **cursor, static bool pull_payload_length(const u8 **cursor,
size_t *max, size_t *max,
bool has_realm,
enum onion_payload_type *type, enum onion_payload_type *type,
size_t *len) size_t *len)
{ {
@ -163,7 +164,7 @@ static bool pull_payload_length(const u8 **cursor,
* length. In this case the `hop_payload_length` is defined to be 32 * length. In this case the `hop_payload_length` is defined to be 32
* bytes. * bytes.
*/ */
if (*len == 0) { if (has_realm && *len == 0) {
if (type) if (type)
*type = ONION_V0_PAYLOAD; *type = ONION_V0_PAYLOAD;
assert(*cursor - start == 1); assert(*cursor - start == 1);
@ -176,10 +177,15 @@ static bool pull_payload_length(const u8 **cursor,
* case the `hop_payload_length` is equal to the numeric value of * case the `hop_payload_length` is equal to the numeric value of
* `length`. * `length`.
*/ */
if (*len > 1) { if (!has_realm || *len > 1) {
/* It's still invalid if it claims to be too long! */ /* It's still invalid if it claims to be too long! */
if (has_realm) {
if (*len > ROUTING_INFO_SIZE - HMAC_SIZE) if (*len > ROUTING_INFO_SIZE - HMAC_SIZE)
return false; return false;
} else {
if (*len > *max)
return false;
}
if (type) if (type)
*type = ONION_TLV_PAYLOAD; *type = ONION_TLV_PAYLOAD;
@ -190,12 +196,12 @@ static bool pull_payload_length(const u8 **cursor,
return false; return false;
} }
size_t onion_payload_length(const u8 *raw_payload, size_t len, size_t onion_payload_length(const u8 *raw_payload, size_t len, bool has_realm,
bool *valid, bool *valid,
enum onion_payload_type *type) enum onion_payload_type *type)
{ {
size_t max = len, payload_len; size_t max = len, payload_len;
*valid = pull_payload_length(&raw_payload, &max, type, &payload_len); *valid = pull_payload_length(&raw_payload, &max, has_realm, type, &payload_len);
/* If it's not valid, copy the entire thing. */ /* If it's not valid, copy the entire thing. */
if (!*valid) if (!*valid)
@ -214,7 +220,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
size_t max = tal_bytelen(cursor), len; size_t max = tal_bytelen(cursor), len;
struct tlv_tlv_payload *tlv; struct tlv_tlv_payload *tlv;
if (!pull_payload_length(&cursor, &max, &p->type, &len)) if (!pull_payload_length(&cursor, &max, true, &p->type, &len))
return tal_free(p); return tal_free(p);
switch (p->type) { switch (p->type) {

2
common/onion.h

@ -39,6 +39,7 @@ u8 *onion_final_hop(const tal_t *ctx,
* onion_payload_length: measure payload length in decrypted onion. * onion_payload_length: measure payload length in decrypted onion.
* @raw_payload: payload to look at. * @raw_payload: payload to look at.
* @len: length of @raw_payload in bytes. * @len: length of @raw_payload in bytes.
* @has_realm: used for HTLCs, where first byte 0 is magical.
* @valid: set to true if it is valid, false otherwise. * @valid: set to true if it is valid, false otherwise.
* @type: if non-NULL, set to type of payload if *@valid is true. * @type: if non-NULL, set to type of payload if *@valid is true.
* *
@ -47,6 +48,7 @@ u8 *onion_final_hop(const tal_t *ctx,
* the return value is @len (i.e. the entire payload). * the return value is @len (i.e. the entire payload).
*/ */
size_t onion_payload_length(const u8 *raw_payload, size_t len, size_t onion_payload_length(const u8 *raw_payload, size_t len,
bool has_realm,
bool *valid, bool *valid,
enum onion_payload_type *type); enum onion_payload_type *type);

5
common/sphinx.c

@ -563,7 +563,8 @@ struct route_step *process_onionpacket(
const struct onionpacket *msg, const struct onionpacket *msg,
const struct secret *shared_secret, const struct secret *shared_secret,
const u8 *assocdata, const u8 *assocdata,
const size_t assocdatalen const size_t assocdatalen,
bool has_realm
) )
{ {
struct route_step *step = talz(ctx, struct route_step); struct route_step *step = talz(ctx, struct route_step);
@ -596,7 +597,7 @@ struct route_step *process_onionpacket(
if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind)) if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind))
return tal_free(step); return tal_free(step);
payload_size = onion_payload_length(paddedheader, ROUTING_INFO_SIZE, payload_size = onion_payload_length(paddedheader, ROUTING_INFO_SIZE, has_realm,
&valid, NULL); &valid, NULL);
/* Can't decode? Treat it as terminal. */ /* Can't decode? Treat it as terminal. */

4
common/sphinx.h

@ -133,13 +133,15 @@ bool onion_shared_secret(
* @hoppayload: the per-hop payload destined for the processing node. * @hoppayload: the per-hop payload destined for the processing node.
* @assocdata: associated data to commit to in HMACs * @assocdata: associated data to commit to in HMACs
* @assocdatalen: length of the assocdata * @assocdatalen: length of the assocdata
* @has_realm: used for HTLCs, where first byte 0 is magical.
*/ */
struct route_step *process_onionpacket( struct route_step *process_onionpacket(
const tal_t * ctx, const tal_t * ctx,
const struct onionpacket *packet, const struct onionpacket *packet,
const struct secret *shared_secret, const struct secret *shared_secret,
const u8 *assocdata, const u8 *assocdata,
const size_t assocdatalen const size_t assocdatalen,
bool has_realm
); );
/** /**

4
devtools/onion.c

@ -128,7 +128,7 @@ static struct route_step *decode_with_privkey(const tal_t *ctx, const u8 *onion,
errx(1, "Error creating shared secret."); errx(1, "Error creating shared secret.");
step = process_onionpacket(ctx, &packet, &shared_secret, assocdata, step = process_onionpacket(ctx, &packet, &shared_secret, assocdata,
tal_bytelen(assocdata)); tal_bytelen(assocdata), true);
return step; return step;
} }
@ -282,7 +282,7 @@ static void runtest(const char *filename)
errx(1, "Error serializing message."); errx(1, "Error serializing message.");
onion_payload_length(step->raw_payload, onion_payload_length(step->raw_payload,
tal_bytelen(step->raw_payload), tal_bytelen(step->raw_payload),
&valid, &type); true, &valid, &type);
assert(valid); assert(valid);
printf(" Type: %d\n", type); printf(" Type: %d\n", type);
printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload)); printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload));

2
lightningd/peer_htlcs.c

@ -1108,7 +1108,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
rs = process_onionpacket(tmpctx, &op, hin->shared_secret, rs = process_onionpacket(tmpctx, &op, hin->shared_secret,
hin->payment_hash.u.u8, hin->payment_hash.u.u8,
sizeof(hin->payment_hash)); sizeof(hin->payment_hash), true);
if (!rs) { if (!rs) {
*badonion = WIRE_INVALID_ONION_HMAC; *badonion = WIRE_INVALID_ONION_HMAC;
log_debug(channel->log, log_debug(channel->log,

3
wallet/test/run-wallet.c

@ -550,7 +550,8 @@ struct route_step *process_onionpacket(
const struct onionpacket *packet UNNEEDED, const struct onionpacket *packet UNNEEDED,
const struct secret *shared_secret UNNEEDED, const struct secret *shared_secret UNNEEDED,
const u8 *assocdata UNNEEDED, const u8 *assocdata UNNEEDED,
const size_t assocdatalen const size_t assocdatalen UNNEEDED,
bool has_realm
) )
{ fprintf(stderr, "process_onionpacket called!\n"); abort(); } { fprintf(stderr, "process_onionpacket called!\n"); abort(); }
/* Generated stub for serialize_onionpacket */ /* Generated stub for serialize_onionpacket */

Loading…
Cancel
Save