From 1a7254c1784557cb69f551ac35401a0d7da7598a Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Thu, 26 Oct 2023 14:28:45 -0400 Subject: [PATCH] Parse blinded forward-as-intro onion payloads Previously, we only parsed blinded receive payloads. --- lightning/src/ln/channelmanager.rs | 2 +- lightning/src/ln/msgs.rs | 30 +++++++++++++++++++++++++++--- lightning/src/ln/onion_payment.rs | 15 ++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index de126084..d56d1349 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -53,7 +53,7 @@ use crate::routing::scoring::{ProbabilisticScorer, ProbabilisticScoringFeeParame use crate::ln::onion_payment::{check_incoming_htlc_cltv, create_recv_pending_htlc_info, create_fwd_pending_htlc_info, decode_incoming_update_add_htlc_onion, InboundOnionErr, NextPacketDetails}; use crate::ln::msgs; use crate::ln::onion_utils; -use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING}; +use crate::ln::onion_utils::HTLCFailReason; use crate::ln::msgs::{ChannelMessageHandler, DecodeError, LightningError}; #[cfg(test)] use crate::ln::outbound_payment; diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 349cc5c7..2d871b35 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -31,7 +31,7 @@ use bitcoin::{secp256k1, Witness}; use bitcoin::blockdata::script::ScriptBuf; use bitcoin::hash_types::Txid; -use crate::blinded_path::payment::ReceiveTlvs; +use crate::blinded_path::payment::{BlindedPaymentTlvs, ForwardTlvs, ReceiveTlvs}; use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret}; use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures}; use crate::ln::onion_utils; @@ -1666,9 +1666,10 @@ pub trait OnionMessageHandler { mod fuzzy_internal_msgs { use bitcoin::secp256k1::PublicKey; - use crate::blinded_path::payment::PaymentConstraints; + use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay}; use crate::prelude::*; use crate::ln::{PaymentPreimage, PaymentSecret}; + use crate::ln::features::BlindedHopFeatures; // These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize // them from untrusted input): @@ -1695,6 +1696,13 @@ mod fuzzy_internal_msgs { amt_msat: u64, outgoing_cltv_value: u32, }, + BlindedForward { + short_channel_id: u64, + payment_relay: PaymentRelay, + payment_constraints: PaymentConstraints, + features: BlindedHopFeatures, + intro_node_blinding_point: PublicKey, + }, BlindedReceive { amt_msat: u64, total_msat: u64, @@ -2354,7 +2362,23 @@ impl ReadableArgs<&NS> for InboundOnionPayload where NS::Target: Node let mut s = Cursor::new(&enc_tlvs); let mut reader = FixedLengthReader::new(&mut s, enc_tlvs.len() as u64); match ChaChaPolyReadAdapter::read(&mut reader, rho)? { - ChaChaPolyReadAdapter { readable: ReceiveTlvs { payment_secret, payment_constraints }} => { + ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Forward(ForwardTlvs { + short_channel_id, payment_relay, payment_constraints, features + })} => { + if amt.is_some() || cltv_value.is_some() || total_msat.is_some() { + return Err(DecodeError::InvalidValue) + } + Ok(Self::BlindedForward { + short_channel_id, + payment_relay, + payment_constraints, + features, + intro_node_blinding_point: blinding_point, + }) + }, + ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs { + payment_secret, payment_constraints + })} => { if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) } Ok(Self::BlindedReceive { amt_msat: amt.ok_or(DecodeError::InvalidValue)?, diff --git a/lightning/src/ln/onion_payment.rs b/lightning/src/ln/onion_payment.rs index c10cdc9a..3c30a445 100644 --- a/lightning/src/ln/onion_payment.rs +++ b/lightning/src/ln/onion_payment.rs @@ -11,7 +11,7 @@ use crate::ln::PaymentHash; use crate::ln::channelmanager::{CLTV_FAR_FAR_AWAY, HTLCFailureMsg, MIN_CLTV_EXPIRY_DELTA, PendingHTLCInfo, PendingHTLCRouting}; use crate::ln::msgs; use crate::ln::onion_utils; -use crate::ln::onion_utils::HTLCFailReason; +use crate::ln::onion_utils::{HTLCFailReason, INVALID_ONION_BLINDING}; use crate::sign::{NodeSigner, Recipient}; use crate::util::logger::Logger; @@ -44,6 +44,7 @@ pub(super) fn create_fwd_pending_htlc_info( let (short_channel_id, amt_to_forward, outgoing_cltv_value) = match hop_data { msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } => (short_channel_id, amt_to_forward, outgoing_cltv_value), + msgs::InboundOnionPayload::BlindedForward { .. } => todo!(), msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } => return Err(InboundOnionErr { msg: "Final Node OnionHopData provided for us as an intermediary node", @@ -90,6 +91,13 @@ pub(super) fn create_recv_pending_htlc_info( msg: "Got non final data with an HMAC of 0", }) }, + msgs::InboundOnionPayload::BlindedForward { .. } => { + return Err(InboundOnionErr { + err_code: INVALID_ONION_BLINDING, + err_data: vec![0; 32], + msg: "Got blinded non final data with an HMAC of 0", + }) + } }; // final_incorrect_cltv_expiry if outgoing_cltv_value > cltv_expiry { @@ -327,6 +335,11 @@ where outgoing_amt_msat: amt_to_forward, outgoing_cltv_value } }, + onion_utils::Hop::Forward { + next_hop_data: msgs::InboundOnionPayload::BlindedForward { .. }, .. + } => { + todo!() + }, onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)), onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } | onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::BlindedReceive { .. }, .. } => -- 2.30.2