Skip to content

Commit 3b0e9a2

Browse files
committed
Replace constant key with ReceiveAuthKey
This commit replaces the hardcoded key used for authenticating the context in incoming `BlindedMessagePath`s with a dedicated `ReceiveAuthKey`. This makes the authentication mechanism explicit and configurable for the user. Changes include: - Introducing `ReceiveAuthKey` to the `NodeSigner`, used to authenticate the context at the final hop of an incoming blinded path. - Updating `BlindedMessagePath::new` to accept a `ReceiveAuthKey` as a parameter during path construction.
1 parent 45f395a commit 3b0e9a2

File tree

14 files changed

+313
-97
lines changed

14 files changed

+313
-97
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ use lightning::routing::router::{
6363
InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters, Router,
6464
};
6565
use lightning::sign::{
66-
EntropySource, InMemorySigner, NodeSigner, PeerStorageKey, Recipient, SignerProvider,
66+
EntropySource, InMemorySigner, NodeSigner, PeerStorageKey, ReceiveAuthKey, Recipient,
67+
SignerProvider,
6768
};
6869
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6970
use lightning::util::config::UserConfig;
@@ -142,8 +143,8 @@ impl MessageRouter for FuzzRouter {
142143
}
143144

144145
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
145-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
146-
_secp_ctx: &Secp256k1<T>,
146+
&self, _recipient: PublicKey, _local_node_receive_key: ReceiveAuthKey,
147+
_context: MessageContext, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
147148
) -> Result<Vec<BlindedMessagePath>, ()> {
148149
unreachable!()
149150
}
@@ -347,6 +348,10 @@ impl NodeSigner for KeyProvider {
347348
PeerStorageKey { inner: [42; 32] }
348349
}
349350

351+
fn get_receive_auth_key(&self) -> ReceiveAuthKey {
352+
ReceiveAuthKey([41; 32])
353+
}
354+
350355
fn sign_bolt12_invoice(
351356
&self, _invoice: &UnsignedBolt12Invoice,
352357
) -> Result<schnorr::Signature, ()> {

fuzz/src/full_stack.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ use lightning::routing::router::{
5757
};
5858
use lightning::routing::utxo::UtxoLookup;
5959
use lightning::sign::{
60-
EntropySource, InMemorySigner, NodeSigner, PeerStorageKey, Recipient, SignerProvider,
60+
EntropySource, InMemorySigner, NodeSigner, PeerStorageKey, ReceiveAuthKey, Recipient,
61+
SignerProvider,
6162
};
6263
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6364
use lightning::util::config::{ChannelConfig, UserConfig};
@@ -173,8 +174,8 @@ impl MessageRouter for FuzzRouter {
173174
}
174175

175176
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
176-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
177-
_secp_ctx: &Secp256k1<T>,
177+
&self, _recipient: PublicKey, _local_node_receive_key: ReceiveAuthKey,
178+
_context: MessageContext, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
178179
) -> Result<Vec<BlindedMessagePath>, ()> {
179180
unreachable!()
180181
}
@@ -438,6 +439,10 @@ impl NodeSigner for KeyProvider {
438439
fn get_peer_storage_key(&self) -> PeerStorageKey {
439440
PeerStorageKey { inner: [42; 32] }
440441
}
442+
443+
fn get_receive_auth_key(&self) -> ReceiveAuthKey {
444+
ReceiveAuthKey([41; 32])
445+
}
441446
}
442447

443448
impl SignerProvider for KeyProvider {

fuzz/src/onion_message.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ use lightning::onion_message::messenger::{
2424
};
2525
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
2626
use lightning::onion_message::packet::OnionMessageContents;
27-
use lightning::sign::{EntropySource, NodeSigner, PeerStorageKey, Recipient, SignerProvider};
27+
use lightning::sign::{
28+
EntropySource, NodeSigner, PeerStorageKey, ReceiveAuthKey, Recipient, SignerProvider,
29+
};
2830
use lightning::types::features::InitFeatures;
2931
use lightning::util::logger::Logger;
3032
use lightning::util::ser::{LengthReadable, Writeable, Writer};
@@ -104,8 +106,8 @@ impl MessageRouter for TestMessageRouter {
104106
}
105107

106108
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
107-
&self, _recipient: PublicKey, _context: MessageContext, _peers: Vec<PublicKey>,
108-
_secp_ctx: &Secp256k1<T>,
109+
&self, _recipient: PublicKey, _local_node_receive_key: ReceiveAuthKey,
110+
_context: MessageContext, _peers: Vec<PublicKey>, _secp_ctx: &Secp256k1<T>,
109111
) -> Result<Vec<BlindedMessagePath>, ()> {
110112
unreachable!()
111113
}
@@ -278,6 +280,10 @@ impl NodeSigner for KeyProvider {
278280
fn get_peer_storage_key(&self) -> PeerStorageKey {
279281
unreachable!()
280282
}
283+
284+
fn get_receive_auth_key(&self) -> ReceiveAuthKey {
285+
ReceiveAuthKey([41; 32])
286+
}
281287
}
282288

