Skip to content

Commit 1ee5f00

Browse files
committed
review: Split outbound initialization into new()/set_up()
To avoid tuple returns from a single initialization function, create a setup_outbound() function that is only callable by the outbound PeerHandshake, but doesn't leak implementation details.
1 parent d952676 commit 1ee5f00

File tree

3 files changed

+57
-10
lines changed

3 files changed

+57
-10
lines changed

fuzz/src/peer_crypt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ impl TestCtx {
9696
let responder_static_public_key = PublicKey::from_secret_key(&curve, &responder_static_private_key);
9797
let responder_ephemeral_private_key = generator.generate_secret_key()?;
9898

99-
let (act1, initiator_handshake) = PeerHandshake::create_and_initialize_outbound(&initiator_static_private_key, &responder_static_public_key, &initiator_ephemeral_private_key);
99+
let mut initiator_handshake = PeerHandshake::new_outbound(&initiator_static_private_key, &responder_static_public_key, &initiator_ephemeral_private_key);
100+
let act1 = initiator_handshake.set_up_outbound();
100101
let responder_handshake = PeerHandshake::new_inbound(&responder_static_private_key, &responder_ephemeral_private_key);
101102

102103
Ok(TestCtx {

lightning/src/ln/peers/handler.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref> PeerManager<D
365365
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
366366
/// socket_disconnected().
367367
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
368-
let (initial_bytes, handshake) = PeerHandshake::create_and_initialize_outbound(&self.our_node_secret, &their_node_id, &self.get_ephemeral_key());
368+
let mut handshake = PeerHandshake::new_outbound(&self.our_node_secret, &their_node_id, &self.get_ephemeral_key());
369+
let initial_bytes = handshake.set_up_outbound();
369370

370371
let mut peers = self.peers.lock().unwrap();
371372
if peers.peers.insert(descriptor, Peer {

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

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,42 @@ mod states;
1313
/// Currently requires explicit ephemeral private key specification.
1414
pub struct PeerHandshake {
1515
state: Option<HandshakeState>,
16+
ready_for_process: bool
1617
}
1718

1819
impl PeerHandshake {
1920
/// Instantiate a new handshake with a node identity secret key and an ephemeral private key
20-
pub fn create_and_initialize_outbound(initiator_static_private_key: &SecretKey, responder_static_public_key: &PublicKey, initiator_ephemeral_private_key: &SecretKey) -> (Vec<u8>, Self) {
21+
pub fn new_outbound(initiator_static_private_key: &SecretKey, responder_static_public_key: &PublicKey, initiator_ephemeral_private_key: &SecretKey) -> Self {
2122
let state = HandshakeState::new_initiator(initiator_static_private_key, responder_static_public_key, initiator_ephemeral_private_key);
2223

23-
// This transition does not have a failure path
24-
let (response_vec_opt, next_state) = state.next(&[]).unwrap();
25-
(response_vec_opt.unwrap(), Self { state: Some(next_state) })
24+
Self {
25+
state: Some(state),
26+
ready_for_process: false
27+
}
2628
}
2729

2830
/// Instantiate a new handshake in anticipation of a peer's first handshake act
2931
pub fn new_inbound(responder_static_private_key: &SecretKey, responder_ephemeral_private_key: &SecretKey) -> Self {
3032
Self {
31-
state: Some(HandshakeState::new_responder(responder_static_private_key, responder_ephemeral_private_key))
33+
state: Some(HandshakeState::new_responder(responder_static_private_key, responder_ephemeral_private_key)),
34+
ready_for_process: true
3235
}
3336
}
3437

38+
/// Initializes the outbound handshake and provides the initial bytes to send to the responder
39+
pub fn set_up_outbound(&mut self) -> Vec<u8> {
40+
assert!(!self.ready_for_process);
41+
let cur_state = self.state.take().unwrap();
42+
43+
// This transition does not have a failure path
44+
let (response_vec_opt, next_state) = cur_state.next(&[]).unwrap();
45+
46+
self.state = Some(next_state);
47+
48+
self.ready_for_process = true;
49+
response_vec_opt.unwrap()
50+
}
51+
3552
/// Process act dynamically
3653
/// # Arguments
3754
/// `input`: Byte slice received from peer as part of the handshake protocol
@@ -41,6 +58,7 @@ impl PeerHandshake {
4158
/// `.0`: Byte vector containing the next act to send back to the peer per the handshake protocol
4259
/// `.1`: Some(Conduit, PublicKey) if the handshake was just processed to completion and messages can now be encrypted and decrypted
4360
pub fn process_act(&mut self, input: &[u8]) -> Result<(Option<Vec<u8>>, Option<(Conduit, PublicKey)>), String> {
61+
assert!(self.ready_for_process);
4462
let cur_state = self.state.take().unwrap();
4563

4664
let (act_opt, mut next_state) = cur_state.next(input)?;
@@ -85,7 +103,8 @@ mod test {
85103
let inbound_static_public_key = PublicKey::from_secret_key(&curve, &inbound_static_private_key);
86104
let inbound_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap();
87105

88-
let (act1, outbound_handshake) = PeerHandshake::create_and_initialize_outbound(&outbound_static_private_key, &inbound_static_public_key, &outbound_ephemeral_private_key);
106+
let mut outbound_handshake= PeerHandshake::new_outbound(&outbound_static_private_key, &inbound_static_public_key, &outbound_ephemeral_private_key);
107+
let act1 = outbound_handshake.set_up_outbound();
89108
let inbound_handshake = PeerHandshake::new_inbound(&inbound_static_private_key, &inbound_ephemeral_private_key);
90109

91110
TestCtx {
@@ -113,17 +132,43 @@ mod test {
113132
}
114133
}
115134

135+
// Test that the outbound needs to call set_up_outbound() before process_act()
136+
#[test]
137+
#[should_panic(expected = "assertion failed: self.ready_for_process")]
138+
fn new_outbound_no_set_up_panics() {
139+
let curve = secp256k1::Secp256k1::new();
140+
141+
let outbound_static_private_key = SecretKey::from_slice(&[0x_11_u8; 32]).unwrap();
142+
let outbound_ephemeral_private_key = SecretKey::from_slice(&[0x_12_u8; 32]).unwrap();
143+
let inbound_static_private_key = SecretKey::from_slice(&[0x_21_u8; 32]).unwrap();
144+
let inbound_static_public_key = PublicKey::from_secret_key(&curve, &inbound_static_private_key);
145+
146+
let mut outbound_handshake= PeerHandshake::new_outbound(&outbound_static_private_key, &inbound_static_public_key, &outbound_ephemeral_private_key);
147+
outbound_handshake.process_act(&[]).unwrap();
148+
}
149+
150+
// Test that calling set_up_outbound() on the inbound panics
151+
#[test]
152+
#[should_panic(expected = "assertion failed: !self.ready_for_process")]
153+
fn new_inbound_calling_set_up_panics() {
154+
let inbound_static_private_key = SecretKey::from_slice(&[0x_21_u8; 32]).unwrap();
155+
let inbound_ephemeral_private_key = SecretKey::from_slice(&[0x_22_u8; 32]).unwrap();
156+
157+
let mut inbound_handshake = PeerHandshake::new_inbound(&inbound_static_private_key, &inbound_ephemeral_private_key);
158+
inbound_handshake.set_up_outbound();
159+
}
160+
116161
// Default Outbound::Uninitiated
117162
#[test]
118-
fn peer_handshake_new_outbound() {
163+
fn new_outbound() {
119164
let test_ctx = TestCtx::new();
120165

121166
assert_matches!(test_ctx.outbound_handshake.state, Some(HandshakeState::InitiatorAwaitingActTwo(_)));
122167
}
123168

124169
// Default Inbound::AwaitingActOne
125170
#[test]
126-
fn peer_handshake_new_inbound() {
171+
fn new_inbound() {
127172
let test_ctx = TestCtx::new();
128173

129174
assert_matches!(test_ctx.inbound_handshake.state, Some(HandshakeState::ResponderAwaitingActOne(_)));

0 commit comments

Comments
 (0)