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. 20
      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

20
common/onion.c

@ -143,6 +143,7 @@ u8 *onion_final_hop(const tal_t *ctx,
/* Returns true if valid, and fills in type. */
static bool pull_payload_length(const u8 **cursor,
size_t *max,
bool has_realm,
enum onion_payload_type *type,
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
* bytes.
*/
if (*len == 0) {
if (has_realm && *len == 0) {
if (type)
*type = ONION_V0_PAYLOAD;
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
* `length`.
*/
if (*len > 1) {
if (!has_realm || *len > 1) {
/* It's still invalid if it claims to be too long! */
if (*len > ROUTING_INFO_SIZE - HMAC_SIZE)
return false;
if (has_realm) {
if (*len > ROUTING_INFO_SIZE - HMAC_SIZE)
return false;
} else {
if (*len > *max)
return false;
}
if (type)
*type = ONION_TLV_PAYLOAD;
@ -190,12 +196,12 @@ static bool pull_payload_length(const u8 **cursor,
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,
enum onion_payload_type *type)
{
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 (!*valid)
@ -214,7 +220,7 @@ struct onion_payload *onion_decode(const tal_t *ctx,
size_t max = tal_bytelen(cursor), len;
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);
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.
* @raw_payload: payload to look at.
* @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.
* @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).
*/
size_t onion_payload_length(const u8 *raw_payload, size_t len,
bool has_realm,
bool *valid,
enum onion_payload_type *type);

5
common/sphinx.c

@ -563,7 +563,8 @@ struct route_step *process_onionpacket(
const struct onionpacket *msg,
const struct secret *shared_secret,
const u8 *assocdata,
const size_t assocdatalen
const size_t assocdatalen,
bool has_realm
)
{
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))
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);
/* 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.
* @assocdata: associated data to commit to in HMACs
* @assocdatalen: length of the assocdata
* @has_realm: used for HTLCs, where first byte 0 is magical.
*/
struct route_step *process_onionpacket(
const tal_t * ctx,
const struct onionpacket *packet,
const struct secret *shared_secret,
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.");
step = process_onionpacket(ctx, &packet, &shared_secret, assocdata,
tal_bytelen(assocdata));
tal_bytelen(assocdata), true);
return step;
}
@ -282,7 +282,7 @@ static void runtest(const char *filename)
errx(1, "Error serializing message.");
onion_payload_length(step->raw_payload,
tal_bytelen(step->raw_payload),
&valid, &type);
true, &valid, &type);
assert(valid);
printf(" Type: %d\n", type);
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,
hin->payment_hash.u.u8,
sizeof(hin->payment_hash));
sizeof(hin->payment_hash), true);
if (!rs) {
*badonion = WIRE_INVALID_ONION_HMAC;
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 secret *shared_secret UNNEEDED,
const u8 *assocdata UNNEEDED,
const size_t assocdatalen
const size_t assocdatalen UNNEEDED,
bool has_realm
)
{ fprintf(stderr, "process_onionpacket called!\n"); abort(); }
/* Generated stub for serialize_onionpacket */

Loading…
Cancel
Save