mirror of
https://github.com/Noratrieb/tls.git
synced 2026-01-14 16:45:02 +01:00
parse helloretryrequest
This commit is contained in:
parent
2266f6f8b6
commit
a81438e7e3
4 changed files with 113 additions and 43 deletions
|
|
@ -14,6 +14,7 @@
|
|||
llvmPackages_16.clang
|
||||
llvmPackages_16.bintools
|
||||
llvmPackages_16.libllvm
|
||||
llvmPackages_16.lldb
|
||||
rustup
|
||||
];
|
||||
# https://github.com/rust-lang/rust-bindgen#environment-variables
|
||||
|
|
|
|||
|
|
@ -40,9 +40,7 @@ impl ClientSetupConnection {
|
|||
formats: vec![proto::ECPointFormat::Uncompressed].into(),
|
||||
},
|
||||
proto::ExtensionCH::SupportedGroups {
|
||||
groups: vec![
|
||||
proto::NamedGroup::X25519,
|
||||
].into(),
|
||||
groups: vec![proto::NamedGroup::X25519].into(),
|
||||
},
|
||||
proto::ExtensionCH::SupportedVersions {
|
||||
versions: vec![proto::TLSV13].into(),
|
||||
|
|
@ -54,6 +52,7 @@ impl ClientSetupConnection {
|
|||
plaintext.write(&mut stream)?;
|
||||
stream.flush()?;
|
||||
|
||||
println!("hello!");
|
||||
let out = proto::TLSPlaintext::read(stream.get_mut())?;
|
||||
dbg!(out);
|
||||
|
||||
|
|
@ -77,6 +76,7 @@ pub enum ErrorKind {
|
|||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(value: io::Error) -> Self {
|
||||
panic!("io error: {value}");
|
||||
Self {
|
||||
kind: ErrorKind::Io(value),
|
||||
}
|
||||
|
|
@ -85,6 +85,7 @@ impl From<io::Error> for Error {
|
|||
|
||||
impl From<ErrorKind> for Error {
|
||||
fn from(value: ErrorKind) -> Self {
|
||||
panic!("error: {value:?}");
|
||||
Self { kind: value }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
107
src/proto.rs
107
src/proto.rs
|
|
@ -9,7 +9,7 @@ use byteorder::{BigEndian as B, ReadBytesExt, WriteBytesExt};
|
|||
|
||||
use crate::ErrorKind;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum TLSPlaintext {
|
||||
Invalid {
|
||||
legacy_version: ProtocolVersion,
|
||||
|
|
@ -34,12 +34,9 @@ impl TLSPlaintext {
|
|||
|
||||
pub fn write(&self, w: &mut impl Write) -> io::Result<()> {
|
||||
match self {
|
||||
TLSPlaintext::Invalid {
|
||||
legacy_version,
|
||||
fragment,
|
||||
} => todo!(),
|
||||
TLSPlaintext::Invalid { .. } => todo!(),
|
||||
TLSPlaintext::ChangeCipherSpec => todo!(),
|
||||
TLSPlaintext::Alert { alert } => todo!(),
|
||||
TLSPlaintext::Alert { .. } => todo!(),
|
||||
TLSPlaintext::Handshake { handshake } => {
|
||||
Self::HANDSHAKE.write(w)?;
|
||||
// MUST be set to 0x0303 for all records
|
||||
|
|
@ -91,13 +88,13 @@ pub type Random = [u8; 32];
|
|||
|
||||
// https://datatracker.ietf.org/doc/html/rfc8446#section-4
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Handshake: u8, (length: u24) {
|
||||
// https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2
|
||||
ClientHello {
|
||||
legacy_version: ProtocolVersion,
|
||||
random: Random,
|
||||
legacy_session_id: List<u8, u8>,
|
||||
legacy_session_id: LegacySessionId,
|
||||
cipher_suites: List<CipherSuite, u16>,
|
||||
legacy_compressions_methods: List<u8, u8>,
|
||||
extensions: List<ExtensionCH, u16>,
|
||||
|
|
@ -105,7 +102,7 @@ proto_enum! {
|
|||
ServerHello {
|
||||
legacy_version: ProtocolVersion,
|
||||
random: Random,
|
||||
legacy_session_id_echo: u8,
|
||||
legacy_session_id_echo: LegacySessionId,
|
||||
cipher_suite: CipherSuite,
|
||||
legacy_compression_method: u8,
|
||||
extensions: List<ExtensionSH, u16>,
|
||||
|
|
@ -122,12 +119,19 @@ proto_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
pub const HELLO_RETRY_REQUEST: [u8; 32] = [
|
||||
0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
|
||||
0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
|
||||
];
|
||||
|
||||
pub const LEGACY_TLSV10: ProtocolVersion = 0x0301;
|
||||
pub const LEGACY_TLSV12: ProtocolVersion = 0x0303;
|
||||
pub const TLSV13: ProtocolVersion = 0x0304;
|
||||
|
||||
type LegacySessionId = List<u8, u8>;
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CipherSuite: [u8; 2] {
|
||||
TlsAes128GcmSha256 = [0x13, 0x01],
|
||||
TlsAes256GcmSha384 = [0x13, 0x02],
|
||||
|
|
@ -138,54 +142,57 @@ proto_enum! {
|
|||
}
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExtensionCH: u16, (length: u16) {
|
||||
ServerName {
|
||||
server_name: ServerNameList,
|
||||
} = 0,
|
||||
MaxFragmentLength = 1,
|
||||
StatusRequest = 5,
|
||||
MaxFragmentLength { todo: Todo, } = 1,
|
||||
StatusRequest { todo: Todo, } = 5,
|
||||
SupportedGroups {
|
||||
groups: NamedGroupList,
|
||||
} = 10,
|
||||
ECPointFormat {
|
||||
formats: ECPointFormatList,
|
||||
} = 11,
|
||||
SignatureAlgorithms = 13,
|
||||
UseSrtp = 14,
|
||||
Heartbeat = 15,
|
||||
ApplicationLayerProtocolNegotiation = 16,
|
||||
SignedCertificateTimestamp = 18,
|
||||
ClientCertificateType = 19,
|
||||
ServerCertificateType = 20,
|
||||
Padding = 21,
|
||||
PreSharedKey = 41,
|
||||
EarlyData = 42,
|
||||
SignatureAlgorithms{ todo: Todo, } = 13,
|
||||
UseSrtp{ todo: Todo, } = 14,
|
||||
Heartbeat { todo: Todo, }= 15,
|
||||
ApplicationLayerProtocolNegotiation{ todo: Todo, } = 16,
|
||||
SignedCertificateTimestamp{ todo: Todo, } = 18,
|
||||
ClientCertificateType{ todo: Todo, } = 19,
|
||||
ServerCertificateType { todo: Todo, }= 20,
|
||||
Padding{ todo: Todo, } = 21,
|
||||
PreSharedKey { todo: Todo, }= 41,
|
||||
EarlyData{ todo: Todo, } = 42,
|
||||
SupportedVersions {
|
||||
versions: List<ProtocolVersion, u8>,
|
||||
} = 43,
|
||||
Cookie = 44,
|
||||
PskKeyExchangeModes = 45,
|
||||
CertificateAuthorities = 47,
|
||||
PostHandshakeAuth = 49,
|
||||
SignatureAlgorithmsCert = 50,
|
||||
KeyShare = 51,
|
||||
Cookie{ todo: Todo, } = 44,
|
||||
PskKeyExchangeModes { todo: Todo, }= 45,
|
||||
CertificateAuthorities { todo: Todo, }= 47,
|
||||
PostHandshakeAuth { todo: Todo, }= 49,
|
||||
SignatureAlgorithmsCert{ todo: Todo, } = 50,
|
||||
KeyShare { todo: Todo, }= 51,
|
||||
}
|
||||
}
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ExtensionSH: u16 {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ExtensionSH: u16, (length: u16) {
|
||||
PreSharedKey = 41,
|
||||
SupportedVersions {
|
||||
selected_version: ProtocolVersion,
|
||||
} = 43,
|
||||
KeyShare = 51,
|
||||
Cookie { todo: Todo, } = 44,
|
||||
KeyShare {
|
||||
group: NamedGroup,
|
||||
} = 51,
|
||||
}
|
||||
}
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ServerName: u8 {
|
||||
HostName {
|
||||
host_name: HostName,
|
||||
|
|
@ -197,7 +204,7 @@ type HostName = List<u8, u16>;
|
|||
type ServerNameList = List<ServerName, u16>;
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ECPointFormat: u8 {
|
||||
Uncompressed = 0,
|
||||
}
|
||||
|
|
@ -205,7 +212,7 @@ proto_enum! {
|
|||
type ECPointFormatList = List<ECPointFormat, u8>;
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum NamedGroup: u16 {
|
||||
/* Elliptic Curve Groups (ECDHE) */
|
||||
Secp256r1 = 0x0017,
|
||||
|
|
@ -225,7 +232,7 @@ proto_enum! {
|
|||
type NamedGroupList = List<NamedGroup, u16>;
|
||||
|
||||
proto_struct! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Alert {
|
||||
level: AlertLevel,
|
||||
description: AlertDescription,
|
||||
|
|
@ -233,7 +240,7 @@ proto_struct! {
|
|||
}
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AlertLevel: u8 {
|
||||
Warning = 1,
|
||||
Fatal = 2,
|
||||
|
|
@ -241,7 +248,7 @@ proto_enum! {
|
|||
}
|
||||
|
||||
proto_enum! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AlertDescription: u8 {
|
||||
CloseNotify = 0,
|
||||
UnexpectedMessage = 10,
|
||||
|
|
@ -408,7 +415,7 @@ macro_rules! proto_enum {
|
|||
},
|
||||
)*
|
||||
|
||||
_ => Err(ErrorKind::InvalidFrame(Box::new(kind)).into()),
|
||||
_ => Err(ErrorKind::InvalidFrame(Box::new(format!("invalid discriminant for {}: 0x{kind:x?}", stringify!($name)))).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -435,7 +442,24 @@ macro_rules! proto_enum {
|
|||
}
|
||||
use proto_enum;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Todo;
|
||||
|
||||
impl Value for Todo {
|
||||
fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn read<R: Read>(r: &mut R) -> crate::Result<Self> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn byte_size(&self) -> usize {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct List<T, Len>(Vec<T>, PhantomData<Len>);
|
||||
|
||||
impl<T, Len: Value> From<Vec<T>> for List<T, Len> {
|
||||
|
|
@ -605,3 +629,6 @@ macro_rules! discard {
|
|||
($($tt:tt)*) => {};
|
||||
}
|
||||
use discard;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
|||
41
src/proto/tests.rs
Normal file
41
src/proto/tests.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_hello_retry_request() {
|
||||
#[rustfmt::skip]
|
||||
let mut bytes: &[u8] = &[
|
||||
0x16, 0x03, 0x03, 0x00, 0x58, 0x02, 0x00, 0x00, 0x54, 0x03, 0x03, 0xcf, 0x21, 0xad, 0x74, 0xe5,
|
||||
0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a,
|
||||
0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, 0x20, 0xdd, 0x0f, 0x25, 0x0a,
|
||||
0xf0, 0xa6, 0xd9, 0xb0, 0x1c, 0x28, 0x2f, 0x55, 0xcb, 0xab, 0x07, 0x94, 0x2e, 0xb3, 0x98, 0x96,
|
||||
0x32, 0x81, 0xad, 0x8d, 0x24, 0x72, 0x52, 0x2a, 0x45, 0x26, 0x10, 0xa2, 0x13, 0x01, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04, 0x00, 0x33, 0x00, 0x02, 0x00, 0x1d,
|
||||
];
|
||||
|
||||
let handshake = TLSPlaintext::read(&mut bytes).unwrap();
|
||||
assert_eq!(
|
||||
handshake,
|
||||
TLSPlaintext::Handshake {
|
||||
handshake: Handshake::ServerHello {
|
||||
legacy_version: LEGACY_TLSV12,
|
||||
random: HELLO_RETRY_REQUEST,
|
||||
legacy_session_id_echo:
|
||||
b"\xdd\x0f\x25\x0a\xf0\xa6\xd9\xb0\x1c\x28\x2f\x55\xcb\xab\x07\x94\
|
||||
\x2e\xb3\x98\x96\x32\x81\xad\x8d\x24\x72\x52\x2a\x45\x26\x10\xa2"
|
||||
.to_vec()
|
||||
.into(),
|
||||
cipher_suite: CipherSuite::TlsAes128GcmSha256,
|
||||
legacy_compression_method: 0,
|
||||
extensions: vec![
|
||||
ExtensionSH::SupportedVersions {
|
||||
selected_version: TLSV13
|
||||
},
|
||||
ExtensionSH::KeyShare {
|
||||
group: NamedGroup::X25519
|
||||
}
|
||||
]
|
||||
.into()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue