Skip to content

Commit ffb84e8

Browse files
committed
make peel_onion a free standing fn
1 parent be9206c commit ffb84e8

File tree

1 file changed

+96
-91
lines changed

1 file changed

+96
-91
lines changed

lightning/src/onion_message/messenger.rs

+96-91
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,101 @@ where
314314
}))
315315
}
316316

317+
/// Decode one layer of an incoming onion message
318+
/// Returns either a Forward (another onion message), or Receive (decrypted content)
319+
pub fn peel_onion<NS: Deref, L: Deref, CMH: Deref, T: CustomOnionMessageContents>(
320+
node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L, custom_handler: &CMH,
321+
msg: &msgs::OnionMessage,
322+
) -> Result<PeeledOnion<CMH>, ()>
323+
where
324+
NS::Target: NodeSigner,
325+
L::Target: Logger,
326+
CMH::Target: CustomOnionMessageHandler,
327+
{
328+
let control_tlvs_ss = match node_signer.ecdh(Recipient::Node, &msg.blinding_point, None) {
329+
Ok(ss) => ss,
330+
Err(e) => {
331+
log_error!(logger, "Failed to retrieve node secret: {:?}", e);
332+
return Err(());
333+
}
334+
};
335+
let onion_decode_ss = {
336+
let blinding_factor = {
337+
let mut hmac = HmacEngine::<Sha256>::new(b"blinded_node_id");
338+
hmac.input(control_tlvs_ss.as_ref());
339+
Hmac::from_engine(hmac).into_inner()
340+
};
341+
match node_signer.ecdh(Recipient::Node, &msg.onion_routing_packet.public_key,
342+
Some(&Scalar::from_be_bytes(blinding_factor).unwrap()))
343+
{
344+
Ok(ss) => ss.secret_bytes(),
345+
Err(()) => {
346+
log_trace!(logger, "Failed to compute onion packet shared secret");
347+
return Err(());
348+
}
349+
}
350+
};
351+
match onion_utils::decode_next_untagged_hop(
352+
onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
353+
(control_tlvs_ss, custom_handler.deref(), logger.deref())
354+
) {
355+
Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
356+
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
357+
}, None)) => {
358+
Ok(PeeledOnion::Receive(message, path_id, reply_path))
359+
},
360+
Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
361+
next_node_id, next_blinding_override
362+
})), Some((next_hop_hmac, new_packet_bytes)))) => {
363+
// TODO: we need to check whether `next_node_id` is our node, in which case this is a dummy
364+
// blinded hop and this onion message is destined for us. In this situation, we should keep
365+
// unwrapping the onion layers to get to the final payload. Since we don't have the option
366+
// of creating blinded paths with dummy hops currently, we should be ok to not handle this
367+
// for now.
368+
let new_pubkey = match onion_utils::next_hop_pubkey(&secp_ctx, msg.onion_routing_packet.public_key, &onion_decode_ss) {
369+
Ok(pk) => pk,
370+
Err(e) => {
371+
log_trace!(logger, "Failed to compute next hop packet pubkey: {}", e);
372+
return Err(())
373+
}
374+
};
375+
let outgoing_packet = Packet {
376+
version: 0,
377+
public_key: new_pubkey,
378+
hop_data: new_packet_bytes,
379+
hmac: next_hop_hmac,
380+
};
381+
let onion_message = msgs::OnionMessage {
382+
blinding_point: match next_blinding_override {
383+
Some(blinding_point) => blinding_point,
384+
None => {
385+
match onion_utils::next_hop_pubkey(
386+
&secp_ctx, msg.blinding_point, control_tlvs_ss.as_ref()
387+
) {
388+
Ok(bp) => bp,
389+
Err(e) => {
390+
log_trace!(logger, "Failed to compute next blinding point: {}", e);
391+
return Err(())
392+
}
393+
}
394+
}
395+
},
396+
onion_routing_packet: outgoing_packet,
397+
};
398+
399+
Ok(PeeledOnion::Forward(next_node_id, onion_message))
400+
},
401+
Err(e) => {
402+
log_trace!(logger, "Errored decoding onion message packet: {:?}", e);
403+
Err(())
404+
},
405+
_ => {
406+
log_trace!(logger, "Received bogus onion message packet, either the sender encoded a final hop as a forwarding hop or vice versa");
407+
Err(())
408+
},
409+
}
410+
}
411+
317412
impl<ES: Deref, NS: Deref, L: Deref, MR: Deref, OMH: Deref, CMH: Deref>
318413
OnionMessenger<ES, NS, L, MR, OMH, CMH>
319414
where
@@ -367,96 +462,6 @@ where
367462
}
368463
}
369464

