tls_packet: impl formatting for extensions
This commit is contained in:
parent
25f9619f4f
commit
337edf7411
306
src/tls.rs
306
src/tls.rs
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue