tls_packet: impl formatting for extensions

This commit is contained in:
occheung 2020-10-13 23:16:18 +08:00
parent 25f9619f4f
commit 337edf7411
2 changed files with 197 additions and 135 deletions

View File

@ -103,127 +103,129 @@ impl<R: RngCore + CryptoRng> TlsSocket<R> {
} }
if self.state == TlsState::START { if self.state == TlsState::START {
// Create TLS representation, length and payload not finalised // // Create TLS representation, length and payload not finalised
let mut random: [u8; 32] = [0; 32]; // let mut random: [u8; 32] = [0; 32];
self.rng.fill_bytes(&mut random); // self.rng.fill_bytes(&mut random);
let mut session_id: [u8; 32] = [0; 32]; // let mut session_id: [u8; 32] = [0; 32];
self.rng.fill_bytes(&mut session_id); // self.rng.fill_bytes(&mut session_id);
//
let cipher_suites_length = 6; // let cipher_suites_length = 6;
let cipher_suites = [ // let cipher_suites = [
CipherSuite::TLS_AES_128_GCM_SHA256, // CipherSuite::TLS_AES_128_GCM_SHA256,
CipherSuite::TLS_AES_256_GCM_SHA384, // CipherSuite::TLS_AES_256_GCM_SHA384,
CipherSuite::TLS_CHACHA20_POLY1305_SHA256, // CipherSuite::TLS_CHACHA20_POLY1305_SHA256,
]; // ];
//
// Length: to be determined // // Length: to be determined
let supported_versions_extension = Extension { // let supported_versions_extension = Extension {
extension_type: ExtensionType::SupportedVersions, // extension_type: ExtensionType::SupportedVersions,
length: 5, // length: 5,
extension_data: &[ // extension_data: &[
4, // Number of supported versions * 2 // 4, // Number of supported versions * 2
// Need 2 bytes to contain a version // // Need 2 bytes to contain a version
0x03, 0x04, // 0x0304: TLS Version 1.3 // 0x03, 0x04, // 0x0304: TLS Version 1.3
0x03, 0x03, // 0x0303: TLS version 1.2 // 0x03, 0x03, // 0x0303: TLS version 1.2
] // ]
}; // };
//
let signature_algorithms_extension = Extension { // let signature_algorithms_extension = Extension {
extension_type: ExtensionType::SignatureAlgorithms, // extension_type: ExtensionType::SignatureAlgorithms,
length: 24, // length: 24,
extension_data: &[ // extension_data: &[
0x00, 22, // Length in bytes // 0x00, 22, // Length in bytes
0x04, 0x03, // ecdsa_secp256r1_sha256 // 0x04, 0x03, // ecdsa_secp256r1_sha256
0x08, 0x07, // ed25519 // 0x08, 0x07, // ed25519
0x08, 0x09, // rsa_pss_pss_sha256 // 0x08, 0x09, // rsa_pss_pss_sha256
0x04, 0x01, // rsa_pkcs1_sha256 // 0x04, 0x01, // rsa_pkcs1_sha256
0x08, 0x04, // rsa_pss_rsae_sha256 // 0x08, 0x04, // rsa_pss_rsae_sha256
0x08, 0x0a, // rsa_pss_pss_sha384 // 0x08, 0x0a, // rsa_pss_pss_sha384
0x05, 0x01, // rsa_pkcs1_sha384 // 0x05, 0x01, // rsa_pkcs1_sha384
0x08, 0x05, // rsa_pss_rsae_sha384 // 0x08, 0x05, // rsa_pss_rsae_sha384
0x08, 0x0b, // rsa_pss_pss_sha512 // 0x08, 0x0b, // rsa_pss_pss_sha512
0x06, 0x01, // rsa_pkcs1_sha512 // 0x06, 0x01, // rsa_pkcs1_sha512
0x08, 0x06, // rsa_pss_rsae_sha512 // 0x08, 0x06, // rsa_pss_rsae_sha512
] // ]
}; // };
//
let supported_groups_extension = Extension { // let supported_groups_extension = Extension {
extension_type: ExtensionType::SupportedGroups, // extension_type: ExtensionType::SupportedGroups,
length: 4, // length: 4,
extension_data: &[ // extension_data: &[
0x00, 0x02, // Length in bytes // 0x00, 0x02, // Length in bytes
0x00, 0x17, // secp256r1 // 0x00, 0x17, // secp256r1
] // ]
}; // };
//
let key_share_extension = Extension { // let key_share_extension = Extension {
extension_type: ExtensionType::KeyShare, // extension_type: ExtensionType::KeyShare,
length: 71, // length: 71,
extension_data: &{ // extension_data: &{
let ecdh_secret = unsafe { EphemeralSecret::random(&mut self.rng) }; // let ecdh_secret = unsafe { EphemeralSecret::random(&mut self.rng) };
let ecdh_public = EncodedPoint::from(&ecdh_secret); // let ecdh_public = EncodedPoint::from(&ecdh_secret);
let x_coor = ecdh_public.x(); // let x_coor = ecdh_public.x();
let y_coor = ecdh_public.y().unwrap(); // let y_coor = ecdh_public.y().unwrap();
let mut data: [u8; 71] = [0; 71]; // let mut data: [u8; 71] = [0; 71];
data[0..2].copy_from_slice(&[0x00, 69]); // Length in bytes // data[0..2].copy_from_slice(&[0x00, 69]); // Length in bytes
data[2..4].copy_from_slice(&[0x00, 0x17]); // secp256r1 // data[2..4].copy_from_slice(&[0x00, 0x17]); // secp256r1
data[4..6].copy_from_slice(&[0x00, 65]); // key exchange length // data[4..6].copy_from_slice(&[0x00, 65]); // key exchange length
data[6..7].copy_from_slice(&[0x04]); // Fixed legacy value // data[6..7].copy_from_slice(&[0x04]); // Fixed legacy value
data[7..39].copy_from_slice(&x_coor); // data[7..39].copy_from_slice(&x_coor);
data[39..71].copy_from_slice(&y_coor); // data[39..71].copy_from_slice(&y_coor);
data // data
} // }
}; // };
//
let psk_key_exchange_modes_extension = Extension { // let psk_key_exchange_modes_extension = Extension {
extension_type: ExtensionType::PSKKeyExchangeModes, // extension_type: ExtensionType::PSKKeyExchangeModes,
length: 2, // length: 2,
extension_data: &[ // extension_data: &[
0x01, // Length in bytes // 0x01, // Length in bytes
0x01, // psk_dhe_ke // 0x01, // psk_dhe_ke
] // ]
}; // };
//
let mut client_hello = ClientHello { // let mut client_hello = ClientHello {
version: TlsVersion::Tls12, // version: TlsVersion::Tls12,
random, // random,
session_id_length: 32, // session_id_length: 32,
session_id, // session_id,
cipher_suites_length, // cipher_suites_length,
cipher_suites: &cipher_suites, // cipher_suites: &cipher_suites,
compression_method_length: 1, // compression_method_length: 1,
compression_methods: 0, // compression_methods: 0,
extension_length: supported_versions_extension.get_length().try_into().unwrap(), // extension_length: supported_versions_extension.get_length().try_into().unwrap(),
extensions: vec![ // extensions: vec![
supported_versions_extension, // supported_versions_extension,
signature_algorithms_extension, // signature_algorithms_extension,
supported_groups_extension, // supported_groups_extension,
psk_key_exchange_modes_extension, // psk_key_exchange_modes_extension,
key_share_extension // key_share_extension
] // ]
}; // };
//
client_hello.extension_length = { // client_hello.extension_length = {
let mut sum = 0; // let mut sum = 0;
for ext in client_hello.extensions.iter() { // for ext in client_hello.extensions.iter() {
sum += ext.get_length(); // sum += ext.get_length();
} // }
sum.try_into().unwrap() // sum.try_into().unwrap()
}; // };
//
let handshake_repr = HandshakeRepr { // let handshake_repr = HandshakeRepr {
msg_type: HandshakeType::ClientHello, // msg_type: HandshakeType::ClientHello,
length: client_hello.get_length(), // length: client_hello.get_length(),
handshake_data: HandshakeData::ClientHello(client_hello), // handshake_data: HandshakeData::ClientHello(client_hello),
}; // };
//
let repr = TlsRepr { // let repr = TlsRepr {
content_type: TlsContentType::Handshake, // content_type: TlsContentType::Handshake,
version: TlsVersion::Tls10, // version: TlsVersion::Tls10,
length: handshake_repr.get_length(), // length: handshake_repr.get_length(),
payload: None, // payload: None,
handshake: Some(handshake_repr), // handshake: Some(handshake_repr),
}; // };
let repr = TlsRepr::new()
.client_hello(&mut self.rng);
log::info!("{:?}", repr); log::info!("{:?}", repr);
@ -394,10 +396,70 @@ impl<'a> TlsBuffer<'a> {
for extension in extensions { for extension in extensions {
self.write_u16(extension.extension_type.into())?; self.write_u16(extension.extension_type.into())?;
self.write_u16(extension.length)?; self.write_u16(extension.length)?;
self.write(extension.extension_data)?; // self.write(extension.extension_data)?;
self.enqueue_extension_data(extension.extension_data)?;
} }
Ok(()) Ok(())
} }
fn enqueue_extension_data(&mut self, extension_data: ExtensionData) -> Result<()> {
use crate::tls_packet::ExtensionData::*;
match extension_data {
SupportedVersions(s) => {
use crate::tls_packet::SupportedVersions::*;
match s {
ClientHello { length, versions } => {
self.write_u16(length)?;
for version in versions.iter() {
self.write_u16((*version).into())?;
}
},
ServerHello { selected_version } => {
self.write_u16(selected_version.into())?;
}
}
},
SignatureAlgorithms(s) => {
self.write_u16(s.length)?;
for sig_alg in s.supported_signature_algorithms.iter() {
self.write_u16((*sig_alg).into())?;
}
},
NegotiatedGroups(n) => {
self.write_u16(n.length)?;
for group in n.named_group_list.iter() {
self.write_u16((*group).into())?;
}
},
KeyShareEntry(k) => {
let key_share_entry_into = |entry: crate::tls_packet::KeyShareEntry| {
self.write_u16(entry.group.into())?;
self.write_u16(entry.length)?;
self.write(entry.key_exchange.as_slice())
};
use crate::tls_packet::KeyShareEntryContent::*;
match k {
KeyShareClientHello { length, client_shares } => {
self.write_u16(length)?;
for share in client_shares.iter() {
key_share_entry_into(*share)?;
}
}
KeyShareHelloRetryRequest { selected_group } => {
self.write_u16(selected_group.into())?;
}
KeyShareServerHello { server_share } => {
key_share_entry_into(server_share)?;
}
}
},
// TODO: Implement buffer formatting for other extensions
_ => todo!()
};
Ok(())
}
} }
macro_rules! export_byte_order_fn { macro_rules! export_byte_order_fn {

View File

@ -274,8 +274,8 @@ impl<'a> ClientHello<'a> {
let length = list.len()*2; let length = list.len()*2;
// Use the list to generate all key shares and store in a vec // Use the list to generate all key shares and store in a vec
let client_shares = Vec::new(); let mut client_shares = Vec::new();
let client_shares_length = 0; let mut client_shares_length = 0;
for named_group in list.iter() { for named_group in list.iter() {
let mut key_exchange = Vec::new(); let mut key_exchange = Vec::new();
let key_share_entry = match named_group { let key_share_entry = match named_group {
@ -317,7 +317,7 @@ impl<'a> ClientHello<'a> {
extension_type: ExtensionType::KeyShare, extension_type: ExtensionType::KeyShare,
length: length.try_into().unwrap(), length: length.try_into().unwrap(),
extension_data, extension_data,
} };
let group_list = NamedGroupList { let group_list = NamedGroupList {
length: length.try_into().unwrap(), length: length.try_into().unwrap(),
@ -329,7 +329,7 @@ impl<'a> ClientHello<'a> {
extension_type: ExtensionType::SupportedGroups, extension_type: ExtensionType::SupportedGroups,
length: length.try_into().unwrap(), length: length.try_into().unwrap(),
extension_data, extension_data,
} };
self.extensions.push(group_list_extension); self.extensions.push(group_list_extension);
self.extensions.push(key_share_extension); self.extensions.push(key_share_extension);
@ -464,7 +464,7 @@ pub(crate) struct Cookie {
cookie: Vec<u8>, cookie: Vec<u8>,
} }
#[derive(Debug, Clone)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)] #[repr(u16)]
pub(crate) enum SignatureScheme { pub(crate) enum SignatureScheme {
/* RSASSA-PKCS1-v1_5 algorithms */ /* RSASSA-PKCS1-v1_5 algorithms */
@ -494,8 +494,8 @@ pub(crate) enum SignatureScheme {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct SignatureSchemeList { pub(crate) struct SignatureSchemeList {
length: u16, pub(crate) length: u16,
supported_signature_algorithms: Vec<SignatureScheme>, pub(crate) supported_signature_algorithms: Vec<SignatureScheme>,
} }
impl SignatureSchemeList { impl SignatureSchemeList {
@ -504,7 +504,7 @@ impl SignatureSchemeList {
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)] #[repr(u16)]
pub(crate) enum NamedGroup { pub(crate) enum NamedGroup {
/* Elliptic Curve Groups (ECDHE) */ /* Elliptic Curve Groups (ECDHE) */
@ -524,8 +524,8 @@ pub(crate) enum NamedGroup {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct NamedGroupList { pub(crate) struct NamedGroupList {
length: u16, pub(crate) length: u16,
named_group_list: Vec<NamedGroup>, pub(crate) named_group_list: Vec<NamedGroup>,
} }
impl NamedGroupList { impl NamedGroupList {
@ -536,9 +536,9 @@ impl NamedGroupList {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct KeyShareEntry { pub(crate) struct KeyShareEntry {
group: NamedGroup, pub(crate) group: NamedGroup,
length: u16, pub(crate) length: u16,
key_exchange: Vec<u8>, pub(crate) key_exchange: Vec<u8>,
} }
impl KeyShareEntry { impl KeyShareEntry {