SaiTLS/src/tls_packet.rs

188 lines
5.1 KiB
Rust

use byteorder::{ByteOrder, NetworkEndian, BigEndian};
use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
use core::convert::TryFrom;
use core::convert::TryInto;
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub(crate) enum TlsContentType {
#[num_enum(default)]
Invalid = 0,
ChangeCipherSpec = 20,
Alert = 21,
Handshake = 22,
ApplicationData = 23
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)]
pub(crate) enum TlsVersion {
#[num_enum(default)]
Unknown = 0x0000,
Tls10 = 0x0301,
Tls11 = 0x0302,
Tls12 = 0x0303,
Tls13 = 0x0304,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct TlsRepr<'a> {
pub(crate) content_type: TlsContentType,
pub(crate) version: TlsVersion,
pub(crate) length: u16,
pub(crate) payload: Option<&'a[u8]>,
pub(crate) handshake: Option<HandshakeRepr<'a>>
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u8)]
pub(crate) enum HandshakeType {
#[num_enum(default)]
Unknown = 0,
ClientHello = 1,
ServerHello = 2,
NewSessionTicket = 4,
EndOfEarlyData = 5,
EncryptedExtensions = 8,
Certificate = 11,
CertificateRequest = 13,
CertificateVerify = 15,
Finished = 20,
KeyUpdate = 24,
MessageHash = 254,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct HandshakeRepr<'a> {
pub(crate) msg_type: HandshakeType,
pub(crate) length: u32,
pub(crate) handshake_data: HandshakeData<'a>,
}
impl<'a, 'b> HandshakeRepr<'a> {
pub(crate) fn get_length(&self) -> u16 {
let mut length :u16 = 1; // Handshake Type
length += 3; // Length of Handshake data
length += u16::try_from(self.handshake_data.get_length()).unwrap();
length
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)]
pub(crate) enum CipherSuite {
TLS_AES_128_GCM_SHA256 = 0x1301,
TLS_AES_256_GCM_SHA384 = 0x1302,
TLS_CHACHA20_POLY1305_SHA256 = 0x1303,
TLS_AES_128_CCM_SHA256 = 0x1304,
TLS_AES_128_CCM_8_SHA256 = 0x1305,
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct ClientHello<'a> {
pub(crate) version: TlsVersion, // Legacy: Must be Tls12 (0x0303)
pub(crate) random: [u8; 32],
pub(crate) session_id_length: u8, // Legacy: Keep it 32
pub(crate) session_id: [u8; 32], // Legacy: Fill this with an unpredictable value
pub(crate) cipher_suites_length: u16,
pub(crate) cipher_suites: &'a[CipherSuite],
pub(crate) compression_method_length: u8, // Legacy: Must be 1, to contain a byte
pub(crate) compression_methods: u8, // Legacy: Must be 1 byte of 0
pub(crate) extension_length: u16,
pub(crate) extensions: &'a[Extension<'a>],
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum HandshakeData<'a> {
Uninitialized,
ClientHello(ClientHello<'a>),
ServerHello(ServerHello<'a>),
}
impl<'a> HandshakeData<'a> {
pub(crate) fn get_length(&self) -> u32 {
match self {
HandshakeData::ClientHello(data) => data.get_length(),
HandshakeData::ServerHello(data) => todo!(),
_ => 0,
}
}
}
impl<'a> ClientHello<'a> {
pub(crate) fn get_length(&self) -> u32 {
let mut length :u32 = 2; // TlsVersion size
length += 32; // Random size
length += 1; // Legacy session_id length size
length += 32; // Legacy session_id size
length += 2; // Cipher_suites_length size
length += (self.cipher_suites.len() as u32) * 2;
length += 1;
length += 1;
length += 2;
for extension in self.extensions.iter() {
length += (extension.get_length() as u32);
}
length
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct ServerHello<'a> {
pub(crate) version: TlsVersion,
pub(crate) random: &'a[u8],
pub(crate) session_id_echo_length: u8,
pub(crate) session_id_echo: &'a[u8],
pub(crate) cipher_suite: CipherSuite,
pub(crate) compression_method: u8, // Always 0
pub(crate) extension_length: u16,
pub(crate) extensions: &'a[Extension<'a>],
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)]
pub(crate) enum ExtensionType {
ServerName = 0,
MaxFragmentLength = 1,
StatusRequest = 5,
SupportedGroups = 10,
SignatureAlgorithms = 13,
UseSRTP = 14,
Heartbeat = 15,
ApplicationLayerProtocolNegotiation = 16,
SignedCertificateTimestamp = 18,
ClientCertificateType = 19,
ServerCertificateType = 20,
Padding = 21,
PreSharedKey = 41,
EarlyData = 42,
SupportedVersions = 43,
Cookie = 44,
PSKKeyExchangeModes = 45,
CertificateAuthorities = 47,
OIDFilters = 48,
PostHandshakeAuth = 49,
SignatureAlgorithmsCert = 50,
KeyShare = 51,
}
impl ExtensionType {
pub(crate) fn get_length(&self) -> u16 {
return 2;
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct Extension<'a> {
pub(crate) extension_type: ExtensionType,
pub(crate) length: u16,
pub(crate) extension_data: &'a[u8],
}
impl<'a> Extension<'a> {
pub(crate) fn get_length(&self) -> u16 {
self.extension_type.get_length() + 2 + (self.extension_data.len() as u16)
}
}