X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fpeer_handler.rs;h=03aeedcdac31453f4d76eabb0d3812bb01b81194;hb=cd8f1de394591c85a635060b861105db9d51716c;hp=cfdc6f1cb81ce9bfff7f0ca335aae4bfe6ba21db;hpb=a6f0281017f1223ef961fb3a000915e37b5719b0;p=rust-lightning diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index cfdc6f1c..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 @@ -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 @@ -517,7 +555,7 @@ 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)).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 }, @@ -587,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 }); } @@ -659,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 => { @@ -1100,6 +1134,8 @@ mod tests { 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(); @@ -1110,7 +1146,7 @@ mod tests { 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); }