Parse blinded forward-as-intro onion payloads
authorValentine Wallace <vwallace@protonmail.com>
Thu, 26 Oct 2023 18:28:45 +0000 (14:28 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Wed, 29 Nov 2023 22:23:29 +0000 (17:23 -0500)
Previously, we only parsed blinded receive payloads.

lightning/src/ln/channelmanager.rs
lightning/src/ln/msgs.rs
lightning/src/ln/onion_payment.rs

index de126084215a6ce9d70d4fee1f7d92566ca7ea14..d56d1349231acffca4143ede3c00f16c458bb77e 100644 (file)
@@ -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;
index 349cc5c728a093fe45412d945e1dded466242225..2d871b354a26d5643bece3211ddaa9986978bebd 100644 (file)
@@ -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<NS: Deref> 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)?,
index c10cdc9ab10ea61e3dbd2d3063835553d57acf2b..3c30a4458f5e21634651eae84c3f26bd7e75a26d 100644 (file)
@@ -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 { .. }, .. } =>