7ab2bd63a9f0fa6556ba8f1f0e99543f948e4b2b
[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, SecretKey};
5 use bitcoin::secp256k1::ecdh::SharedSecret;
6 use bitcoin::secp256k1::ecdsa::RecoverableSignature;
7
8 use lightning::chain::keysinterface::{Recipient, KeyMaterial, KeysInterface};
9 use lightning::ln::msgs::{self, DecodeError};
10 use lightning::ln::script::ShutdownScript;
11 use lightning::util::enforcing_trait_impls::EnforcingSigner;
12 use lightning::util::logger::Logger;
13 use lightning::util::ser::{Readable, Writer};
14 use lightning::onion_message::OnionMessenger;
15
16 use utils::test_logger;
17
18 use std::io::Cursor;
19 use std::sync::atomic::{AtomicU64, Ordering};
20
21 #[inline]
22 /// Actual fuzz test, method signature and name are fixed
23 pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
24         if let Ok(msg) = <msgs::OnionMessage as Readable>::read(&mut Cursor::new(data)) {
25                 let mut secret_bytes = [0; 32];
26                 secret_bytes[31] = 2;
27                 let secret = SecretKey::from_slice(&secret_bytes).unwrap();
28                 let keys_manager = KeyProvider {
29                         node_secret: secret,
30                         counter: AtomicU64::new(0),
31                 };
32                 let onion_messenger = OnionMessenger::new(&keys_manager, logger);
33                 let mut pk = [2; 33]; pk[1] = 0xff;
34                 let peer_node_id_not_used = PublicKey::from_slice(&pk).unwrap();
35                 onion_messenger.handle_onion_message(&peer_node_id_not_used, &msg);
36         }
37 }
38
39 /// Method that needs to be added manually, {name}_test
40 pub fn onion_message_test<Out: test_logger::Output>(data: &[u8], out: Out) {
41         let logger = test_logger::TestLogger::new("".to_owned(), out);
42         do_test(data, &logger);
43 }
44
45 /// Method that needs to be added manually, {name}_run
46 #[no_mangle]
47 pub extern "C" fn onion_message_run(data: *const u8, datalen: usize) {
48         let logger = test_logger::TestLogger::new("".to_owned(), test_logger::DevNull {});
49         do_test(unsafe { std::slice::from_raw_parts(data, datalen) }, &logger);
50 }
51
52 pub struct VecWriter(pub Vec<u8>);
53 impl Writer for VecWriter {
54         fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> {
55                 self.0.extend_from_slice(buf);
56                 Ok(())
57         }
58 }
59 struct KeyProvider {
60         node_secret: SecretKey,
61         counter: AtomicU64,
62 }
63 impl KeysInterface for KeyProvider {
64         type Signer = EnforcingSigner;
65
66         fn get_node_secret(&self, _recipient: Recipient) -> Result<SecretKey, ()> {
67                 Ok(self.node_secret.clone())
68         }
69
70         fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()> {
71                 let mut node_secret = self.get_node_secret(recipient)?;
72                 if let Some(tweak) = tweak {
73                         node_secret = node_secret.mul_tweak(tweak).map_err(|_| ())?;
74                 }
75                 Ok(SharedSecret::new(other_key, &node_secret))
76         }
77
78         fn get_inbound_payment_key_material(&self) -> KeyMaterial { unreachable!() }
79
80         fn get_destination_script(&self) -> Script { unreachable!() }
81
82         fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!() }
83
84         fn get_channel_signer(&self, _inbound: bool, _channel_value_satoshis: u64) -> EnforcingSigner {
85                 unreachable!()
86         }
87
88         fn get_secure_random_bytes(&self) -> [u8; 32] {
89                 let ctr = self.counter.fetch_add(1, Ordering::Relaxed);
90                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
91                 (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]
92         }
93
94         fn read_chan_signer(&self, _data: &[u8]) -> Result<EnforcingSigner, DecodeError> { unreachable!() }
95
96         fn sign_invoice(&self, _hrp_bytes: &[u8], _invoice_data: &[u5], _recipient: Recipient) -> Result<RecoverableSignature, ()> {
97                 unreachable!()
98         }
99 }
100
101 #[cfg(test)]
102 mod tests {
103         use lightning::util::logger::{Logger, Record};
104         use std::collections::HashMap;
105         use std::sync::Mutex;
106
107         struct TrackingLogger {
108                 /// (module, message) -> count
109                 pub lines: Mutex<HashMap<(String, String), usize>>,
110         }
111         impl Logger for TrackingLogger {
112                 fn log(&self, record: &Record) {
113                         *self.lines.lock().unwrap().entry((record.module_path.to_string(), format!("{}", record.args))).or_insert(0) += 1;
114                         println!("{:<5} [{} : {}, {}] {}", record.level.to_string(), record.module_path, record.file, record.line, record.args);
115                 }
116         }
117
118         #[test]
119         fn test_no_onion_message_breakage() {
120                 let one_hop_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01120410950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009300000000000000000000000000000000000000000000000000000000000000";
121                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
122                 super::do_test(&::hex::decode(one_hop_om).unwrap(), &logger);
123                 {
124                         let log_entries = logger.lines.lock().unwrap();
125                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Received an onion message with path_id: None".to_string())), Some(&1));
126                 }
127
128                 let two_unblinded_hops_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e0135043304210200000000000000000000000000000000000000000000000000000000000000039500000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000001204105e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
129                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
130                 super::do_test(&::hex::decode(two_unblinded_hops_om).unwrap(), &logger);
131                 {
132                         let log_entries = logger.lines.lock().unwrap();
133                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
134                 }
135
136                 let two_unblinded_two_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e01350433042102000000000000000000000000000000000000000000000000000000000000000395000000000000000000000000000000530000000000000000000000000000000000000000000000000000000000000058045604210200000000000000000000000000000000000000000000000000000000000000040821020000000000000000000000000000000000000000000000000000000000000e015e0000000000000000000000000000006b0000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000054b000000000000000000000000000000e800000000000000000000000000000000000000000000000000000000000000120410ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
137                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
138                 super::do_test(&::hex::decode(two_unblinded_two_blinded_om).unwrap(), &logger);
139                 {
140                         let log_entries = logger.lines.lock().unwrap();
141                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
142                 }
143
144                 let three_blinded_om = "020000000000000000000000000000000000000000000000000000000000000e01055600020000000000000000000000000000000000000000000000000000000000000e013504330421020000000000000000000000000000000000000000000000000000000000000003950000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000035043304210200000000000000000000000000000000000000000000000000000000000000045e0000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000001204104a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b300000000000000000000000000000000000000000000000000000000000000";
145                 let logger = TrackingLogger { lines: Mutex::new(HashMap::new()) };
146                 super::do_test(&::hex::decode(three_blinded_om).unwrap(), &logger);
147                 {
148                         let log_entries = logger.lines.lock().unwrap();
149                         assert_eq!(log_entries.get(&("lightning::onion_message::messenger".to_string(), "Forwarding an onion message to peer 020000000000000000000000000000000000000000000000000000000000000003".to_string())), Some(&1));
150                 }
151         }
152 }