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:
Rusty Russell 2023-01-12 14:25:38 +10:30
parent 8e630e7c53
commit 9aefe3d40a
5 changed files with 75 additions and 46 deletions

View file

@ -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. */

View file

@ -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`

View file

@ -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));

View file

@ -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);

View file

@ -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;