Skip to content

Commit ffbf5ec

Browse files
committed
make linter complain less about docs
fix last lint doc issue? make the &Some matches explicit for Rust 1.22 appease Rust 1.22 some more with ampersandery appease Rust 1.22 by using byte_utils for endianness functionality appease Rust 1.22 by using byte_utils and ref in match arms experimenting some more with ref matching for Rust 1.22 might Rust 1.22 finally work? Rearranged a lot of borrowing locations and macro behavior and definition locations fix bug that was kindly caught by fuzz tests fix fuzz test improve error messaging the different rust versions are a balancing act, and I can't juggle
1 parent 986f25f commit ffbf5ec

File tree

7 files changed

+156
-84
lines changed

7 files changed

+156
-84
lines changed

lightning/src/ln/peer_handler.rs

Lines changed: 68 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ enum PeerState {
114114

115115
impl PeerState {
116116
fn is_ready_for_encryption(&self) -> bool {
117-
if let PeerState::Connected(_) = self {
117+
if let &PeerState::Connected(_) = self {
118118
true
119119
} else {
120120
false
@@ -285,7 +285,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
285285
if peers.peers.insert(descriptor, Peer {
286286
encryptor: PeerState::Handshake(handshake),
287287
outbound: true,
288-
their_node_id: None,
288+
their_node_id: Some(their_node_id.clone()),
289289
their_features: None,
290290

291291
pending_outbound_buffer: LinkedList::new(),
@@ -313,7 +313,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
313313
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
314314
/// disconnect_event.
315315
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
316-
let handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key());
316+
let mut handshake = PeerHandshake::new(&self.our_node_secret, &self.get_ephemeral_key());
317+
handshake.make_inbound();
317318

318319
let mut peers = self.peers.lock().unwrap();
319320
if peers.peers.insert(descriptor, Peer {
@@ -465,78 +466,83 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
465466
peer.pending_read_buffer.extend_from_slice(&data);
466467
while peer.pending_read_buffer.len() > 0 {
467468

468-
macro_rules! encode_and_send_msg {
469-
($msg: expr) => {
470-
{
471-
log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap()));
472-
if let PeerState::Connected(ref mut conduit) = peer.encryptor {
473-
peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..]));
474-
}
475-
peers.peers_needing_send.insert(peer_descriptor.clone());
476-
}
469+
let mut conduit_option = None;
470+
let mut remote_pubkey_option = None;
471+
472+
if let &mut PeerState::Handshake(ref mut handshake) = &mut peer.encryptor {
473+
let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap();
474+
peer.pending_read_buffer.drain(..); // we read it all
475+
476+
if let Some(key) = remote_pubkey {
477+
remote_pubkey_option = Some(key);
477478
}
478-
}
479479

480-
macro_rules! try_potential_handleerror {
481-
($thing: expr) => {
482-
match $thing {
483-
Ok(x) => x,
484-
Err(e) => {
485-
match e.action {
486-
msgs::ErrorAction::DisconnectPeer { msg: _ } => {
487-
//TODO: Try to push msg
488-
log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err);
489-
return Err(PeerHandleError{ no_connection_possible: false });
490-
},
491-
msgs::ErrorAction::IgnoreError => {
492-
log_trace!(self, "Got Err handling message, ignoring because {}", e.err);
493-
continue;
494-
},
495-
msgs::ErrorAction::SendErrorMessage { msg } => {
496-
log_trace!(self, "Got Err handling message, sending Error message because {}", e.err);
497-
encode_and_send_msg!(msg);
498-
continue;
499-
},
500-
}
501-
}
502-
};
480+
peer.pending_outbound_buffer.push_back(response);
481+
if let Some(conduit) = conduit {
482+
conduit_option = Some(conduit);
503483
}
504484
}
505485

506-
macro_rules! insert_node_id {
507-
() => {
508-
match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) {
509-
hash_map::Entry::Occupied(_) => {
510-
log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap()));
511-
peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event
512-
return Err(PeerHandleError{ no_connection_possible: false })
513-
},
514-
hash_map::Entry::Vacant(entry) => {
515-
log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap()));
516-
entry.insert(peer_descriptor.clone())
517-
},
518-
};
519-
}
486+
if let Some(key) = remote_pubkey_option {
487+
peer.their_node_id = Some(key);
520488
}
521489

522-
if let PeerState::Handshake(ref mut handshake) = &mut peer.encryptor {
523-
let (response, conduit, remote_pubkey) = handshake.process_act(&peer.pending_read_buffer, None).unwrap();
524-
peer.pending_read_buffer.drain(..); // we read it all
490+
if let Some(conduit) = conduit_option {
491+
// Rust 1.22 does not allow assignment in a borrowed context, even if mutable
492+
peer.encryptor = PeerState::Connected(conduit);
493+
}
525494

526-
peer.pending_outbound_buffer.push_back(response);
527-
if let Some(conduit) = conduit {
528-
peer.encryptor = PeerState::Connected(conduit);
495+
if let &mut PeerState::Connected(ref mut conduit) = &mut peer.encryptor {
496+
497+
macro_rules! encode_and_send_msg {
498+
($msg: expr) => {
499+
{
500+
log_trace!(self, "Encoding and sending message of type {} to {}", $msg.type_id(), log_pubkey!(peer.their_node_id.unwrap()));
501+
// we are in a context where conduit is known
502+
peer.pending_outbound_buffer.push_back(conduit.encrypt(&encode_msg!(&$msg)[..]));
503+
peers.peers_needing_send.insert(peer_descriptor.clone());
504+
}
505+
}
506+
}
507+
508+
macro_rules! try_potential_handleerror {
509+
($thing: expr) => {
510+
match $thing {
511+
Ok(x) => x,
512+
Err(e) => {
513+
match e.action {
514+
msgs::ErrorAction::DisconnectPeer { msg: _ } => {
515+
//TODO: Try to push msg
516+
log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err);
517+
return Err(PeerHandleError{ no_connection_possible: false });
518+
},
519+
msgs::ErrorAction::IgnoreError => {
520+
log_trace!(self, "Got Err handling message, ignoring because {}", e.err);
521+
continue;
522+
},
523+
msgs::ErrorAction::SendErrorMessage { msg } => {
524+
log_trace!(self, "Got Err handling message, sending Error message because {}", e.err);
525+
encode_and_send_msg!(msg);
526+
continue;
527+
},
528+
}
529+
}
530+
};
531+
}
529532
}
530-
}
531533

532-
if let PeerState::Connected(ref mut conduit) = &mut peer.encryptor {
533-
let mut messages = conduit.decrypt_message_stream(Some(&peer.pending_read_buffer));
534+
let mut next_message_result = conduit.decrypt(&peer.pending_read_buffer);
534535

535-
if messages.len() != 1 {
536-
break; // the length should initially be one, though there will be a possibility of decrypting multiple messages at once in the future
536+
let offset = next_message_result.1;
537+
if offset == 0 {
538+
// nothing got read
539+
break;
540+
}else{
541+
peer.pending_read_buffer.drain(0..offset);
537542
}
538543

539-
let msg_data = messages.remove(1);
544+
// something got read, so we definitely have a message
545+
let msg_data = next_message_result.0.unwrap();
540546

541547
let mut reader = ::std::io::Cursor::new(&msg_data[..]);
542548
let message_result = wire::read(&mut reader);

lightning/src/ln/peers/chacha.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
use util::byte_utils;
12
use util::chacha20poly1305rfc::ChaCha20Poly1305RFC;
23

34
pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8]) -> Vec<u8> {
45
let mut nonce_bytes = [0; 12];
5-
nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes());
6+
nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce));
67

78
let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data);
89
let mut ciphertext = vec![0u8; plaintext.len()];
@@ -17,11 +18,15 @@ pub fn encrypt(key: &[u8], nonce: u64, associated_data: &[u8], plaintext: &[u8])
1718

