Skip to content

Commit 4deb290

Browse files
committed
Split conduit into encryptor and decryptor components (to allow for borrow splits). Extract handshake response method in peer handler into separate method. Create iterator pattern for decryptor.
1 parent f1940e9 commit 4deb290

File tree

7 files changed

+272
-216
lines changed

7 files changed

+272
-216
lines changed

fuzz/src/full_stack.rs

Lines changed: 10 additions & 10 deletions
Large diffs are not rendered by default.

lightning-net-tokio/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ use tokio::{io, time};
6666
use tokio::sync::mpsc;
6767
use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
6868

69-
use lightning::ln::peer_handler;
70-
use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
69+
use lightning::ln::peers::handler;
70+
use lightning::ln::peers::handler::SocketDescriptor as LnSocketTrait;
7171
use lightning::ln::msgs::ChannelMessageHandler;
7272

7373
use std::{task, thread};

lightning/src/ln/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub mod channelmonitor;
1414
pub mod msgs;
1515
pub mod router;
1616
pub mod peers;
17-
pub mod peer_handler;
1817
pub mod chan_utils;
1918
pub mod features;
2019
pub(crate) mod onchaintx;

lightning/src/ln/peers/conduit.rs

Lines changed: 121 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,120 @@ const KEY_ROTATION_INDEX: u32 = 1000;
1515
/// Automatically handles key rotation.
1616
/// For decryption, it is recommended to call `decrypt_message_stream` for automatic buffering.
1717
pub struct Conduit {
18-
pub(crate) sending_key: SymmetricKey,
19-
pub(crate) receiving_key: SymmetricKey,
18+
pub(super) encryptor: Encryptor,
19+
pub(super) decryptor: Decryptor
2020

21-
pub(crate) sending_chaining_key: SymmetricKey,
22-
pub(crate) receiving_chaining_key: SymmetricKey,
21+
}
22+
23+
pub(super) struct Encryptor {
24+
sending_key: SymmetricKey,
25+
sending_chaining_key: SymmetricKey,
26+
sending_nonce: u32,
27+
}
2328

24-
pub(crate) receiving_nonce: u32,
25-
pub(crate) sending_nonce: u32,
29+
pub(super) struct Decryptor {
30+
receiving_key: SymmetricKey,
31+
receiving_chaining_key: SymmetricKey,
32+
receiving_nonce: u32,
2633

27-
pub(super) read_buffer: Option<Vec<u8>>,
34+
pending_message_length: Option<usize>,
35+
read_buffer: Option<Vec<u8>>,
36+
}
37+
38+
impl Iterator for Decryptor {
39+
type Item = Vec<u8>;
40+
41+
fn next(&mut self) -> Option<Self::Item> {
42+
self.decrypt_single_message(None)
43+
}
2844
}
2945

3046
impl Conduit {
47+
/// Instantiate a new Conduit with specified sending and receiving keys
48+
pub fn new(sending_key: SymmetricKey, sending_chaining_key: SymmetricKey, receiving_key: SymmetricKey, receiving_chaining_key: SymmetricKey) -> Self {
49+
Conduit {
50+
encryptor: Encryptor {
51+
sending_key,
52+
sending_chaining_key,
53+
sending_nonce: 0
54+
},
55+
decryptor: Decryptor {
56+
receiving_key,
57+
receiving_chaining_key,
58+
receiving_nonce: 0,
59+
read_buffer: None,
60+
pending_message_length: None
61+
}
62+
}
63+
}
64+
3165
/// Encrypt data to be sent to peer
3266
pub fn encrypt(&mut self, buffer: &[u8]) -> Vec<u8> {
67+
self.encryptor.encrypt(buffer)
68+
}
69+
70+
pub(super) fn read(&mut self, data: &[u8]) {
71+
self.decryptor.read(data)
72+
}
73+
74+
/// Decrypt a single message. If data containing more than one message has been received,
75+
/// only the first message will be returned, and the rest stored in the internal buffer.
76+
/// If a message pending in the buffer still hasn't been decrypted, that message will be
77+
/// returned in lieu of anything new, even if new data is provided.
78+
pub fn decrypt_single_message(&mut self, new_data: Option<&[u8]>) -> Option<Vec<u8>> {
79+
self.decryptor.decrypt_single_message(new_data)
80+
}
81+
82+
/// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes.
83+
fn decrypt(&mut self, buffer: &[u8]) -> (Option<Vec<u8>>, usize) {
84+
self.decryptor.decrypt(buffer)
85+
}
86+
87+
fn increment_sending_nonce(&mut self) {
88+
self.encryptor.increment_nonce()
89+
}
90+
91+
fn increment_receiving_nonce(&mut self) {
92+
self.decryptor.increment_nonce()
93+
}
94+
95+
fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) {
96+
*nonce += 1;
97+
if *nonce == KEY_ROTATION_INDEX {
98+
Self::rotate_key(chaining_key, key);
99+
*nonce = 0;
100+
}
101+
}
102+
103+
fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) {
104+
let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key);
105+
chaining_key.copy_from_slice(&new_chaining_key);
106+
key.copy_from_slice(&new_key);
107+
}
108+
}
109+
110+
impl Encryptor {
111+
pub(super) fn encrypt(&mut self, buffer: &[u8]) -> Vec<u8> {
33112
let length = buffer.len() as u16;
34113
let length_bytes = byte_utils::be16_to_array(length);
35114

36115
let mut ciphertext = vec![0u8; TAGGED_MESSAGE_LENGTH_HEADER_SIZE + length as usize + chacha::TAG_SIZE];
37116

38117
ciphertext[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], &length_bytes));
39-
self.increment_sending_nonce();
118+
self.increment_nonce();
40119

