diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index df3b20b0386..090758b1682 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -22,7 +22,7 @@ use lightning::chain::transaction::OutPoint; use lightning::chain::keysinterface::{InMemoryChannelKeys, KeysInterface}; use lightning::ln::channelmonitor; use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage, PaymentSecret}; -use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor}; +use lightning::ln::peers::handler::{MessageHandler,PeerManager,SocketDescriptor}; use lightning::routing::router::get_route; use lightning::routing::network_graph::NetGraphMsgHandler; use lightning::util::events::{EventsProvider,Event}; @@ -892,15 +892,15 @@ mod tests { super::do_test(&::hex::decode("00000000000000000000000000000000000000000000000000000000000000000000000001000300000000000000000000000000000000000000000000000000000000000000000300320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030012000a0300000000000000000000000000000003001a00100002200000022000030000000000000000000000000000000300120141030000000000000000000000000000000300fe00207500000000000000000000000000000000000000000000000000000000000000ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679000000000000c35000000000000000000000000000000222ffffffffffffffff00000000000002220000000000000000000000fd000601e3030000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000000000000000000000000000000000002030000000000000000000000000000000000000000000000000000000000000003030000000000000000000000000000000000000000000000000000000000000004030053030000000000000000000000000000000000000000000000000000000000000005030000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000fd00fd00fd0300120084030000000000000000000000000000000300940022ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb1819096793d00000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001030000000000000000000000000000000c005e020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0150c3000000000000220020ae00000000000000000000000000000000000000000000000000000000000000000000000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c00000c000003001200430300000000000000000000000000000003005300243d0000000000000000000000000000000000000000000000000000000000000003010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000010301320003000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000030142000302000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003000000000000000000000000000000030112000a0100000000000000000000000000000003011a0010000220000002200001000000000000000000000000000000050103020000000000000000000000000000000000000000000000000000000000000000c3500003e800fd00fd00fd0301120110010000000000000000000000000000000301ff00210000000000000000000000000000000000000000000000000000000000000e02000000000000001a00000000004c4b4000000000000003e800000000000003e80000000203f00005030000000000000000000000000000000000000000000000000000000000000100030000000000000000000000000000000000000000000000000000000000000200030000000000000000000000000000000000000000000000000000000000000300030000000000000000000000000000000000000000000000000000000000000400030000000000000000000000000000000000000000000000000000000000000500030000000000000000000000000000000301210000000000000000000000000000000000010000000000000000000000000000000a03011200620100000000000000000000000000000003017200233900000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100010000000000000000000000000000000b030112004301000000000000000000000000000000030153002439000000000000000000000000000000000000000000000000000000000000000301000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112004a0100000000000000000000000000000003015a008239000000000000000000000000000000000000000000000000000000000000000000000000000000ff008888888888888888888888888888888888888888888888888888888888880100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000000000000000000000000000301120063010000000000000000000000000000000301730085390000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d0000000000000000000000000000000000000000000000000000000000000000000000000000010000000000003e80ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e000001000000000000000003e80000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000303000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d00000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030400000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000703011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000003011200630100000000000000000000000000000003017300853900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000030112002c0100000000000000000000000000000003013c00833900000000000000000000000000000000000000000000000000000000000000000000000000000100000100000000000000000000000000000003011200640100000000000000000000000000000003017400843900000000000000000000000000000000000000000000000000000000000000fb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000001000000000000000000000000000000030112006301000000000000000000000000000000030173008539000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000703001200630300000000000000000000000000000003007300853d0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000305000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000003001200640300000000000000000000000000000003007400843d000000000000000000000000000000000000000000000000000000000000003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000300000000000000000000000000000003001205ac030000000000000000000000000000000300ff00803d00000000000000000000000000000000000000000000000000000000000000000000000000000200000000000b0838ff0000000000000000000000000000000000000000000000000000000000000000000121000300000000000000000000000000000000000000000000000000000000000005550000000e0000010000000000000003e8000000007b0000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0300c1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff95000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000fd03001200a4030000000000000000000000000000000300b400843d000000000000000000000000000000000000000000000000000000000000007b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f000000000000000300000000000000000000000000000003001200630300000000000000000000000000000003007300853d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003060000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000070c007d02000000013900000000000000000000000000000000000000000000000000000000000000000000000000000080020001000000000000220020bb000000000000000000000000000000000000000000000000000000000000006cc10000000000001600142b000000000000000000000000000000000000000500002000fd00fd0c005e0200000001a100000000000000000000000000000000000000000000000000000000000000000000000000000000014f00000000000000220020f600000000000000000000000000000000000000000000000000000000000000000000000c00000c000000fd0c00000c00000c000007").unwrap(), &(Arc::clone(&logger) as Arc)); let log_entries = logger.lines.lock().unwrap(); - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8 - assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); // 9 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling SendAcceptChannel event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel ff4f00f805273c1b203bb5ebf8436bfde57b3be8c2f5e95d9491dbb181909679".to_string())), Some(&1)); // 1 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling SendFundingSigned event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 2 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 3 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling SendFundingLocked event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 4 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4)); // 5 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 6 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3900000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3)); // 7 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1)); // 8 + assert_eq!(log_entries.get(&("lightning::ln::peers::handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000000 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2)); // 9 assert_eq!(log_entries.get(&("lightning::ln::channelmonitor".to_string(), "Input spending remote commitment tx (00000000000000000000000000000000000000000000000000000000000000a1:0) in 0000000000000000000000000000000000000000000000000000000000000018 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1)); // 10 } } diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index d2494d270ee..402a6bc7d5e 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -28,7 +28,7 @@ //! type ChainWatchInterface = dyn lightning::chain::chaininterface::ChainWatchInterface; //! type ChannelMonitor = lightning::ln::channelmonitor::SimpleManyChannelMonitor, Arc, Arc, Arc>; //! type ChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager; -//! type PeerManager = lightning::ln::peer_handler::SimpleArcPeerManager; +//! type PeerManager = lightning::ln::peers::handler::SimpleArcPeerManager; //! //! // Connect to node with pubkey their_node_id at addr: //! async fn connect_to_node(peer_manager: PeerManager, channel_monitor: Arc, channel_manager: ChannelManager, their_node_id: PublicKey, addr: SocketAddr) { @@ -68,8 +68,8 @@ use tokio::{io, time}; use tokio::sync::mpsc; use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}; -use lightning::ln::peer_handler; -use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait; +use lightning::ln::peers::handler; +use lightning::ln::peers::handler::SocketDescriptor as LnSocketTrait; use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler}; use lightning::util::logger::Logger; @@ -124,7 +124,7 @@ impl Connection { _ => panic!() } } - async fn schedule_read(peer_manager: Arc, Arc, Arc>>, us: Arc>, mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where + async fn schedule_read(peer_manager: Arc, Arc, Arc>>, us: Arc>, mut reader: io::ReadHalf, mut read_wake_receiver: mpsc::Receiver<()>, mut write_avail_receiver: mpsc::Receiver<()>) where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -237,7 +237,7 @@ impl Connection { /// not need to poll the provided future in order to make progress. /// /// See the module-level documentation for how to handle the event_notify mpsc::Sender. -pub fn setup_inbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future where +pub fn setup_inbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, stream: TcpStream) -> impl std::future::Future where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -279,7 +279,7 @@ pub fn setup_inbound(peer_manager: Arc(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future where +pub fn setup_outbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, stream: TcpStream) -> impl std::future::Future where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -351,7 +351,7 @@ pub fn setup_outbound(peer_manager: Arc(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option> where +pub async fn connect_outbound(peer_manager: Arc, Arc, Arc>>, event_notify: mpsc::Sender<()>, their_node_id: PublicKey, addr: SocketAddr) -> Option> where CMH: ChannelMessageHandler + 'static, RMH: RoutingMessageHandler + 'static, L: Logger + 'static + ?Sized { @@ -402,7 +402,7 @@ impl SocketDescriptor { Self { conn, id } } } -impl peer_handler::SocketDescriptor for SocketDescriptor { +impl handler::SocketDescriptor for SocketDescriptor { fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize { // To send data, we take a lock on our Connection to access the WriteHalf of the TcpStream, // writing to it if there's room in the kernel buffer, or otherwise create a new Waker with @@ -494,7 +494,7 @@ impl Hash for SocketDescriptor { mod tests { use lightning::ln::features::*; use lightning::ln::msgs::*; - use lightning::ln::peer_handler::{MessageHandler, PeerManager}; + use lightning::ln::peers::handler::{MessageHandler, PeerManager}; use lightning::util::events::*; use bitcoin::secp256k1::{Secp256k1, SecretKey, PublicKey}; diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index 163799b0031..eea78b62a06 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -12,7 +12,7 @@ pub mod channelmanager; pub mod channelmonitor; pub mod msgs; -pub mod peer_handler; +pub mod peers; pub mod chan_utils; pub mod features; pub(crate) mod onchaintx; diff --git a/lightning/src/ln/peers/chacha.rs b/lightning/src/ln/peers/chacha.rs new file mode 100644 index 00000000000..4e8d948706f --- /dev/null +++ b/lightning/src/ln/peers/chacha.rs @@ -0,0 +1,40 @@ +use util::byte_utils; +use util::chacha20poly1305rfc::ChaCha20Poly1305RFC; + +pub const TAG_SIZE: usize = 16; + +pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) -> Vec { + let mut nonce_bytes = [0; 12]; + nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); + + let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); + let mut ciphertext = vec![0u8; plaintext.len()]; + let mut authentication_tag = [0u8; 16]; + chacha.encrypt(plaintext, &mut ciphertext, &mut authentication_tag); + + let mut tagged_ciphertext = ciphertext; + tagged_ciphertext.extend_from_slice(&authentication_tag); + tagged_ciphertext +} + +pub fn decrypt(key: &[u8], nonce: u64, associated_data: &[u8], tagged_ciphertext: &[u8]) -> Result, String> { + let mut nonce_bytes = [0; 12]; + nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce)); + + let length = tagged_ciphertext.len(); + if length < 16 { + return Err("ciphertext cannot be shorter than tag length of 16 bytes".to_string()); + } + let end_index = length - 16; + let ciphertext = &tagged_ciphertext[0..end_index]; + let authentication_tag = &tagged_ciphertext[end_index..length]; + + let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data); + let mut plaintext = vec![0u8; length - 16]; + let success = chacha.decrypt(ciphertext, &mut plaintext, authentication_tag); + if success { + Ok(plaintext.to_vec()) + } else { + Err("invalid hmac".to_string()) + } +} diff --git a/lightning/src/ln/peers/conduit.rs b/lightning/src/ln/peers/conduit.rs new file mode 100644 index 00000000000..74e420b192a --- /dev/null +++ b/lightning/src/ln/peers/conduit.rs @@ -0,0 +1,297 @@ +//! Handles all over the wire message encryption and decryption upon handshake completion. + +use ln::peers::{chacha, hkdf}; +use util::byte_utils; + +pub(super) type SymmetricKey = [u8; 32]; + +const MESSAGE_LENGTH_HEADER_SIZE: usize = 2; +const TAGGED_MESSAGE_LENGTH_HEADER_SIZE: usize = MESSAGE_LENGTH_HEADER_SIZE + chacha::TAG_SIZE; + +const KEY_ROTATION_INDEX: u32 = 1000; + +/// Returned after a successful handshake to encrypt and decrypt communication with peer nodes. +/// It should not normally be manually instantiated. +/// Automatically handles key rotation. +/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering. +pub struct Conduit { + pub(super) encryptor: Encryptor, + pub(super) decryptor: Decryptor + +} + +pub(super) struct Encryptor { + sending_key: SymmetricKey, + sending_chaining_key: SymmetricKey, + sending_nonce: u32, +} + +pub(super) struct Decryptor { + receiving_key: SymmetricKey, + receiving_chaining_key: SymmetricKey, + receiving_nonce: u32, + + pending_message_length: Option, + read_buffer: Option>, +} + +impl Iterator for Decryptor { + type Item = Vec; + + fn next(&mut self) -> Option { + self.decrypt_single_message(None) + } +} + +impl Conduit { + /// Instantiate a new Conduit with specified sending and receiving keys + pub fn new(sending_key: SymmetricKey, receiving_key: SymmetricKey, chaining_key: SymmetricKey) -> Self { + Conduit { + encryptor: Encryptor { + sending_key, + sending_chaining_key: chaining_key, + sending_nonce: 0 + }, + decryptor: Decryptor { + receiving_key, + receiving_chaining_key: chaining_key, + receiving_nonce: 0, + read_buffer: None, + pending_message_length: None + } + } + } + + /// Encrypt data to be sent to peer + pub fn encrypt(&mut self, buffer: &[u8]) -> Vec { + self.encryptor.encrypt(buffer) + } + + pub(super) fn read(&mut self, data: &[u8]) { + self.decryptor.read(data) + } + + /// Decrypt a single message. If data containing more than one message has been received, + /// only the first message will be returned, and the rest stored in the internal buffer. + /// If a message pending in the buffer still hasn't been decrypted, that message will be + /// returned in lieu of anything new, even if new data is provided. + pub fn decrypt_single_message(&mut self, new_data: Option<&[u8]>) -> Option> { + self.decryptor.decrypt_single_message(new_data) + } + + /// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes. + fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { + self.decryptor.decrypt(buffer) + } + + fn increment_sending_nonce(&mut self) { + self.encryptor.increment_nonce() + } + + fn increment_receiving_nonce(&mut self) { + self.decryptor.increment_nonce() + } + + fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { + *nonce += 1; + if *nonce == KEY_ROTATION_INDEX { + Self::rotate_key(chaining_key, key); + *nonce = 0; + } + } + + fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) { + let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key); + chaining_key.copy_from_slice(&new_chaining_key); + key.copy_from_slice(&new_key); + } +} + +impl Encryptor { + pub(super) fn encrypt(&mut self, buffer: &[u8]) -> Vec { + let length = buffer.len() as u16; + let length_bytes = byte_utils::be16_to_array(length); + + let mut ciphertext = vec![0u8; TAGGED_MESSAGE_LENGTH_HEADER_SIZE + length as usize + chacha::TAG_SIZE]; + + ciphertext[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes)); + self.increment_nonce(); + + ciphertext[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer)); + self.increment_nonce(); + + ciphertext + } + + fn increment_nonce(&mut self) { + Conduit::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key); + } +} + +impl Decryptor { + pub(super) fn read(&mut self, data: &[u8]) { + let read_buffer = self.read_buffer.get_or_insert(Vec::new()); + read_buffer.extend_from_slice(data); + } + + /// Decrypt a single message. If data containing more than one message has been received, + /// only the first message will be returned, and the rest stored in the internal buffer. + /// If a message pending in the buffer still hasn't been decrypted, that message will be + /// returned in lieu of anything new, even if new data is provided. + pub fn decrypt_single_message(&mut self, new_data: Option<&[u8]>) -> Option> { + let mut read_buffer = if let Some(buffer) = self.read_buffer.take() { + buffer + } else { + Vec::new() + }; + + if let Some(data) = new_data { + read_buffer.extend_from_slice(data); + } + + let (current_message, offset) = self.decrypt(&read_buffer[..]); + read_buffer.drain(..offset); // drain the read buffer + self.read_buffer = Some(read_buffer); // assign the new value to the built-in buffer + current_message + } + + fn decrypt(&mut self, buffer: &[u8]) -> (Option>, usize) { + let message_length = if let Some(length) = self.pending_message_length { + // we have already decrypted the header + length + } else { + if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE { + // A message must be at least 18 bytes (2 for encrypted length, 16 for the tag) + return (None, 0); + } + + let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE]; + let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE]; + length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap()); + + self.increment_nonce(); + + // the message length + byte_utils::slice_to_be16(&length_bytes) as usize + }; + + let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE; + + if buffer.len() < message_end_index { + self.pending_message_length = Some(message_length); + return (None, 0); + } + + self.pending_message_length = None; + + let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index]; + + let message = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_message).unwrap(); + + self.increment_nonce(); + + (Some(message), message_end_index) + } + + fn increment_nonce(&mut self) { + Conduit::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key); + } +} + +#[cfg(test)] +mod tests { + use hex; + + use ln::peers::conduit::Conduit; + + fn setup_peers() -> (Conduit, Conduit) { + let chaining_key_vec = hex::decode("919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01").unwrap(); + let mut chaining_key = [0u8; 32]; + chaining_key.copy_from_slice(&chaining_key_vec); + + let sending_key_vec = hex::decode("969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9").unwrap(); + let mut sending_key = [0u8; 32]; + sending_key.copy_from_slice(&sending_key_vec); + + let receiving_key_vec = hex::decode("bb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442").unwrap(); + let mut receiving_key = [0u8; 32]; + receiving_key.copy_from_slice(&receiving_key_vec); + + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); + let remote_peer = Conduit::new(receiving_key, sending_key, chaining_key); + + (connected_peer, remote_peer) + } + + #[test] + fn test_empty_message() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + + let message: Vec = vec![]; + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message.len(), 2 + 16 + 16); + + let decrypted_message = remote_peer.decrypt_single_message(Some(&encrypted_message)).unwrap(); + assert_eq!(decrypted_message, vec![]); + } + + #[test] + fn test_nonce_chaining() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + let message = hex::decode("68656c6c6f").unwrap(); + + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message, hex::decode("cf2b30ddf0cf3f80e7c35a6e6730b59fe802473180f396d88a8fb0db8cbcf25d2f214cf9ea1d95").unwrap()); + + // the second time the same message is encrypted, the ciphertext should be different + let encrypted_message = connected_peer.encrypt(&message); + assert_eq!(encrypted_message, hex::decode("72887022101f0b6753e0c7de21657d35a4cb2a1f5cde2650528bbc8f837d0f0d7ad833b1a256a1").unwrap()); + } + + #[test] + /// Based on RFC test vectors: https://github.com/lightningnetwork/lightning-rfc/blob/master/08-transport.md#message-encryption-tests + fn test_key_rotation() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + + let message = hex::decode("68656c6c6f").unwrap(); + let mut encrypted_messages: Vec> = Vec::new(); + + for _ in 0..1002 { + let encrypted_message = connected_peer.encrypt(&message); + encrypted_messages.push(encrypted_message); + } + + assert_eq!(encrypted_messages[500], hex::decode("178cb9d7387190fa34db9c2d50027d21793c9bc2d40b1e14dcf30ebeeeb220f48364f7a4c68bf8").unwrap()); + assert_eq!(encrypted_messages[501], hex::decode("1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd").unwrap()); + assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap()); + assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap()); + } + + #[test] + fn test_decryption_buffering() { + let (mut connected_peer, mut remote_peer) = setup_peers(); + + let message = hex::decode("68656c6c6f").unwrap(); + let mut encrypted_messages: Vec> = Vec::new(); + + for _ in 0..1002 { + let encrypted_message = connected_peer.encrypt(&message); + encrypted_messages.push(encrypted_message); + } + + for _ in 0..501 { + // read two messages at once, filling buffer + let mut current_encrypted_message = encrypted_messages.remove(0); + let mut next_encrypted_message = encrypted_messages.remove(0); + current_encrypted_message.extend_from_slice(&next_encrypted_message); + let decrypted_message = remote_peer.decrypt_single_message(Some(¤t_encrypted_message)).unwrap(); + assert_eq!(decrypted_message, message); + } + + for _ in 0..501 { + // decrypt messages directly from buffer without adding to it + let decrypted_message = remote_peer.decrypt_single_message(None).unwrap(); + assert_eq!(decrypted_message, message); + } + } +} \ No newline at end of file diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peers/handler.rs similarity index 82% rename from lightning/src/ln/peer_handler.rs rename to lightning/src/ln/peers/handler.rs index e5a973bca36..54e996214ce 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peers/handler.rs @@ -30,6 +30,9 @@ use std::ops::Deref; use bitcoin::hashes::sha256::Hash as Sha256; use bitcoin::hashes::sha256::HashEngine as Sha256Engine; use bitcoin::hashes::{HashEngine, Hash}; +use ln::peers::handshake::PeerHandshake; +use ln::peers::conduit::Conduit; +use ln::peers::handshake::acts::Act; /// Provides references to trait impls which handle different types of messages. pub struct MessageHandler where @@ -110,8 +113,66 @@ enum InitSyncTracker{ NodesSyncing(PublicKey), } +enum PeerState { + Authenticating(PeerHandshake), + Connected(Conduit), +} + +enum PeerDataProcessingDecision { + CompleteHandshake(bool, Option), + Continue, + Disconnect(PeerHandleError) +} + +impl PeerState { + fn is_ready_for_encryption(&self) -> bool { + match self { + &PeerState::Connected(_) => true, + _ => false + } + } + + fn process_peer_data(&mut self, data: &[u8], mutable_response_buffer: &mut LinkedList>) -> PeerDataProcessingDecision { + let mut conduit_option = None; + let mut decision_option = None; + + match self { + &mut PeerState::Authenticating(ref mut handshake) => { + let (next_act, conduit) = match handshake.process_act(data) { + Ok(act_result) => act_result, + Err(e) => { + return PeerDataProcessingDecision::Disconnect(PeerHandleError { no_connection_possible: false }); + } + }; + + let requires_response = next_act.is_some(); + if let Some(act) = next_act { + mutable_response_buffer.push_back(act.serialize()); + } + + let remote_pubkey_option = handshake.get_remote_pubkey(); + if let Some(conduit) = conduit { + conduit_option = Some(conduit); + decision_option = Some(PeerDataProcessingDecision::CompleteHandshake(requires_response, remote_pubkey_option)); + } + } + + &mut PeerState::Connected(ref mut conduit) => { + conduit.read(data); + } + }; + + if let (Some(conduit), Some(decision)) = (conduit_option, decision_option) { + *self = PeerState::Connected(conduit); + return decision; + } + + PeerDataProcessingDecision::Continue + } +} + struct Peer { - channel_encryptor: PeerChannelEncryptor, + encryptor: PeerState, outbound: bool, their_node_id: Option, their_features: Option, @@ -120,10 +181,6 @@ struct Peer { pending_outbound_buffer_first_msg_offset: usize, awaiting_write_event: bool, - pending_read_buffer: Vec, - pending_read_buffer_pos: usize, - pending_read_is_header: bool, - sync_status: InitSyncTracker, awaiting_pong: bool, @@ -270,7 +327,7 @@ impl PeerManager Vec { let peers = self.peers.lock().unwrap(); peers.peers.values().filter_map(|p| { - if !p.channel_encryptor.is_ready_for_encryption() || p.their_features.is_none() { + if !p.encryptor.is_ready_for_encryption() || p.their_features.is_none() { return None; } p.their_node_id @@ -299,25 +356,21 @@ impl PeerManager Result, PeerHandleError> { - let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key()); - let res = peer_encryptor.get_act_one().to_vec(); - let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes + let mut handshake = PeerHandshake::new_outbound(&self.our_node_secret, &their_node_id, &self.get_ephemeral_key()); + let (act, ..) = handshake.process_act(&[]).unwrap(); + let res = act.unwrap().serialize(); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - channel_encryptor: peer_encryptor, + encryptor: PeerState::Authenticating(handshake), outbound: true, - their_node_id: None, + their_node_id: Some(their_node_id.clone()), their_features: None, pending_outbound_buffer: LinkedList::new(), pending_outbound_buffer_first_msg_offset: 0, awaiting_write_event: false, - pending_read_buffer: pending_read_buffer, - pending_read_buffer_pos: 0, - pending_read_is_header: false, - sync_status: InitSyncTracker::NoSyncRequested, awaiting_pong: false, @@ -337,12 +390,11 @@ impl PeerManager Result<(), PeerHandleError> { - let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret); - let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes + let handshake = PeerHandshake::new_inbound(&self.our_node_secret, &self.get_ephemeral_key()); let mut peers = self.peers.lock().unwrap(); if peers.peers.insert(descriptor, Peer { - channel_encryptor: peer_encryptor, + encryptor: PeerState::Authenticating(handshake), outbound: false, their_node_id: None, their_features: None, @@ -351,10 +403,6 @@ impl PeerManager PeerManager { { log_trace!(self.logger, "Encoding and sending sync update message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap())); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg)[..])); + match peer.encryptor { + PeerState::Connected(ref mut conduit) => peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!($msg)[..])), + _ => panic!("peer must be connected!") + } } } } @@ -492,7 +543,10 @@ impl PeerManager peer.pending_outbound_buffer.push_back(conduit.encrypt(&encoded_message[..])), + _ => panic!("peer must be connected!") + } peers_needing_send.insert(descriptor); } @@ -503,145 +557,118 @@ impl PeerManager panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { - assert!(peer.pending_read_buffer.len() > 0); - assert!(peer.pending_read_buffer.len() > peer.pending_read_buffer_pos); - let mut read_pos = 0; - while read_pos < data.len() { - { - let data_to_copy = cmp::min(peer.pending_read_buffer.len() - peer.pending_read_buffer_pos, data.len() - read_pos); - peer.pending_read_buffer[peer.pending_read_buffer_pos..peer.pending_read_buffer_pos + data_to_copy].copy_from_slice(&data[read_pos..read_pos + data_to_copy]); - read_pos += data_to_copy; - peer.pending_read_buffer_pos += data_to_copy; + let mut send_init_message = false; + + let data_processing_decision = peer.encryptor.process_peer_data(data, &mut peer.pending_outbound_buffer); + match data_processing_decision { + PeerDataProcessingDecision::Disconnect(e) => { + log_trace!(self.logger, "Invalid act message; disconnecting: {}", e); + return Err(e); } - if peer.pending_read_buffer_pos == peer.pending_read_buffer.len() { - peer.pending_read_buffer_pos = 0; - - macro_rules! try_potential_handleerror { - ($thing: expr) => { - match $thing { - Ok(x) => x, - Err(e) => { - match e.action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self.logger, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self.logger, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self.logger, "Got Err handling message, sending Error message because {}", e.err); - self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg); - continue; - }, - } - } - }; - } + PeerDataProcessingDecision::CompleteHandshake(needs_to_send_init_message, remote_pubkey_option) => { + send_init_message = needs_to_send_init_message; + + if let Some(key) = remote_pubkey_option { + peer.their_node_id = Some(key); } - macro_rules! insert_node_id { - () => { - match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { - hash_map::Entry::Occupied(_) => { - log_trace!(self.logger, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); - peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event - return Err(PeerHandleError{ no_connection_possible: false }) - }, - hash_map::Entry::Vacant(entry) => { - log_trace!(self.logger, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); - entry.insert(peer_descriptor.clone()) - }, - }; + // insert node id + match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { + hash_map::Entry::Occupied(_) => { + log_trace!(self.logger, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); + peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event + return Err(PeerHandleError { no_connection_possible: false }); } - } + hash_map::Entry::Vacant(entry) => { + log_trace!(self.logger, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); + entry.insert(peer_descriptor.clone()) + } + }; + } + _ => {} + }; - let next_step = peer.channel_encryptor.get_noise_step(); - match next_step { - NextNoiseStep::ActOne => { - let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_keys(&peer.pending_read_buffer[..], &self.our_node_secret, self.get_ephemeral_key())).to_vec(); - peer.pending_outbound_buffer.push_back(act_two); - peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long - }, - NextNoiseStep::ActTwo => { - let (act_three, their_node_id) = try_potential_handleerror!(peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..], &self.our_node_secret)); - peer.pending_outbound_buffer.push_back(act_three.to_vec()); - peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes - peer.pending_read_is_header = true; - - peer.their_node_id = Some(their_node_id); - insert_node_id!(); - let mut features = InitFeatures::known(); - if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { - features.clear_initial_routing_sync(); - } + if send_init_message { + let mut features = InitFeatures::known(); + if !self.message_handler.route_handler.should_request_full_sync(&peer.their_node_id.unwrap()) { + features.clear_initial_routing_sync(); + } - let resp = msgs::Init { features }; - self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp); - }, - NextNoiseStep::ActThree => { - let their_node_id = try_potential_handleerror!(peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..])); - peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes - peer.pending_read_is_header = true; - peer.their_node_id = Some(their_node_id); - insert_node_id!(); - }, - NextNoiseStep::NoiseComplete => { - if peer.pending_read_is_header { - let msg_len = try_potential_handleerror!(peer.channel_encryptor.decrypt_length_header(&peer.pending_read_buffer[..])); - peer.pending_read_buffer = Vec::with_capacity(msg_len as usize + 16); - peer.pending_read_buffer.resize(msg_len as usize + 16, 0); - if msg_len < 2 { // Need at least the message type tag - return Err(PeerHandleError{ no_connection_possible: false }); + let resp = msgs::Init { features }; + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &resp); + send_init_message = false + } + + let mut received_messages = vec![]; + if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor { + let encryptor = &mut conduit.encryptor; + let decryptor = &mut conduit.decryptor; + + for msg_data in decryptor { + let mut reader = ::std::io::Cursor::new(&msg_data[..]); + let message_result = wire::read(&mut reader); + let message = match message_result { + Ok(x) => x, + Err(e) => { + match e { + msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::UnknownRequiredFeature => { + log_debug!(self.logger, "Got a channel/node announcement with an known required feature flag, you may want to update!"); + continue; } - peer.pending_read_is_header = false; - } else { - let msg_data = try_potential_handleerror!(peer.channel_encryptor.decrypt_message(&peer.pending_read_buffer[..])); - assert!(msg_data.len() >= 2); - - // Reset read buffer - peer.pending_read_buffer = [0; 18].to_vec(); - peer.pending_read_is_header = true; - - let mut reader = ::std::io::Cursor::new(&msg_data[..]); - let message_result = wire::read(&mut reader); - let message = match message_result { - Ok(x) => x, - Err(e) => { - match e { - msgs::DecodeError::UnknownVersion => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self.logger, "Got a channel/node announcement with an known required feature flag, you may want to update!"); - continue; - } - msgs::DecodeError::InvalidValue => { - log_debug!(self.logger, "Got an invalid value while deserializing message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::ShortRead => { - log_debug!(self.logger, "Deserialization failed due to shortness of message"); - return Err(PeerHandleError { no_connection_possible: false }); - } - msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), - msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), - } - } - }; - - if let Err(handling_error) = self.handle_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), message){ - match handling_error { - MessageHandlingError::PeerHandleError(e) => { return Err(e) }, - MessageHandlingError::LightningError(e) => { - try_potential_handleerror!(Err(e)); - }, - } + msgs::DecodeError::InvalidValue => { + log_debug!(self.logger, "Got an invalid value while deserializing message"); + return Err(PeerHandleError { no_connection_possible: false }); + } + msgs::DecodeError::ShortRead => { + log_debug!(self.logger, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError { no_connection_possible: false }); } + msgs::DecodeError::BadLengthDescriptor => return Err(PeerHandleError { no_connection_possible: false }), + msgs::DecodeError::Io(_) => return Err(PeerHandleError { no_connection_possible: false }), } } + }; + + received_messages.push(message); + } + } + + for message in received_messages { + macro_rules! try_potential_handleerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(e) => { + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self.logger, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self.logger, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self.logger, "Got Err handling message, sending Error message because {}", e.err); + self.enqueue_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), &msg); + continue; + }, + } + } + }; + } + } + + if let Err(handling_error) = self.handle_message(&mut peers.peers_needing_send, peer, peer_descriptor.clone(), message){ + match handling_error { + MessageHandlingError::PeerHandleError(e) => { return Err(e) }, + MessageHandlingError::LightningError(e) => { + try_potential_handleerror!(Err(e)); + }, } } } @@ -889,7 +916,9 @@ impl PeerManager { @@ -899,7 +928,9 @@ impl PeerManager { @@ -911,7 +942,9 @@ impl PeerManager { @@ -922,7 +955,9 @@ impl PeerManager { @@ -932,7 +967,9 @@ impl PeerManager { @@ -943,7 +980,9 @@ impl PeerManager { @@ -956,22 +995,24 @@ impl PeerManager { @@ -981,7 +1022,9 @@ impl PeerManager { @@ -991,7 +1034,9 @@ impl PeerManager { @@ -1001,7 +1046,9 @@ impl PeerManager { @@ -1011,7 +1058,9 @@ impl PeerManager { @@ -1021,8 +1070,8 @@ impl PeerManager PeerManager PeerManager PeerManager PeerManager PeerManager PeerManager PeerManager Vec { + match self { + &Act::One(ref act) => { + act.0.to_vec() + } + &Act::Two(ref act) => { + act.0.to_vec() + } + &Act::Three(ref act) => { + act.0.to_vec() + } + } + } +} \ No newline at end of file diff --git a/lightning/src/ln/peers/handshake/hash.rs b/lightning/src/ln/peers/handshake/hash.rs new file mode 100644 index 00000000000..e7704b37e34 --- /dev/null +++ b/lightning/src/ln/peers/handshake/hash.rs @@ -0,0 +1,25 @@ +use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; + +pub(crate) struct HandshakeHash { + pub(super) value: [u8; 32] +} + +impl HandshakeHash { + pub(super) fn new(first_input: &[u8]) -> Self { + let mut hash = Self { + value: [0; 32] + }; + let mut sha = Sha256::engine(); + sha.input(first_input); + hash.value = Sha256::from_engine(sha).into_inner(); + hash + } + + pub(super) fn update(&mut self, input: &[u8]) { + let mut sha = Sha256::engine(); + sha.input(self.value.as_ref()); + sha.input(input); + self.value = Sha256::from_engine(sha).into_inner(); + } +} diff --git a/lightning/src/ln/peers/handshake/mod.rs b/lightning/src/ln/peers/handshake/mod.rs new file mode 100644 index 00000000000..32efc969a22 --- /dev/null +++ b/lightning/src/ln/peers/handshake/mod.rs @@ -0,0 +1,394 @@ +//! Execute handshakes for peer-to-peer connection establishment. +//! Handshake states can be advanced automatically, or by manually calling the appropriate step. +//! Once complete, returns an instance of Conduit. + +use bitcoin::secp256k1; + +use bitcoin::hashes::{Hash, HashEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::secp256k1::{PublicKey, SecretKey}; + +use ln::peers::{chacha, hkdf}; +use ln::peers::conduit::{Conduit, SymmetricKey}; +use ln::peers::handshake::acts::{ActOne, ActThree, ActTwo, ACT_ONE_LENGTH, ACT_TWO_LENGTH, ACT_THREE_LENGTH, Act}; +use ln::peers::handshake::hash::HandshakeHash; +use ln::peers::handshake::states::{ActOneExpectation, ActThreeExpectation, ActTwoExpectation, HandshakeState}; + +pub(crate) mod acts; +mod hash; +mod states; +mod tests; + +/// Object for managing handshakes. +/// Currently requires explicit ephemeral private key specification. +pub struct PeerHandshake { + state: Option, + private_key: SecretKey, + remote_public_key: Option, + ephemeral_private_key: SecretKey, + + read_buffer: Vec, +} + +impl PeerHandshake { + /// Instantiate a new handshake with a node identity secret key and an ephemeral private key + pub fn new_outbound(private_key: &SecretKey, remote_public_key: &PublicKey, ephemeral_private_key: &SecretKey) -> Self { + Self { + state: Some(HandshakeState::Uninitiated), + private_key: (*private_key).clone(), + remote_public_key: Some(remote_public_key.clone()), + ephemeral_private_key: (*ephemeral_private_key).clone(), + read_buffer: Vec::new(), + } + } + + /// Instantiate a new handshake in anticipation of a peer's first handshake act + pub fn new_inbound(private_key: &SecretKey, ephemeral_private_key: &SecretKey) -> Self { + let mut handshake = Self { + state: Some(HandshakeState::Uninitiated), + private_key: (*private_key).clone(), + remote_public_key: None, + ephemeral_private_key: (*ephemeral_private_key).clone(), + read_buffer: Vec::new(), + }; + let public_key = Self::private_key_to_public_key(&private_key); + let (hash, chaining_key) = Self::initialize_state(&public_key); + handshake.state = Some(HandshakeState::AwaitingActOne(ActOneExpectation { + hash, + chaining_key, + })); + handshake + } + + /// Return the remote public key once it has been extracted from the third act. + /// Potentially useful for inbound connections + pub fn get_remote_pubkey(&self) -> Option { + self.remote_public_key + } + + fn initialize_state(public_key: &PublicKey) -> (HandshakeHash, [u8; 32]) { + let protocol_name = b"Noise_XK_secp256k1_ChaChaPoly_SHA256"; + let prologue = b"lightning"; + + let mut sha = Sha256::engine(); + sha.input(protocol_name); + let chaining_key = Sha256::from_engine(sha).into_inner(); + + let mut initial_hash_preimage = chaining_key.to_vec(); + initial_hash_preimage.extend_from_slice(prologue.as_ref()); + + let mut hash = HandshakeHash::new(initial_hash_preimage.as_slice()); + hash.update(&public_key.serialize()); + + (hash, chaining_key) + } + + /// Process act dynamically + /// # Arguments + /// `input`: Byte slice received from peer as part of the handshake protocol + /// + /// # Return values + /// Returns a tuple with the following components: + /// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol + /// `.1`: Conduit option if the handshake was just processed to completion and messages can now be encrypted and decrypted + pub fn process_act(&mut self, input: &[u8]) -> Result<(Option, Option), String> { + let mut response = None; + let mut connected_peer = None; + + self.read_buffer.extend_from_slice(input); + let read_buffer_length = self.read_buffer.len(); + + match &self.state { + &Some(HandshakeState::Uninitiated) => { + let remote_public_key = &self.remote_public_key.ok_or("outbound connections must be initialized with new_outbound")?; + let act_one = self.initiate(&remote_public_key)?; + response = Some(Act::One(act_one)); + } + &Some(HandshakeState::AwaitingActOne(_)) => { + if read_buffer_length < ACT_ONE_LENGTH { + return Err("need at least 50 bytes".to_string()); + } + + let mut act_one_buffer = [0u8; ACT_ONE_LENGTH]; + act_one_buffer.copy_from_slice(&self.read_buffer[..ACT_ONE_LENGTH]); + self.read_buffer.drain(..ACT_ONE_LENGTH); + + let act_two = self.process_act_one(ActOne(act_one_buffer))?; + response = Some(Act::Two(act_two)); + } + &Some(HandshakeState::AwaitingActTwo(_)) => { + if read_buffer_length < ACT_TWO_LENGTH { + return Err("need at least 50 bytes".to_string()); + } + + let mut act_two_buffer = [0u8; ACT_TWO_LENGTH]; + act_two_buffer.copy_from_slice(&self.read_buffer[..ACT_TWO_LENGTH]); + self.read_buffer.drain(..ACT_TWO_LENGTH); + + let (act_three, mut conduit) = self.process_act_two(ActTwo(act_two_buffer))?; + + if self.read_buffer.len() > 0 { // have we received more data still? + conduit.read(&self.read_buffer[..]); + self.read_buffer.drain(..); + } + + response = Some(Act::Three(act_three)); + connected_peer = Some(conduit); + } + &Some(HandshakeState::AwaitingActThree(_)) => { + if read_buffer_length < ACT_THREE_LENGTH { + return Err("need at least 66 bytes".to_string()); + } + + let mut act_three_buffer = [0u8; ACT_THREE_LENGTH]; + act_three_buffer.copy_from_slice(&self.read_buffer[..ACT_THREE_LENGTH]); + self.read_buffer.drain(..ACT_THREE_LENGTH); + + let (public_key, mut conduit) = self.process_act_three(ActThree(act_three_buffer))?; + + if self.read_buffer.len() > 0 { // have we received more data still? + conduit.read(&self.read_buffer[..]); + self.read_buffer.drain(..); + } + + connected_peer = Some(conduit); + self.remote_public_key = Some(public_key); + } + _ => { + panic!("no acts left to process"); + } + }; + Ok((response, connected_peer)) + } + + /// Initiate the handshake with a peer and return the first act + pub fn initiate(&mut self, remote_public_key: &PublicKey) -> Result { + if let &Some(HandshakeState::Uninitiated) = &self.state {} else { + return Err("Handshakes can only be initiated from the uninitiated state".to_string()); + } + + let (mut hash, chaining_key) = Self::initialize_state(&remote_public_key); + + // serialize act one + let (act_one, chaining_key, temporary_key) = Self::calculate_act_message( + &self.ephemeral_private_key, + remote_public_key, + chaining_key, + &mut hash, + ); + + self.state = Some(HandshakeState::AwaitingActTwo(ActTwoExpectation { + hash, + chaining_key, + temporary_key, + ephemeral_private_key: (*&self.ephemeral_private_key).clone(), + })); + + Ok(ActOne(act_one)) + } + + /// Process a peer's incoming first act and return the second act + pub(crate) fn process_act_one(&mut self, act: ActOne) -> Result { + let state = self.state.take(); + let act_one_expectation = match state { + Some(HandshakeState::AwaitingActOne(act_state)) => act_state, + Some(HandshakeState::Uninitiated) => { + let public_key = Self::private_key_to_public_key(&self.private_key); + let (hash, chaining_key) = Self::initialize_state(&public_key); + ActOneExpectation { + hash, + chaining_key, + } + } + _ => { + self.state = state; + panic!("unexpected state"); + } + }; + + let mut hash = act_one_expectation.hash; + let (remote_ephemeral_public_key, chaining_key, _) = Self::process_act_message( + act.0, + &self.private_key, + act_one_expectation.chaining_key, + &mut hash, + )?; + + let ephemeral_private_key = (*&self.ephemeral_private_key).clone(); + + let (act_two, chaining_key, temporary_key) = Self::calculate_act_message( + &ephemeral_private_key, + &remote_ephemeral_public_key, + chaining_key, + &mut hash, + ); + + self.state = Some(HandshakeState::AwaitingActThree(ActThreeExpectation { + hash, + chaining_key, + temporary_key, + ephemeral_private_key, + remote_ephemeral_public_key, + })); + + Ok(ActTwo(act_two)) + } + + /// Process a peer's incoming second act and return the third act alongside a Conduit instance + pub(crate) fn process_act_two(&mut self, act: ActTwo) -> Result<(ActThree, Conduit), String> { + let state = self.state.take(); + let act_two_expectation = match state { + Some(HandshakeState::AwaitingActTwo(act_state)) => act_state, + _ => { + self.state = state; + panic!("unexpected state".to_string()); + } + }; + + let mut hash = act_two_expectation.hash; + let (remote_ephemeral_public_key, chaining_key, temporary_key) = Self::process_act_message( + act.0, + &act_two_expectation.ephemeral_private_key, + act_two_expectation.chaining_key, + &mut hash, + )?; + + self.state = Some(HandshakeState::Complete); + + // start serializing act three + + let static_public_key = Self::private_key_to_public_key(&self.private_key); + let tagged_encrypted_pubkey = chacha::encrypt(&temporary_key, 1, &hash.value, &static_public_key.serialize()); + hash.update(&tagged_encrypted_pubkey); + + let ecdh = Self::ecdh(&self.private_key, &remote_ephemeral_public_key); + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + let authentication_tag = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); + let (sending_key, receiving_key) = hkdf::derive(&chaining_key, &[0; 0]); + + let mut act_three = [0u8; ACT_THREE_LENGTH]; + act_three[1..50].copy_from_slice(&tagged_encrypted_pubkey); + act_three[50..].copy_from_slice(authentication_tag.as_slice()); + + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); + Ok((ActThree(act_three), connected_peer)) + } + + /// Process a peer's incoming third act and return a Conduit instance + pub(crate) fn process_act_three(&mut self, act: ActThree) -> Result<(PublicKey, Conduit), String> { + let state = self.state.take(); + let act_three_expectation = match state { + Some(HandshakeState::AwaitingActThree(act_state)) => act_state, + _ => { + self.state = state; + panic!("unexpected state".to_string()); + } + }; + + let version = act.0[0]; + if version != 0 { + // this should not crash the process, hence no panic + return Err("unexpected version".to_string()); + } + + let mut tagged_encrypted_pubkey = [0u8; 49]; + tagged_encrypted_pubkey.copy_from_slice(&act.0[1..50]); + + let mut chacha_tag = [0u8; 16]; + chacha_tag.copy_from_slice(&act.0[50..66]); + + let mut hash = act_three_expectation.hash; + + let remote_pubkey_vec = chacha::decrypt(&act_three_expectation.temporary_key, 1, &hash.value, &tagged_encrypted_pubkey)?; + let mut remote_pubkey_bytes = [0u8; 33]; + remote_pubkey_bytes.copy_from_slice(remote_pubkey_vec.as_slice()); + let remote_pubkey = if let Ok(public_key) = PublicKey::from_slice(&remote_pubkey_bytes) { + public_key + } else { + return Err("invalid remote public key".to_string()); + }; + + hash.update(&tagged_encrypted_pubkey); + + let ecdh = Self::ecdh(&act_three_expectation.ephemeral_private_key, &remote_pubkey); + let (chaining_key, temporary_key) = hkdf::derive(&act_three_expectation.chaining_key, &ecdh); + let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; + let (receiving_key, sending_key) = hkdf::derive(&chaining_key, &[0; 0]); + + let connected_peer = Conduit::new(sending_key, receiving_key, chaining_key); + Ok((remote_pubkey, connected_peer)) + } + + fn calculate_act_message(local_private_key: &SecretKey, remote_public_key: &PublicKey, chaining_key: [u8; 32], hash: &mut HandshakeHash) -> ([u8; 50], SymmetricKey, SymmetricKey) { + let local_public_key = Self::private_key_to_public_key(local_private_key); + + hash.update(&local_public_key.serialize()); + + let ecdh = Self::ecdh(local_private_key, &remote_public_key); + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + let tagged_ciphertext = chacha::encrypt(&temporary_key, 0, &hash.value, &[0; 0]); + + hash.update(&tagged_ciphertext); + + let mut act = [0u8; 50]; + act[1..34].copy_from_slice(&local_public_key.serialize()); + act[34..].copy_from_slice(tagged_ciphertext.as_slice()); + + (act, chaining_key, temporary_key) + } + + // Due to the very high similarity of acts 1 and 2, this method is used to process both + fn process_act_message(act_bytes: [u8; 50], local_private_key: &SecretKey, chaining_key: SymmetricKey, hash: &mut HandshakeHash) -> Result<(PublicKey, SymmetricKey, SymmetricKey), String> { + let version = act_bytes[0]; + if version != 0 { + // this should not crash the process, hence no panic + return Err("unexpected version".to_string()); + } + + let mut ephemeral_public_key_bytes = [0u8; 33]; + ephemeral_public_key_bytes.copy_from_slice(&act_bytes[1..34]); + let ephemeral_public_key = if let Ok(public_key) = PublicKey::from_slice(&ephemeral_public_key_bytes) { + public_key + } else { + return Err("invalid remote ephemeral public key".to_string()); + }; + + let mut chacha_tag = [0u8; 16]; + chacha_tag.copy_from_slice(&act_bytes[34..50]); + + // process the act message + + // update hash with partner's pubkey + hash.update(&ephemeral_public_key.serialize()); + + // calculate ECDH with partner's pubkey and local privkey + let ecdh = Self::ecdh(local_private_key, &ephemeral_public_key); + + // HKDF(chaining key, ECDH) -> chaining key' + next temporary key + let (chaining_key, temporary_key) = hkdf::derive(&chaining_key, &ecdh); + + // Validate chacha tag (temporary key, 0, hash, chacha_tag) + let _tag_check = chacha::decrypt(&temporary_key, 0, &hash.value, &chacha_tag)?; + + hash.update(&chacha_tag); + + Ok((ephemeral_public_key, chaining_key, temporary_key)) + } + + fn private_key_to_public_key(private_key: &SecretKey) -> PublicKey { + let curve = secp256k1::Secp256k1::new(); + let pk_object = PublicKey::from_secret_key(&curve, &private_key); + pk_object + } + + fn ecdh(private_key: &SecretKey, public_key: &PublicKey) -> SymmetricKey { + let curve = secp256k1::Secp256k1::new(); + let mut pk_object = public_key.clone(); + pk_object.mul_assign(&curve, &private_key[..]).expect("invalid multiplication"); + + let preimage = pk_object.serialize(); + let mut sha = Sha256::engine(); + sha.input(preimage.as_ref()); + Sha256::from_engine(sha).into_inner() + } +} diff --git a/lightning/src/ln/peers/handshake/states.rs b/lightning/src/ln/peers/handshake/states.rs new file mode 100644 index 00000000000..2a7401f5e9b --- /dev/null +++ b/lightning/src/ln/peers/handshake/states.rs @@ -0,0 +1,30 @@ +use ln::peers::handshake::hash::HandshakeHash; +use bitcoin::secp256k1::{SecretKey, PublicKey}; + +pub enum HandshakeState { + Uninitiated, + AwaitingActOne(ActOneExpectation), + AwaitingActTwo(ActTwoExpectation), + AwaitingActThree(ActThreeExpectation), + Complete, +} + +pub struct ActOneExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], +} + +pub struct ActTwoExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], + pub(super) temporary_key: [u8; 32], + pub(super) ephemeral_private_key: SecretKey, +} + +pub struct ActThreeExpectation { + pub(super) hash: HandshakeHash, + pub(super) chaining_key: [u8; 32], + pub(super) temporary_key: [u8; 32], + pub(super) ephemeral_private_key: SecretKey, + pub(super) remote_ephemeral_public_key: PublicKey, +} diff --git a/lightning/src/ln/peers/handshake/tests.rs b/lightning/src/ln/peers/handshake/tests.rs new file mode 100644 index 00000000000..e99500d1399 --- /dev/null +++ b/lightning/src/ln/peers/handshake/tests.rs @@ -0,0 +1,39 @@ +#![cfg(test)] + +use hex; +use bitcoin::secp256k1; + +use bitcoin::secp256k1::key::{PublicKey, SecretKey}; + +use ln::peers::handshake::PeerHandshake; + +#[test] +fn test_exchange() { + let curve = secp256k1::Secp256k1::new(); + + let local_private_key = SecretKey::from_slice(&[0x_11_u8; 32]).unwrap(); + let remote_private_key = SecretKey::from_slice(&[0x_21_u8; 32]).unwrap(); + + let local_ephemeral_private_key = SecretKey::from_slice(&[0x_12_u8; 32]).unwrap(); + let remote_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap(); + + let remote_public_key = PublicKey::from_secret_key(&curve, &remote_private_key); + + let mut local_handshake = PeerHandshake::new_outbound(&local_private_key, &remote_public_key, &local_ephemeral_private_key); + let mut remote_handshake = PeerHandshake::new_inbound(&remote_private_key, &remote_ephemeral_private_key); + + let act_1 = local_handshake.initiate(&remote_public_key).unwrap(); + let act_1_hex = hex::encode(&act_1.0.to_vec()); + assert_eq!(act_1_hex, "00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a"); + + let act_2 = remote_handshake.process_act_one(act_1).unwrap(); + let act_2_hex = hex::encode(&act_2.0.to_vec()); + assert_eq!(act_2_hex, "0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae"); + + let act_2_result = local_handshake.process_act_two(act_2).unwrap(); + let act_3 = act_2_result.0; + let act_3_hex = hex::encode(&act_3.0.to_vec()); + assert_eq!(act_3_hex, "00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba"); + + remote_handshake.process_act_three(act_3).unwrap(); +} diff --git a/lightning/src/ln/peers/hkdf.rs b/lightning/src/ln/peers/hkdf.rs new file mode 100644 index 00000000000..48415594114 --- /dev/null +++ b/lightning/src/ln/peers/hkdf.rs @@ -0,0 +1,18 @@ +use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine}; +use bitcoin::hashes::sha256::Hash as Sha256; + +pub fn derive(salt: &[u8], master: &[u8]) -> ([u8; 32], [u8; 32]) { + let mut hmac = HmacEngine::::new(salt); + hmac.input(master); + let prk = Hmac::from_engine(hmac).into_inner(); // prk = sha256(master) + + let mut hmac = HmacEngine::::new(&prk[..]); + hmac.input(&[1; 1]); + let t1 = Hmac::from_engine(hmac).into_inner(); // t1 = sha256(prk | 1) + + let mut hmac = HmacEngine::::new(&prk[..]); + hmac.input(&t1); + hmac.input(&[2; 1]); + // sha256(prk | t1 | 2) = sha256(sha256(master) | sha256(sha256(sha256(master) | 1) | 2) + (t1, Hmac::from_engine(hmac).into_inner()) +} diff --git a/lightning/src/ln/peers/mod.rs b/lightning/src/ln/peers/mod.rs new file mode 100644 index 00000000000..f8082c50f10 --- /dev/null +++ b/lightning/src/ln/peers/mod.rs @@ -0,0 +1,10 @@ +//! Everything that has to do with over-the-wire peer communication. +//! The handshake module exposes mechanisms to conduct inbound and outbound handshakes. +//! When a handshake completes, it returns an instance of Conduit. +//! Conduit enables message encryption and decryption, and automatically handles key rotation. + +mod chacha; +pub mod conduit; +pub mod handshake; +pub mod handler; +mod hkdf;