Skip to content

Commit 96db8aa

Browse files
Add onion message AsyncPaymentsContext for inbound payments
This context is included in static invoice's blinded message paths, provided back to us in HeldHtlcAvailable onion messages for blinded path authentication. In future work, we will check if this context is valid and respond with a ReleaseHeldHtlc message to release the upstream payment if so. We also add creation methods for the hmac used for authenticating said blinded path.
1 parent 84f200f commit 96db8aa

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

lightning/src/blinded_path/message.rs

+22
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,24 @@ pub enum AsyncPaymentsContext {
402402
/// containing the expected [`PaymentId`].
403403
hmac: Hmac<Sha256>,
404404
},
405+
/// Context contained within the [`BlindedMessagePath`]s we put in static invoices, provided back
406+
/// to us in corresponding [`HeldHtlcAvailable`] messages.
407+
///
408+
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
409+
InboundPayment {
410+
/// A nonce used for authenticating that a [`HeldHtlcAvailable`] message is valid for a
411+
/// preceding static invoice.
412+
///
413+
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
414+
nonce: Nonce,
415+
/// Authentication code for the [`HeldHtlcAvailable`] message.
416+
///
417+
/// Prevents nodes from creating their own blinded path to us, sending a [`HeldHtlcAvailable`]
418+
/// message and trivially getting notified whenever we come online.
419+
///
420+
/// [`HeldHtlcAvailable`]: crate::onion_message::async_payments::HeldHtlcAvailable
421+
hmac: Hmac<Sha256>,
422+
},
405423
}
406424

407425
impl_writeable_tlv_based_enum!(MessageContext,
@@ -433,6 +451,10 @@ impl_writeable_tlv_based_enum!(AsyncPaymentsContext,
433451
(2, nonce, required),
434452
(4, hmac, required),
435453
},
454+
(1, InboundPayment) => {
455+
(0, nonce, required),
456+
(2, hmac, required),
457+
},
436458
);
437459

438460
/// Contains a simple nonce for use in a blinded path's context.

lightning/src/ln/channelmanager.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -12209,7 +12209,12 @@ where
1220912209

1221012210
fn handle_release_held_htlc(&self, _message: ReleaseHeldHtlc, _context: AsyncPaymentsContext) {
1221112211
#[cfg(async_payments)] {
12212-
let AsyncPaymentsContext::OutboundPayment { payment_id, hmac, nonce } = _context;
12212+
let (payment_id, nonce, hmac) = match _context {
12213+
AsyncPaymentsContext::OutboundPayment { payment_id, hmac, nonce } => {
12214+
(payment_id, nonce, hmac)
12215+
},
12216+
_ => return
12217+
};
1221312218
if payment_id.verify_for_async_payment(hmac, nonce, &self.inbound_payment_key).is_err() { return }
1221412219
if let Err(e) = self.send_payment_for_static_invoice(payment_id) {
1221512220
log_trace!(

lightning/src/offers/signer.rs

+18
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ const PAYMENT_HASH_HMAC_INPUT: &[u8; 16] = &[7; 16];
5050
// HMAC input for `ReceiveTlvs`. The HMAC is used in `blinded_path::payment::PaymentContext`.
5151
const PAYMENT_TLVS_HMAC_INPUT: &[u8; 16] = &[8; 16];
5252

53+
// HMAC input used in `AsyncPaymentsContext::InboundPayment` to authenticate inbound
54+
// held_htlc_available onion messages.
55+
#[cfg(async_payments)]
56+
const ASYNC_PAYMENTS_HELD_HTLC_HMAC_INPUT: &[u8; 16] = &[9; 16];
57+
5358
/// Message metadata which possibly is derived from [`MetadataMaterial`] such that it can be
5459
/// verified.
5560
#[derive(Clone)]
@@ -483,3 +488,16 @@ pub(crate) fn verify_payment_tlvs(
483488
) -> Result<(), ()> {
484489
if hmac_for_payment_tlvs(receive_tlvs, nonce, expanded_key) == hmac { Ok(()) } else { Err(()) }
485490
}
491+
492+
#[cfg(async_payments)]
493+
pub(crate) fn hmac_for_held_htlc_available_context(
494+
nonce: Nonce, expanded_key: &ExpandedKey,
495+
) -> Hmac<Sha256> {
496+
const IV_BYTES: &[u8; IV_LEN] = b"LDK Held HTLC OM";
497+
let mut hmac = expanded_key.hmac_for_offer();
498+
hmac.input(IV_BYTES);
499+
hmac.input(&nonce.0);
500+
hmac.input(ASYNC_PAYMENTS_HELD_HTLC_HMAC_INPUT);
501+
502+
Hmac::from_engine(hmac)
503+
}

0 commit comments

Comments
 (0)