changed ClientHelloData serialisation
the old variant using bincode did not produce constant-length output in some cases
This commit is contained in:
@@ -111,9 +111,7 @@ fn parse_message_from_type_and_content(
|
||||
content.to_vec(),
|
||||
))),
|
||||
MessageType::ClientHello => {
|
||||
let data: ClientHelloData = lp_bincode_serializer()
|
||||
.deserialize(content)
|
||||
.map_err(|e| LpError::DeserializationError(e.to_string()))?;
|
||||
let data = ClientHelloData::decode(content)?;
|
||||
Ok(LpMessage::ClientHello(data))
|
||||
}
|
||||
MessageType::KKTRequest => Ok(LpMessage::KKTRequest(KKTRequestData(content.to_vec()))),
|
||||
@@ -791,7 +789,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_client_hello_malformed_bincode() {
|
||||
fn test_parse_client_hello_malformed_data() {
|
||||
// Create a buffer with ClientHello message type but invalid bincode data
|
||||
let mut buf = BytesMut::new();
|
||||
buf.extend_from_slice(&[1, 0, 0, 0]); // Version + reserved
|
||||
@@ -799,15 +797,15 @@ mod tests {
|
||||
buf.extend_from_slice(&123u64.to_le_bytes()); // Counter
|
||||
buf.extend_from_slice(&MessageType::ClientHello.to_u32().to_le_bytes()); // ClientHello type
|
||||
|
||||
// Add malformed bincode data (random bytes that won't deserialize to ClientHelloData)
|
||||
buf.extend_from_slice(&[0xFF; 50]); // Invalid bincode data
|
||||
// Add data that does not equal to ClientHelloData::LEN
|
||||
buf.extend_from_slice(&[0xFF; 50]); // invalid data
|
||||
buf.extend_from_slice(&[0; TRAILER_LEN]); // Trailer
|
||||
|
||||
// Attempt to parse
|
||||
let result = parse_lp_packet(&buf, None);
|
||||
assert!(result.is_err());
|
||||
match result {
|
||||
Err(LpError::DeserializationError(_)) => {} // Expected error
|
||||
Err(LpError::DeserializationError(msg)) => {} // Expected error
|
||||
Err(e) => panic!("Expected DeserializationError, got {:?}", e),
|
||||
Ok(_) => panic!("Expected error, but got Ok"),
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::LpError;
|
||||
use crate::serialisation::{BincodeOptions, lp_bincode_serializer};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
@@ -22,6 +23,8 @@ pub struct ClientHelloData {
|
||||
}
|
||||
|
||||
impl ClientHelloData {
|
||||
pub const LEN: usize = 100;
|
||||
|
||||
/// Generates a new ClientHelloData with fresh salt.
|
||||
///
|
||||
/// Salt format: 8 bytes timestamp (u64 LE) + 24 bytes random nonce
|
||||
@@ -61,6 +64,33 @@ impl ClientHelloData {
|
||||
timestamp_bytes.copy_from_slice(&self.salt[..8]);
|
||||
u64::from_le_bytes(timestamp_bytes)
|
||||
}
|
||||
|
||||
pub fn encode(&self) -> Vec<u8> {
|
||||
let mut out = Vec::with_capacity(Self::LEN);
|
||||
out.put_u32_le(self.receiver_index);
|
||||
out.put_slice(&self.client_lp_public_key);
|
||||
out.put_slice(&self.client_ed25519_public_key);
|
||||
out.put_slice(&self.salt);
|
||||
out
|
||||
}
|
||||
pub fn decode(b: &[u8]) -> Result<Self, LpError> {
|
||||
if b.len() != Self::LEN {
|
||||
return Err(LpError::DeserializationError(format!(
|
||||
"Expected {} bytes to deserialise ClientHelloData. got {}",
|
||||
Self::LEN,
|
||||
b.len()
|
||||
)));
|
||||
}
|
||||
|
||||
// SAFETY: we checked for valid byte lengths
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Ok(ClientHelloData {
|
||||
receiver_index: u32::from_le_bytes([b[0], b[1], b[2], b[3]]),
|
||||
client_lp_public_key: b[4..36].try_into().unwrap(),
|
||||
client_ed25519_public_key: b[36..68].try_into().unwrap(),
|
||||
salt: b[68..].try_into().unwrap(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
|
||||
@@ -238,8 +268,8 @@ impl LpMessage {
|
||||
LpMessage::Busy => 0,
|
||||
LpMessage::Handshake(payload) => payload.0.len(),
|
||||
LpMessage::EncryptedData(payload) => payload.0.len(),
|
||||
// 4 bytes receiver_index + 32 bytes x25519 key + 32 bytes ed25519 key + 32 bytes salt + bincode overhead
|
||||
LpMessage::ClientHello(_) => 101,
|
||||
// 4 bytes receiver_index + 32 bytes x25519 key + 32 bytes ed25519 key + 32 bytes salt
|
||||
LpMessage::ClientHello(_) => ClientHelloData::LEN,
|
||||
LpMessage::KKTRequest(payload) => payload.0.len(),
|
||||
LpMessage::KKTResponse(payload) => payload.0.len(),
|
||||
LpMessage::ForwardPacket(data) => {
|
||||
@@ -286,11 +316,7 @@ impl LpMessage {
|
||||
dst.put_slice(&payload.0);
|
||||
}
|
||||
LpMessage::ClientHello(data) => {
|
||||
// Serialize ClientHelloData using bincode
|
||||
let serialized = lp_bincode_serializer()
|
||||
.serialize(data)
|
||||
.expect("Failed to serialize ClientHelloData");
|
||||
dst.put_slice(&serialized);
|
||||
dst.put_slice(&data.encode());
|
||||
}
|
||||
LpMessage::KKTRequest(payload) => {
|
||||
dst.put_slice(&payload.0);
|
||||
|
||||
Reference in New Issue
Block a user