Skip to content

Commit 09ffa57

Browse files
committed
Propagate Trampoline blinding errors
When a blinded hop fails to decode, we send a special malformed error. However, we previously simply checked the presence of a blinding point within the `UpdateAddHTLC` message, which is not necessarily applicable to Trampoline, so now we additionally return a flag if the error stemmed from an inner onion's blinded hop decoding failure.
1 parent 7b05135 commit 09ffa57

File tree

3 files changed

+19
-13
lines changed

3 files changed

+19
-13
lines changed

Diff for: lightning/src/ln/channelmanager.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5984,7 +5984,7 @@ where
59845984
onion_packet.hmac, payment_hash, None, &*self.node_signer
59855985
) {
59865986
Ok(res) => res,
5987-
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
5987+
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code, .. }) => {
59885988
let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).to_byte_array();
59895989
// In this scenario, the phantom would have sent us an
59905990
// `update_fail_malformed_htlc`, meaning here we encrypt the error as

Diff for: lightning/src/ln/onion_payment.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -474,10 +474,10 @@ where
474474
L::Target: Logger,
475475
{
476476
macro_rules! return_malformed_err {
477-
($msg: expr, $err_code: expr) => {
477+
($msg: expr, $err_code: expr, $force_blinding_error: expr) => {
478478
{
479479
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
480-
let (sha256_of_onion, failure_code) = if msg.blinding_point.is_some() {
480+
let (sha256_of_onion, failure_code) = if $force_blinding_error || msg.blinding_point.is_some() {
481481
([0; 32], INVALID_ONION_BLINDING)
482482
} else {
483483
(Sha256::hash(&msg.onion_routing_packet.hop_data).to_byte_array(), $err_code)
@@ -493,7 +493,7 @@ where
493493
}
494494

495495
if let Err(_) = msg.onion_routing_packet.public_key {
496-
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
496+
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6, false);
497497
}
498498

499499
if msg.onion_routing_packet.version != 0 {
@@ -503,12 +503,12 @@ where
503503
//receiving node would have to brute force to figure out which version was put in the
504504
//packet by the node that send us the message, in the case of hashing the hop_data, the
505505
//node knows the HMAC matched, so they already know what is there...
506-
return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
506+
return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4, false);
507507
}
508508

509509
let encode_relay_error = |message: &str, err_code: u16, shared_secret: [u8; 32], trampoline_shared_secret: Option<[u8; 32]>, data: &[u8]| {
510510
if msg.blinding_point.is_some() {
511-
return_malformed_err!(message, INVALID_ONION_BLINDING)
511+
return_malformed_err!(message, INVALID_ONION_BLINDING, false)
512512
}
513513

514514
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", message);
@@ -526,8 +526,8 @@ where
526526
msg.payment_hash, msg.blinding_point, node_signer
527527
) {
528528
Ok(res) => res,
529-
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
530-
return_malformed_err!(err_msg, err_code);
529+
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code, trampoline_onion_blinding }) => {
530+
return_malformed_err!(err_msg, err_code, trampoline_onion_blinding);
531531
},
532532
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code, shared_secret, trampoline_shared_secret }) => {
533533
return encode_relay_error(err_msg, err_code, shared_secret.secret_bytes(), trampoline_shared_secret.map(|tss| tss.secret_bytes()), &[0; 0]);

Diff for: lightning/src/ln/onion_utils.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,10 @@ impl Hop {
16731673
#[derive(Debug)]
16741674
pub(crate) enum OnionDecodeErr {
16751675
/// The HMAC of the onion packet did not match the hop data.
1676-
Malformed { err_msg: &'static str, err_code: u16 },
1676+
///
1677+
/// If the malformed onion packet was a blinded Trampoline hop, we communicate it up the call
1678+
/// stack for appropriate error handling.
1679+
Malformed { err_msg: &'static str, err_code: u16, trampoline_onion_blinding: bool },
16771680
/// We failed to decode the onion payload.
16781681
///
16791682
/// If the payload we failed to decode belonged to a Trampoline onion, following the successful
@@ -1732,6 +1735,7 @@ where
17321735
err_msg:
17331736
"Final Node OnionHopData provided for us as an intermediary node",
17341737
err_code: INVALID_ONION_BLINDING,
1738+
trampoline_onion_blinding: false,
17351739
});
17361740
}
17371741
Err(OnionDecodeErr::Relay {
@@ -1830,13 +1834,13 @@ where
18301834
}),
18311835
Ok((_, None)) => Err(OnionDecodeErr::Malformed {
18321836
err_msg: "Non-final Trampoline onion data provided to us as last hop",
1833-
// todo: find more suitable error code
1834-
err_code: 0x4000 | 22,
1837+
err_code: INVALID_ONION_BLINDING,
1838+
trampoline_onion_blinding: true,
18351839
}),
18361840
Ok((_, Some(_))) => Err(OnionDecodeErr::Malformed {
18371841
err_msg: "Final Trampoline onion data provided to us as intermediate hop",
1838-
// todo: find more suitable error code
1839-
err_code: 0x4000 | 22,
1842+
err_code: INVALID_ONION_BLINDING,
1843+
trampoline_onion_blinding: true,
18401844
}),
18411845
Err(e) => Err(e),
18421846
}
@@ -1846,6 +1850,7 @@ where
18461850
return Err(OnionDecodeErr::Malformed {
18471851
err_msg: "Intermediate Node OnionHopData provided for us as a final node",
18481852
err_code: INVALID_ONION_BLINDING,
1853+
trampoline_onion_blinding: false,
18491854
});
18501855
}
18511856
Err(OnionDecodeErr::Relay {
@@ -1980,6 +1985,7 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
19801985
return Err(OnionDecodeErr::Malformed {
19811986
err_msg: "HMAC Check failed",
19821987
err_code: 0x8000 | 0x4000 | 5,
1988+
trampoline_onion_blinding: false,
19831989
});
19841990
}
19851991

0 commit comments

Comments
 (0)