mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-21 22:31:48 +01:00
common: update to latest onion-message spec.
``` make check-source-bolt CHECK_BOLT_PREFIX="--prefix=BOLT-onion-message" BOLTVERSION=guilt/offers ``` Mainly textual, though I neatened the extra fields check for TLVs with blinding, and implemented the "no other fields" requirement for non-final onion message hops. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
8e630e7c53
commit
9aefe3d40a
5 changed files with 75 additions and 46 deletions
|
@ -205,8 +205,9 @@ struct tlv_encrypted_data_tlv *decrypt_encrypted_data(const tal_t *ctx,
|
|||
|
||||
/* BOLT-onion-message #4:
|
||||
*
|
||||
* - if the `enctlv` is not a valid TLV...
|
||||
* - MUST drop the message.
|
||||
* - MUST return an error if `encrypted_recipient_data` does not decrypt
|
||||
* using the blinding point as described in
|
||||
* [Route Blinding](#route-blinding).
|
||||
*/
|
||||
/* Note: our parser consider nothing is a valid TLV, but decrypt_encmsg_raw
|
||||
* returns NULL if it couldn't decrypt. */
|
||||
|
|
|
@ -9,6 +9,54 @@
|
|||
#include <common/sphinx.h>
|
||||
#include <sodium/crypto_aead_chacha20poly1305.h>
|
||||
|
||||
/* BOLT-route-blinding #4:
|
||||
* - If `encrypted_recipient_data` is present:
|
||||
*...
|
||||
* - If it is not the final node:
|
||||
* - MUST return an error if the payload contains other tlv fields than
|
||||
* `encrypted_recipient_data` and `current_blinding_point`.
|
||||
*/
|
||||
static bool check_nonfinal_tlv(const struct tlv_tlv_payload *tlv,
|
||||
u64 *failtlvtype)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(tlv->fields); i++) {
|
||||
switch (tlv->fields[i].numtype) {
|
||||
case TLV_TLV_PAYLOAD_BLINDING_POINT:
|
||||
case TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA:
|
||||
continue;
|
||||
}
|
||||
*failtlvtype = tlv->fields[i].numtype;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* BOLT-route-blinding #4:
|
||||
* - If `encrypted_recipient_data` is present:
|
||||
*...
|
||||
* - If it is the final node:
|
||||
* - MUST return an error if the payload contains other tlv fields than
|
||||
* `encrypted_recipient_data`, `current_blinding_point`, `amt_to_forward`,
|
||||
* `outgoing_cltv_value` and `total_amount_msat`.
|
||||
*/
|
||||
static bool check_final_tlv(const struct tlv_tlv_payload *tlv,
|
||||
u64 *failtlvtype)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(tlv->fields); i++) {
|
||||
switch (tlv->fields[i].numtype) {
|
||||
case TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA:
|
||||
case TLV_TLV_PAYLOAD_BLINDING_POINT:
|
||||
case TLV_TLV_PAYLOAD_AMT_TO_FORWARD:
|
||||
case TLV_TLV_PAYLOAD_OUTGOING_CLTV_VALUE:
|
||||
case TLV_TLV_PAYLOAD_TOTAL_AMOUNT_MSAT:
|
||||
continue;
|
||||
}
|
||||
*failtlvtype = tlv->fields[i].numtype;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static u64 ceil_div(u64 a, u64 b)
|
||||
{
|
||||
return (a + b - 1) / b;
|
||||
|
@ -23,18 +71,8 @@ static bool handle_blinded_forward(struct onion_payload *p,
|
|||
{
|
||||
u64 amt = amount_in.millisatoshis; /* Raw: allowed to wrap */
|
||||
|
||||
/* BOLT-route-blinding #4:
|
||||
* - If it is not the final node:
|
||||
* - MUST return an error if the payload contains other tlv fields
|
||||
* than `encrypted_recipient_data` and `current_blinding_point`.
|
||||
*/
|
||||
for (size_t i = 0; i < tal_count(tlv->fields); i++) {
|
||||
if (tlv->fields[i].numtype != TLV_TLV_PAYLOAD_BLINDING_POINT
|
||||
&& tlv->fields[i].numtype != TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA) {
|
||||
*failtlvtype = tlv->fields[i].numtype;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!check_nonfinal_tlv(tlv, failtlvtype))
|
||||
return false;
|
||||
|
||||
/* BOLT-route-blinding #4:
|
||||
* - If it is not the final node:
|
||||
|
@ -84,22 +122,8 @@ static bool handle_blinded_terminal(struct onion_payload *p,
|
|||
const struct tlv_encrypted_data_tlv *enc,
|
||||
u64 *failtlvtype)
|
||||
{
|
||||
/* BOLT-route-blinding #4:
|
||||
* - If it is the final node:
|
||||
* - MUST return an error if the payload contains other tlv fields than
|
||||
* `encrypted_recipient_data`, `current_blinding_point`, `amt_to_forward`,
|
||||
* `outgoing_cltv_value` and `total_amount_msat`.
|
||||
*/
|
||||
for (size_t i = 0; i < tal_count(tlv->fields); i++) {
|
||||
if (tlv->fields[i].numtype != TLV_TLV_PAYLOAD_BLINDING_POINT
|
||||
&& tlv->fields[i].numtype != TLV_TLV_PAYLOAD_ENCRYPTED_RECIPIENT_DATA
|
||||
&& tlv->fields[i].numtype != TLV_TLV_PAYLOAD_AMT_TO_FORWARD
|
||||
&& tlv->fields[i].numtype != TLV_TLV_PAYLOAD_OUTGOING_CLTV_VALUE
|
||||
&& tlv->fields[i].numtype != TLV_TLV_PAYLOAD_TOTAL_AMOUNT_MSAT) {
|
||||
*failtlvtype = tlv->fields[i].numtype;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!check_final_tlv(tlv, failtlvtype))
|
||||
return false;
|
||||
|
||||
/* BOLT-route-blinding #4:
|
||||
* - MUST return an error if `amt_to_forward`, `outgoing_cltv_value`
|
||||
|
|
|
@ -50,25 +50,19 @@ static bool decrypt_forwarding_onionmsg(const struct pubkey *blinding,
|
|||
return false;
|
||||
|
||||
/* BOLT-onion-message #4:
|
||||
*
|
||||
* The reader:
|
||||
* - if it is not the final node according to the onion encryption:
|
||||
*...
|
||||
* - if the `enctlv` ... does not contain
|
||||
* `next_node_id`:
|
||||
* - MUST drop the message.
|
||||
* - if the `encrypted_data_tlv` contains `path_id`:
|
||||
* - MUST ignore the message.
|
||||
*/
|
||||
if (!encmsg->next_node_id)
|
||||
if (encmsg->path_id)
|
||||
return false;
|
||||
|
||||
/* BOLT-onion-message #4:
|
||||
* The reader:
|
||||
* - if it is not the final node according to the onion encryption:
|
||||
*...
|
||||
* - if the `enctlv` contains `path_id`:
|
||||
* - MUST drop the message.
|
||||
* - SHOULD forward the message using `onion_message` to the next peer
|
||||
* indicated by `next_node_id`.
|
||||
*/
|
||||
if (encmsg->path_id)
|
||||
if (!encmsg->next_node_id)
|
||||
return false;
|
||||
|
||||
*next_node = *encmsg->next_node_id;
|
||||
|
@ -145,7 +139,6 @@ bool onion_message_parse(const tal_t *ctx,
|
|||
tal_hex(tmpctx, rs->raw_payload));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rs->nextcase == ONION_END) {
|
||||
*next_onion_msg = NULL;
|
||||
*final_om = tal_steal(ctx, om);
|
||||
|
@ -167,6 +160,18 @@ bool onion_message_parse(const tal_t *ctx,
|
|||
|
||||
*final_om = NULL;
|
||||
|
||||
/* BOLT-onion-message #4:
|
||||
* - if it is not the final node according to the onion encryption:
|
||||
* - if the `onionmsg_tlv` contains other tlv fields than `encrypted_recipient_data`:
|
||||
* - MUST ignore the message.
|
||||
*/
|
||||
if (tal_count(om->fields) != 1) {
|
||||
status_peer_debug(peer,
|
||||
"onion_message_parse: "
|
||||
"disallowed tlv field");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This fails as expected if no enctlv. */
|
||||
if (!decrypt_forwarding_onionmsg(blinding, &ss, om->encrypted_recipient_data, next_node_id,
|
||||
&next_blinding)) {
|
||||
|
@ -175,7 +180,6 @@ bool onion_message_parse(const tal_t *ctx,
|
|||
tal_hex(tmpctx, om->encrypted_recipient_data));
|
||||
return false;
|
||||
}
|
||||
|
||||
*next_onion_msg = towire_onion_message(ctx,
|
||||
&next_blinding,
|
||||
serialize_onionpacket(tmpctx, rs->next));
|
||||
|
|
|
@ -337,7 +337,7 @@ int main(int argc, char *argv[])
|
|||
sphinx_path->session_key = &session_key;
|
||||
|
||||
/* BOLT-onion-message #4:
|
||||
* - SHOULD set `len` to 1366 or 32834.
|
||||
* - SHOULD set `onion_message_packet` `len` to 1366 or 32834.
|
||||
*/
|
||||
op = create_onionpacket(tmpctx, sphinx_path, ROUTING_INFO_SIZE,
|
||||
&path_secrets);
|
||||
|
|
|
@ -216,7 +216,7 @@ static struct command_result *json_sendonionmessage(struct command *cmd,
|
|||
sphinx_add_hop(sphinx_path, &hops[i].node, hops[i].tlv);
|
||||
|
||||
/* BOLT-onion-message #4:
|
||||
* - SHOULD set `len` to 1366 or 32834.
|
||||
* - SHOULD set `onion_message_packet` `len` to 1366 or 32834.
|
||||
*/
|
||||
if (sphinx_path_payloads_size(sphinx_path) <= ROUTING_INFO_SIZE)
|
||||
onion_size = ROUTING_INFO_SIZE;
|
||||
|
|
Loading…
Add table
Reference in a new issue