41120
ciphertext[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..].copy_from_slice(&chacha::encrypt(&self.sending_key, self.sending_nonce as u64, &[0; 0], buffer));
42-
self.increment_sending_nonce();
121+
self.increment_nonce();
43122

44123
ciphertext
45124
}
46125

126+
fn increment_nonce(&mut self) {
127+
Conduit::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key);
128+
}
129+
}
130+
131+
impl Decryptor {
47132
pub(super) fn read(&mut self, data: &[u8]) {
48133
let read_buffer = self.read_buffer.get_or_insert(Vec::new());
49134
read_buffer.extend_from_slice(data);
@@ -70,61 +155,53 @@ impl Conduit {
70155
current_message
71156
}
72157

73-
/// Decrypt a message from the beginning of the provided buffer. Returns the consumed number of bytes.
74158
fn decrypt(&mut self, buffer: &[u8]) -> (Option<Vec<u8>>, usize) {
75-
if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE {
76-
// A message must be at least 18 bytes (2 for encrypted length, 16 for the tag)
77-
return (None, 0);
78-
}
159+
let message_length = if let Some(length) = self.pending_message_length {
160+
// we have already decrypted the header
161+
length
162+
} else {
163+
if buffer.len() < TAGGED_MESSAGE_LENGTH_HEADER_SIZE {
164+
// A message must be at least 18 bytes (2 for encrypted length, 16 for the tag)
165+
return (None, 0);
166+
}
167+
168+
let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE];
169+
let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE];
170+
length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap());
79171

80-
let encrypted_length = &buffer[0..TAGGED_MESSAGE_LENGTH_HEADER_SIZE];
81-
let mut length_bytes = [0u8; MESSAGE_LENGTH_HEADER_SIZE];
82-
length_bytes.copy_from_slice(&chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_length).unwrap());
83-
// message_length is the length of the encrypted message excluding its trailing 16-byte tag
84-
let message_length = byte_utils::slice_to_be16(&length_bytes) as usize;
172+
self.increment_nonce();
173+
174+
// the message length
175+
byte_utils::slice_to_be16(&length_bytes) as usize
176+
};
85177

86178
let message_end_index = TAGGED_MESSAGE_LENGTH_HEADER_SIZE + message_length + chacha::TAG_SIZE;
179+
87180
if buffer.len() < message_end_index {
181+
self.pending_message_length = Some(message_length);
88182
return (None, 0);
89183
}
90184

91-
let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index];
185+
self.pending_message_length = None;
92186

93-
self.increment_receiving_nonce();
187+
let encrypted_message = &buffer[TAGGED_MESSAGE_LENGTH_HEADER_SIZE..message_end_index];
94188

95189
let message = chacha::decrypt(&self.receiving_key, self.receiving_nonce as u64, &[0; 0], encrypted_message).unwrap();
96190

97-
self.increment_receiving_nonce();
191+
self.increment_nonce();
98192

99193
(Some(message), message_end_index)
100194
}
101195

102-
fn increment_sending_nonce(&mut self) {
103-
Self::increment_nonce(&mut self.sending_nonce, &mut self.sending_chaining_key, &mut self.sending_key);
104-
}
105-
106-
fn increment_receiving_nonce(&mut self) {
107-
Self::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key);
108-
}
109-
110-
fn increment_nonce(nonce: &mut u32, chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) {
111-
*nonce += 1;
112-
if *nonce == KEY_ROTATION_INDEX {
113-
Self::rotate_key(chaining_key, key);
114-
*nonce = 0;
115-
}
116-
}
117-
118-
fn rotate_key(chaining_key: &mut SymmetricKey, key: &mut SymmetricKey) {
119-
let (new_chaining_key, new_key) = hkdf::derive(chaining_key, key);
120-
chaining_key.copy_from_slice(&new_chaining_key);
121-
key.copy_from_slice(&new_key);
196+
fn increment_nonce(&mut self) {
197+
Conduit::increment_nonce(&mut self.receiving_nonce, &mut self.receiving_chaining_key, &mut self.receiving_key);
122198
}
123199
}
124200

125201
#[cfg(test)]
126202
mod tests {
127203
use hex;
204+
128205
use ln::peers::conduit::Conduit;
129206

130207
fn setup_peers() -> (Conduit, Conduit) {
@@ -140,25 +217,8 @@ mod tests {
140217
let mut receiving_key = [0u8; 32];
141218
receiving_key.copy_from_slice(&receiving_key_vec);
142219

143-
let connected_peer = Conduit {
144-
sending_key,
145-
receiving_key,
146-
sending_chaining_key: chaining_key,
147-
receiving_chaining_key: chaining_key,
148-
sending_nonce: 0,
149-
receiving_nonce: 0,
150-
read_buffer: None,
151-
};
152-
153-
let remote_peer = Conduit {
154-
sending_key: receiving_key,
155-
receiving_key: sending_key,
156-
sending_chaining_key: chaining_key,
157-
receiving_chaining_key: chaining_key,
158-
sending_nonce: 0,
159-
receiving_nonce: 0,
160-
read_buffer: None,
161-
};
220+
let connected_peer = Conduit::new(sending_key, chaining_key, receiving_key, chaining_key);
221+
let remote_peer = Conduit::new(receiving_key, chaining_key, sending_key, chaining_key);
162222

163223
(connected_peer, remote_peer)
164224
}

0 commit comments

Comments
 (0)