Skip to content

Commit 6b8735b

Browse files
Error if onion payloads exceed max length on packet construction.
Ensure that if we call construct_onion_packet and friends where payloads are too large for the allotted packet length, we'll fail to construct. Previously, senders would happily construct invalid packets by array-shifting the final node's HMAC out of the packet when adding an intermediate onion layer, causing the receiver to error with "final payload provided for us as an intermediate node."
1 parent 0c1f9cb commit 6b8735b

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lightning/src/ln/onion_payment.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ pub(super) fn check_incoming_htlc_cltv(
375375
mod tests {
376376
use bitcoin::hashes::Hash;
377377
use bitcoin::hashes::sha256::Hash as Sha256;
378-
use bitcoin::secp256k1::{PublicKey, SecretKey};
378+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
379379
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
380380
use crate::ln::ChannelId;
381381
use crate::ln::channelmanager::RecipientOnionFields;
@@ -385,6 +385,38 @@ mod tests {
385385
use crate::routing::router::{Path, RouteHop};
386386
use crate::util::test_utils;
387387

388+
#[test]
389+
fn fail_construct_onion_on_too_big_payloads() {
390+
// Ensure that if we call `construct_onion_packet` and friends where payloads are too large for
391+
// the allotted packet length, we'll fail to construct. Previously, senders would happily
392+
// construct invalid packets by array-shifting the final node's HMAC out of the packet when
393+
// adding an intermediate onion layer, causing the receiver to error with "final payload
394+
// provided for us as an intermediate node."
395+
let secp_ctx = Secp256k1::new();
396+
let bob = crate::sign::KeysManager::new(&[2; 32], 42, 42);
397+
let bob_pk = PublicKey::from_secret_key(&secp_ctx, &bob.get_node_secret_key());
398+
let charlie = crate::sign::KeysManager::new(&[3; 32], 42, 42);
399+
let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
400+
401+
let (
402+
session_priv, total_amt_msat, cur_height, mut recipient_onion, keysend_preimage, payment_hash,
403+
prng_seed, hops, ..
404+
) = payment_onion_args(bob_pk, charlie_pk);
405+
406+
// Ensure the onion will not fit all the payloads by adding a large custom TLV.
407+
recipient_onion.custom_tlvs.push((13377331, vec![0; 1156]));
408+
409+
let path = Path { hops, blinded_tail: None, };
410+
let onion_keys = super::onion_utils::construct_onion_keys(&secp_ctx, &path, &session_priv).unwrap();
411+
let (onion_payloads, ..) = super::onion_utils::build_onion_payloads(
412+
&path, total_amt_msat, recipient_onion, cur_height + 1, &Some(keysend_preimage)
413+
).unwrap();
414+
415+
assert!(super::onion_utils::construct_onion_packet(
416+
onion_payloads, onion_keys, prng_seed, &payment_hash
417+
).is_err());
418+
}
419+
388420
#[test]
389421
fn test_peel_payment_onion() {
390422
use super::*;

lightning/src/ln/onion_utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,12 @@ fn construct_onion_packet_with_init_noise<HD: Writeable, P: Packet>(
343343
};
344344

345345
let mut hmac_res = [0; 32];
346+
let mut packet_len_without_filler = 0;
346347
for (i, (payload, keys)) in payloads.iter_mut().zip(onion_keys.iter()).rev().enumerate() {
347348
let mut payload_len = LengthCalculatingWriter(0);
348349
payload.write(&mut payload_len).expect("Failed to calculate length");
350+
packet_len_without_filler += payload_len.0 + 32;
351+
if packet_len_without_filler > packet_data.as_mut().len() { return Err(()) }
349352

350353
let packet_data = packet_data.as_mut();
351354
shift_slice_right(packet_data, payload_len.0 + 32);

0 commit comments

Comments
 (0)