ensure packets with incompatible versions are rejected (#6326)
This commit is contained in:
committed by
GitHub
parent
1a3c1fa466
commit
3b75af34e8
+23
-23
@@ -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,
|
||||
},
|
||||
|
||||
@@ -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 },
|
||||
}
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -603,7 +603,7 @@ mod tests {
|
||||
|
||||
let resp_header = LpHeader {
|
||||
protocol_version: 1,
|
||||
reserved: 0,
|
||||
reserved: [0u8; 3],
|
||||
receiver_idx: 0,
|
||||
counter: 0,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ mod tests {
|
||||
// Create the header
|
||||
let header = LpHeader {
|
||||
protocol_version,
|
||||
reserved: 0u16, // reserved
|
||||
reserved: [0u8; 3], // reserved
|
||||
receiver_idx,
|
||||
counter,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user