@@ -198,6 +198,8 @@ pub enum PendingHTLCRouting {
198
198
custom_tlvs: Vec<(u64, Vec<u8>)>,
199
199
/// Set if this HTLC is the final hop in a multi-hop blinded path.
200
200
requires_blinded_error: bool,
201
+ /// An HMAC of `payment_context` along with a nonce used to construct it.
202
+ authentication: Option<(Hmac<Sha256>, Nonce)>,
201
203
},
202
204
/// The onion indicates that this is for payment to us but which contains the preimage for
203
205
/// claiming included, and is unrelated to any invoice we'd previously generated (aka a
@@ -5994,19 +5996,19 @@ where
5994
5996
let blinded_failure = routing.blinded_failure();
5995
5997
let (
5996
5998
cltv_expiry, onion_payload, payment_data, payment_context, phantom_shared_secret,
5997
- mut onion_fields, has_recipient_created_payment_secret
5999
+ mut onion_fields, has_recipient_created_payment_secret, authentication,
5998
6000
) = match routing {
5999
6001
PendingHTLCRouting::Receive {
6000
6002
payment_data, payment_metadata, payment_context,
6001
6003
incoming_cltv_expiry, phantom_shared_secret, custom_tlvs,
6002
- requires_blinded_error: _
6004
+ requires_blinded_error: _, authentication,
6003
6005
} => {
6004
6006
let _legacy_hop_data = Some(payment_data.clone());
6005
6007
let onion_fields = RecipientOnionFields { payment_secret: Some(payment_data.payment_secret),
6006
6008
payment_metadata, custom_tlvs };
6007
6009
(incoming_cltv_expiry, OnionPayload::Invoice { _legacy_hop_data },
6008
6010
Some(payment_data), payment_context, phantom_shared_secret, onion_fields,
6009
- true)
6011
+ true, authentication )
6010
6012
},
6011
6013
PendingHTLCRouting::ReceiveKeysend {
6012
6014
payment_data, payment_preimage, payment_metadata,
@@ -6019,7 +6021,7 @@ where
6019
6021
custom_tlvs,
6020
6022
};
6021
6023
(incoming_cltv_expiry, OnionPayload::Spontaneous(payment_preimage),
6022
- payment_data, None, None, onion_fields, has_recipient_created_payment_secret)
6024
+ payment_data, None, None, onion_fields, has_recipient_created_payment_secret, None )
6023
6025
},
6024
6026
_ => {
6025
6027
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
@@ -6204,6 +6206,16 @@ where
6204
6206
payment_preimage
6205
6207
} else { fail_htlc!(claimable_htlc, payment_hash); }
6206
6208
} else { None };
6209
+
6210
+ // Authenticate the PaymentContext received over a BlindedPaymentPath
6211
+ if let Some(payment_context) = payment_context.as_ref() {
6212
+ if let Some((hmac, nonce)) = authentication {
6213
+ if payment_context.verify_for_offer_payment(hmac, nonce, &self.inbound_payment_key).is_err() {
6214
+ fail_htlc!(claimable_htlc, payment_hash);
6215
+ }
6216
+ }
6217
+ }
6218
+
6207
6219
match claimable_htlc.onion_payload {
6208
6220
OnionPayload::Invoice { .. } => {
6209
6221
let payment_data = payment_data.unwrap();
@@ -12362,6 +12374,7 @@ impl_writeable_tlv_based_enum!(PendingHTLCRouting,
12362
12374
(5, custom_tlvs, optional_vec),
12363
12375
(7, requires_blinded_error, (default_value, false)),
12364
12376
(9, payment_context, option),
12377
+ (11, authentication, option),
12365
12378
},
12366
12379
(2, ReceiveKeysend) => {
12367
12380
(0, payment_preimage, required),
0 commit comments