Export Onion Message structs in their respective modules
[rust-lightning] / fuzz / src / onion_message.rs
1 // Imports that need to be added manually
2 use bitcoin::bech32::u5;
3 use bitcoin::blockdata::script::Script;
4 use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
5 use bitcoin::secp256k1::ecdh::SharedSecret;
6 use bitcoin::secp256k1::ecdsa::RecoverableSignature;
7 use bitcoin::secp256k1::schnorr;
8
9 use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
10 use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
11 use lightning::ln::script::ShutdownScript;
12 use lightning::offers::invoice::UnsignedBolt12Invoice;
13 use lightning::offers::invoice_request::UnsignedInvoiceRequest;
14 use lightning::util::test_channel_signer::TestChannelSigner;
15 use lightning::util::logger::Logger;
16 use lightning::util::ser::{Readable, Writeable, Writer};
17 use lightning::onion_message::messenger::{CustomOnionMessageHandler, MessageRouter, OnionMessenger, Destination, OnionMessagePath};
18 use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
19 use lightning::onion_message::packet::CustomOnionMessageContents;
20
21 use crate::utils::test_logger;
22
23 use std::io::{self, Cursor};
24 use std::sync::atomic::{AtomicU64, Ordering};
25
26 #[inline]
27 /// Actual fuzz test, method signature and name are fixed
28 pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
29         if let Ok(msg) = <msgs::OnionMessage as Readable>::read(&mut Cursor::new(data)) {
30                 let mut secret_bytes = [1; 32];
31                 secret_bytes[31] = 2;
32                 let secret = SecretKey::from_slice(&secret_bytes).unwrap();
33                 let keys_manager = KeyProvider {
34                         node_secret: secret,
35                         counter: AtomicU64::new(0),
36                 };
37                 let message_router = TestMessageRouter {};
38                 let offers_msg_handler = TestOffersMessageHandler {};
39                 let custom_msg_handler = TestCustomMessageHandler {};
40                 let onion_messenger = OnionMessenger::new(
41                         &keys_manager, &keys_manager, logger, &message_router, &offers_msg_handler,
42                         &custom_msg_handler
43                 );
44                 let mut pk = [2; 33]; pk[1] = 0xff;
45                 let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap();
46                 onion_messenger.handle_onion_message(&peer_node_id_not_used, &msg);
47         }
48 }
49
50 /// Method that needs to be added manually, {name}_test
51 pub fn onion_message_test<Out: test_logger::Output>(data: &[u8], out: Out) {
52         let logger = test_logger::TestLogger::new("".to_owned(), out);
53         do_test(data, &logger);
54 }
55
56 /// Method that needs to be added manually, {name}_run
57 #[no_mangle]
58 pub extern "C" fn onion_message_run(data: *const u8, datalen: usize) {
59         let logger = test_logger::TestLogger::new("".to_owned(), test_logger::DevNull {});
60         do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, &logger);
61 }
62
63 struct TestMessageRouter {}
64
65 impl MessageRouter for TestMessageRouter {
66         fn find_path(
67                 &self, _sender: PublicKey, _peers: Vec<PublicKey>, destination: Destination
68         ) -> Result<OnionMessagePath, ()> {
69                 Ok(OnionMessagePath {
70                         intermediate_nodes: vec![],
71                         destination,
72                 })
73         }
74 }
75
76 struct TestOffersMessageHandler {}
77
78 impl OffersMessageHandler for TestOffersMessageHandler {
79         fn handle_message(&self, _message: OffersMessage) -> Option<OffersMessage> {
80                 None
81         }
82 }
83
84 struct TestCustomMessage {}
85
86 const CUSTOM_MESSAGE_TYPE: u64 = 4242;
87 const CUSTOM_MESSAGE_CONTENTS: [u8; 32] = [42; 32];
88
89 impl CustomOnionMessageContents for TestCustomMessage {
90         fn tlv_type(&self) -> u64 {
91                 CUSTOM_MESSAGE_TYPE
92         }
93 }
94
95 impl Writeable for TestCustomMessage {
96         fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
97                 Ok(CUSTOM_MESSAGE_CONTENTS.write(w)?)
98         }
99 }
100
101 struct TestCustomMessageHandler {}
102
103 impl CustomOnionMessageHandler for TestCustomMessageHandler {
104         type CustomMessage = TestCustomMessage;
105         fn handle_custom_message(&self, _msg: Self::CustomMessage) -> Option<Self::CustomMessage> {
106                 Some(TestCustomMessage {})
107         }
108         fn read_custom_message<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
109                 let mut buf = Vec::new();
110                 buffer.read_to_end(&mut buf)?;
111                 return Ok(Some(TestCustomMessage {}))
112         }
113 }
114
115 pub struct VecWriter(pub Vec<u8>);
116 impl Writer for VecWriter {
117         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
118                 self.0.extend_from_slice(buf);
119                 Ok(())
120         }
121 }
122 struct KeyProvider {
123         node_secret: SecretKey,
124         counter: AtomicU64,
125 }
126
127 impl EntropySource for KeyProvider {
128         fn get_secure_random_bytes(&self) -> [u8; 32] {
129                 let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
130                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
131                         (ctr >> 8*7) as u8, (ctr >> 8*6) as u8, (ctr >> 8*5) as u8, (ctr >> 8*4) as u8, (ctr >> 8*3) as u8, (ctr >> 8*2) as u8, (ctr >> 8*1) as u8, 14, (ctr >> 8*0) as u8]
132         }
133 }
134
135 impl NodeSigner for KeyProvider {
136         fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
137                 let node_secret = match recipient {
138                         Recipient::Node => Ok(&self.node_secret),
139                         Recipient::PhantomNode => Err(())
140                 }?;
141                 Ok(PublicKey::from_secret_key(&Secp256k1::signing_only(), node_secret))
142         }
143
144         fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
145                 let mut node_secret = match recipient {
146                         Recipient::Node => Ok(self.node_secret.clone()),
147                         Recipient::PhantomNode => Err(())
148                 }?;
149                 if let Some(tweak) = tweak {
150                         node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
151                 }
152                 Ok(SharedSecret::new(other_key, &node_secret))
153         }
154
155         fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!() }
156
157         fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
158                 unreachable!()
159         }
160
161         fn sign_bolt12_invoice_request(
162                 &self, _invoice_request: &UnsignedInvoiceRequest
163         ) -> Result<schnorr::Signature, ()> {
164                 unreachable!()
165         }
166
167         fn sign_bolt12_invoice(
168                 &self, _invoice: &UnsignedBolt12Invoice,
169         ) -> Result<schnorr::Signature, ()> {
170                 unreachable!()
171         }
172
173         fn sign_gossip_message(&self, _msg: lightning::ln::msgs::UnsignedGossipMessage) -> Result<bitcoin::secp256k1::ecdsa::Signature, ()> {
174                 unreachable!()
175         }
176 }
177
178 impl SignerProvider for KeyProvider {
179         type Signer = TestChannelSigner;
180
181         fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32] { unreachable!() }
182
183         fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer {
184                 unreachable!()
185         }
186
187         fn read_chan_signer(&self, _data: &[u8]) -> Result<TestChannelSigner, DecodeError> { unreachable!() }
188
189         fn get_destination_script(&self) -> Result<Script, ()> { unreachable!() }
190
191         fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> { unreachable!() }
192 }
193
194 #[cfg(test)]
195 mod tests {
196         use lightning::util::logger::{Logger, Record};
197         use std::collections::HashMap;
198         use std::sync::Mutex;
199
200         struct TrackingLogger {
201                 /// (module, message) -> count
202                 pub lines: Mutex<HashMap<(String, String), usize>>,
203         }
204         impl Logger for TrackingLogger {
205                 fn log(&self, record: &Record) {
206                         *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
207                         println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args);
208                 }
209         }
210
211         #[test]
212         fn test_no_onion_message_breakage() {
213                 let one_hop_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01ae0276020000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000000000000000000000e0101022a0000000000000000000000000000014551231950b75fc4402da1732fc9bebf00109500000000000000000000000000000004106d000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000";
214                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
215                 super::do_test(&::hex::decode(one_hop_om).unwrap(), &logger);
216                 {
217                         let log_entries = logger.lines.lock().unwrap();
218                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
219                                                 "Received an onion message with path_id None and a reply_path".to_string())), Some(&1));
220                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
221                                                 "Responding to onion message with path_id None".to_string())), Some(&1));
222                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(),
223                                                 "Failed responding to onion message with path_id None: TooFewBlindedHops".to_string())), Some(&1));
224                 }
225
226                 let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210202020202020202020202020202020202020202020202020202020202020202026d000000000000000000000000000000eb0000000000000000000000000000000000000000000000000000000000000036041096000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000";
227                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
228                 super::do_test(&::hex::decode(two_unblinded_hops_om).unwrap(), &logger);
229                 {
230                         let log_entries = logger.lines.lock().unwrap();
231                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020202020202020202020202020202020202020202020202020202020202020202".to_string())), Some(&1));
232                 }
233
234                 let two_unblinded_two_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210202020202020202020202020202020202020202020202020202020202020202026d0000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000058045604210203030303030303030303030303030303030303030303030303030303030303020821020000000000000000000000000000000000000000000000000000000000000e0196000000000000000000000000000000e9000000000000000000000000000000000000000000000000000000000000003504330421020404040404040404040404040404040404040404040404040404040404040402ca00000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000003604103f000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000";
235                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
236                 super::do_test(&::hex::decode(two_unblinded_two_blinded_om).unwrap(), &logger);
237                 {
238                         let log_entries = logger.lines.lock().unwrap();
239                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020202020202020202020202020202020202020202020202020202020202020202".to_string())), Some(&1));
240                 }
241
242                 let three_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210202020202020202020202020202020202020202020202020202020202020202026d000000000000000000000000000000b20000000000000000000000000000000000000000000000000000000000000035043304210203030303030303030303030303030303030303030303030303030303030303029600000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003604104e000000000000000000000000000000fd1092202a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000";
243                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
244                 super::do_test(&::hex::decode(three_blinded_om).unwrap(), &logger);
245                 {
246                         let log_entries = logger.lines.lock().unwrap();
247                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020202020202020202020202020202020202020202020202020202020202020202".to_string())), Some(&1));
248                 }
249         }
250 }