Error when attempting to send an OM to a blinded route with 0 hops
authorValentine Wallace <vwallace@protonmail.com>
Thu, 23 Jun 2022 19:51:43 +0000 (15:51 -0400)
committerValentine Wallace <vwallace@protonmail.com>
Tue, 2 Aug 2022 23:19:39 +0000 (19:19 -0400)
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs

index 560028c5bbaaf86228b2ded9a2d4e7bec70686b1..695064e467c49dc935728a117472ed1ac1a1e880 100644 (file)
@@ -119,3 +119,24 @@ fn too_big_packet_error() {
        let err = nodes[0].messenger.send_onion_message(&hops, Destination::Node(hop_node_id)).unwrap_err();
        assert_eq!(err, SendError::TooBigPacket);
 }
+
+#[test]
+fn invalid_blinded_route_error() {
+       // Make sure we error as expected if a provided blinded route has 0 or 1 hops.
+       let mut nodes = create_nodes(3);
+       let (node1, node2, node3) = (nodes.remove(0), nodes.remove(0), nodes.remove(0));
+
+       // 0 hops
+       let secp_ctx = Secp256k1::new();
+       let mut blinded_route = BlindedRoute::new::<EnforcingSigner, _, _>(&[node2.get_node_pk(), node3.get_node_pk()], &*node3.keys_manager, &secp_ctx).unwrap();
+       blinded_route.blinded_hops.clear();
+       let err = node1.messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route)).unwrap_err();
+       assert_eq!(err, SendError::TooFewBlindedHops);
+
+       // 1 hop
+       let mut blinded_route = BlindedRoute::new::<EnforcingSigner, _, _>(&[node2.get_node_pk(), node3.get_node_pk()], &*node3.keys_manager, &secp_ctx).unwrap();
+       blinded_route.blinded_hops.remove(0);
+       assert_eq!(blinded_route.blinded_hops.len(), 1);
+       let err = node1.messenger.send_onion_message(&[], Destination::BlindedRoute(blinded_route)).unwrap_err();
+       assert_eq!(err, SendError::TooFewBlindedHops);
+}
index 6f5d9e8a52cfbab42b5818540dc686398dabb20d..7eba3cdd254af6418132fc29bfac3cde59bd2292 100644 (file)
@@ -118,6 +118,9 @@ pub enum SendError {
        /// Because implementations such as Eclair will drop onion messages where the message packet
        /// exceeds 32834 bytes, we refuse to send messages where the packet exceeds this size.
        TooBigPacket,
+       /// The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two
+       /// blinded hops.
+       TooFewBlindedHops,
 }
 
 impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
@@ -140,6 +143,11 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
        /// Send an empty onion message to `destination`, routing it through `intermediate_nodes`.
        /// See [`OnionMessenger`] for example usage.
        pub fn send_onion_message(&self, intermediate_nodes: &[PublicKey], destination: Destination) -> Result<(), SendError> {
+               if let Destination::BlindedRoute(BlindedRoute { ref blinded_hops, .. }) = destination {
+                       if blinded_hops.len() < 2 {
+                               return Err(SendError::TooFewBlindedHops);
+                       }
+               }
                let blinding_secret_bytes = self.keys_manager.get_secure_random_bytes();
                let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
                let (introduction_node_id, blinding_point) = if intermediate_nodes.len() != 0 {