From 35b75fd1fdae40e0d2316da6ddcc725d35c60c50 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Tue, 2 Jul 2024 16:55:59 -0500 Subject: [PATCH] Authenticate InvoiceRequest using OfferContext When an InvoiceRequest is handled with an OfferContext, use the containing nonce to verify that it is for a valid Offer. Otherwise, fall back to using Offer::metadata, which also contains the nonce. The latter is useful for supporting offers without blinded paths or those created prior to including an OffersContext in their blinded paths. --- lightning/src/ln/channelmanager.rs | 32 ++++++++++++++++++------- lightning/src/offers/invoice_request.rs | 2 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 9f05877b9..80faffc0d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -10703,19 +10703,35 @@ where Some(responder) => responder, None => return ResponseInstruction::NoResponse, }; + + let nonce = match context { + OffersContext::Unknown {} if invoice_request.metadata().is_some() => None, + OffersContext::InvoiceRequest { nonce } => Some(nonce), + _ => return ResponseInstruction::NoResponse, + }; + + let invoice_request = match nonce { + Some(nonce) => match invoice_request.verify_using_recipient_data( + nonce, expanded_key, secp_ctx, + ) { + Ok(invoice_request) => invoice_request, + Err(()) => return ResponseInstruction::NoResponse, + }, + None => match invoice_request.verify(expanded_key, secp_ctx) { + Ok(invoice_request) => invoice_request, + Err(()) => { + let error = Bolt12SemanticError::InvalidMetadata; + return responder.respond(OffersMessage::InvoiceError(error.into())); + }, + }, + }; + let amount_msats = match InvoiceBuilder::::amount_msats( - &invoice_request + &invoice_request.inner ) { Ok(amount_msats) => amount_msats, Err(error) => return responder.respond(OffersMessage::InvoiceError(error.into())), }; - let invoice_request = match invoice_request.verify(expanded_key, secp_ctx) { - Ok(invoice_request) => invoice_request, - Err(()) => { - let error = Bolt12SemanticError::InvalidMetadata; - return responder.respond(OffersMessage::InvoiceError(error.into())); - }, - }; let relative_expiry = DEFAULT_RELATIVE_EXPIRY.as_secs() as u32; let (payment_hash, payment_secret) = match self.create_inbound_payment( diff --git a/lightning/src/offers/invoice_request.rs b/lightning/src/offers/invoice_request.rs index 8c09721f2..6011ca79b 100644 --- a/lightning/src/offers/invoice_request.rs +++ b/lightning/src/offers/invoice_request.rs @@ -613,7 +613,7 @@ pub struct VerifiedInvoiceRequest { pub offer_id: OfferId, /// The verified request. - inner: InvoiceRequest, + pub(crate) inner: InvoiceRequest, /// Keys used for signing a [`Bolt12Invoice`] if they can be derived. /// -- 2.39.5