diff --git a/crates/pdu/src/lib.rs b/crates/pdu/src/lib.rs index fa823174..7014e013 100644 --- a/crates/pdu/src/lib.rs +++ b/crates/pdu/src/lib.rs @@ -13,6 +13,7 @@ pub mod input; pub mod mcs; pub mod nego; pub mod padding; +pub mod pcb; pub mod rdp; pub mod tpdu; pub mod tpkt; @@ -23,10 +24,8 @@ pub(crate) mod basic_output; pub(crate) mod ber; pub(crate) mod crypto; pub(crate) mod per; -pub(crate) mod preconnection; pub use crate::basic_output::{bitmap, fast_path, surface_commands}; -pub use crate::preconnection::{PreconnectionPdu, PreconnectionPduError}; pub use crate::rdp::vc::dvc; pub type Result = core::result::Result; diff --git a/crates/pdu/src/pcb.rs b/crates/pdu/src/pcb.rs new file mode 100644 index 00000000..dfd02b86 --- /dev/null +++ b/crates/pdu/src/pcb.rs @@ -0,0 +1,303 @@ +//! This module contains the RDP_PRECONNECTION_PDU_V1 and RDP_PRECONNECTION_PDU_V2 structures. + +use crate::{cursor::ReadCursor, padding::Padding, Error, Pdu, PduDecode, PduEncode, Result}; + +/// Preconnection PDU version +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct PcbVersion(pub u32); + +impl PcbVersion { + pub const V1: Self = Self(0x1); + pub const V2: Self = Self(0x2); +} + +/// RDP preconnection PDU +/// +/// The RDP_PRECONNECTION_PDU_V1 is used by the client to let the listening process +/// know which RDP source the connection is intended for. +/// +/// The RDP_PRECONNECTION_PDU_V2 extends the RDP_PRECONNECTION_PDU_V1 packet by +/// adding a variable-size Unicode character string. The receiver of this PDU can +/// use this string and the Id field of the RDP_PRECONNECTION_PDU_V1 packet to +/// determine the RDP source. This string is opaque to the protocol. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PreconnectionBlob { + /// Preconnection PDU version + pub version: PcbVersion, + /// This field is used to uniquely identify the RDP source. Although the Id can be + /// as simple as a process ID, it is often client-specific or server-specific and + /// can be obfuscated. + pub id: u32, + /// V2 PCB string + pub v2_payload: Option, +} + +impl PreconnectionBlob { + pub const FIXED_PART_SIZE: usize = 16; +} + +impl Pdu for PreconnectionBlob { + const NAME: &'static str = "PreconnectionBlob"; +} + +impl<'de> PduDecode<'de> for PreconnectionBlob { + fn decode(src: &mut ReadCursor<'de>) -> Result { + ensure_fixed_part_size!(in: src); + + let pcb_size: usize = cast_length!(src.read_u32(), "cbSize")?; + + if pcb_size < Self::FIXED_PART_SIZE { + return Err(Error::InvalidMessage { + name: Self::NAME, + field: "cbSize", + reason: "advertised size too small for Preconnection PDU V1", + }); + } + + Padding::<4>::read(src); // flags + + // The version field SHOULD be initialized by the client and SHOULD be ignored by the server, + // as specified in sections 3.1.5.1 and 3.2.5.1. + // That’s why, following code doesn’t depend on the value of this field. + let version = PcbVersion(src.read_u32()); + + let id = src.read_u32(); + + let remaining_size = pcb_size - Self::FIXED_PART_SIZE; + + ensure_size!(in: src, size: remaining_size); + + if remaining_size >= 2 { + let cch_pcb = usize::from(src.read_u16()); + let cb_pcb = cch_pcb * 2; + + if remaining_size - 2 < cb_pcb { + return Err(Error::InvalidMessage { + name: Self::NAME, + field: "cchPCB", + reason: "PCB string bigger than advertised size", + }); + } + + let wsz_pcb_utf16 = src.read_slice(cb_pcb); + + let mut trimed_pcb_utf16: Vec = Vec::with_capacity(cch_pcb); + + for chunk in wsz_pcb_utf16.chunks_exact(2) { + let code_unit = u16::from_le_bytes([chunk[0], chunk[1]]); + + // Stop reading at the null terminator + if code_unit == 0 { + break; + } + + trimed_pcb_utf16.push(code_unit); + } + + let payload = String::from_utf16(&trimed_pcb_utf16).map_err(|_| Error::InvalidMessage { + name: Self::NAME, + field: "wszPCB", + reason: "invalid UTF-16", + })?; + + let leftover_size = remaining_size - 2 - cb_pcb; + src.advance(leftover_size); // Consume (unused) leftover data + + Ok(Self { + version, + id, + v2_payload: Some(payload), + }) + } else { + Ok(Self { + version, + id, + v2_payload: None, + }) + } + } +} + +impl PduEncode for PreconnectionBlob { + fn encode(&self, dst: &mut crate::cursor::WriteCursor<'_>) -> Result<()> { + if self.v2_payload.is_some() && self.version == PcbVersion::V1 { + return Err(Error::InvalidMessage { + name: Self::NAME, + field: "version", + reason: "there is no string payload in Preconnection PDU V1", + }); + } + + let pcb_size = self.size(); + + ensure_size!(in: dst, size: pcb_size); + + dst.write_u32(cast_length!(pcb_size, "cbSize")?); // cbSize + Padding::<4>::write(dst); // flags + dst.write_u32(self.version.0); // version + dst.write_u32(self.id); // id + + if let Some(v2_payload) = &self.v2_payload { + // cchPCB + let utf16_character_count = v2_payload.encode_utf16().count() + 1; // +1 for null terminator + dst.write_u16(cast_length!(utf16_character_count, "cchPCB")?); + + // wszPCB + v2_payload.encode_utf16().for_each(|c| dst.write_u16(c)); + dst.write_u16(0); // null terminator + } + + Ok(()) + } + + fn name(&self) -> &'static str { + Self::NAME + } + + fn size(&self) -> usize { + let fixed_part_size = Self::FIXED_PART_SIZE; + + let variable_part = if let Some(v2_payload) = &self.v2_payload { + let utf16_character_count = v2_payload.encode_utf16().count() + 1; // +1 for null terminator + 2 + utf16_character_count * 2 + } else { + 0 + }; + + fixed_part_size + variable_part + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const PRECONNECTION_PDU_V1_NULL_SIZE_BUF: [u8; 16] = [ + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x00 = 0 bytes + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 + 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 + 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 + ]; + const PRECONNECTION_PDU_V1_LARGE_SIZE_BUF: [u8; 16] = [ + 0xff, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0xff + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 + 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 + 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 + ]; + const PRECONNECTION_PDU_V1_BUF: [u8; 16] = [ + 0x10, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x10 = 16 bytes + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 + 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 + 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 + ]; + const PRECONNECTION_PDU_V2_LARGE_PAYLOAD_SIZE_BUF: [u8; 32] = [ + 0x20, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x20 = 32 bytes + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 + 0x02, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 2 + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Id = 0 + 0xff, 0x00, // -> RDP_PRECONNECTION_PDU_V2::cchPCB = 0xff + 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x00, + 0x00, // -> RDP_PRECONNECTION_PDU_V2::wszPCB -> "TestVM\0" + ]; + const PRECONNECTION_PDU_V2_BUF: [u8; 32] = [ + 0x20, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x20 = 32 bytes + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 + 0x02, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 2 + 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Id = 0 + 0x07, 0x00, // -> RDP_PRECONNECTION_PDU_V2::cchPCB = 0x7 = 7 characters + 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x00, + 0x00, // -> RDP_PRECONNECTION_PDU_V2::wszPCB -> "TestVM\0" + ]; + + const PRECONNECTION_PDU_V1: PreconnectionBlob = PreconnectionBlob { + version: PcbVersion::V1, + id: 4_005_992_939, + v2_payload: None, + }; + + lazy_static::lazy_static! { + static ref PRECONNECTION_PDU_V2: PreconnectionBlob = PreconnectionBlob { + version: PcbVersion::V2, + id: 0, + v2_payload: Some(String::from("TestVM")), + }; + } + + #[test] + fn null_size() { + let e = crate::decode::(&PRECONNECTION_PDU_V1_NULL_SIZE_BUF) + .err() + .unwrap(); + + if let Error::InvalidMessage { field, reason, .. } = e { + assert_eq!(field, "cbSize"); + assert_eq!(reason, "advertised size too small for Preconnection PDU V1"); + } else { + panic!("unexpected error: {e}"); + } + } + + #[test] + fn truncated() { + let e = crate::decode::(&PRECONNECTION_PDU_V1_LARGE_SIZE_BUF) + .err() + .unwrap(); + + if let Error::NotEnoughBytes { received, expected, .. } = e { + assert_eq!(received, 0); + assert_eq!(expected, 239); + } else { + panic!("unexpected error: {e}"); + } + } + + #[test] + fn v1_decode() { + let pcb = crate::decode::(&PRECONNECTION_PDU_V1_BUF).unwrap(); + assert_eq!(pcb, PRECONNECTION_PDU_V1); + } + + #[test] + fn v1_encode() { + let mut buf = Vec::new(); + crate::encode_buf(&PRECONNECTION_PDU_V1, &mut buf).unwrap(); + assert_eq!(buf, PRECONNECTION_PDU_V1_BUF); + } + + #[test] + fn v1_size() { + assert_eq!(PRECONNECTION_PDU_V1.size(), PRECONNECTION_PDU_V1_BUF.len()); + } + + #[test] + fn v2_string_too_big() { + let e = crate::decode::(&PRECONNECTION_PDU_V2_LARGE_PAYLOAD_SIZE_BUF) + .err() + .unwrap(); + + if let Error::InvalidMessage { field, reason, .. } = e { + assert_eq!(field, "cchPCB"); + assert_eq!(reason, "PCB string bigger than advertised size"); + } else { + panic!("unexpected error: {e}"); + } + } + + #[test] + fn v2_decode() { + let pcb = crate::decode::(&PRECONNECTION_PDU_V2_BUF).unwrap(); + assert_eq!(pcb, *PRECONNECTION_PDU_V2); + } + + #[test] + fn v2_encode() { + let mut buf = Vec::new(); + crate::encode_buf(&*PRECONNECTION_PDU_V2, &mut buf).unwrap(); + assert_eq!(buf, PRECONNECTION_PDU_V2_BUF); + } + + #[test] + fn v2_size() { + assert_eq!(PRECONNECTION_PDU_V2.size(), PRECONNECTION_PDU_V2_BUF.len()); + } +} diff --git a/crates/pdu/src/preconnection.rs b/crates/pdu/src/preconnection.rs deleted file mode 100644 index 42197ebf..00000000 --- a/crates/pdu/src/preconnection.rs +++ /dev/null @@ -1,251 +0,0 @@ -use std::io; - -use byteorder::{LittleEndian, ReadBytesExt as _, WriteBytesExt as _}; -use num_derive::{FromPrimitive, ToPrimitive}; -use num_traits::{FromPrimitive as _, ToPrimitive as _}; -use thiserror::Error; - -use crate::utils::{self, SplitTo}; -use crate::PduBufferParsing; - -const PRECONNECTION_PDU_V1_SIZE: usize = 16; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct PreconnectionPdu { - pub id: u32, - pub cch_pcb: u16, - pub payload: Option, -} - -impl PreconnectionPdu {} - -impl PduBufferParsing<'_> for PreconnectionPdu { - type Error = PreconnectionPduError; - - fn from_buffer_consume(buffer: &mut &[u8]) -> Result { - if buffer.len() < PRECONNECTION_PDU_V1_SIZE { - return Err(PreconnectionPduError::IoError(io::Error::new( - io::ErrorKind::UnexpectedEof, - "More data required to parse Preconnection PDU header", - ))); - } - - let size = buffer.read_u32::()? as usize; - - if (size % 2 != 0) || (size < PRECONNECTION_PDU_V1_SIZE) { - return Err(PreconnectionPduError::InvalidHeader); - } - - buffer.read_u32::()?; // flags - let version = buffer.read_u32::()?; - let version = Version::from_u32(version).ok_or(PreconnectionPduError::UnexpectedVersion(version))?; - - let id = buffer.read_u32::()?; - - let remaining_size = size - PRECONNECTION_PDU_V1_SIZE; - - if buffer.len() < remaining_size { - return Err(PreconnectionPduError::IoError(io::Error::new( - io::ErrorKind::UnexpectedEof, - "More data required to parse Preconnection PDU payload", - ))); - } - - let mut buffer = buffer.split_to(remaining_size); - - let (cch_pcb, payload) = match version { - Version::V1 => (0, None), - Version::V2 => { - let cch_pcb = buffer.read_u16::()?; - if buffer.len() < usize::from(cch_pcb) * 2 { - return Err(PreconnectionPduError::InvalidHeader); - } - - let payload_bytes = buffer.split_to(usize::from(cch_pcb) * 2); - let payload = utils::from_utf16_bytes(payload_bytes).trim_end_matches('\0').into(); - - (cch_pcb, Some(payload)) - } - }; - - Ok(Self { id, cch_pcb, payload }) - } - - fn to_buffer_consume(&self, buffer: &mut &mut [u8]) -> Result<(), Self::Error> { - let size = self.buffer_length(); - - buffer.write_u32::(size as u32)?; - buffer.write_u32::(0)?; // flags - buffer.write_u32::(Version::from(self).to_u32().unwrap())?; - buffer.write_u32::(self.id)?; - - if let Some(ref payload) = self.payload { - buffer.write_u16::(payload.len() as u16 + 1)?; // + null terminator - utils::write_string_with_null_terminator(buffer, payload.as_str(), utils::CharacterSet::Unicode)?; - } - - Ok(()) - } - - fn buffer_length(&self) -> usize { - let cch_pcb = if self.cch_pcb > 0 { - self.cch_pcb as usize - } else { - self.payload.as_ref().map(|p| (p.len() + 1)).unwrap_or(0) - }; - - let version: Version = self.into(); - - match version { - Version::V1 => PRECONNECTION_PDU_V1_SIZE, - Version::V2 => PRECONNECTION_PDU_V1_SIZE + 2 + (cch_pcb * 2), - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, FromPrimitive, ToPrimitive)] -enum Version { - V1 = 0x1, - V2 = 0x2, -} - -impl From<&PreconnectionPdu> for Version { - fn from(p: &PreconnectionPdu) -> Self { - if p.payload.is_some() { - Self::V2 - } else { - Self::V1 - } - } -} - -#[derive(Debug, Error)] -pub enum PreconnectionPduError { - #[error("IO error")] - IoError(#[from] io::Error), - #[error("Provided data is not an valid preconnection Pdu")] - InvalidHeader, - #[error("Unexpected version: {0}")] - UnexpectedVersion(u32), -} - -#[cfg(test)] -mod tests { - use lazy_static::lazy_static; - - use super::*; - - const PRECONNECTION_PDU_V1_EMPTY_SIZE_BUFFER: [u8; 16] = [ - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x00 = 0 bytes - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 - 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 - 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 - ]; - const PRECONNECTION_PDU_V1_LARGE_DATA_LENGTH_BUFFER: [u8; 16] = [ - 0xff, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0xff - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 - 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 - 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 - ]; - const PRECONNECTION_PDU_V1_BUFFER: [u8; 16] = [ - 0x10, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x10 = 16 bytes - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 - 0x01, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 1 - 0xeb, 0x99, 0xc6, 0xee, // -> RDP_PRECONNECTION_PDU_V1::Id = 0xEEC699EB = 4005992939 - ]; - const PRECONNECTION_PDU_V2_LARGE_PAYLOAD_SIZE_BUFFER: [u8; 32] = [ - 0x20, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x20 = 32 bytes - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 - 0x02, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 2 - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Id = 0 - 0xff, 0x00, // -> RDP_PRECONNECTION_PDU_V2::cchPCB = 0xff - 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x00, - 0x00, // -> RDP_PRECONNECTION_PDU_V2::wszPCB -> "TestVM" (including null terminator) - ]; - const PRECONNECTION_PDU_V2_BUFFER: [u8; 32] = [ - 0x20, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::cbSize = 0x20 = 32 bytes - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Flags = 0 - 0x02, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Version = 2 - 0x00, 0x00, 0x00, 0x00, // -> RDP_PRECONNECTION_PDU_V1::Id = 0 - 0x07, 0x00, // -> RDP_PRECONNECTION_PDU_V2::cchPCB = 0x7 = 7 characters - 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x56, 0x00, 0x4d, 0x00, 0x00, - 0x00, // -> RDP_PRECONNECTION_PDU_V2::wszPCB -> "TestVM" (including null terminator) - ]; - - const PRECONNECTION_PDU_V1: PreconnectionPdu = PreconnectionPdu { - id: 4_005_992_939, - cch_pcb: 0, - payload: None, - }; - - lazy_static! { - static ref PRECONNECTION_PDU_V2: PreconnectionPdu = PreconnectionPdu { - id: 0, - cch_pcb: 7, - payload: Some(String::from("TestVM")), - }; - } - - #[test] - fn from_buffer_for_preconnection_pdu_returns_error_on_empty_size() { - assert!(PreconnectionPdu::from_buffer(PRECONNECTION_PDU_V1_EMPTY_SIZE_BUFFER.as_ref()).is_err()); - } - - #[test] - fn from_buffer_for_preconnection_pdu_returns_error_on_data_length_greater_then_available_data() { - assert!(PreconnectionPdu::from_buffer(PRECONNECTION_PDU_V1_LARGE_DATA_LENGTH_BUFFER.as_ref()).is_err()); - } - - #[test] - fn from_buffer_correctly_parses_preconnection_pdu_v1() { - assert_eq!( - PRECONNECTION_PDU_V1, - PreconnectionPdu::from_buffer(PRECONNECTION_PDU_V1_BUFFER.as_ref()).unwrap() - ); - } - - #[test] - fn to_buffer_correctly_serializes_preconnection_pdu_v1() { - let expected = PRECONNECTION_PDU_V1_BUFFER.as_ref(); - let mut buffer = vec![0; expected.len()]; - - PRECONNECTION_PDU_V1 - .to_buffer_consume(&mut buffer.as_mut_slice()) - .unwrap(); - assert_eq!(expected, buffer.as_slice()); - } - - #[test] - fn buffer_length_is_correct_for_preconnection_pdu_v1() { - assert_eq!(PRECONNECTION_PDU_V1_BUFFER.len(), PRECONNECTION_PDU_V1.buffer_length()); - } - - #[test] - fn from_buffer_for_preconnection_pdu_v2_returns_error_on_payload_size_greater_then_available_data() { - assert!(PreconnectionPdu::from_buffer(PRECONNECTION_PDU_V2_LARGE_PAYLOAD_SIZE_BUFFER.as_ref()).is_err()); - } - - #[test] - fn from_buffer_correctly_parses_preconnection_pdu_v2() { - assert_eq!( - *PRECONNECTION_PDU_V2, - PreconnectionPdu::from_buffer(PRECONNECTION_PDU_V2_BUFFER.as_ref()).unwrap() - ); - } - - #[test] - fn to_buffer_correctly_serializes_preconnection_pdu_v2() { - let expected = PRECONNECTION_PDU_V2_BUFFER.as_ref(); - let mut buffer = vec![0; expected.len()]; - - PRECONNECTION_PDU_V2 - .to_buffer_consume(&mut buffer.as_mut_slice()) - .unwrap(); - assert_eq!(expected, buffer.as_slice()); - } - - #[test] - fn buffer_length_is_correct_for_preconnection_pdu_v2() { - assert_eq!(PRECONNECTION_PDU_V2_BUFFER.len(), PRECONNECTION_PDU_V2.buffer_length()); - } -} diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 232e61a3..443fb686 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -24,7 +24,6 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time", ] [[package]] @@ -56,6 +55,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bit_field" version = "0.10.2" @@ -110,6 +115,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + [[package]] name = "cpufeatures" version = "0.2.5" @@ -130,10 +141,16 @@ dependencies = [ ] [[package]] -name = "data-encoding" -version = "2.3.3" +name = "der" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" +checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "zeroize", +] [[package]] name = "der-parser" @@ -144,11 +161,22 @@ dependencies = [ "asn1-rs", "displaydoc", "nom", - "num-bigint", "num-traits", "rusticata-macros", ] +[[package]] +name = "der_derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "114792ba6b7545d3f3dd693794aed3a312a67795cd577fcc725c148d84fabe32" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "derive_arbitrary" version = "1.2.3" @@ -181,6 +209,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "flagset" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" + [[package]] name = "funty" version = "2.0.0" @@ -238,15 +272,9 @@ dependencies = [ "sha1", "tap", "thiserror", - "x509-parser", + "x509-cert", ] -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - [[package]] name = "jobserver" version = "0.1.26" @@ -351,21 +379,36 @@ dependencies = [ "autocfg", ] -[[package]] -name = "oid-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" -dependencies = [ - "asn1-rs", -] - [[package]] name = "once_cell" version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.56" @@ -399,12 +442,6 @@ dependencies = [ "nom", ] -[[package]] -name = "serde" -version = "1.0.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" - [[package]] name = "sha1" version = "0.10.5" @@ -416,6 +453,16 @@ dependencies = [ "digest", ] +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "syn" version = "1.0.109" @@ -476,33 +523,6 @@ dependencies = [ "syn 2.0.15", ] -[[package]] -name = "time" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - -[[package]] -name = "time-macros" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" -dependencies = [ - "time-core", -] - [[package]] name = "typenum" version = "1.16.0" @@ -537,18 +557,18 @@ dependencies = [ ] [[package]] -name = "x509-parser" -version = "0.15.0" +name = "x509-cert" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab0c2f54ae1d92f4fcb99c0b7ccf0b1e3451cbd395e5f115ccbdbcb18d4f634" +checksum = "0103e822c47e037cb45b34873a31e33181dc4db3a97123b2ecce49c6d4081bab" dependencies = [ - "asn1-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "rusticata-macros", - "thiserror", - "time", + "const-oid", + "der", + "spki", ] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/fuzz/fuzz_targets/pdu_decoding.rs b/fuzz/fuzz_targets/pdu_decoding.rs index 3c861139..0500541a 100644 --- a/fuzz/fuzz_targets/pdu_decoding.rs +++ b/fuzz/fuzz_targets/pdu_decoding.rs @@ -15,7 +15,7 @@ fuzz_target!(|data: &[u8]| { let _ = ClientInfoPdu::from_buffer(data); let _ = capability_sets::CapabilitySet::from_buffer(data); let _ = headers::ShareControlHeader::from_buffer(data); - let _ = PreconnectionPdu::from_buffer(data); + let _ = decode::(data); let _ = server_error_info::ServerSetErrorInfoPdu::from_buffer(data); let _ = gcc::ClientGccBlocks::from_buffer(data);