370-
/// Decode one layer of an incoming onion message
371-
/// Returns either a Forward (another onion message), or Receive (decrypted content)
372-
pub fn peel_onion<T: CustomOnionMessageContents>(
373-
node_signer: &NS, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L, custom_handler: &CMH,
374-
msg: &msgs::OnionMessage,
375-
) -> Result<PeeledOnion<CMH>, ()> {
376-
let control_tlvs_ss = match node_signer.ecdh(Recipient::Node, &msg.blinding_point, None) {
377-
Ok(ss) => ss,
378-
Err(e) => {
379-
log_error!(logger, "Failed to retrieve node secret: {:?}", e);
380-
return Err(());
381-
}
382-
};
383-
let onion_decode_ss = {
384-
let blinding_factor = {
385-
let mut hmac = HmacEngine::<Sha256>::new(b"blinded_node_id");
386-
hmac.input(control_tlvs_ss.as_ref());
387-
Hmac::from_engine(hmac).into_inner()
388-
};
389-
match node_signer.ecdh(Recipient::Node, &msg.onion_routing_packet.public_key,
390-
Some(&Scalar::from_be_bytes(blinding_factor).unwrap()))
391-
{
392-
Ok(ss) => ss.secret_bytes(),
393-
Err(()) => {
394-
log_trace!(logger, "Failed to compute onion packet shared secret");
395-
return Err(());
396-
}
397-
}
398-
};
399-
match onion_utils::decode_next_untagged_hop(
400-
onion_decode_ss, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac,
401-
(control_tlvs_ss, custom_handler.deref(), logger.deref())
402-
) {
403-
Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
404-
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,
405-
}, None)) => {
406-
Ok(PeeledOnion::Receive(message, path_id, reply_path))
407-
},
408-
Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
409-
next_node_id, next_blinding_override
410-
})), Some((next_hop_hmac, new_packet_bytes)))) => {
411-
// TODO: we need to check whether `next_node_id` is our node, in which case this is a dummy
412-
// blinded hop and this onion message is destined for us. In this situation, we should keep
413-
// unwrapping the onion layers to get to the final payload. Since we don't have the option
414-
// of creating blinded paths with dummy hops currently, we should be ok to not handle this
415-
// for now.
416-
let new_pubkey = match onion_utils::next_hop_pubkey(&secp_ctx, msg.onion_routing_packet.public_key, &onion_decode_ss) {
417-
Ok(pk) => pk,
418-
Err(e) => {
419-
log_trace!(logger, "Failed to compute next hop packet pubkey: {}", e);
420-
return Err(())
421-
}
422-
};
423-
let outgoing_packet = Packet {
424-
version: 0,
425-
public_key: new_pubkey,
426-
hop_data: new_packet_bytes,
427-
hmac: next_hop_hmac,
428-
};
429-
let onion_message = msgs::OnionMessage {
430-
blinding_point: match next_blinding_override {
431-
Some(blinding_point) => blinding_point,
432-
None => {
433-
match onion_utils::next_hop_pubkey(
434-
&secp_ctx, msg.blinding_point, control_tlvs_ss.as_ref()
435-
) {
436-
Ok(bp) => bp,
437-
Err(e) => {
438-
log_trace!(logger, "Failed to compute next blinding point: {}", e);
439-
return Err(())
440-
}
441-
}
442-
}
443-
},
444-
onion_routing_packet: outgoing_packet,
445-
};
446-
447-
Ok(PeeledOnion::Forward(next_node_id, onion_message))
448-
},
449-
Err(e) => {
450-
log_trace!(logger, "Errored decoding onion message packet: {:?}", e);
451-
Err(())
452-
},
453-
_ => {
454-
log_trace!(logger, "Received bogus onion message packet, either the sender encoded a final hop as a forwarding hop or vice versa");
455-
Err(())
456-
},
457-
}
458-
}
459-
460465
fn respond_with_onion_message<T: CustomOnionMessageContents>(
461466
&self, response: OnionMessageContents<T>, path_id: Option<[u8; 32]>,
462467
reply_path: Option<BlindedPath>
@@ -557,7 +562,7 @@ where
557562
/// soon we'll delegate the onion message to a handler that can generate invoices or send
558563
/// payments.
559564
fn handle_onion_message(&self, _peer_node_id: &PublicKey, msg: &msgs::OnionMessage) {
560-
match Self::peel_onion::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage>(
565+
match peel_onion::<NS, L, CMH, <<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage>(
561566
&self.node_signer, &self.secp_ctx, &self.logger, &self.custom_handler, msg
562567
) {
563568
Ok(PeeledOnion::Receive(message, path_id, reply_path)) => {

0 commit comments

Comments
 (0)