use bytes::Bytes;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TlsClientHello {
pub record_version: TlsVersion,
pub legacy_version: TlsVersion,
pub random: [u8; 32],
pub session_id: Bytes,
pub cipher_suites: Vec<u16>,
pub compression: Bytes,
pub sni: Option<String>,
pub alpn: Vec<String>,
pub supported_versions: Vec<TlsVersion>,
pub supported_groups: Vec<u16>,
pub extension_types: Vec<u16>,
}
impl TlsClientHello {
pub fn sni(&self) -> Option<&str> {
self.sni.as_deref()
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TlsServerHello {
pub record_version: TlsVersion,
pub legacy_version: TlsVersion,
pub random: [u8; 32],
pub session_id: Bytes,
pub cipher_suite: u16,
pub compression: u8,
pub alpn: Option<String>,
pub supported_version: Option<TlsVersion>,
}
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TlsAlert {
pub level: TlsAlertLevel,
pub description: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(tag = "kind", content = "value", rename_all = "snake_case")
)]
pub enum TlsAlertLevel {
Warning,
Fatal,
Other(u8),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(tag = "kind", content = "value", rename_all = "snake_case")
)]
pub enum TlsVersion {
Ssl3_0,
Tls1_0,
Tls1_1,
Tls1_2,
Tls1_3,
Other(u16),
}
impl TlsVersion {
pub fn from_raw(v: u16) -> Self {
match v {
0x0300 => TlsVersion::Ssl3_0,
0x0301 => TlsVersion::Tls1_0,
0x0302 => TlsVersion::Tls1_1,
0x0303 => TlsVersion::Tls1_2,
0x0304 => TlsVersion::Tls1_3,
other => TlsVersion::Other(other),
}
}
pub fn to_raw(self) -> u16 {
match self {
TlsVersion::Ssl3_0 => 0x0300,
TlsVersion::Tls1_0 => 0x0301,
TlsVersion::Tls1_1 => 0x0302,
TlsVersion::Tls1_2 => 0x0303,
TlsVersion::Tls1_3 => 0x0304,
TlsVersion::Other(v) => v,
}
}
}
#[derive(Debug, Clone)]
pub struct TlsConfig {
pub ja3: bool,
pub ja4: bool,
pub max_buffer: usize,
}
impl Default for TlsConfig {
fn default() -> Self {
Self {
ja3: false,
ja4: false,
max_buffer: 64 * 1024,
}
}
}