]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add OffersContext::InvoiceRequest
authorJeffrey Czyz <jkczyz@gmail.com>
Wed, 3 Jul 2024 18:47:07 +0000 (13:47 -0500)
committerJeffrey Czyz <jkczyz@gmail.com>
Mon, 22 Jul 2024 16:34:03 +0000 (11:34 -0500)
To authenticate that an InvoiceRequest is for a valid Offer, include the
nonce from the Offer::metadata in the Offer::paths. This can be used to
prevent de-anonymization attacks where an attacker sends requests using
self-constructed paths to nodes near the Offer::paths' introduction
nodes.

lightning/src/blinded_path/message.rs
lightning/src/ln/channelmanager.rs
lightning/src/offers/nonce.rs

index c910689cebe34fcaaa179532f63764e32cda7f10..74d31c5b99efb82d592977670a022177a7243370 100644 (file)
@@ -22,6 +22,7 @@ use crate::io;
 use crate::io::Cursor;
 use crate::ln::channelmanager::PaymentId;
 use crate::ln::onion_utils;
+use crate::offers::nonce::Nonce;
 use crate::onion_message::packet::ControlTlvs;
 use crate::sign::{NodeSigner, Recipient};
 use crate::crypto::streams::ChaChaPolyReadAdapter;
@@ -112,6 +113,20 @@ pub enum OffersContext {
        /// This variant is used when a message is sent without using a [`BlindedPath`] or over one
        /// created prior to LDK version 0.0.124.
        Unknown {},
+       /// Context used by a [`BlindedPath`] within an [`Offer`].
+       ///
+       /// This variant is intended to be received when handling an [`InvoiceRequest`].
+       ///
+       /// [`Offer`]: crate::offers::offer::Offer
+       /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
+       InvoiceRequest {
+               /// A nonce used for authenticating that an [`InvoiceRequest`] is for a valid [`Offer`] and
+               /// for deriving the offer's signing keys.
+               ///
+               /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
+               /// [`Offer`]: crate::offers::offer::Offer
+               nonce: Nonce,
+       },
        /// Context used by a [`BlindedPath`] within a [`Refund`] or as a reply path for an
        /// [`InvoiceRequest`].
        ///
@@ -138,7 +153,10 @@ impl_writeable_tlv_based_enum!(MessageContext,
 
 impl_writeable_tlv_based_enum!(OffersContext,
        (0, Unknown) => {},
-       (1, OutboundPayment) => {
+       (1, InvoiceRequest) => {
+               (0, nonce, required),
+       },
+       (2, OutboundPayment) => {
                (0, payment_id, required),
        },
 );
index 34267adeda9ebbe4a31d2c71c4714c1e82c7e986..9f05877b95129b422be39e34d0664ac94d2f9acc 100644 (file)
@@ -8786,7 +8786,8 @@ macro_rules! create_offer_builder { ($self: ident, $builder: ty) => {
                let secp_ctx = &$self.secp_ctx;
 
                let nonce = Nonce::from_entropy_source(entropy);
-               let path = $self.create_blinded_paths_using_absolute_expiry(OffersContext::Unknown {}, absolute_expiry)
+               let context = OffersContext::InvoiceRequest { nonce };
+               let path = $self.create_blinded_paths_using_absolute_expiry(context, absolute_expiry)
                        .and_then(|paths| paths.into_iter().next().ok_or(()))
                        .map_err(|_| Bolt12SemanticError::MissingPaths)?;
                let builder = OfferBuilder::deriving_signing_pubkey(node_id, expanded_key, nonce, secp_ctx)
index 965a39d84ea590661a4069a4d7a96a080a341e99..be4c1d3d2543a67c7ae4a1330a89a6f72cbf5e05 100644 (file)
@@ -9,7 +9,10 @@
 
 //! A number used only once.
 
+use crate::io::{self, Read};
+use crate::ln::msgs::DecodeError;
 use crate::sign::EntropySource;
+use crate::util::ser::{Readable, Writeable, Writer};
 use core::ops::Deref;
 
 #[allow(unused_imports)]
@@ -62,3 +65,15 @@ impl TryFrom<&[u8]> for Nonce {
                Ok(Self(copied_bytes))
        }
 }
+
+impl Writeable for Nonce {
+       fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
+               self.0.write(w)
+       }
+}
+
+impl Readable for Nonce {
+       fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
+               Ok(Nonce(Readable::read(r)?))
+       }
+}