Skip to content

Commit b379209

Browse files
committed
Add nonce to OffersContext::OutboundPayment
To authenticate that a Bolt12Invoice is for a valid InvoiceRequest or Refund, include the nonce from the payer_metadata in the InvoiceRequest reply path or Refund::paths, respectively. This can be used to prevent de-anonymization attacks where an attacker sends invoices using self-constructed paths to nodes near the blinded paths' introduction nodes.
1 parent 4dbd6fc commit b379209

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

lightning/src/blinded_path/message.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,13 @@ pub enum OffersContext {
135135
///
136136
/// [`Refund`]: crate::offers::refund::Refund
137137
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
138-
payment_id: PaymentId
138+
payment_id: PaymentId,
139+
/// A nonce used for authenticating that an [`Invoice`] is for a valid [`Refund`] or
140+
/// [`InvoiceRequest`] and for deriving their signing keys.
141+
///
142+
/// [`Refund`]: crate::offers::refund::Refund
143+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
144+
nonce: Nonce,
139145
},
140146
/// Context used by a [`BlindedPath`] for replying to a [`Bolt12Invoice`] with an
141147
/// [`InvoiceError`].
@@ -162,6 +168,7 @@ impl_writeable_tlv_based_enum!(OffersContext,
162168
},
163169
(2, OutboundPayment) => {
164170
(0, payment_id, required),
171+
(1, nonce, required),
165172
},
166173
(3, InboundPayment) => {
167174
(0, payment_hash, required),

lightning/src/ln/channelmanager.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -8698,7 +8698,7 @@ macro_rules! create_refund_builder { ($self: ident, $builder: ty) => {
86988698
let secp_ctx = &$self.secp_ctx;
86998699

87008700
let nonce = Nonce::from_entropy_source(entropy);
8701-
let context = OffersContext::OutboundPayment { payment_id };
8701+
let context = OffersContext::OutboundPayment { payment_id, nonce };
87028702
let path = $self.create_blinded_path_using_absolute_expiry(context, Some(absolute_expiry))
87038703
.map_err(|_| Bolt12SemanticError::MissingPaths)?;
87048704
let builder = RefundBuilder::deriving_payer_id(
@@ -8824,7 +8824,7 @@ where
88248824
};
88258825
let invoice_request = builder.build_and_sign()?;
88268826

8827-
let context = OffersContext::OutboundPayment { payment_id };
8827+
let context = OffersContext::OutboundPayment { payment_id, nonce };
88288828
let reply_path = self.create_blinded_path(context).map_err(|_| Bolt12SemanticError::MissingPaths)?;
88298829

88308830
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
@@ -10514,7 +10514,7 @@ where
1051410514

1051510515
let abandon_if_payment = |context| {
1051610516
match context {
10517-
OffersContext::OutboundPayment { payment_id } => self.abandon_payment(payment_id),
10517+
OffersContext::OutboundPayment { payment_id, .. } => self.abandon_payment(payment_id),
1051810518
_ => {},
1051910519
}
1052010520
};
@@ -10625,7 +10625,7 @@ where
1062510625
OffersMessage::Invoice(invoice) => {
1062610626
let expected_payment_id = match context {
1062710627
OffersContext::Unknown {} if invoice.is_for_refund_without_paths() => None,
10628-
OffersContext::OutboundPayment { payment_id } => Some(payment_id),
10628+
OffersContext::OutboundPayment { payment_id, .. } => Some(payment_id),
1062910629
_ => return ResponseInstruction::NoResponse,
1063010630
};
1063110631

0 commit comments

Comments
 (0)