ensure packets with incompatible versions are rejected (#6326)

This commit is contained in:
Jędrzej Stuczyński
2026-01-16 08:58:20 +00:00
committed by GitHub
parent 1a3c1fa466
commit 3b75af34e8
7 changed files with 79 additions and 44 deletions
+23 -23
View File
@@ -164,7 +164,7 @@ pub fn parse_lp_packet(src: &[u8], outer_key: Option<&OuterAeadKey>) -> Result<L
let header = LpHeader {
protocol_version,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: outer_header.receiver_idx,
counter: outer_header.counter,
};
@@ -208,7 +208,7 @@ pub fn parse_lp_packet(src: &[u8], outer_key: Option<&OuterAeadKey>) -> Result<L
let header = LpHeader {
protocol_version,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: outer_header.receiver_idx,
counter: outer_header.counter,
};
@@ -336,7 +336,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 123,
},
@@ -367,7 +367,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 123,
},
@@ -405,7 +405,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 123,
},
@@ -620,7 +620,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 123,
},
@@ -670,7 +670,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 100,
counter: 200,
},
@@ -766,7 +766,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: version as u32,
counter: version as u64,
},
@@ -799,7 +799,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 999,
counter: 555,
},
@@ -837,7 +837,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 999,
},
@@ -866,7 +866,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 999,
},
@@ -913,7 +913,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 999,
},
@@ -942,7 +942,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 999,
},
@@ -971,7 +971,7 @@ mod tests {
let packet1 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 1,
},
@@ -982,7 +982,7 @@ mod tests {
let packet2 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 2, // Different counter
},
@@ -1017,7 +1017,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 12345,
counter: 999,
},
@@ -1043,7 +1043,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 54321,
counter: 12345678,
},
@@ -1076,7 +1076,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 99999,
counter: 2,
},
@@ -1106,7 +1106,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 100,
},
@@ -1135,7 +1135,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 123,
counter: 456,
},
@@ -1168,7 +1168,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 789,
counter: 1000,
},
@@ -1201,7 +1201,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 200,
},
@@ -1256,7 +1256,7 @@ mod tests {
let packet = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 54321,
counter: 999,
},
+8
View File
@@ -82,4 +82,12 @@ pub enum LpError {
/// Outer AEAD authentication tag verification failed.
#[error("AEAD authentication tag verification failed")]
AeadTagMismatch,
/// Received an LP packet with an incompatible, future, version
#[error("incompatible LP packet version. got: {got}, highest supported: {highest_supported}")]
IncompatibleFuturePacketVersion { got: u8, highest_supported: u8 },
/// Received an LP packet with an incompatible, legacy, version
#[error("incompatible LP packet version. got: {got}, lowest supported: {lowest_supported}")]
IncompatibleLegacyPacketVersion { got: u8, lowest_supported: u8 },
}
+6 -6
View File
@@ -100,7 +100,7 @@ mod tests {
let packet1 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42, // Matches session's sending_index assumption for this test
counter: 0,
},
@@ -129,7 +129,7 @@ mod tests {
let packet2 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 0, // Same counter as before (replay)
},
@@ -159,7 +159,7 @@ mod tests {
let packet3 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 1, // Incremented counter
},
@@ -238,7 +238,7 @@ mod tests {
let packet1 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: receiver_index,
counter: 0,
},
@@ -271,7 +271,7 @@ mod tests {
let packet2 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: receiver_index,
counter: 1,
},
@@ -299,7 +299,7 @@ mod tests {
let packet3 = LpPacket {
header: LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: receiver_index,
counter: 0, // Replay of first packet
},
+1 -1
View File
@@ -603,7 +603,7 @@ mod tests {
let resp_header = LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 0,
counter: 0,
};
+33 -6
View File
@@ -10,6 +10,7 @@ use parking_lot::Mutex;
use std::fmt::Write;
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
use tracing::warn;
#[allow(dead_code)]
pub(crate) const UDP_HEADER_LEN: usize = 8;
@@ -25,6 +26,11 @@ pub const TRAILER_LEN: usize = 16;
#[allow(dead_code)]
pub(crate) const UDP_PAYLOAD_SIZE: usize = MTU - UDP_OVERHEAD - TRAILER_LEN;
pub mod version {
/// The current version of the Lewes Protocol that is put into each new constructed header.
pub const CURRENT: u8 = 1;
}
#[derive(Clone)]
pub struct LpPacket {
pub(crate) header: LpHeader,
@@ -187,7 +193,7 @@ impl OuterHeader {
#[derive(Debug, Clone)]
pub struct LpHeader {
pub protocol_version: u8,
pub reserved: u16,
pub reserved: [u8; 3],
pub receiver_idx: u32,
pub counter: u64,
}
@@ -199,8 +205,8 @@ impl LpHeader {
impl LpHeader {
pub fn new(receiver_idx: u32, counter: u64) -> Self {
Self {
protocol_version: 1,
reserved: 0,
protocol_version: version::CURRENT,
reserved: [0u8; 3],
receiver_idx,
counter,
}
@@ -211,7 +217,7 @@ impl LpHeader {
dst.put_u8(self.protocol_version);
// reserved
dst.put_slice(&[0, 0, 0]);
dst.put_slice(&self.reserved);
// sender index
dst.put_slice(&self.receiver_idx.to_le_bytes());
@@ -226,7 +232,28 @@ impl LpHeader {
}
let protocol_version = src[0];
// Skip reserved bytes [1..4]
// Ensure we are using compatible protocol
// right now only support a single version
if protocol_version > version::CURRENT {
return Err(LpError::IncompatibleFuturePacketVersion {
got: protocol_version,
highest_supported: version::CURRENT,
});
}
if protocol_version < version::CURRENT {
return Err(LpError::IncompatibleLegacyPacketVersion {
got: protocol_version,
lowest_supported: version::CURRENT,
});
}
// skip reserved bytes, but log if they're different from the expected zeroes
let reserved = [src[1], src[2], src[3]];
if reserved != [0u8; 3] {
warn!("received non-zero reserved bytes. got: {reserved:?}");
}
let mut receiver_idx_bytes = [0u8; 4];
receiver_idx_bytes.copy_from_slice(&src[4..8]);
@@ -238,7 +265,7 @@ impl LpHeader {
Ok(LpHeader {
protocol_version,
reserved: 0,
reserved: [0u8; 3],
receiver_idx,
counter,
})
+1 -1
View File
@@ -21,7 +21,7 @@ mod tests {
// Create the header
let header = LpHeader {
protocol_version,
reserved: 0u16, // reserved
reserved: [0u8; 3], // reserved
receiver_idx,
counter,
};
+7 -7
View File
@@ -1520,7 +1520,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 42,
counter: 0,
},
@@ -1586,7 +1586,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 99,
counter: 5,
},
@@ -1626,7 +1626,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 100,
counter: 10,
},
@@ -1667,7 +1667,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 200,
counter: 20,
},
@@ -1719,7 +1719,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 300,
counter: 30,
},
@@ -1784,7 +1784,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 0,
counter: 0,
},
@@ -1854,7 +1854,7 @@ mod tests {
let packet = LpPacket::new(
LpHeader {
protocol_version: 1,
reserved: 0,
reserved: [0u8; 3],
receiver_idx: 0,
counter: 0,
},