Skip to content

Commit 2c2f3fe

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 14634c6 commit 2c2f3fe

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
@@ -10807,36 +10807,41 @@ where
1080710807
}
1080810808
},
1080910809
OffersMessage::Invoice(invoice) => {
10810-
let expected_payment_id = match context {
10810+
let payer_data = match context {
1081110811
OffersContext::Unknown {} if invoice.is_for_refund_without_paths() => None,
10812-
OffersContext::OutboundPayment { payment_id, .. } => Some(payment_id),
10812+
OffersContext::OutboundPayment { payment_id, nonce } => Some((payment_id, nonce)),
1081310813
_ => return ResponseInstruction::NoResponse,
1081410814
};
1081510815

10816-
let result = match invoice.verify(expanded_key, secp_ctx) {
10817-
Ok(payment_id) => {
10818-
if let Some(expected_payment_id) = expected_payment_id {
10819-
if payment_id != expected_payment_id {
10820-
return ResponseInstruction::NoResponse;
10821-
}
10822-
}
10823-
10824-
let features = self.bolt12_invoice_features();
10825-
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10826-
Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
10827-
} else if self.default_configuration.manually_handle_bolt12_invoices {
10828-
let event = Event::InvoiceReceived { payment_id, invoice, responder };
10829-
self.pending_events.lock().unwrap().push_back((event, None));
10830-
return ResponseInstruction::NoResponse;
10816+
let payment_id = match payer_data {
10817+
Some((payment_id, nonce)) => {
10818+
if invoice.verify_using_payer_data(payment_id, nonce, expanded_key, secp_ctx) {
10819+
payment_id
1083110820
} else {
10832-
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
10833-
.map_err(|e| {
10834-
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
10835-
InvoiceError::from_string(format!("{:?}", e))
10836-
})
10821+
return ResponseInstruction::NoResponse;
1083710822
}
1083810823
},
10839-
Err(()) => return ResponseInstruction::NoResponse,
10824+
None => match invoice.verify(expanded_key, secp_ctx) {
10825+
Ok(payment_id) => payment_id,
10826+
Err(()) => return ResponseInstruction::NoResponse,
10827+
},
10828+
};
10829+
10830+
let result = {
10831+
let features = self.bolt12_invoice_features();
10832+
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10833+
Err(InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures))
10834+
} else if self.default_configuration.manually_handle_bolt12_invoices {
10835+
let event = Event::InvoiceReceived { payment_id, invoice, responder };
10836+
self.pending_events.lock().unwrap().push_back((event, None));
10837+
return ResponseInstruction::NoResponse;
10838+
} else {
10839+
self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id)
10840+
.map_err(|e| {
10841+
log_trace!(self.logger, "Failed paying invoice: {:?}", e);
10842+
InvoiceError::from_string(format!("{:?}", e))
10843+
})
10844+
}
1084010845
};
1084110846

1084210847
match result {

0 commit comments

Comments
 (0)