X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fpeer_handler.rs;h=03aeedcdac31453f4d76eabb0d3812bb01b81194;hb=cd8f1de394591c85a635060b861105db9d51716c;hp=87a2e6d1c242b64f6e9b15fb0e9de9ef7cb8f74e;hpb=3c44d6beca2d5c3c50a8454d072ef54f735d5000;p=rust-lightning diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 87a2e6d1..03aeedcd 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -20,6 +20,10 @@ use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{cmp,error,hash,fmt}; +use bitcoin_hashes::sha256::Hash as Sha256; +use bitcoin_hashes::sha256::HashEngine as Sha256Engine; +use bitcoin_hashes::{HashEngine, Hash}; + /// Provides references to trait impls which handle different types of messages. pub struct MessageHandler { /// A message handler which handles messages specific to channels. Usually this is just a @@ -113,7 +117,7 @@ struct Peer { } impl Peer { - /// Returns true if the the channel announcements/updates for the given channel should be + /// Returns true if the channel announcements/updates for the given channel should be /// forwarded to this peer. /// If we are sending our routing table to this peer and we have not yet sent channel /// announcements/updates for the given channel_id then we will send it when we get to that @@ -151,12 +155,25 @@ impl PeerHolder { } } +#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))] +fn _check_usize_is_32_or_64() { + // See below, less than 32 bit pointers may be unsafe here! + unsafe { mem::transmute::<*const usize, [u8; 4]>(panic!()); } +} + /// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket /// events into messages which it passes on to its MessageHandlers. pub struct PeerManager { message_handler: MessageHandler, peers: Mutex>, our_node_secret: SecretKey, + ephemeral_key_midstate: Sha256Engine, + + // Usize needs to be at least 32 bits to avoid overflowing both low and high. If usize is 64 + // bits we will never realistically count into high: + peer_counter_low: AtomicUsize, + peer_counter_high: AtomicUsize, + initial_syncs_sent: AtomicUsize, logger: Arc, } @@ -188,7 +205,12 @@ const INITIAL_SYNCS_TO_SEND: usize = 5; /// PeerIds may repeat, but only after disconnect_event() has been called. impl PeerManager { /// Constructs a new PeerManager with the given message handlers and node_id secret key - pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, logger: Arc) -> PeerManager { + /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be + /// cryptographically secure random bytes. + pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: Arc) -> PeerManager { + let mut ephemeral_key_midstate = Sha256::engine(); + ephemeral_key_midstate.input(ephemeral_random_data); + PeerManager { message_handler: message_handler, peers: Mutex::new(PeerHolder { @@ -197,6 +219,9 @@ impl PeerManager { node_id_to_descriptor: HashMap::new() }), our_node_secret: our_node_secret, + ephemeral_key_midstate, + peer_counter_low: AtomicUsize::new(0), + peer_counter_high: AtomicUsize::new(0), initial_syncs_sent: AtomicUsize::new(0), logger, } @@ -217,6 +242,19 @@ impl PeerManager { }).collect() } + fn get_ephemeral_key(&self) -> SecretKey { + let mut ephemeral_hash = self.ephemeral_key_midstate.clone(); + let low = self.peer_counter_low.fetch_add(1, Ordering::AcqRel); + let high = if low == 0 { + self.peer_counter_high.fetch_add(1, Ordering::AcqRel) + } else { + self.peer_counter_high.load(Ordering::Acquire) + }; + ephemeral_hash.input(&byte_utils::le64_to_array(low as u64)); + ephemeral_hash.input(&byte_utils::le64_to_array(high as u64)); + SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!") + } + /// Indicates a new outbound connection has been established to a node with the given node_id. /// Note that if an Err is returned here you MUST NOT call disconnect_event for the new /// descriptor but must disconnect the connection immediately. @@ -226,7 +264,7 @@ impl PeerManager { /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { - let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone()); + 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 @@ -234,7 +272,7 @@ impl PeerManager { if peers.peers.insert(descriptor, Peer { channel_encryptor: peer_encryptor, outbound: true, - their_node_id: Some(their_node_id), + their_node_id: None, their_global_features: None, their_local_features: None, @@ -438,9 +476,6 @@ impl PeerManager { macro_rules! try_potential_handleerror { ($thing: expr) => { - try_potential_handleerror!($thing, false); - }; - ($thing: expr, $pre_noise: expr) => { match $thing { Ok(x) => x, Err(e) => { @@ -449,9 +484,6 @@ impl PeerManager { msgs::ErrorAction::DisconnectPeer { msg: _ } => { //TODO: Try to push msg log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); - if $pre_noise { - peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event - } return Err(PeerHandleError{ no_connection_possible: false }); }, msgs::ErrorAction::IgnoreError => { @@ -481,11 +513,17 @@ impl PeerManager { match e { msgs::DecodeError::UnknownVersion => return Err(PeerHandleError{ no_connection_possible: false }), msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to udpate!"); + log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); continue; }, - msgs::DecodeError::InvalidValue => return Err(PeerHandleError{ no_connection_possible: false }), - msgs::DecodeError::ShortRead => return Err(PeerHandleError{ no_connection_possible: false }), + msgs::DecodeError::InvalidValue => { + log_debug!(self, "Got an invalid value while deserializing message"); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::DecodeError::ShortRead => { + log_debug!(self, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError{ no_connection_possible: false }); + }, msgs::DecodeError::ExtraAddressesPerType => { log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); continue; @@ -517,16 +555,17 @@ impl PeerManager { 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_key(&peer.pending_read_buffer[..], &self.our_node_secret), true).to_vec(); + 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 = try_potential_handleerror!(peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..], &self.our_node_secret), true).to_vec(); - peer.pending_outbound_buffer.push_back(act_three); + 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 local_features = msgs::LocalFeatures::new(); if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { @@ -539,7 +578,7 @@ impl PeerManager { }, 16); }, NextNoiseStep::ActThree => { - let their_node_id = try_potential_handleerror!(peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..]), true); + 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); @@ -586,10 +625,6 @@ impl PeerManager { log_info!(self, "Peer local features required data_loss_protect"); return Err(PeerHandleError{ no_connection_possible: true }); } - if msg.local_features.requires_upfront_shutdown_script() { - log_info!(self, "Peer local features required upfront_shutdown_script"); - return Err(PeerHandleError{ no_connection_possible: true }); - } if peer.their_global_features.is_some() { return Err(PeerHandleError{ no_connection_possible: false }); } @@ -658,11 +693,11 @@ impl PeerManager { // Channel control: 32 => { let msg = try_potential_decodeerror!(msgs::OpenChannel::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), &msg)); + try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_local_features.clone().unwrap(), &msg)); }, 33 => { let msg = try_potential_decodeerror!(msgs::AcceptChannel::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), &msg)); + try_potential_handleerror!(self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_local_features.clone().unwrap(), &msg)); }, 34 => { @@ -1096,10 +1131,11 @@ mod tests { } fn create_network(peer_count: usize) -> Vec> { - let secp_ctx = Secp256k1::new(); let mut peers = Vec::new(); let mut rng = thread_rng(); let logger : Arc = Arc::new(test_utils::TestLogger::new()); + let mut ephemeral_bytes = [0; 32]; + rng.fill_bytes(&mut ephemeral_bytes); for _ in 0..peer_count { let chan_handler = test_utils::TestChannelMessageHandler::new(); @@ -1107,10 +1143,10 @@ mod tests { let node_id = { let mut key_slice = [0;32]; rng.fill_bytes(&mut key_slice); - SecretKey::from_slice(&secp_ctx, &key_slice).unwrap() + SecretKey::from_slice(&key_slice).unwrap() }; let msg_handler = MessageHandler { chan_handler: Arc::new(chan_handler), route_handler: Arc::new(router) }; - let peer = PeerManager::new(msg_handler, node_id, Arc::clone(&logger)); + let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, Arc::clone(&logger)); peers.push(peer); } @@ -1128,7 +1164,7 @@ mod tests { #[test] fn test_disconnect_peer() { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and - // push an DisconnectPeer event to remove the node flagged by id + // push a DisconnectPeer event to remove the node flagged by id let mut peers = create_network(2); establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);