bugfix: setting correct LpPeerConfig during handshake
This commit is contained in:
@@ -65,6 +65,7 @@ impl LpPeerConfig {
|
||||
rng.random(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a new client to exit config.
|
||||
/// Inputs:
|
||||
/// hop_id: this value must be in the range (1..=15). This function returns an error if this is not the case.
|
||||
@@ -79,6 +80,7 @@ impl LpPeerConfig {
|
||||
{
|
||||
Self::new(rng, hop_id, true, false, censorship_resistance)
|
||||
}
|
||||
|
||||
/// Creates a new client to an intermediate node config.
|
||||
/// Inputs:
|
||||
/// hop_id: this value must be in the range (1..=14). This function returns an error if this is not the case.
|
||||
@@ -130,6 +132,7 @@ impl LpPeerConfig {
|
||||
rng.random(),
|
||||
)
|
||||
}
|
||||
|
||||
fn build(
|
||||
hop_id: u8,
|
||||
is_exit: bool,
|
||||
@@ -147,6 +150,7 @@ impl LpPeerConfig {
|
||||
seed,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_checked(
|
||||
hop_id: u8,
|
||||
is_exit: bool,
|
||||
@@ -203,6 +207,7 @@ impl LpPeerConfig {
|
||||
output_bytes[4..].copy_from_slice(&self.seed);
|
||||
output_bytes
|
||||
}
|
||||
|
||||
pub fn deserialize(bytes: &[u8]) -> Result<Self, LpError> {
|
||||
if bytes.len() != LP_PEER_CONFIG_SIZE {
|
||||
return Err(LpError::DeserializationError(format!(
|
||||
|
||||
@@ -24,10 +24,31 @@ use nym_kkt::message::{KKTRequest, KKTResponse};
|
||||
use rand09::SeedableRng;
|
||||
use tracing::debug;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum HandshakeMode {
|
||||
// Client <> Entry
|
||||
OneWayEntry,
|
||||
|
||||
// Client <> Exit
|
||||
OneWayExit,
|
||||
|
||||
// Entry <> Exit
|
||||
MutualInternode,
|
||||
// in the future more variants will be supported (such as individual mix hops)
|
||||
}
|
||||
|
||||
impl HandshakeMode {
|
||||
pub fn is_mutual(&self) -> bool {
|
||||
matches!(self, HandshakeMode::MutualInternode)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PSQHandshakeStateInitiator<'a, S> {
|
||||
pub(super) inner_state: PSQHandshakeState<'a, S>,
|
||||
pub(super) initiator_data: InitiatorData,
|
||||
pub(super) mutual: bool,
|
||||
|
||||
/// The mode of the handshake (mutual node-node, client-entry, entry-exit)
|
||||
pub(super) mode: HandshakeMode,
|
||||
}
|
||||
|
||||
pub(crate) fn build_psq_principal<R>(
|
||||
@@ -78,13 +99,23 @@ impl<'a, S> PSQHandshakeStateInitiator<'a, S>
|
||||
where
|
||||
S: LpHandshakeChannel + Unpin,
|
||||
{
|
||||
pub fn set_mutual_kkt(mut self) -> Result<Self, LpError> {
|
||||
if self.inner_state.local_peer.kem_keypairs.is_none() {
|
||||
return Err(LpError::PSQMutualInitiatorMissingKemKey);
|
||||
}
|
||||
fn lp_peer_config<R>(&self, rng: &mut R) -> Result<LpPeerConfig, LpError>
|
||||
where
|
||||
R: rand09::CryptoRng,
|
||||
{
|
||||
// for now we don't support censorship resistance flag
|
||||
let censorship_resistance = false;
|
||||
|
||||
self.mutual = true;
|
||||
Ok(self)
|
||||
match self.mode {
|
||||
HandshakeMode::OneWayEntry => Ok(LpPeerConfig::new_client_to_entry(
|
||||
rng,
|
||||
censorship_resistance,
|
||||
)),
|
||||
HandshakeMode::OneWayExit => {
|
||||
LpPeerConfig::new_client_to_exit(rng, 1, censorship_resistance)
|
||||
}
|
||||
HandshakeMode::MutualInternode => LpPeerConfig::new_node_to_node(rng),
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempt to send KKT request to begin the handshake
|
||||
@@ -132,7 +163,7 @@ where
|
||||
let ciphersuite = self.inner_state.local_peer.ciphersuite();
|
||||
let kem = ciphersuite.kem();
|
||||
|
||||
let lp_peer_config = LpPeerConfig::new_client_to_entry(rng, false);
|
||||
let lp_peer_config = self.lp_peer_config(rng)?;
|
||||
|
||||
// 1. retrieve the expected kem key hash. if we don't know it,
|
||||
let dir_hash = self
|
||||
@@ -141,7 +172,7 @@ where
|
||||
.expected_kem_key_hash(ciphersuite)?;
|
||||
|
||||
// 2. prepare and send KKT request
|
||||
let (mut initiator, kkt_request) = if self.mutual {
|
||||
let (mut initiator, kkt_request) = if self.mode.is_mutual() {
|
||||
// this has been verified when setting the mutual flag
|
||||
let Some(local_encapsulation_key) = self.inner_state.local_peer.encoded_kem_key(kem)
|
||||
else {
|
||||
@@ -273,8 +304,8 @@ mod tests {
|
||||
resp.ciphersuite = ciphersuite;
|
||||
let initiator_data = InitiatorData::new(1, resp_remote);
|
||||
|
||||
let handshake_init =
|
||||
PSQHandshakeState::new(conn_init, init).as_initiator(initiator_data);
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init)
|
||||
.as_initiator(initiator_data, HandshakeMode::OneWayEntry)?;
|
||||
|
||||
let mut init_rng = DeterministicRng09Send::new(u64_seeded_rng_09(1));
|
||||
|
||||
@@ -396,8 +427,7 @@ mod tests {
|
||||
let initiator_data = InitiatorData::new(1, resp_remote);
|
||||
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init)
|
||||
.as_initiator(initiator_data)
|
||||
.set_mutual_kkt()?;
|
||||
.as_initiator(initiator_data, HandshakeMode::MutualInternode)?;
|
||||
|
||||
let mut init_rng = DeterministicRng09Send::new(u64_seeded_rng_09(1));
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ mod helpers;
|
||||
pub mod initiator;
|
||||
pub mod responder;
|
||||
|
||||
use crate::LpError;
|
||||
use crate::psq::initiator::HandshakeMode;
|
||||
pub use initiator::PSQHandshakeStateInitiator;
|
||||
pub use responder::PSQHandshakeStateResponder;
|
||||
|
||||
@@ -107,12 +109,20 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_initiator(self, initiator_data: InitiatorData) -> PSQHandshakeStateInitiator<'a, S> {
|
||||
PSQHandshakeStateInitiator {
|
||||
pub fn as_initiator(
|
||||
self,
|
||||
initiator_data: InitiatorData,
|
||||
mode: HandshakeMode,
|
||||
) -> Result<PSQHandshakeStateInitiator<'a, S>, LpError> {
|
||||
if mode.is_mutual() && self.local_peer.kem_keypairs.is_none() {
|
||||
return Err(LpError::PSQMutualInitiatorMissingKemKey);
|
||||
}
|
||||
|
||||
Ok(PSQHandshakeStateInitiator {
|
||||
initiator_data,
|
||||
inner_state: self,
|
||||
mutual: false,
|
||||
}
|
||||
mode,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_responder(self, responder_data: ResponderData) -> PSQHandshakeStateResponder<'a, S> {
|
||||
@@ -160,8 +170,10 @@ mod tests {
|
||||
resp.ciphersuite = ciphersuite;
|
||||
let resp_remote = resp.as_remote();
|
||||
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init)
|
||||
.as_initiator(InitiatorData::new(1, resp_remote));
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init).as_initiator(
|
||||
InitiatorData::new(1, resp_remote),
|
||||
HandshakeMode::OneWayEntry,
|
||||
)?;
|
||||
let handshake_resp =
|
||||
PSQHandshakeState::new(conn_resp, resp).as_responder(ResponderData::default());
|
||||
|
||||
@@ -232,9 +244,10 @@ mod tests {
|
||||
let resp_remote = resp.as_remote();
|
||||
let init_remote = init.as_remote();
|
||||
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init)
|
||||
.as_initiator(InitiatorData::new(1, resp_remote))
|
||||
.set_mutual_kkt()?;
|
||||
let handshake_init = PSQHandshakeState::new(conn_init, init).as_initiator(
|
||||
InitiatorData::new(1, resp_remote),
|
||||
HandshakeMode::MutualInternode,
|
||||
)?;
|
||||
let handshake_resp = PSQHandshakeState::new(conn_resp, resp).as_responder(
|
||||
ResponderData::default()
|
||||
.with_initiator_kem_hashes(init_remote.expected_kem_key_digests),
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::codec::{decrypt_lp_packet, encrypt_lp_packet};
|
||||
use crate::packet::{EncryptedLpPacket, LpHeader, LpMessage, LpPacket};
|
||||
use crate::peer::{LpLocalPeer, LpRemotePeer};
|
||||
use crate::peer_config::LpReceiverIndex;
|
||||
use crate::psq::initiator::HandshakeMode;
|
||||
use crate::psq::{
|
||||
InitiatorData, PSQHandshakeState, PSQHandshakeStateInitiator, PSQHandshakeStateResponder,
|
||||
ResponderData,
|
||||
@@ -154,12 +155,34 @@ impl LpTransportSession {
|
||||
local_peer: LpLocalPeer,
|
||||
remote_peer: LpRemotePeer,
|
||||
remote_protocol_version: u8,
|
||||
) -> PSQHandshakeStateInitiator<'_, S>
|
||||
mode: HandshakeMode,
|
||||
) -> Result<PSQHandshakeStateInitiator<'_, S>, LpError>
|
||||
where
|
||||
S: LpHandshakeChannel + Unpin,
|
||||
{
|
||||
PSQHandshakeState::new(connection, local_peer)
|
||||
.as_initiator(InitiatorData::new(remote_protocol_version, remote_peer))
|
||||
PSQHandshakeState::new(connection, local_peer).as_initiator(
|
||||
InitiatorData::new(remote_protocol_version, remote_peer),
|
||||
mode,
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to create `PSQHandshakeState` for the handshake initiator for mutual KKT
|
||||
pub fn psq_handshake_initiator_mutual_internode<S>(
|
||||
connection: &'_ mut S,
|
||||
local_peer: LpLocalPeer,
|
||||
remote_peer: LpRemotePeer,
|
||||
remote_protocol_version: u8,
|
||||
) -> Result<PSQHandshakeStateInitiator<'_, S>, LpError>
|
||||
where
|
||||
S: LpHandshakeChannel + Unpin,
|
||||
{
|
||||
Self::psq_handshake_initiator(
|
||||
connection,
|
||||
local_peer,
|
||||
remote_peer,
|
||||
remote_protocol_version,
|
||||
HandshakeMode::MutualInternode,
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to create `PSQHandshakeState` for the handshake responder
|
||||
|
||||
@@ -17,9 +17,10 @@ mod tests {
|
||||
use nym_lp::peer::LpLocalPeer;
|
||||
use nym_node::config::{LpConfig, LpDebug};
|
||||
use nym_node::node::GatewayStorage;
|
||||
use nym_node::node::lp::control::ingress::client_handler::LpConnectionHandler;
|
||||
use nym_node::node::lp::control::ingress::client_handler::LpClientConnectionHandler;
|
||||
use nym_node::node::lp::error::LpHandlerError;
|
||||
use nym_node::node::lp::{SharedLpControlState, SharedLpState};
|
||||
use nym_node::node::lp::state::{ActiveLpSessions, NestedConnectionsManager};
|
||||
use nym_node::node::lp::{SharedLpClientControlState, SharedLpState};
|
||||
use nym_node::wireguard::{PeerManager, PeerRegistrator};
|
||||
use nym_registration_client::{LpClientError, LpRegistrationClient};
|
||||
use nym_test_utils::helpers::{CryptoRng09, seeded_rng};
|
||||
@@ -35,7 +36,7 @@ mod tests {
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Semaphore;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
use tokio::sync::mpsc::{Receiver, channel};
|
||||
use tokio::task::JoinHandle;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::error;
|
||||
@@ -120,7 +121,7 @@ mod tests {
|
||||
enum SpawnedLpConnectionHandlerState {
|
||||
NotCreated,
|
||||
Ready {
|
||||
handler: LpConnectionHandler<MockIOStream>,
|
||||
handler: LpClientConnectionHandler<MockIOStream>,
|
||||
},
|
||||
Running {
|
||||
handle: JoinHandle<Option<Result<(), LpHandlerError>>>,
|
||||
@@ -130,7 +131,7 @@ mod tests {
|
||||
|
||||
struct Gateway {
|
||||
base: Party,
|
||||
lp_state: SharedLpControlState,
|
||||
lp_state: SharedLpClientControlState,
|
||||
ip_pool: IpPool,
|
||||
mock_peer_controller: SpawnedPeerController,
|
||||
|
||||
@@ -216,6 +217,9 @@ mod tests {
|
||||
let (mock_peer_controller, peer_controller_state) =
|
||||
mock_peer_controller(peer_request_rx);
|
||||
|
||||
let (connection_ctrl_sender, _connection_manager_receiver) = channel(42);
|
||||
let nested_connections_manager = NestedConnectionsManager::new(connection_ctrl_sender);
|
||||
|
||||
// registering particular responses for peer controller is up to given test
|
||||
let ecash_verifier = Arc::new(ecash_verifier);
|
||||
|
||||
@@ -225,7 +229,7 @@ mod tests {
|
||||
upgrade_mode_details,
|
||||
);
|
||||
|
||||
let lp_state = SharedLpControlState {
|
||||
let lp_state = SharedLpClientControlState {
|
||||
local_lp_peer: base.peer.clone(),
|
||||
|
||||
forward_semaphore,
|
||||
@@ -235,8 +239,9 @@ mod tests {
|
||||
shared: SharedLpState {
|
||||
metrics: Default::default(),
|
||||
lp_config,
|
||||
session_states: Arc::new(Default::default()),
|
||||
session_states: ActiveLpSessions::new(),
|
||||
},
|
||||
nested_connections_manager,
|
||||
};
|
||||
|
||||
Ok(Gateway {
|
||||
@@ -262,7 +267,7 @@ mod tests {
|
||||
};
|
||||
|
||||
self.lp_connection_handler = SpawnedLpConnectionHandlerState::Ready {
|
||||
handler: LpConnectionHandler::new(
|
||||
handler: LpClientConnectionHandler::new(
|
||||
client_connection,
|
||||
client_address,
|
||||
self.lp_state.clone(),
|
||||
@@ -290,7 +295,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn spawn_lp_handler(&mut self) {
|
||||
let SpawnedLpConnectionHandlerState::Ready { handler } = mem::replace(
|
||||
let SpawnedLpConnectionHandlerState::Ready { mut handler } = mem::replace(
|
||||
&mut self.lp_connection_handler,
|
||||
SpawnedLpConnectionHandlerState::NotCreated,
|
||||
) else {
|
||||
|
||||
@@ -14,6 +14,7 @@ use nym_crypto::asymmetric::{ed25519, x25519};
|
||||
use nym_lp::LpTransportSession;
|
||||
use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer};
|
||||
use nym_lp::peer_config::LpReceiverIndex;
|
||||
use nym_lp::psq::initiator::HandshakeMode;
|
||||
use nym_lp::transport::traits::LpTransportChannel;
|
||||
use nym_lp::transport::{LpHandshakeChannel, LpTransportError};
|
||||
use nym_lp::{Ciphersuite, packet::EncryptedLpPacket, packet::version};
|
||||
@@ -396,7 +397,8 @@ where
|
||||
local_peer,
|
||||
remote_peer,
|
||||
protocol_version,
|
||||
)
|
||||
HandshakeMode::OneWayEntry,
|
||||
)?
|
||||
.complete_handshake()
|
||||
.await?;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ use nym_crypto::asymmetric::{ed25519, x25519};
|
||||
use nym_lp::packet::version;
|
||||
use nym_lp::packet::{EncryptedLpPacket, LpMessage};
|
||||
use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer};
|
||||
use nym_lp::psq::initiator::HandshakeMode;
|
||||
use nym_lp::transport::LpHandshakeChannel;
|
||||
use nym_lp::transport::traits::LpTransportChannel;
|
||||
use nym_lp::{Ciphersuite, KEM, LpTransportSession};
|
||||
@@ -185,7 +186,8 @@ impl NestedLpSession {
|
||||
local_peer,
|
||||
remote_peer,
|
||||
protocol_version,
|
||||
)
|
||||
HandshakeMode::OneWayExit,
|
||||
)?
|
||||
.complete_handshake()
|
||||
.await?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user