diff --git a/src/lib.rs b/src/lib.rs index 4602de6..516ca7d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ impl ClientSetupConnection { let handshake = proto::Handshake::ClientHello { legacy_version: proto::LEGACY_TLSV12, random: rand::random(), - legacy_session_id: [(); 32].map(|()| rand::random()).to_vec().into(), + legacy_session_id: rand::random::<[u8; 32]>().to_vec().into(), cipher_suites: vec![proto::CipherSuite::TlsAes128GcmSha256].into(), legacy_compressions_methods: vec![0].into(), extensions: vec![ @@ -44,6 +44,17 @@ impl ClientSetupConnection { proto::ExtensionCH::SupportedGroups { groups: vec![proto::NamedGroup::X25519].into(), }, + // passing this doesnt work and shows up as TLSv1.2 in wireshark and gives a handshake error + /*proto::ExtensionCH::KeyShare { + entries: vec![proto::KeyShareEntry::X25519 { + len: 32, + key_exchange: rand::random(), + }] + .into(), + }, + proto::ExtensionCH::SignatureAlgorithms { + supported_signature_algorithms: vec![proto::SignatureScheme::ED25519].into(), + },*/ proto::ExtensionCH::SupportedVersions { versions: vec![proto::TLSV13].into(), }, @@ -54,7 +65,6 @@ impl ClientSetupConnection { plaintext.write(&mut stream)?; stream.flush()?; - println!("hello!"); let out = proto::TLSPlaintext::read(stream.get_mut())?; dbg!(&out); diff --git a/src/proto.rs b/src/proto.rs index 762a8da..89beec8 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -1,4 +1,4 @@ -mod ser_de; +pub mod ser_de; use std::{ fmt::Debug, @@ -155,25 +155,29 @@ proto_enum! { ECPointFormat { formats: ECPointFormatList, } = 11, - 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, + SignatureAlgorithms { + supported_signature_algorithms: List, + } = 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, } = 43, Cookie{ todo: Todo, } = 44, - PskKeyExchangeModes { todo: Todo, }= 45, - CertificateAuthorities { todo: Todo, }= 47, - PostHandshakeAuth { todo: Todo, }= 49, + PskKeyExchangeModes { todo: Todo, } = 45, + CertificateAuthorities { todo: Todo, } = 47, + PostHandshakeAuth { todo: Todo, } = 49, SignatureAlgorithmsCert{ todo: Todo, } = 50, - KeyShare { todo: Todo, }= 51, + KeyShare { + entries: List, + } = 51, } } @@ -213,29 +217,74 @@ type ECPointFormatList = List; proto_enum! { #[derive(Debug, Clone, PartialEq, Eq)] + pub enum KeyShareEntry: super::NamedGroup { + X25519 { + len: u16, + key_exchange: [u8; 32], + } = super::NamedGroup::X25519, + } +} + +proto_enum! { + #[derive(Debug, Clone, PartialEq, Eq)] + #[allow(non_camel_case_types)] pub enum NamedGroup: u16 { /* Elliptic Curve Groups (ECDHE) */ - Secp256r1 = 0x0017, - Secp384r1 = 0x0018, - Secp521r1 = 0x0019, + SECP256R1 = 0x0017, + SECP384R1 = 0x0018, + SECP521R1 = 0x0019, X25519 = 0x001D, X448 = 0x001E, /* Finite Field Groups (DHE) */ - Ffdhe2048 = 0x0100, - Ffdhe3072 = 0x0101, - Ffdhe4096 = 0x0102, - Ffdhe6144 = 0x0103, - Ffdhe8192 = 0x0104, + FFDHE2048 = 0x0100, + FFDHE3072 = 0x0101, + FFDHE4096 = 0x0102, + FFDHE6144 = 0x0103, + FFDHE8192 = 0x0104, } } type NamedGroupList = List; +proto_enum! { + #[derive(Debug, Clone, PartialEq, Eq)] + #[allow(non_camel_case_types)] + pub enum SignatureScheme: u32 { + /* RSASSA-PKCS1-v1_5 algorithms */ + RSA_PKCS1_SHA256 = 0x0401, + RSA_PKCS1_SHA384 = 0x0501, + RSA_PKCS1_SHA512 = 0x0601, + + /* ECDSA algorithms */ + ECDSA_SECP256R1_SHA256 = 0x0403, + ECDSA_SECP384R1_SHA384 = 0x0503, + ECDSA_SECP521R1_SHA512 = 0x0603, + + /* RSASSA-PSS algorithms with public key OID rsaEncryption */ + RSA_PSS_RSAE_SHA256 = 0x0804, + RSA_PSS_RSAE_SHA384 = 0x0805, + RSA_PSS_RSAE_SHA512 = 0x0806, + + /* EdDSA algorithms */ + ED25519 = 0x0807, + ED448 = 0x0808, + + /* RSASSA-PSS algorithms with public key OID RSASSA-PSS */ + RSA_PSS_PSS_SHA256 = 0x0809, + RSA_PSS_PSS_SHA384 = 0x080a, + RSA_PSS_PSS_SHA512 = 0x080b, + + /* Legacy algorithms */ + RSA_PKCS1_SHA1 = 0x0201, + ECDSA_SHA1 = 0x0203, + } +} + proto_struct! { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Alert { - level: AlertLevel, - description: AlertDescription, + pub level: AlertLevel, + pub description: AlertDescription, } } diff --git a/src/proto/ser_de.rs b/src/proto/ser_de.rs index 4cf3041..d3513b9 100644 --- a/src/proto/ser_de.rs +++ b/src/proto/ser_de.rs @@ -1,16 +1,24 @@ use byteorder::{BigEndian as B, ReadBytesExt, WriteBytesExt}; -use std::fmt::Debug; +use std::{ + fmt::Debug, + io::{self, Read, Write}, + marker::PhantomData, + num::TryFromIntError, +}; +/// ```ignore +/// proto_struct! {} +/// ``` macro_rules! proto_struct { {$(#[$meta:meta])* pub struct $name:ident { $( - $field_name:ident : $field_ty:ty, + pub $field_name:ident : $field_ty:ty, )* }} => { $(#[$meta])* pub struct $name { $( - $field_name: $field_ty, + pub $field_name: $field_ty, )* } @@ -39,14 +47,12 @@ macro_rules! proto_struct { } }; } -use std::{ - io::{self, Read, Write}, - marker::PhantomData, - num::TryFromIntError, -}; pub(crate) use proto_struct; +/// ```ignore +/// proto_enum! {} +/// ``` macro_rules! proto_enum { {$(#[$meta:meta])* pub enum $name:ident: $discr_ty:ty $( ,(length: $len_ty:ty) )? { $( @@ -116,13 +122,16 @@ macro_rules! proto_enum { fn read(r: &mut R) -> crate::Result { mod discr_consts { + #[allow(unused_imports)] + use super::*; + pub type Type = $discr_ty; $( #[allow(non_upper_case_globals)] pub(super) const $KindName: $discr_ty = $discriminant; )* } - let kind: $discr_ty = crate::proto::ser_de::Value::read(r)?; + let kind: discr_consts::Type = crate::proto::ser_de::Value::read(r)?; $( let _len = <$len_ty>::read(r)?;