Skip to content

Commit aa7e013

Browse files
committed
Authenticate Bolt12Invoice using BlindedPath data
When a Bolt12Invoice is handled with an OfferContext, use both the containing payment_id and nonce to verify that it is for a pending outbound payment. Previously, the nonce the payment_id were taken from the payer_metadata and the latter was compared against the payment_id in the OfferContext. The payer_metadata thus no longer needs to include either when a blinded path is used. However, some payer_metadata will still be needed as per the spec.
1 parent 82f10fa commit aa7e013

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10644,36 +10644,41 @@ where
1064410644
}
1064510645
},
1064610646
OffersMessage::Invoice(invoice) => {
10647-
let expected_payment_id = match context {
10647+
let payer_data = match context {
1064810648
OffersContext::Unknown {} if invoice.is_for_refund_without_paths() => None,
10649-
OffersContext::OutboundPayment { payment_id, .. } => Some(payment_id),
10649+
OffersContext::OutboundPayment { payment_id, nonce } => Some((payment_id, nonce)),
1065010650
_ => return ResponseInstruction::NoResponse,
1065110651
};
1065210652

10653-
let result = match invoice.verify(expanded_key, secp_ctx) {
10654-
Ok(payment_id) => {
10655-
if let Some(expected_payment_id) = expected_payment_id {
10656-
if payment_id != expected_payment_id {
10657-
return ResponseInstruction::NoResponse;
10658-
}
10659-
}
10660-
10661-
let features = self.bolt12_invoice_features();
10662-
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10663-
Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
10664-
} else if self.default_configuration.manually_handle_bolt12_invoices {
10665-
let event = Event::InvoiceReceived { payment_id, invoice, responder };
10666-
self.pending_events.lock().unwrap().push_back((event, None));
10667-
return ResponseInstruction::NoResponse;
10653+
let payment_id = match payer_data {
10654+
Some((payment_id, nonce)) => {
10655+
if invoice.verify_using_payer_data(payment_id, nonce, expanded_key, secp_ctx) {
10656+
payment_id
1066810657
} else {
10669-
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
10670-
.map_err(|e| {
10671-
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
10672-
InvoiceError::from_string(format!("{:?}", e))
10673-
})
10658+
return ResponseInstruction::NoResponse;
1067410659
}
1067510660
},
10676-
Err(()) => return ResponseInstruction::NoResponse,
10661+
None => match invoice.verify(expanded_key, secp_ctx) {
10662+
Ok(payment_id) => payment_id,
10663+
Err(()) => return ResponseInstruction::NoResponse,
10664+
},
10665+
};
10666+
10667+
let result = {
10668+
let features = self.bolt12_invoice_features();
10669+
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10670+
Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
10671+
} else if self.default_configuration.manually_handle_bolt12_invoices {
10672+
let event = Event::InvoiceReceived { payment_id, invoice, responder };
10673+
self.pending_events.lock().unwrap().push_back((event, None));
10674+
return ResponseInstruction::NoResponse;
10675+
} else {
10676+
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
10677+
.map_err(|e| {
10678+
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
10679+
InvoiceError::from_string(format!("{:?}", e))
10680+
})
10681+
}
1067710682
};
1067810683

1067910684
match result {

0 commit comments

Comments
 (0)