Skip to content

Commit 12d8847

Browse files
f check for invalid provided blinded payment TLVs
1 parent c44ecfc commit 12d8847

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

lightning/src/blinded_path/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,25 @@ impl BlindedPath {
8080
/// Create a blinded path for a payment, to be forwarded along `path`. The last node
8181
/// in `path` will be the destination node.
8282
///
83-
/// Errors if `path` is empty, a node id in `path` is invalid, or [`BlindedPayInfo`] calculation
84-
/// results in an integer overflow.
83+
/// Errors if:
84+
/// * `path` is empty
85+
/// * a node id in `path` is invalid
86+
/// * [`BlindedPayInfo`] calculation results in an integer overflow
87+
/// * the list of [`BlindedPaymentTlvs`] does not consist of 0 or more
88+
/// `BlindedPaymentTlvs::Forward` followed by 1 `BlindedPaymentTlvs::Receive`
8589
// TODO: make all payloads the same size with padding + add dummy hops
8690
pub fn new_for_payment<ES: EntropySource, T: secp256k1::Signing + secp256k1::Verification>(
8791
path: &[(PublicKey, BlindedPaymentTlvs)], entropy_source: &ES, secp_ctx: &Secp256k1<T>
8892
) -> Result<(BlindedPayInfo, Self), ()> {
8993
if path.len() < 1 { return Err(()) }
94+
let mut found_recv_payload = false;
95+
for (_, payload) in path.iter() {
96+
if let BlindedPaymentTlvs::Receive { .. } = payload {
97+
if found_recv_payload { return Err(()) }
98+
found_recv_payload = true;
99+
} else if found_recv_payload { return Err(()) }
100+
}
101+
90102
let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
91103
let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
92104

lightning/src/blinded_path/payment.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@ impl_writeable_msg!(PaymentConstraints, {
203203

204204
#[cfg(test)]
205205
mod tests {
206-
use bitcoin::secp256k1::PublicKey;
206+
use bitcoin::network::constants::Network;
207+
use bitcoin::secp256k1::{PublicKey, Secp256k1};
208+
use crate::blinded_path::BlindedPath;
207209
use crate::blinded_path::payment::{BlindedPaymentTlvs, PaymentConstraints, PaymentRelay};
208210
use crate::ln::PaymentSecret;
209211
use crate::ln::features::BlindedHopFeatures;
212+
use crate::util::test_utils;
210213

211214
#[test]
212215
fn compute_payinfo() {
@@ -266,4 +269,47 @@ mod tests {
266269
assert_eq!(blinded_payinfo.cltv_expiry_delta, 0);
267270
assert_eq!(blinded_payinfo.htlc_minimum_msat, 1);
268271
}
272+
273+
#[test]
274+
fn invalid_payloads() {
275+
let dummy_pk = PublicKey::from_slice(&[2; 33]).unwrap();
276+
let secp_ctx = Secp256k1::new();
277+
let keys_manager = test_utils::TestKeysInterface::new(&[42 as u8; 32], Network::Testnet);
278+
279+
let out_of_order_payloads_path = vec![(dummy_pk, BlindedPaymentTlvs::Receive {
280+
payment_secret: PaymentSecret([0; 32]),
281+
payment_constraints: PaymentConstraints {
282+
max_cltv_expiry: 0,
283+
htlc_minimum_msat: 1,
284+
},
285+
}), (dummy_pk, BlindedPaymentTlvs::Forward {
286+
short_channel_id: 0,
287+
payment_relay: PaymentRelay {
288+
cltv_expiry_delta: 144,
289+
fee_proportional_millionths: 500,
290+
fee_base_msat: 100,
291+
},
292+
payment_constraints: PaymentConstraints {
293+
max_cltv_expiry: 0,
294+
htlc_minimum_msat: 100,
295+
},
296+
features: BlindedHopFeatures::empty(),
297+
})];
298+
assert!(BlindedPath::new_for_payment(&out_of_order_payloads_path[..], &keys_manager, &secp_ctx).is_err());
299+
300+
let multiple_recv_payloads_path = vec![(dummy_pk, BlindedPaymentTlvs::Receive {
301+
payment_secret: PaymentSecret([0; 32]),
302+
payment_constraints: PaymentConstraints {
303+
max_cltv_expiry: 0,
304+
htlc_minimum_msat: 1,
305+
},
306+
}), (dummy_pk, BlindedPaymentTlvs::Receive {
307+
payment_secret: PaymentSecret([0; 32]),
308+
payment_constraints: PaymentConstraints {
309+
max_cltv_expiry: 0,
310+
htlc_minimum_msat: 1,
311+
},
312+
})];
313+
assert!(BlindedPath::new_for_payment(&multiple_recv_payloads_path[..], &keys_manager, &secp_ctx).is_err());
314+
}
269315
}

0 commit comments

Comments
 (0)