mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
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>
This commit is contained in:
parent
b162a0e5e2
commit
24984ec680
7 changed files with 26 additions and 14 deletions
|
@ -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 (*len > ROUTING_INFO_SIZE - HMAC_SIZE)
|
if (has_realm) {
|
||||||
return false;
|
if (*len > ROUTING_INFO_SIZE - HMAC_SIZE)
|
||||||
|
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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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…
Add table
Reference in a new issue