Simplify, clean up
This commit is contained in:
@@ -247,6 +247,7 @@ criterion = "0.5"
|
||||
csv = "1.3.1"
|
||||
ctr = "0.9.1"
|
||||
cupid = "0.6.1"
|
||||
curve25519-dalek = "4.1.3"
|
||||
dashmap = "5.5.3"
|
||||
# We want https://github.com/DefGuard/wireguard-rs/pull/64 , but there's no crates.io release being pushed out anymore
|
||||
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.7" }
|
||||
|
||||
+16
-16
@@ -1,7 +1,7 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::message::{ClientHelloData, LpMessage, MessageType};
|
||||
use crate::message::{ClientHelloData, EncryptedDataPayload, HandshakeData, LpMessage, MessageType};
|
||||
use crate::packet::{LpHeader, LpPacket, TRAILER_LEN};
|
||||
use crate::LpError;
|
||||
use bytes::BytesMut;
|
||||
@@ -43,18 +43,18 @@ pub fn parse_lp_packet(src: &[u8]) -> Result<LpPacket, LpError> {
|
||||
if message_size != 0 {
|
||||
return Err(LpError::InvalidPayloadSize {
|
||||
expected: 0,
|
||||
actual: message_size,
|
||||
actual: message_size,
|
||||
});
|
||||
}
|
||||
LpMessage::Busy
|
||||
}
|
||||
MessageType::Handshake => {
|
||||
// No size validation needed here for Handshake, it's variable
|
||||
LpMessage::Handshake(payload_slice.to_vec())
|
||||
LpMessage::Handshake(HandshakeData(payload_slice.to_vec()))
|
||||
}
|
||||
MessageType::EncryptedData => {
|
||||
// No size validation needed here for EncryptedData, it's variable
|
||||
LpMessage::EncryptedData(payload_slice.to_vec())
|
||||
LpMessage::EncryptedData(EncryptedDataPayload(payload_slice.to_vec()))
|
||||
}
|
||||
MessageType::ClientHello => {
|
||||
// ClientHello has structured data
|
||||
@@ -105,7 +105,7 @@ mod tests {
|
||||
// Import standalone functions
|
||||
use super::{parse_lp_packet, serialize_lp_packet};
|
||||
// Keep necessary imports
|
||||
use crate::message::{LpMessage, MessageType};
|
||||
use crate::message::{EncryptedDataPayload, HandshakeData, LpMessage, MessageType};
|
||||
use crate::packet::{LpHeader, LpPacket, TRAILER_LEN};
|
||||
use crate::LpError;
|
||||
use bytes::BytesMut;
|
||||
@@ -120,6 +120,7 @@ mod tests {
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 123,
|
||||
},
|
||||
@@ -150,10 +151,11 @@ mod tests {
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 123,
|
||||
},
|
||||
message: LpMessage::Handshake(payload.clone()),
|
||||
message: LpMessage::Handshake(HandshakeData(payload.clone())),
|
||||
trailer: [0; TRAILER_LEN],
|
||||
};
|
||||
|
||||
@@ -171,7 +173,7 @@ mod tests {
|
||||
// Verify message type and data
|
||||
match decoded.message {
|
||||
LpMessage::Handshake(decoded_payload) => {
|
||||
assert_eq!(decoded_payload, payload);
|
||||
assert_eq!(decoded_payload, HandshakeData(payload));
|
||||
}
|
||||
_ => panic!("Expected Handshake message"),
|
||||
}
|
||||
@@ -187,10 +189,11 @@ mod tests {
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 123,
|
||||
},
|
||||
message: LpMessage::EncryptedData(payload.clone()),
|
||||
message: LpMessage::EncryptedData(EncryptedDataPayload(payload.clone())),
|
||||
trailer: [0; TRAILER_LEN],
|
||||
};
|
||||
|
||||
@@ -208,7 +211,7 @@ mod tests {
|
||||
// Verify message type and data
|
||||
match decoded.message {
|
||||
LpMessage::EncryptedData(decoded_payload) => {
|
||||
assert_eq!(decoded_payload, payload);
|
||||
assert_eq!(decoded_payload, EncryptedDataPayload(payload));
|
||||
}
|
||||
_ => panic!("Expected EncryptedData message"),
|
||||
}
|
||||
@@ -387,11 +390,9 @@ mod tests {
|
||||
|
||||
// Create ClientHelloData
|
||||
let client_key = [42u8; 32];
|
||||
let protocol_version = 1u8;
|
||||
let salt = [99u8; 32];
|
||||
let hello_data = ClientHelloData {
|
||||
client_lp_public_key: client_key,
|
||||
protocol_version,
|
||||
salt,
|
||||
};
|
||||
|
||||
@@ -399,6 +400,7 @@ mod tests {
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 123,
|
||||
},
|
||||
@@ -421,7 +423,6 @@ mod tests {
|
||||
match decoded.message {
|
||||
LpMessage::ClientHello(decoded_data) => {
|
||||
assert_eq!(decoded_data.client_lp_public_key, client_key);
|
||||
assert_eq!(decoded_data.protocol_version, protocol_version);
|
||||
assert_eq!(decoded_data.salt, salt);
|
||||
}
|
||||
_ => panic!("Expected ClientHello message"),
|
||||
@@ -437,12 +438,13 @@ mod tests {
|
||||
|
||||
// Create ClientHelloData with fresh salt
|
||||
let client_key = [7u8; 32];
|
||||
let hello_data = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello_data = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
|
||||
// Create a ClientHello message packet
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 100,
|
||||
counter: 200,
|
||||
},
|
||||
@@ -460,7 +462,6 @@ mod tests {
|
||||
match decoded.message {
|
||||
LpMessage::ClientHello(decoded_data) => {
|
||||
assert_eq!(decoded_data.client_lp_public_key, client_key);
|
||||
assert_eq!(decoded_data.protocol_version, 1);
|
||||
assert_eq!(decoded_data.salt, hello_data.salt);
|
||||
|
||||
// Verify timestamp can be extracted
|
||||
@@ -531,13 +532,13 @@ mod tests {
|
||||
|
||||
let hello_data = ClientHelloData {
|
||||
client_lp_public_key: [version; 32],
|
||||
protocol_version: version,
|
||||
salt: [version.wrapping_add(1); 32],
|
||||
};
|
||||
|
||||
let packet = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: version as u32,
|
||||
counter: version as u64,
|
||||
},
|
||||
@@ -550,7 +551,6 @@ mod tests {
|
||||
|
||||
match decoded.message {
|
||||
LpMessage::ClientHello(decoded_data) => {
|
||||
assert_eq!(decoded_data.protocol_version, version);
|
||||
assert_eq!(decoded_data.client_lp_public_key, [version; 32]);
|
||||
}
|
||||
_ => panic!("Expected ClientHello message for version {}", version),
|
||||
|
||||
@@ -124,6 +124,7 @@ mod tests {
|
||||
let packet1 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42, // Matches session's sending_index assumption for this test
|
||||
counter: 0,
|
||||
},
|
||||
@@ -152,6 +153,7 @@ mod tests {
|
||||
let packet2 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 0, // Same counter as before (replay)
|
||||
},
|
||||
@@ -181,6 +183,7 @@ mod tests {
|
||||
let packet3 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 1, // Incremented counter
|
||||
},
|
||||
@@ -241,6 +244,7 @@ mod tests {
|
||||
let packet1 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: lp_id,
|
||||
counter: 0,
|
||||
},
|
||||
@@ -273,6 +277,7 @@ mod tests {
|
||||
let packet2 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: lp_id,
|
||||
counter: 1,
|
||||
},
|
||||
@@ -300,6 +305,7 @@ mod tests {
|
||||
let packet3 = LpPacket {
|
||||
header: LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: lp_id,
|
||||
counter: 0, // Replay of first packet
|
||||
},
|
||||
|
||||
@@ -10,8 +10,6 @@ use serde::{Deserialize, Serialize};
|
||||
pub struct ClientHelloData {
|
||||
/// Client's LP x25519 public key (32 bytes)
|
||||
pub client_lp_public_key: [u8; 32],
|
||||
/// Protocol version for future compatibility
|
||||
pub protocol_version: u8,
|
||||
/// Salt for PSK derivation (32 bytes: 8-byte timestamp + 24-byte nonce)
|
||||
pub salt: [u8; 32],
|
||||
}
|
||||
@@ -24,7 +22,7 @@ impl ClientHelloData {
|
||||
/// # Arguments
|
||||
/// * `client_lp_public_key` - Client's x25519 public key
|
||||
/// * `protocol_version` - Protocol version number
|
||||
pub fn new_with_fresh_salt(client_lp_public_key: [u8; 32], protocol_version: u8) -> Self {
|
||||
pub fn new_with_fresh_salt(client_lp_public_key: [u8; 32]) -> Self {
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
// Generate salt: timestamp + nonce
|
||||
@@ -43,7 +41,6 @@ impl ClientHelloData {
|
||||
|
||||
Self {
|
||||
client_lp_public_key,
|
||||
protocol_version,
|
||||
salt,
|
||||
}
|
||||
}
|
||||
@@ -89,11 +86,17 @@ impl MessageType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct HandshakeData(pub Vec<u8>);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EncryptedDataPayload(pub Vec<u8>);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LpMessage {
|
||||
Busy,
|
||||
Handshake(Vec<u8>),
|
||||
EncryptedData(Vec<u8>),
|
||||
Handshake(HandshakeData),
|
||||
EncryptedData(EncryptedDataPayload),
|
||||
ClientHello(ClientHelloData),
|
||||
}
|
||||
|
||||
@@ -112,17 +115,17 @@ impl LpMessage {
|
||||
pub fn payload(&self) -> &[u8] {
|
||||
match self {
|
||||
LpMessage::Busy => &[],
|
||||
LpMessage::Handshake(payload) => payload,
|
||||
LpMessage::EncryptedData(payload) => payload,
|
||||
LpMessage::ClientHello(_) => &[], // Structured data, serialized in encode_content
|
||||
LpMessage::Handshake(payload) => payload.0.as_slice(),
|
||||
LpMessage::EncryptedData(payload) => payload.0.as_slice(),
|
||||
LpMessage::ClientHello(_) => unimplemented!(), // Structured data, serialized in encode_content
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
LpMessage::Busy => true,
|
||||
LpMessage::Handshake(payload) => payload.is_empty(),
|
||||
LpMessage::EncryptedData(payload) => payload.is_empty(),
|
||||
LpMessage::Handshake(payload) => payload.0.is_empty(),
|
||||
LpMessage::EncryptedData(payload) => payload.0.is_empty(),
|
||||
LpMessage::ClientHello(_) => false, // Always has data
|
||||
}
|
||||
}
|
||||
@@ -130,8 +133,8 @@ impl LpMessage {
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
LpMessage::Busy => 0,
|
||||
LpMessage::Handshake(payload) => payload.len(),
|
||||
LpMessage::EncryptedData(payload) => payload.len(),
|
||||
LpMessage::Handshake(payload) => payload.0.len(),
|
||||
LpMessage::EncryptedData(payload) => payload.0.len(),
|
||||
LpMessage::ClientHello(_) => 65, // 32 bytes key + 1 byte version + 32 bytes salt
|
||||
}
|
||||
}
|
||||
@@ -149,10 +152,10 @@ impl LpMessage {
|
||||
match self {
|
||||
LpMessage::Busy => { /* No content */ }
|
||||
LpMessage::Handshake(payload) => {
|
||||
dst.put_slice(payload);
|
||||
dst.put_slice(&payload.0);
|
||||
}
|
||||
LpMessage::EncryptedData(payload) => {
|
||||
dst.put_slice(payload);
|
||||
dst.put_slice(&payload.0);
|
||||
}
|
||||
LpMessage::ClientHello(data) => {
|
||||
// Serialize ClientHelloData using bincode
|
||||
@@ -172,10 +175,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn encoding() {
|
||||
let message = LpMessage::EncryptedData(vec![11u8; 124]);
|
||||
let message = LpMessage::EncryptedData(EncryptedDataPayload(vec![11u8; 124]));
|
||||
|
||||
let resp_header = LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 0,
|
||||
counter: 0,
|
||||
};
|
||||
@@ -195,7 +199,7 @@ mod tests {
|
||||
// Verify correct data in message
|
||||
match &packet.message {
|
||||
LpMessage::EncryptedData(data) => {
|
||||
assert_eq!(*data, vec![11u8; 124]);
|
||||
assert_eq!(*data, EncryptedDataPayload(vec![11u8; 124]));
|
||||
}
|
||||
_ => panic!("Wrong message type"),
|
||||
}
|
||||
@@ -204,8 +208,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_client_hello_salt_generation() {
|
||||
let client_key = [1u8; 32];
|
||||
let hello1 = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello2 = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello1 = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
let hello2 = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
|
||||
// Different salts should be generated
|
||||
assert_ne!(hello1.salt, hello2.salt);
|
||||
@@ -219,7 +223,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_client_hello_timestamp_extraction() {
|
||||
let client_key = [2u8; 32];
|
||||
let hello = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
|
||||
let timestamp = hello.extract_timestamp();
|
||||
let now = std::time::SystemTime::now()
|
||||
@@ -234,7 +238,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_client_hello_salt_format() {
|
||||
let client_key = [3u8; 32];
|
||||
let hello = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
|
||||
// First 8 bytes should be non-zero timestamp
|
||||
let timestamp_bytes = &hello.salt[..8];
|
||||
|
||||
@@ -126,7 +126,7 @@ impl LpPacket {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LpHeader {
|
||||
pub protocol_version: u8,
|
||||
|
||||
pub reserved: u16,
|
||||
pub session_id: u32,
|
||||
pub counter: u64,
|
||||
}
|
||||
@@ -139,6 +139,7 @@ impl LpHeader {
|
||||
pub fn new(session_id: u32, counter: u64) -> Self {
|
||||
Self {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id,
|
||||
counter,
|
||||
}
|
||||
@@ -176,6 +177,7 @@ impl LpHeader {
|
||||
|
||||
Ok(LpHeader {
|
||||
protocol_version,
|
||||
reserved: 0,
|
||||
session_id,
|
||||
counter,
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//! This module implements session management functionality, including replay protection
|
||||
//! and Noise protocol state handling.
|
||||
|
||||
use crate::message::{EncryptedDataPayload, HandshakeData};
|
||||
use crate::noise_protocol::{NoiseError, NoiseProtocol, ReadResult};
|
||||
use crate::packet::LpHeader;
|
||||
use crate::replay::ReceivingKeyCounterValidator;
|
||||
@@ -178,7 +179,7 @@ impl LpSession {
|
||||
let mut noise_state = self.noise_state.lock();
|
||||
if let Some(message) = noise_state.get_bytes_to_send() {
|
||||
match message {
|
||||
Ok(message) => Some(Ok(LpMessage::Handshake(message))),
|
||||
Ok(message) => Some(Ok(LpMessage::Handshake(HandshakeData(message)))),
|
||||
Err(e) => Some(Err(LpError::NoiseError(e))),
|
||||
}
|
||||
} else {
|
||||
@@ -203,7 +204,7 @@ impl LpSession {
|
||||
let mut noise_state = self.noise_state.lock();
|
||||
|
||||
match message {
|
||||
LpMessage::Handshake(payload) => {
|
||||
LpMessage::Handshake(HandshakeData(payload)) => {
|
||||
// The sans-io NoiseProtocol::read_message expects only the payload.
|
||||
noise_state.read_message(payload)
|
||||
}
|
||||
@@ -235,7 +236,7 @@ impl LpSession {
|
||||
return Err(NoiseError::IncorrectStateError);
|
||||
}
|
||||
let payload = noise_state.write_message(payload)?;
|
||||
Ok(LpMessage::EncryptedData(payload))
|
||||
Ok(LpMessage::EncryptedData(EncryptedDataPayload(payload)))
|
||||
}
|
||||
|
||||
/// Decrypts an incoming Noise message containing application data.
|
||||
@@ -612,7 +613,7 @@ mod tests {
|
||||
// Attempt to decrypt before handshake (using dummy ciphertext)
|
||||
let dummy_ciphertext = vec![0u8; 32];
|
||||
let result_decrypt =
|
||||
initiator_session.decrypt_data(&LpMessage::EncryptedData(dummy_ciphertext));
|
||||
initiator_session.decrypt_data(&LpMessage::EncryptedData(EncryptedDataPayload(dummy_ciphertext)));
|
||||
assert!(result_decrypt.is_err());
|
||||
match result_decrypt.unwrap_err() {
|
||||
NoiseError::IncorrectStateError => {} // Expected error
|
||||
|
||||
@@ -21,6 +21,7 @@ mod tests {
|
||||
// Create the header
|
||||
let header = LpHeader {
|
||||
protocol_version,
|
||||
reserved: 0u16, // reserved
|
||||
session_id,
|
||||
counter,
|
||||
};
|
||||
@@ -307,7 +308,7 @@ mod tests {
|
||||
1,
|
||||
lp_id,
|
||||
counter_b,
|
||||
LpMessage::EncryptedData(plaintext_b_to_a.to_vec()), // Using plaintext here, but content doesn't matter for replay check
|
||||
LpMessage::EncryptedData(crate::message::EncryptedDataPayload(plaintext_b_to_a.to_vec())), // Using plaintext here, but content doesn't matter for replay check
|
||||
);
|
||||
let mut encoded_data_b_to_a_replay = BytesMut::new();
|
||||
serialize_lp_packet(&message_b_to_a_replay, &mut encoded_data_b_to_a_replay)
|
||||
|
||||
@@ -112,16 +112,22 @@ impl LpConnectionHandler {
|
||||
// Derive LP keypair from gateway's ed25519 identity using proper conversion
|
||||
// This creates a valid x25519 keypair for ECDH operations in Noise protocol
|
||||
let x25519_private = self.state.local_identity.private_key().to_x25519();
|
||||
let x25519_public = self.state.local_identity.public_key().to_x25519()
|
||||
.map_err(|e| GatewayError::LpHandshakeError(
|
||||
format!("Failed to convert ed25519 public key to x25519: {}", e)
|
||||
))?;
|
||||
let x25519_public = self
|
||||
.state
|
||||
.local_identity
|
||||
.public_key()
|
||||
.to_x25519()
|
||||
.map_err(|e| {
|
||||
GatewayError::LpHandshakeError(format!(
|
||||
"Failed to convert ed25519 public key to x25519: {}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
|
||||
let lp_private = LpPrivateKey::from_bytes(x25519_private.as_bytes());
|
||||
let lp_public = PublicKey::from_bytes(x25519_public.as_bytes())
|
||||
.map_err(|e| GatewayError::LpHandshakeError(
|
||||
format!("Failed to create LP public key: {}", e)
|
||||
))?;
|
||||
let lp_public = PublicKey::from_bytes(x25519_public.as_bytes()).map_err(|e| {
|
||||
GatewayError::LpHandshakeError(format!("Failed to create LP public key: {}", e))
|
||||
})?;
|
||||
|
||||
let gateway_keypair = Keypair::from_keys(lp_private, lp_public);
|
||||
|
||||
@@ -279,14 +285,6 @@ impl LpConnectionHandler {
|
||||
// Verify it's a ClientHello message
|
||||
match packet.message() {
|
||||
LpMessage::ClientHello(hello_data) => {
|
||||
// Validate protocol version (currently only v1)
|
||||
if hello_data.protocol_version != 1 {
|
||||
return Err(GatewayError::LpProtocolError(format!(
|
||||
"Unsupported protocol version: {}",
|
||||
hello_data.protocol_version
|
||||
)));
|
||||
}
|
||||
|
||||
// Extract and validate timestamp (nym-110: replay protection)
|
||||
let timestamp = hello_data.extract_timestamp();
|
||||
Self::validate_timestamp(timestamp, self.state.lp_config.timestamp_tolerance_secs)?;
|
||||
@@ -341,11 +339,9 @@ impl LpConnectionHandler {
|
||||
}
|
||||
|
||||
// Decrypt the packet payload using the established session
|
||||
let decrypted_bytes = session
|
||||
.decrypt_data(packet.message())
|
||||
.map_err(|e| {
|
||||
GatewayError::LpProtocolError(format!("Failed to decrypt registration request: {}", e))
|
||||
})?;
|
||||
let decrypted_bytes = session.decrypt_data(packet.message()).map_err(|e| {
|
||||
GatewayError::LpProtocolError(format!("Failed to decrypt registration request: {}", e))
|
||||
})?;
|
||||
|
||||
// Deserialize the decrypted bytes into LpRegistrationRequest
|
||||
bincode::deserialize(&decrypted_bytes).map_err(|e| {
|
||||
@@ -368,9 +364,9 @@ impl LpConnectionHandler {
|
||||
})?;
|
||||
|
||||
// Encrypt data first (this increments Noise internal counter)
|
||||
let encrypted_message = session.encrypt_data(&data).map_err(|e| {
|
||||
GatewayError::LpProtocolError(format!("Failed to encrypt data: {}", e))
|
||||
})?;
|
||||
let encrypted_message = session
|
||||
.encrypt_data(&data)
|
||||
.map_err(|e| GatewayError::LpProtocolError(format!("Failed to encrypt data: {}", e)))?;
|
||||
|
||||
// Create LP packet with encrypted message (this increments LP protocol counter)
|
||||
let packet = session.next_packet(encrypted_message).map_err(|e| {
|
||||
@@ -467,7 +463,10 @@ impl LpConnectionHandler {
|
||||
"lp_connection_bytes_received_total",
|
||||
self.stats.bytes_received as i64
|
||||
);
|
||||
inc_by!("lp_connection_bytes_sent_total", self.stats.bytes_sent as i64);
|
||||
inc_by!(
|
||||
"lp_connection_bytes_sent_total",
|
||||
self.stats.bytes_sent as i64
|
||||
);
|
||||
|
||||
// Track completion type
|
||||
if graceful {
|
||||
@@ -486,7 +485,7 @@ mod tests {
|
||||
use bytes::BytesMut;
|
||||
use nym_lp::codec::{parse_lp_packet, serialize_lp_packet};
|
||||
use nym_lp::keypair::Keypair;
|
||||
use nym_lp::message::{ClientHelloData, LpMessage};
|
||||
use nym_lp::message::{ClientHelloData, EncryptedDataPayload, HandshakeData, LpMessage};
|
||||
use nym_lp::packet::{LpHeader, LpPacket};
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
@@ -670,6 +669,7 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 42,
|
||||
counter: 0,
|
||||
},
|
||||
@@ -732,6 +732,7 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 99,
|
||||
counter: 5,
|
||||
},
|
||||
@@ -771,10 +772,11 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 100,
|
||||
counter: 10,
|
||||
},
|
||||
LpMessage::Handshake(handshake_data),
|
||||
LpMessage::Handshake(HandshakeData(handshake_data)),
|
||||
);
|
||||
handler.send_lp_packet(&packet).await
|
||||
});
|
||||
@@ -788,7 +790,7 @@ mod tests {
|
||||
assert_eq!(received.header().session_id, 100);
|
||||
assert_eq!(received.header().counter, 10);
|
||||
match received.message() {
|
||||
LpMessage::Handshake(data) => assert_eq!(data, &expected_data),
|
||||
LpMessage::Handshake(data) => assert_eq!(data, &HandshakeData(expected_data)),
|
||||
_ => panic!("Expected Handshake message"),
|
||||
}
|
||||
}
|
||||
@@ -811,10 +813,11 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 200,
|
||||
counter: 20,
|
||||
},
|
||||
LpMessage::EncryptedData(encrypted_payload),
|
||||
LpMessage::EncryptedData(EncryptedDataPayload(encrypted_payload)),
|
||||
);
|
||||
handler.send_lp_packet(&packet).await
|
||||
});
|
||||
@@ -828,7 +831,7 @@ mod tests {
|
||||
assert_eq!(received.header().session_id, 200);
|
||||
assert_eq!(received.header().counter, 20);
|
||||
match received.message() {
|
||||
LpMessage::EncryptedData(data) => assert_eq!(data, &expected_payload),
|
||||
LpMessage::EncryptedData(data) => assert_eq!(data, &EncryptedDataPayload(expected_payload)),
|
||||
_ => panic!("Expected EncryptedData message"),
|
||||
}
|
||||
}
|
||||
@@ -842,7 +845,7 @@ mod tests {
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
let client_key = [7u8; 32];
|
||||
let hello_data = ClientHelloData::new_with_fresh_salt(client_key, 1);
|
||||
let hello_data = ClientHelloData::new_with_fresh_salt(client_key);
|
||||
let expected_salt = hello_data.salt; // Clone salt before moving hello_data
|
||||
|
||||
let server_task = tokio::spawn(async move {
|
||||
@@ -853,6 +856,7 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 300,
|
||||
counter: 30,
|
||||
},
|
||||
@@ -872,7 +876,6 @@ mod tests {
|
||||
match received.message() {
|
||||
LpMessage::ClientHello(data) => {
|
||||
assert_eq!(data.client_lp_public_key, client_key);
|
||||
assert_eq!(data.protocol_version, 1);
|
||||
assert_eq!(data.salt, expected_salt);
|
||||
}
|
||||
_ => panic!("Expected ClientHello message"),
|
||||
@@ -899,13 +902,12 @@ mod tests {
|
||||
|
||||
// Create and send valid ClientHello
|
||||
let client_keypair = Keypair::default();
|
||||
let hello_data = ClientHelloData::new_with_fresh_salt(
|
||||
client_keypair.public_key().to_bytes(),
|
||||
1, // protocol version
|
||||
);
|
||||
let hello_data =
|
||||
ClientHelloData::new_with_fresh_salt(client_keypair.public_key().to_bytes());
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 0,
|
||||
counter: 0,
|
||||
},
|
||||
@@ -944,7 +946,7 @@ mod tests {
|
||||
// Create ClientHello with old timestamp
|
||||
let client_keypair = Keypair::default();
|
||||
let mut hello_data =
|
||||
ClientHelloData::new_with_fresh_salt(client_keypair.public_key().to_bytes(), 1);
|
||||
ClientHelloData::new_with_fresh_salt(client_keypair.public_key().to_bytes());
|
||||
|
||||
// Manually set timestamp to be very old (100 seconds ago)
|
||||
let old_timestamp = SystemTime::now()
|
||||
@@ -957,6 +959,7 @@ mod tests {
|
||||
let packet = LpPacket::new(
|
||||
LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
session_id: 0,
|
||||
counter: 0,
|
||||
},
|
||||
|
||||
@@ -235,7 +235,6 @@ impl LpRegistrationClient {
|
||||
// Step 1: Generate ClientHelloData with fresh salt (timestamp + nonce)
|
||||
let client_hello_data = nym_lp::ClientHelloData::new_with_fresh_salt(
|
||||
self.local_keypair.public_key().to_bytes(),
|
||||
1, // protocol_version
|
||||
);
|
||||
let salt = client_hello_data.salt;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user