Skip to content

Commit 8c9f53b

Browse files
committed
(f?) Solely use shared secret calculated within decode_next_payment_hop
1 parent 4cdff56 commit 8c9f53b

File tree

3 files changed

+58
-50
lines changed

3 files changed

+58
-50
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5856,7 +5856,6 @@ where
58565856
if let PendingHTLCRouting::Forward { ref onion_packet, .. } = routing {
58575857
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
58585858
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.chain_hash) {
5859-
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
58605859
let next_hop = match onion_utils::decode_next_payment_hop(
58615860
Recipient::PhantomNode, &onion_packet.public_key.unwrap(), &onion_packet.hop_data,
58625861
onion_packet.hmac, payment_hash, None, &*self.node_signer
@@ -5870,15 +5869,17 @@ where
58705869
// of the onion.
58715870
failed_payment!(err_msg, err_code, sha256_of_onion.to_vec(), None);
58725871
},
5873-
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
5872+
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code, shared_secret }) => {
5873+
let phantom_shared_secret = shared_secret.secret_bytes();
58745874
failed_payment!(err_msg, err_code, Vec::new(), Some(phantom_shared_secret));
58755875
},
58765876
};
5877-
let inbound_onion_payload = match next_hop {
5878-
onion_utils::Hop::Receive { hop_data, .. } => msgs::InboundOnionPayload::Receive(hop_data),
5879-
onion_utils::Hop::BlindedReceive { hop_data, .. } => msgs::InboundOnionPayload::BlindedReceive(hop_data),
5877+
let (inbound_onion_payload, shared_secret) = match next_hop {
5878+
onion_utils::Hop::Receive { hop_data, shared_secret } => (msgs::InboundOnionPayload::Receive(hop_data), shared_secret),
5879+
onion_utils::Hop::BlindedReceive { hop_data, shared_secret } => (msgs::InboundOnionPayload::BlindedReceive(hop_data), shared_secret),
58805880
_ => panic!()
58815881
};
5882+
let phantom_shared_secret = shared_secret.secret_bytes();
58825883
let current_height: u32 = self.best_block.read().unwrap().height;
58835884
match create_recv_pending_htlc_info(inbound_onion_payload,
58845885
incoming_shared_secret, payment_hash, outgoing_amt_msat,

lightning/src/ln/onion_payment.rs

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
//! Primarily features [`peel_payment_onion`], which allows the decoding of an onion statelessly
44
//! and can be used to predict whether we'd accept a payment.
55
6-
use bitcoin::hashes::{Hash, HashEngine};
7-
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
6+
use bitcoin::hashes::Hash;
87
use bitcoin::hashes::sha256::Hash as Sha256;
9-
use bitcoin::secp256k1::{self, PublicKey, Scalar, Secp256k1};
8+
use bitcoin::secp256k1::{self, PublicKey, Secp256k1};
109

1110
use crate::blinded_path;
1211
use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
@@ -385,16 +384,6 @@ where
385384
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
386385
}
387386

388-
let blinded_node_id_tweak = msg.blinding_point.map(|bp| {
389-
let blinded_tlvs_ss = node_signer.ecdh(Recipient::Node, &bp, None).unwrap().secret_bytes();
390-
let mut hmac = HmacEngine::<Sha256>::new(b"blinded_node_id");
391-
hmac.input(blinded_tlvs_ss.as_ref());
392-
Scalar::from_be_bytes(Hmac::from_engine(hmac).to_byte_array()).unwrap()
393-
});
394-
let shared_secret = node_signer.ecdh(
395-
Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), blinded_node_id_tweak.as_ref()
396-
).unwrap().secret_bytes();
397-
398387
if msg.onion_routing_packet.version != 0 {
399388
//TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
400389
//sha256_of_onion error data packets), or the entire onion_routing_packet. Either way,
@@ -404,23 +393,20 @@ where
404393
//node knows the HMAC matched, so they already know what is there...
405394
return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
406395
}
407-
macro_rules! return_err {
408-
($msg: expr, $err_code: expr, $data: expr) => {
409-
{
410-
if msg.blinding_point.is_some() {
411-
return_malformed_err!($msg, INVALID_ONION_BLINDING)
412-
}
413396

414-
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
415-
return Err(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
416-
channel_id: msg.channel_id,
417-
htlc_id: msg.htlc_id,
418-
reason: HTLCFailReason::reason($err_code, $data.to_vec())
419-
.get_encrypted_failure_packet(&shared_secret, &None),
420-
}));
421-
}
397+
let encode_relay_error = |message: &str, err_code: u16, shared_secret: [u8; 32], data: &[u8]| {
398+
if msg.blinding_point.is_some() {
399+
return_malformed_err!(message, INVALID_ONION_BLINDING)
422400
}
423-
}
401+
402+
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", message);
403+
return Err(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
404+
channel_id: msg.channel_id,
405+
htlc_id: msg.htlc_id,
406+
reason: HTLCFailReason::reason(err_code, data.to_vec())
407+
.get_encrypted_failure_packet(&shared_secret, &None),
408+
}));
409+
};
424410

425411
let next_hop = match onion_utils::decode_next_payment_hop(
426412
Recipient::Node, &msg.onion_routing_packet.public_key.unwrap(), &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
@@ -430,32 +416,32 @@ where
430416
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
431417
return_malformed_err!(err_msg, err_code);
432418
},
433-
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
434-
return_err!(err_msg, err_code, &[0; 0]);
419+
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code, shared_secret }) => {
420+
return encode_relay_error(err_msg, err_code, shared_secret.secret_bytes(), &[0; 0]);
435421
},
436422
};
437423