1819
pub fn decrypt(key: &[u8], nonce: u64, associated_data: &[u8], tagged_ciphertext: &[u8]) -> Result<Vec<u8>, String> {
1920
let mut nonce_bytes = [0; 12];
20-
nonce_bytes[4..].copy_from_slice(&nonce.to_le_bytes());
21+
nonce_bytes[4..].copy_from_slice(&byte_utils::le64_to_array(nonce));
2122

2223
let length = tagged_ciphertext.len();
23-
let ciphertext = &tagged_ciphertext[0..length - 16];
24-
let authentication_tag = &tagged_ciphertext[length - 16..length];
24+
if length < 16 {
25+
return Err("ciphertext cannot be shorter than tag length of 16 bytes".to_string());
26+
}
27+
let end_index = length - 16;
28+
let ciphertext = &tagged_ciphertext[0..end_index];
29+
let authentication_tag = &tagged_ciphertext[end_index..length];
2530

2631
let mut chacha = ChaCha20Poly1305RFC::new(key, &nonce_bytes, associated_data);
2732
let mut plaintext = vec![0u8; length - 16];

lightning/src/ln/peers/conduit.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
//! Handles all over the wire message encryption and decryption upon handshake completion.
2+
13
use ln::peers::{chacha, hkdf};
4+
use util::byte_utils;
25

36
/// Returned after a successful handshake to encrypt and decrypt communication with peer nodes
7+
/// Automatically handles key rotation.
8+
/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
49
pub struct Conduit {
510
pub(crate) sending_key: [u8; 32],
611
pub(crate) receiving_key: [u8; 32],
@@ -15,9 +20,10 @@ pub struct Conduit {
1520
}
1621

1722
impl Conduit {
23+
/// Encrypt data to be sent to peer
1824
pub fn encrypt(&mut self, buffer: &[u8]) -> Vec<u8> {
1925
let length = buffer.len() as u16;
20-
let length_bytes = length.to_be_bytes();
26+
let length_bytes = byte_utils::be16_to_array(length);
2127

2228
let encrypted_length = chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes);
2329
self.increment_sending_nonce();
@@ -69,7 +75,7 @@ impl Conduit {
6975
}
7076

7177
/// Decrypt a single message. Buffer is an undelimited amount of bytes
72-
fn decrypt(&mut self, buffer: &[u8]) -> (Option<Vec<u8>>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from
78+
pub(crate) fn decrypt(&mut self, buffer: &[u8]) -> (Option<Vec<u8>>, usize) { // the response slice should have the same lifetime as the argument. It's the slice data is read from
7379
if buffer.len() < 18 {
7480
return (None, 0);
7581
}
@@ -78,9 +84,9 @@ impl Conduit {
7884
let length_vec = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap();
7985
let mut length_bytes = [0u8; 2];
8086
length_bytes.copy_from_slice(length_vec.as_slice());
81-
let message_length = u16::from_be_bytes(length_bytes) as usize;
87+
let message_length = byte_utils::slice_to_be16(&length_bytes) as usize;
8288

83-
let message_end_index = message_length + 18; // todo: abort if too short
89+
let message_end_index = message_length + 18 + 16; // todo: abort if too short
8490
if buffer.len() < message_end_index {
8591
return (None, 0);
8692
}
@@ -121,6 +127,7 @@ impl Conduit {
121127

122128
#[cfg(test)]
123129
mod tests {
130+
use hex;
124131
use ln::peers::conduit::Conduit;
125132

126133
#[test]
@@ -147,6 +154,16 @@ mod tests {
147154
read_buffer: None,
148155
};
149156

157+
let mut remote_peer = Conduit {
158+
sending_key: receiving_key,
159+
receiving_key: sending_key,
160+
sending_chaining_key: chaining_key,
161+
receiving_chaining_key: chaining_key,
162+
sending_nonce: 0,
163+
receiving_nonce: 0,
164+
read_buffer: None,
165+
};
166+
150167
let message = hex::decode("68656c6c6f").unwrap();
151168
let mut encrypted_messages: Vec<Vec<u8>> = Vec::new();
152169

@@ -161,5 +178,13 @@ mod tests {
161178
assert_eq!(encrypted_messages[501], hex::decode("1b186c57d44eb6de4c057c49940d79bb838a145cb528d6e8fd26dbe50a60ca2c104b56b60e45bd").unwrap());
162179
assert_eq!(encrypted_messages[1000], hex::decode("4a2f3cc3b5e78ddb83dcb426d9863d9d9a723b0337c89dd0b005d89f8d3c05c52b76b29b740f09").unwrap());
163180
assert_eq!(encrypted_messages[1001], hex::decode("2ecd8c8a5629d0d02ab457a0fdd0f7b90a192cd46be5ecb6ca570bfc5e268338b1a16cf4ef2d36").unwrap());
181+
182+
for _ in 0..1002 {
183+
let encrypted_message = encrypted_messages.remove(0);
184+
let mut decrypted_messages = remote_peer.decrypt_message_stream(Some(&encrypted_message));
185+
assert_eq!(decrypted_messages.len(), 1);
186+
let decrypted_message = decrypted_messages.remove(0);
187+
assert_eq!(decrypted_message, hex::decode("68656c6c6f").unwrap());
188+
}
164189
}
165190
}

lightning/src/ln/peers/handshake/acts.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
1+
/// Wrapper for the first act message
12
pub struct ActOne(
23
pub(super) [u8; 50]
34
);
45

6+
/// Wrapper for the second act message
57
pub struct ActTwo(
68
pub(super) [u8; 50]
79
);
810

11+
/// Wrapper for the third act message
912
pub struct ActThree(
1013
pub(super) [u8; 66]
1114
);
1215

16+
/// Wrapper for any act message
1317
pub enum Act {
1418
One(ActOne),
1519
Two(ActTwo),
1620
Three(ActThree),
1721
}
1822

1923
impl Act {
24+
/// Convert any act into a byte vector
2025
pub fn serialize(&self) -> Vec<u8> {
2126
match self {
22-
Act::One(act) => {
27+
&Act::One(ref act) => {
2328
act.0.to_vec()
2429
}
25-
Act::Two(act) => {
30+
&Act::Two(ref act) => {
2631
act.0.to_vec()
2732
}
28-
Act::Three(act) => {
33+
&Act::Three(ref act) => {
2934
act.0.to_vec()
3035
}
3136
}

0 commit comments

Comments
 (0)