283289
impl SignerProvider for KeyProvider {

lightning-dns-resolver/src/lib.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ mod test {
174174
AOnionMessenger, Destination, MessageRouter, OnionMessagePath, OnionMessenger,
175175
};
176176
use lightning::routing::router::RouteParametersConfig;
177-
use lightning::sign::{KeysManager, NodeSigner, Recipient};
177+
use lightning::sign::{KeysManager, NodeSigner, ReceiveAuthKey, Recipient};
178178
use lightning::types::features::InitFeatures;
179179
use lightning::types::payment::PaymentHash;
180180
use lightning::util::logger::Logger;
@@ -230,11 +230,18 @@ mod test {
230230
}
231231

232232
fn create_blinded_paths<T: secp256k1::Signing + secp256k1::Verification>(
233-
&self, recipient: PublicKey, context: MessageContext, _peers: Vec<PublicKey>,
234-
secp_ctx: &Secp256k1<T>,
233+
&self, recipient: PublicKey, local_node_receive_key: ReceiveAuthKey,
234+
context: MessageContext, _peers: Vec<PublicKey>, secp_ctx: &Secp256k1<T>,
235235
) -> Result<Vec<BlindedMessagePath>, ()> {
236236
let keys = KeysManager::new(&[0; 32], 42, 43);
237-
Ok(vec![BlindedMessagePath::one_hop(recipient, context, &keys, secp_ctx).unwrap()])
237+
Ok(vec![BlindedMessagePath::one_hop(
238+
recipient,
239+
local_node_receive_key,
240+
context,
241+
&keys,
242+
secp_ctx,
243+
)
244+
.unwrap()])
238245
}
239246
}
240247
impl Deref for DirectlyConnectedRouter {
@@ -336,8 +343,15 @@ mod test {
336343
let (msg, context) =
337344
payer.resolver.resolve_name(payment_id, name.clone(), &*payer_keys).unwrap();
338345
let query_context = MessageContext::DNSResolver(context);
339-
let reply_path =
340-
BlindedMessagePath::one_hop(payer_id, query_context, &*payer_keys, &secp_ctx).unwrap();
346+
let receive_key = payer_keys.get_receive_auth_key();
347+
let reply_path = BlindedMessagePath::one_hop(
348+
payer_id,
349+
receive_key,
350+
query_context,
351+
&*payer_keys,
352+
&secp_ctx,
353+
)
354+
.unwrap();
341355
payer.pending_messages.lock().unwrap().push((
342356
DNSResolverMessage::DNSSECQuery(msg),
343357
MessageSendInstructions::WithSpecifiedReplyPath {

lightning/src/blinded_path/message.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ impl Readable for BlindedMessagePath {
5656
impl BlindedMessagePath {
5757
/// Create a one-hop blinded path for a message.
5858
pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
59-
recipient_node_id: PublicKey, context: MessageContext, entropy_source: ES,
60-
secp_ctx: &Secp256k1<T>,
59+
recipient_node_id: PublicKey, local_node_receive_key: ReceiveAuthKey,
60+
context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>,
6161
) -> Result<Self, ()>
6262
where
6363
ES::Target: EntropySource,
6464
{
65-
Self::new(&[], recipient_node_id, context, entropy_source, secp_ctx)
65+
Self::new(&[], recipient_node_id, local_node_receive_key, context, entropy_source, secp_ctx)
6666
}
6767

6868
/// Create a path for an onion message, to be forwarded along `node_pks`. The last node
@@ -72,7 +72,8 @@ impl BlindedMessagePath {
7272
// TODO: make all payloads the same size with padding + add dummy hops
7373
pub fn new<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
7474
intermediate_nodes: &[MessageForwardNode], recipient_node_id: PublicKey,
75-
context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>,
75+
local_node_receive_key: ReceiveAuthKey, context: MessageContext, entropy_source: ES,
76+
secp_ctx: &Secp256k1<T>,
7677
) -> Result<Self, ()>
7778
where
7879
ES::Target: EntropySource,
@@ -93,7 +94,7 @@ impl BlindedMessagePath {
9394
recipient_node_id,
9495
context,
9596
&blinding_secret,
96-
ReceiveAuthKey([41; 32]), // TODO: Pass this in
97+
local_node_receive_key,
9798
)
9899
.map_err(|_| ())?,
99100
}))

lightning/src/ln/async_payments_tests.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ fn create_static_invoice<T: secp256k1::Signing + secp256k1::Verification>(
109109
.message_router
110110
.create_blinded_paths(
111111
always_online_counterparty.node.get_our_node_id(),
112+
always_online_counterparty.keys_manager.get_receive_auth_key(),
112113
MessageContext::Offers(OffersContext::InvoiceRequest { nonce: Nonce([42; 16]) }),
113114
Vec::new(),
114115
&secp_ctx,
@@ -219,6 +220,7 @@ fn static_invoice_unknown_required_features() {
219220
.message_router
220221
.create_blinded_paths(
221222
nodes[1].node.get_our_node_id(),
223+
nodes[1].keys_manager.get_receive_auth_key(),
222224
MessageContext::Offers(OffersContext::InvoiceRequest { nonce: Nonce([42; 16]) }),
223225
Vec::new(),
224226
&secp_ctx,
@@ -848,6 +850,7 @@ fn invalid_async_receive_with_retry<F1, F2>(
848850
.message_router
849851
.create_blinded_paths(
850852
nodes[1].node.get_our_node_id(),
853+
nodes[1].keys_manager.get_receive_auth_key(),
851854
MessageContext::Offers(OffersContext::InvoiceRequest { nonce: Nonce([42; 16]) }),
852855
Vec::new(),
853856
&secp_ctx,

lightning/src/ln/blinded_payment_tests.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::offers::invoice::UnsignedBolt12Invoice;
3636
use crate::offers::nonce::Nonce;
3737
use crate::prelude::*;
3838
use crate::routing::router::{BlindedTail, Path, Payee, PaymentParameters, RouteHop, RouteParameters, TrampolineHop};
39-
use crate::sign::{NodeSigner, PeerStorageKey, Recipient};
39+
use crate::sign::{NodeSigner, PeerStorageKey, ReceiveAuthKey, Recipient};
4040
use crate::util::config::UserConfig;
4141
use crate::util::ser::{WithoutLength, Writeable};
4242
use crate::util::test_utils;
@@ -1638,6 +1638,7 @@ fn route_blinding_spec_test_vector() {
16381638
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
16391639
) -> Result<RecoverableSignature, ()> { unreachable!() }
16401640
fn get_peer_storage_key(&self) -> PeerStorageKey { unreachable!() }
1641+
fn get_receive_auth_key(&self) -> ReceiveAuthKey { unreachable!() }
16411642
fn sign_bolt12_invoice(
16421643
&self, _invoice: &UnsignedBolt12Invoice,
16431644
) -> Result<schnorr::Signature, ()> { unreachable!() }
@@ -1948,6 +1949,7 @@ fn test_trampoline_inbound_payment_decoding() {
19481949
&self, _invoice: &RawBolt11Invoice, _recipient: Recipient,
19491950
) -> Result<RecoverableSignature, ()> { unreachable!() }
19501951
fn get_peer_storage_key(&self) -> PeerStorageKey { unreachable!() }
1952+
fn get_receive_auth_key(&self) -> ReceiveAuthKey { unreachable!() }
19511953
fn sign_bolt12_invoice(
19521954
&self, _invoice: &UnsignedBolt12Invoice,
19531955
) -> Result<schnorr::Signature, ()> { unreachable!() }

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,7 +3750,7 @@ where
37503750
let flow = OffersMessageFlow::new(
37513751
ChainHash::using_genesis_block(params.network), params.best_block,
37523752
our_network_pubkey, current_timestamp, expanded_inbound_key,
3753-
secp_ctx.clone(), message_router
3753+
node_signer.get_receive_auth_key(), secp_ctx.clone(), message_router
37543754
);
37553755

37563756
ChannelManager {
@@ -15658,7 +15658,7 @@ where
1565815658
let flow = OffersMessageFlow::new(
1565915659
chain_hash, best_block, our_network_pubkey,
1566015660
highest_seen_timestamp, expanded_inbound_key,
15661-
secp_ctx.clone(), args.message_router
15661+
args.node_signer.get_receive_auth_key(), secp_ctx.clone(), args.message_router
1566215662
).with_async_payments_offers_cache(async_receive_offer_cache);
1566315663

1566415664
let channel_manager = ChannelManager {

lightning/src/offers/flow.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ use crate::onion_message::messenger::{Destination, MessageRouter, MessageSendIns
5454
use crate::onion_message::offers::OffersMessage;
5555
use crate::onion_message::packet::OnionMessageContents;
5656
use crate::routing::router::Router;
57-
use crate::sign::{EntropySource, NodeSigner};
57+
use crate::sign::{EntropySource, NodeSigner, ReceiveAuthKey};
5858
use crate::sync::{Mutex, RwLock};
5959
use crate::types::payment::{PaymentHash, PaymentSecret};
6060
use crate::util::ser::Writeable;
@@ -94,6 +94,8 @@ where
9494
highest_seen_timestamp: AtomicUsize,
9595
inbound_payment_key: inbound_payment::ExpandedKey,
9696

97+
receive_auth_key: ReceiveAuthKey,
98+
9799
secp_ctx: Secp256k1<secp256k1::All>,
98100
message_router: MR,
99101

@@ -122,7 +124,7 @@ where
122124
pub fn new(
123125
chain_hash: ChainHash, best_block: BestBlock, our_network_pubkey: PublicKey,
124126
current_timestamp: u32, inbound_payment_key: inbound_payment::ExpandedKey,
125-
secp_ctx: Secp256k1<secp256k1::All>, message_router: MR,
127+
receive_auth_key: ReceiveAuthKey, secp_ctx: Secp256k1<secp256k1::All>, message_router: MR,
126128
) -> Self {
127129
Self {
128130
chain_hash,
@@ -132,6 +134,8 @@ where
132134
highest_seen_timestamp: AtomicUsize::new(current_timestamp as usize),
133135
inbound_payment_key,
134136

137+
receive_auth_key,
138+
135139
secp_ctx,
136140
message_router,
137141

@@ -187,6 +191,10 @@ where
187191
self.our_network_pubkey
188192
}
189193

194+
fn get_receive_auth_key(&self) -> ReceiveAuthKey {
195+
self.receive_auth_key
196+
}
197+
190198
fn duration_since_epoch(&self) -> Duration {
191199
#[cfg(not(feature = "std"))]
192200
let now = Duration::from_secs(self.highest_seen_timestamp.load(Ordering::Acquire) as u64);
@@ -278,11 +286,12 @@ where
278286
&self, peers: Vec<MessageForwardNode>, context: MessageContext,
279287
) -> Result<Vec<BlindedMessagePath>, ()> {
280288
let recipient = self.get_our_node_id();
289+
let receive_key = self.get_receive_auth_key();
281290
let secp_ctx = &self.secp_ctx;
282291

283292
let peers = peers.into_iter().map(|node| node.node_id).collect();
284293
self.message_router
285-
.create_blinded_paths(recipient, context, peers, secp_ctx)
294+
.create_blinded_paths(recipient, receive_key, context, peers, secp_ctx)
286295
.and_then(|paths| (!paths.is_empty()).then(|| paths).ok_or(()))
287296
}
288297

@@ -294,11 +303,13 @@ where
294303
&self, peers: Vec<MessageForwardNode>, context: OffersContext,
295304
) -> Result<Vec<BlindedMessagePath>, ()> {
296305
let recipient = self.get_our_node_id();
306+
let receive_key = self.get_receive_auth_key();
297307
let secp_ctx = &self.secp_ctx;
298308

299309
self.message_router
300310
.create_compact_blinded_paths(
301311
recipient,
312+
receive_key,
302313
MessageContext::Offers(context),
303314
peers,
304315
secp_ctx,

0 commit comments

Comments
 (0)