438424
let next_packet_details = match next_hop {
439-
Hop::Forward { next_hop_data: msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }, .. } => {
425+
Hop::Forward { next_hop_data: msgs::InboundOnionForwardPayload { short_channel_id, amt_to_forward, outgoing_cltv_value }, shared_secret, .. } => {
440426
let next_packet_pubkey = onion_utils::next_hop_pubkey(secp_ctx,
441-
msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
427+
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
442428
Some(NextPacketDetails {
443429
next_packet_pubkey, outgoing_scid: short_channel_id,
444430
outgoing_amt_msat: amt_to_forward, outgoing_cltv_value
445431
})
446432
}
447-
Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, .. } => {
433+
Hop::BlindedForward { next_hop_data: msgs::InboundOnionBlindedForwardPayload { short_channel_id, ref payment_relay, ref payment_constraints, ref features, .. }, shared_secret, .. } => {
448434
let (amt_to_forward, outgoing_cltv_value) = match check_blinded_forward(
449435
msg.amount_msat, msg.cltv_expiry, &payment_relay, &payment_constraints, &features
450436
) {
451437
Ok((amt, cltv)) => (amt, cltv),
452438
Err(()) => {
453-
return_err!("Underflow calculating outbound amount or cltv value for blinded forward",
454-
INVALID_ONION_BLINDING, &[0; 32]);
439+
return encode_relay_error("Underflow calculating outbound amount or cltv value for blinded forward",
440+
INVALID_ONION_BLINDING, shared_secret.secret_bytes(), &[0; 32]);
455441
}
456442
};
457443
let next_packet_pubkey = onion_utils::next_hop_pubkey(&secp_ctx,
458-
msg.onion_routing_packet.public_key.unwrap(), &shared_secret);
444+
msg.onion_routing_packet.public_key.unwrap(), &shared_secret.secret_bytes());
459445
Some(NextPacketDetails {
460446
next_packet_pubkey, outgoing_scid: short_channel_id, outgoing_amt_msat: amt_to_forward,
461447
outgoing_cltv_value

lightning/src/ln/onion_utils.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ pub(crate) enum OnionDecodeErr {
14851485
/// The HMAC of the onion packet did not match the hop data.
14861486
Malformed { err_msg: &'static str, err_code: u16 },
14871487
/// We failed to decode the onion payload.
1488-
Relay { err_msg: &'static str, err_code: u16 },
1488+
Relay { err_msg: &'static str, err_code: u16, shared_secret: SharedSecret },
14891489
}
14901490

14911491
pub(crate) fn decode_next_payment_hop<NS: Deref>(
@@ -1530,10 +1530,20 @@ where
15301530
new_packet_bytes,
15311531
})
15321532
},
1533-
_ => Err(OnionDecodeErr::Relay {
1534-
err_msg: "Final Node OnionHopData provided for us as an intermediary node",
1535-
err_code: 0x4000 | 22,
1536-
}),
1533+
_ => {
1534+
if blinding_point.is_some() {
1535+
return Err(OnionDecodeErr::Malformed {
1536+
err_msg:
1537+
"Final Node OnionHopData provided for us as an intermediary node",
1538+
err_code: INVALID_ONION_BLINDING,
1539+
});
1540+
}
1541+
Err(OnionDecodeErr::Relay {
1542+
err_msg: "Final Node OnionHopData provided for us as an intermediary node",
1543+
err_code: 0x4000 | 22,
1544+
shared_secret: SharedSecret::from_bytes(shared_secret),
1545+
})
1546+
},
15371547
}
15381548
},
15391549
Ok((next_hop_data, None)) => match next_hop_data {
@@ -1545,10 +1555,19 @@ where
15451555
shared_secret: SharedSecret::from_bytes(shared_secret),
15461556
hop_data,
15471557
}),
1548-
_ => Err(OnionDecodeErr::Relay {
1549-
err_msg: "Intermediate Node OnionHopData provided for us as a final node",
1550-
err_code: 0x4000 | 22,
1551-
}),
1558+
_ => {
1559+
if blinding_point.is_some() {
1560+
return Err(OnionDecodeErr::Malformed {
1561+
err_msg: "Intermediate Node OnionHopData provided for us as a final node",
1562+
err_code: INVALID_ONION_BLINDING,
1563+
});
1564+
}
1565+
Err(OnionDecodeErr::Relay {
1566+
err_msg: "Intermediate Node OnionHopData provided for us as a final node",
1567+
err_code: 0x4000 | 22,
1568+
shared_secret: SharedSecret::from_bytes(shared_secret),
1569+
})
1570+
},
15521571
},
15531572
Err(e) => Err(e),
15541573
}
@@ -1694,6 +1713,7 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
16941713
return Err(OnionDecodeErr::Relay {
16951714
err_msg: "Unable to decode our hop data",
16961715
err_code: error_code,
1716+
shared_secret: SharedSecret::from_bytes(shared_secret),
16971717
});
16981718
},
16991719
Ok(msg) => {
@@ -1702,6 +1722,7 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
17021722
return Err(OnionDecodeErr::Relay {
17031723
err_msg: "Unable to decode our hop data",
17041724
err_code: 0x4000 | 22,
1725+
shared_secret: SharedSecret::from_bytes(shared_secret),
17051726
});
17061727
}
17071728
if hmac == [0; 32] {

0 commit comments

Comments
 (0)