From f6ff5cc431bc99bf4c82cd3182553d249ed40a6d Mon Sep 17 00:00:00 2001 From: occheung Date: Mon, 19 Oct 2020 17:05:26 +0800 Subject: [PATCH] fix: mismatch cipher, ee parse --- src/buffer.rs | 14 +++++++ src/encrypted.rs | 2 - src/main.rs | 101 ++++++++++++++++++++++++++++++---------------- src/parse.rs | 98 ++++++++++++++++++++++++++++++++++++++------ src/session.rs | 14 ++++--- src/tls.rs | 44 +++++++++++++------- src/tls_packet.rs | 5 ++- 7 files changed, 208 insertions(+), 70 deletions(-) delete mode 100644 src/encrypted.rs diff --git a/src/buffer.rs b/src/buffer.rs index 8060622..6fae4b6 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -107,6 +107,9 @@ impl<'a> TlsBuffer<'a> { HandshakeData::ClientHello(client_hello) => { self.enqueue_client_hello(client_hello) } + HandshakeData::ServerHello(server_hello) => { + self.euqueue_server_hello(server_hello) + } _ => { Err(Error::Unrecognized) } @@ -128,6 +131,17 @@ impl<'a> TlsBuffer<'a> { self.enqueue_extensions(client_hello.extensions) } + fn euqueue_server_hello(&mut self, server_hello: ServerHello<'a>) -> Result<()> { + self.write_u16(server_hello.version.into())?; + self.write(&server_hello.random)?; + self.write_u8(server_hello.session_id_echo_length)?; + self.write(&server_hello.session_id_echo)?; + self.write_u16(server_hello.cipher_suite.into())?; + self.write_u8(server_hello.compression_method)?; + self.write_u16(server_hello.extension_length)?; + self.enqueue_extensions(server_hello.extensions) + } + fn enqueue_extensions(&mut self, extensions: Vec) -> Result<()> { for extension in extensions { self.write_u16(extension.extension_type.into())?; diff --git a/src/encrypted.rs b/src/encrypted.rs deleted file mode 100644 index 44211e3..0000000 --- a/src/encrypted.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub const ENCRYPTED_DATA :[u8; 1141] = [ 0xda, 0x1e, 0xc2, 0xd7, 0xbd, 0xa8, 0xeb, 0xf7, 0x3e, 0xdd, 0x50, 0x10, 0xfb, 0xa8, 0x08, 0x9f, 0xd4, 0x26, 0xb0, 0xea, 0x1e, 0xa4, 0xd8, 0x8d, 0x07, 0x4f, 0xfe, 0xa8, 0xa9, 0x87, 0x3a, 0xf5, 0xf5, 0x02, 0x26, 0x1e, 0x34, 0xb1, 0x56, 0x33, 0x43, 0xe9, 0xbe, 0xb6, 0x13, 0x2e, 0x7e, 0x83, 0x6d, 0x65, 0xdb, 0x6d, 0xcf, 0x00, 0xbc, 0x40, 0x19, 0x35, 0xae, 0x36, 0x9c, 0x44, 0x0d, 0x67, 0xaf, 0x71, 0x9e, 0xc0, 0x3b, 0x98, 0x4c, 0x45, 0x21, 0xb9, 0x05, 0xd5, 0x8b, 0xa2, 0x19, 0x7c, 0x45, 0xc4, 0xf7, 0x73, 0xbd, 0x9d, 0xd1, 0x21, 0xb4, 0xd2, 0xd4, 0xe6, 0xad, 0xff, 0xfa, 0x27, 0xc2, 0xa8, 0x1a, 0x99, 0xa8, 0xef, 0xe8, 0x56, 0xc3, 0x5e, 0xe0, 0x8b, 0x71, 0xb3, 0xe4, 0x41, 0xbb, 0xec, 0xaa, 0x65, 0xfe, 0x72, 0x08, 0x15, 0xca, 0xb5, 0x8d, 0xb3, 0xef, 0xa8, 0xd1, 0xe5, 0xb7, 0x1c, 0x58, 0xe8, 0xd1, 0xfd, 0xb6, 0xb2, 0x1b, 0xfc, 0x66, 0xa9, 0x86, 0x5f, 0x85, 0x2c, 0x1b, 0x4b, 0x64, 0x0e, 0x94, 0xbd, 0x90, 0x84, 0x69, 0xe7, 0x15, 0x1f, 0x9b, 0xbc, 0xa3, 0xce, 0x53, 0x22, 0x4a, 0x27, 0x06, 0x2c, 0xeb, 0x24, 0x0a, 0x10, 0x5b, 0xd3, 0x13, 0x2d, 0xc1, 0x85, 0x44, 0x47, 0x77, 0x94, 0xc3, 0x73, 0xbc, 0x0f, 0xb5, 0xa2, 0x67, 0x88, 0x5c, 0x85, 0x7d, 0x4c, 0xcb, 0x4d, 0x31, 0x74, 0x2b, 0x7a, 0x29, 0x62, 0x40, 0x29, 0xfd, 0x05, 0x94, 0x0d, 0xe3, 0xf9, 0xf9, 0xb6, 0xe0, 0xa9, 0xa2, 0x37, 0x67, 0x2b, 0xc6, 0x24, 0xba, 0x28, 0x93, 0xa2, 0x17, 0x09, 0x83, 0x3c, 0x52, 0x76, 0xd4, 0x13, 0x63, 0x1b, 0xdd, 0xe6, 0xae, 0x70, 0x08, 0xc6, 0x97, 0xa8, 0xef, 0x42, 0x8a, 0x79, 0xdb, 0xf6, 0xe8, 0xbb, 0xeb, 0x47, 0xc4, 0xe4, 0x08, 0xef, 0x65, 0x6d, 0x9d, 0xc1, 0x9b, 0x8b, 0x5d, 0x49, 0xbc, 0x09, 0x1e, 0x21, 0x77, 0x35, 0x75, 0x94, 0xc8, 0xac, 0xd4, 0x1c, 0x10, 0x1c, 0x77, 0x50, 0xcb, 0x11, 0xb5, 0xbe, 0x6a, 0x19, 0x4b, 0x8f, 0x87, 0x70, 0x88, 0xc9, 0x82, 0x8e, 0x35, 0x07, 0xda, 0xda, 0x17, 0xbb, 0x14, 0xbb, 0x2c, 0x73, 0x89, 0x03, 0xc7, 0xaa, 0xb4, 0x0c, 0x54, 0x5c, 0x46, 0xaa, 0x53, 0x82, 0x3b, 0x12, 0x01, 0x81, 0xa1, 0x6c, 0xe9, 0x28, 0x76, 0x28, 0x8c, 0x4a, 0xcd, 0x81, 0x5b, 0x23, 0x3d, 0x96, 0xbb, 0x57, 0x2b, 0x16, 0x2e, 0xc1, 0xb9, 0xd7, 0x12, 0xf2, 0xc3, 0x96, 0x6c, 0xaa, 0xc9, 0xcf, 0x17, 0x4f, 0x3a, 0xed, 0xfe, 0xc4, 0xd1, 0x9f, 0xf9, 0xa8, 0x7f, 0x8e, 0x21, 0xe8, 0xe1, 0xa9, 0x78, 0x9b, 0x49, 0x0b, 0xa0, 0x5f, 0x1d, 0xeb, 0xd2, 0x17, 0x32, 0xfb, 0x2e, 0x15, 0xa0, 0x17, 0xc4, 0x75, 0xc4, 0xfd, 0x00, 0xbe, 0x04, 0x21, 0x86, 0xdc, 0x29, 0xe6, 0x8b, 0xb7, 0xec, 0xe1, 0x92, 0x43, 0x8f, 0x3b, 0x0c, 0x5e, 0xf8, 0xe4, 0xa5, 0x35, 0x83, 0xa0, 0x19, 0x43, 0xcf, 0x84, 0xbb, 0xa5, 0x84, 0x21, 0x73, 0xa6, 0xb3, 0xa7, 0x28, 0x95, 0x66, 0x68, 0x7c, 0x30, 0x18, 0xf7, 0x64, 0xab, 0x18, 0x10, 0x31, 0x69, 0x91, 0x93, 0x28, 0x71, 0x3c, 0x3b, 0xd4, 0x63, 0xd3, 0x39, 0x8a, 0x1f, 0xeb, 0x8e, 0x68, 0xe4, 0x4c, 0xfe, 0x48, 0x2f, 0x72, 0x84, 0x7f, 0x46, 0xc8, 0x0e, 0x6c, 0xc7, 0xf6, 0xcc, 0xf1, 0x79, 0xf4, 0x82, 0xc8, 0x88, 0x59, 0x4e, 0x76, 0x27, 0x66, 0x53, 0xb4, 0x83, 0x98, 0xa2, 0x6c, 0x7c, 0x9e, 0x42, 0x0c, 0xb6, 0xc1, 0xd3, 0xbc, 0x76, 0x46, 0xf3, 0x3b, 0xb8, 0x32, 0xbf, 0xba, 0x98, 0x48, 0x9c, 0xad, 0xfb, 0xd5, 0x5d, 0xd8, 0xb2, 0xc5, 0x76, 0x87, 0xa4, 0x7a, 0xcb, 0xa4, 0xab, 0x39, 0x01, 0x52, 0xd8, 0xfb, 0xb3, 0xf2, 0x03, 0x27, 0xd8, 0x24, 0xb2, 0x84, 0xd2, 0x88, 0xfb, 0x01, 0x52, 0xe4, 0x9f, 0xc4, 0x46, 0x78, 0xae, 0xd4, 0xd3, 0xf0, 0x85, 0xb7, 0xc5, 0x5d, 0xe7, 0x7b, 0xd4, 0x5a, 0xf8, 0x12, 0xfc, 0x37, 0x94, 0x4a, 0xd2, 0x45, 0x4f, 0x99, 0xfb, 0xb3, 0x4a, 0x58, 0x3b, 0xf1, 0x6b, 0x67, 0x65, 0x9e, 0x6f, 0x21, 0x6d, 0x34, 0xb1, 0xd7, 0x9b, 0x1b, 0x4d, 0xec, 0xc0, 0x98, 0xa4, 0x42, 0x07, 0xe1, 0xc5, 0xfe, 0xeb, 0x6c, 0xe3, 0x0a, 0xcc, 0x2c, 0xf7, 0xe2, 0xb1, 0x34, 0x49, 0x0b, 0x44, 0x27, 0x44, 0x77, 0x2d, 0x18, 0x4e, 0x59, 0x03, 0x8a, 0xa5, 0x17, 0xa9, 0x71, 0x54, 0x18, 0x1e, 0x4d, 0xfd, 0x94, 0xfe, 0x72, 0xa5, 0xa4, 0xca, 0x2e, 0x7e, 0x22, 0xbc, 0xe7, 0x33, 0xd0, 0x3e, 0x7d, 0x93, 0x19, 0x71, 0x0b, 0xef, 0xbc, 0x30, 0xd7, 0x82, 0x6b, 0x72, 0x85, 0x19, 0xba, 0x74, 0x69, 0x0e, 0x4f, 0x90, 0x65, 0x87, 0xa0, 0x38, 0x28, 0x95, 0xb9, 0x0d, 0x82, 0xed, 0x3e, 0x35, 0x7f, 0xaf, 0x8e, 0x59, 0xac, 0xa8, 0x5f, 0xd2, 0x06, 0x3a, 0xb5, 0x92, 0xd8, 0x3d, 0x24, 0x5a, 0x91, 0x9e, 0xa5, 0x3c, 0x50, 0x1b, 0x9a, 0xcc, 0xd2, 0xa1, 0xed, 0x95, 0x1f, 0x43, 0xc0, 0x49, 0xab, 0x9d, 0x25, 0xc7, 0xf1, 0xb7, 0x0a, 0xe4, 0xf9, 0x42, 0xed, 0xb1, 0xf3, 0x11, 0xf7, 0x41, 0x78, 0x33, 0x06, 0x22, 0x45, 0xb4, 0x29, 0xd4, 0xf0, 0x13, 0xae, 0x90, 0x19, 0xff, 0x52, 0x04, 0x4c, 0x97, 0xc7, 0x3b, 0x88, 0x82, 0xcf, 0x03, 0x95, 0x5c, 0x73, 0x9f, 0x87, 0x4a, 0x02, 0x96, 0x37, 0xc0, 0xf0, 0x60, 0x71, 0x00, 0xe3, 0x07, 0x0f, 0x40, 0x8d, 0x08, 0x2a, 0xa7, 0xa2, 0xab, 0xf1, 0x3e, 0x73, 0xbd, 0x1e, 0x25, 0x2c, 0x22, 0x8a, 0xba, 0x7a, 0x9c, 0x1f, 0x07, 0x5b, 0xc4, 0x39, 0x57, 0x1b, 0x35, 0x93, 0x2f, 0x5c, 0x91, 0x2c, 0xb0, 0xb3, 0x8d, 0xa1, 0xc9, 0x5e, 0x64, 0xfc, 0xf9, 0xbf, 0xec, 0x0b, 0x9b, 0x0d, 0xd8, 0xf0, 0x42, 0xfd, 0xf0, 0x5e, 0x50, 0x58, 0x29, 0x9e, 0x96, 0xe4, 0x18, 0x50, 0x74, 0x91, 0x9d, 0x90, 0xb7, 0xb3, 0xb0, 0xa9, 0x7e, 0x22, 0x42, 0xca, 0x08, 0xcd, 0x99, 0xc9, 0xec, 0xb1, 0x2f, 0xc4, 0x9a, 0xdb, 0x2b, 0x25, 0x72, 0x40, 0xcc, 0x38, 0x78, 0x02, 0xf0, 0x0e, 0x0e, 0x49, 0x95, 0x26, 0x63, 0xea, 0x27, 0x84, 0x08, 0x70, 0x9b, 0xce, 0x5b, 0x36, 0x3c, 0x03, 0x60, 0x93, 0xd7, 0xa0, 0x5d, 0x44, 0x0c, 0x9e, 0x7a, 0x7a, 0xbb, 0x3d, 0x71, 0xeb, 0xb4, 0xd1, 0x0b, 0xfc, 0x77, 0x81, 0xbc, 0xd6, 0x6f, 0x79, 0x32, 0x2c, 0x18, 0x26, 0x2d, 0xfc, 0x2d, 0xcc, 0xf3, 0xe5, 0xf1, 0xea, 0x98, 0xbe, 0xa3, 0xca, 0xae, 0x8a, 0x83, 0x70, 0x63, 0x12, 0x76, 0x44, 0x23, 0xa6, 0x92, 0xae, 0x0c, 0x1e, 0x2e, 0x23, 0xb0, 0x16, 0x86, 0x5f, 0xfb, 0x12, 0x5b, 0x22, 0x38, 0x57, 0x54, 0x7a, 0xc7, 0xe2, 0x46, 0x84, 0x33, 0xb5, 0x26, 0x98, 0x43, 0xab, 0xba, 0xbb, 0xe9, 0xf6, 0xf4, 0x38, 0xd7, 0xe3, 0x87, 0xe3, 0x61, 0x7a, 0x21, 0x9f, 0x62, 0x54, 0x0e, 0x73, 0x43, 0xe1, 0xbb, 0xf4, 0x93, 0x55, 0xfb, 0x5a, 0x19, 0x38, 0x04, 0x84, 0x39, 0xcb, 0xa5, 0xce, 0xe8, 0x19, 0x19, 0x9b, 0x2b, 0x5c, 0x39, 0xfd, 0x35, 0x1a, 0xa2, 0x74, 0x53, 0x6a, 0xad, 0xb6, 0x82, 0xb5, 0x78, 0x94, 0x3f, 0x0c, 0xcf, 0x48, 0xe4, 0xec, 0x7d, 0xdc, 0x93, 0x8e, 0x2f, 0xd0, 0x1a, 0xcf, 0xaa, 0x1e, 0x72, 0x17, 0xf7, 0xb3, 0x89, 0x28, 0x5c, 0x0d, 0xfd, 0x31, 0xa1, 0x54, 0x5e, 0xd3, 0xa8, 0x5f, 0xac, 0x8e, 0xb9, 0xda, 0xb6, 0xee, 0x82, 0x6a, 0xf9, 0x0f, 0x9e, 0x1e, 0xe5, 0xd5, 0x55, 0xdd, 0x1c, 0x05, 0xae, 0xc0, 0x77, 0xf7, 0xc8, 0x03, 0xcb, 0xc2, 0xf1, 0xcf, 0x98, 0x39, 0x3f, 0x0f, 0x37, 0x83, 0x8f, 0xfe, 0xa3, 0x72, 0xff, 0x70, 0x88, 0x86, 0xb0, 0x59, 0x34, 0xe1, 0xa6, 0x45, 0x12, 0xde, 0x14, 0x46, 0x08, 0x86, 0x4a, 0x88, 0xa5, 0xc3, 0xa1, 0x73, 0xfd, 0xcf, 0xdf, 0x57, 0x25, 0xda, 0x91, 0x6e, 0xd5, 0x07, 0xe4, 0xca, 0xec, 0x87, 0x87, 0xbe, 0xfb, 0x91, 0xe3, 0xec, 0x9b, 0x22, 0x2f, 0xa0, 0x9f, 0x37, 0x4b, 0xd9, 0x68, 0x81, 0xac, 0x2d, 0xdd, 0x1f, 0x88, 0x5d, 0x42, 0xea, 0x58, 0x4c, - 0xe0, 0x8b, 0x0e, 0x45, 0x5a, 0x35, 0x0a, 0xe5, 0x4d, 0x76, 0x34, 0x9a, 0xa6, 0x8c, 0x71, 0xae]; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6a4033c..983c604 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,8 +22,6 @@ use hkdf::Hkdf; use smoltcp_tls::key::*; use smoltcp_tls::buffer::TlsBuffer; -mod encrypted; -use encrypted::ENCRYPTED_DATA; struct CountingRng(u64); @@ -76,24 +74,32 @@ fn main() { // tls_socket.tls_connect(&mut sockets).unwrap(); - let psk: [u8; 32] = [0; 32]; - let early_secret = Hkdf::::new(None, &psk); + let hello_hash = { + Sha384::new() + .chain(&CLIENT_HELLO) + .chain(&SERVER_HELLO) + .finalize() + }; + println!("Hash: {:?}", hello_hash); + + let psk: [u8; 48] = [0; 48]; + let early_secret = Hkdf::::new(None, &psk); let derived_secret = derive_secret( &early_secret, "derived", - Sha256::new().chain("") + Sha384::new().chain("") ); - let (handshake_secret, handshake_secret_hkdf) = Hkdf::::extract( + let (handshake_secret, handshake_secret_hkdf) = Hkdf::::extract( Some(&derived_secret), &SHARED_SECRET ); let client_handshake_traffic_secret = { let hkdf_label = HkdfLabel { - length: 32, + length: 48, label_length: 18, label: b"tls13 c hs traffic", - context_length: 32, - context: &HELLO_HASH, + context_length: 48, + context: &hello_hash, }; let mut array = [0; 100]; let mut buffer = TlsBuffer::new(&mut array); @@ -101,17 +107,18 @@ fn main() { let info: &[u8] = buffer.into(); // Define output key material (OKM), dynamically sized by hash - let mut okm: GenericArray = GenericArray::default(); + let mut okm: GenericArray = GenericArray::default(); handshake_secret_hkdf.expand(info, &mut okm).unwrap(); okm }; + let server_handshake_traffic_secret = { let hkdf_label = HkdfLabel { - length: 32, + length: 48, label_length: 18, label: b"tls13 s hs traffic", - context_length: 32, - context: &HELLO_HASH, + context_length: 48, + context: &hello_hash, }; let mut array = [0; 100]; let mut buffer = TlsBuffer::new(&mut array); @@ -119,13 +126,14 @@ fn main() { let info: &[u8] = buffer.into(); // Define output key material (OKM), dynamically sized by hash - let mut okm: GenericArray = GenericArray::default(); + let mut okm: GenericArray = GenericArray::default(); handshake_secret_hkdf.expand(info, &mut okm).unwrap(); okm }; + let server_handshake_write_key = { let hkdf_label = HkdfLabel { - length: 16, + length: 32, label_length: 9, label: b"tls13 key", context_length: 0, @@ -136,9 +144,9 @@ fn main() { buffer.enqueue_hkdf_label(hkdf_label); let info: &[u8] = buffer.into(); - // Define output key material (OKM), dynamically sized by hash - let mut okm: GenericArray = GenericArray::default(); - Hkdf::::from_prk(&server_handshake_traffic_secret) + // Define output key material (OKM), dynamically sized by cipher key + let mut okm: GenericArray = GenericArray::default(); + Hkdf::::from_prk(&server_handshake_traffic_secret) .unwrap() .expand(info, &mut okm); okm @@ -158,18 +166,18 @@ fn main() { // Define output key material (OKM), dynamically sized by hash let mut okm: GenericArray = GenericArray::default(); - Hkdf::::from_prk(&server_handshake_traffic_secret) + Hkdf::::from_prk(&server_handshake_traffic_secret) .unwrap() .expand(info, &mut okm); okm }; - let cipher: Aes128Gcm = Aes128Gcm::new(&server_handshake_write_key); + let cipher: Aes256Gcm = Aes256Gcm::new(&server_handshake_write_key); let decrypted_data = { - let mut vec: Vec = Vec::from_slice(&ENCRYPTED_DATA).unwrap(); + let mut vec: Vec = Vec::from_slice(&CIPHERTEXT).unwrap(); cipher.decrypt_in_place( &server_handshake_write_iv, &[ - 0x17, 0x03, 0x03, 0x04, 0x75 + 0x17, 0x03, 0x03, 0x00, 0x27 ], &mut vec ).unwrap(); @@ -178,22 +186,47 @@ fn main() { println!("{:x?}", client_handshake_traffic_secret); println!("{:x?}", server_handshake_traffic_secret); - println!("{:x?}", server_handshake_write_key); - println!("{:x?}", server_handshake_write_iv); + println!("Server handshake key: {:?}", server_handshake_write_key); + println!("Server handshake iv: {:?}", server_handshake_write_iv); println!("{:x?}", decrypted_data); - + println!("Decrypted data length: {:?}", decrypted_data.len()); } const SHARED_SECRET: [u8; 32] = [ - 0xdf, 0x4a, 0x29, 0x1b, 0xaa, 0x1e, 0xb7, 0xcf, - 0xa6, 0x93, 0x4b, 0x29, 0xb4, 0x74, 0xba, 0xad, - 0x26, 0x97, 0xe2, 0x9f, 0x1f, 0x92, 0x0d, 0xcc, - 0x77, 0xc8, 0xa0, 0xa0, 0x88, 0x44, 0x76, 0x24 + 43, 165, 163, 26, 69, 90, 77, 219, 49, 63, 128, 28, 75, 77, 23, 115, 28, 228, 145, 134, 124, 198, 18, 28, 27, 165, 10, 201, 94, 156, 148, 150 ]; -const HELLO_HASH: [u8; 32] = [ - 0xda, 0x75, 0xce, 0x11, 0x39, 0xac, 0x80, 0xda, - 0xe4, 0x04, 0x4d, 0xa9, 0x32, 0x35, 0x0c, 0xf6, - 0x5c, 0x97, 0xcc, 0xc9, 0xe3, 0x3f, 0x1e, 0x6f, - 0x7d, 0x2d, 0x4b, 0x18, 0xb7, 0x36, 0xff, 0xd5 +const CLIENT_HELLO: [u8; 0xCB] = [ + 0x01, 0x00, 0x00, 0xc7, 0x03, 0x03, 0x95, 0x2a, 0xfc, 0xc8, 0xee, 0x76, 0xab, 0xaf, 0x6e, 0x99, + 0xd0, 0x63, 0x03, 0x0b, 0x7d, 0x5e, 0x44, 0xa2, 0x2d, 0x00, 0x99, 0xb4, 0x10, 0x0b, 0x22, 0x55, + 0xf6, 0xe9, 0x7e, 0xbf, 0xdc, 0xd5, 0x20, 0x81, 0x52, 0xe7, 0x4f, 0x58, 0x54, 0x5a, 0x9f, 0x89, + 0xc1, 0x2b, 0xd5, 0x40, 0x61, 0x53, 0xeb, 0x50, 0x8e, 0x77, 0x3a, 0xa9, 0x44, 0x07, 0x0c, 0x2c, + 0xab, 0xeb, 0xf5, 0x6b, 0x3d, 0x91, 0x6e, 0x00, 0x08, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0x13, + 0x04, 0x01, 0x00, 0x00, 0x76, 0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x18, + 0x00, 0x16, 0x04, 0x03, 0x08, 0x07, 0x08, 0x09, 0x04, 0x01, 0x08, 0x04, 0x08, 0x0a, 0x05, 0x01, + 0x08, 0x05, 0x08, 0x0b, 0x06, 0x01, 0x08, 0x06, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x17, + 0x00, 0x33, 0x00, 0x47, 0x00, 0x45, 0x00, 0x17, 0x00, 0x41, 0x04, 0x0e, 0x9f, 0xff, 0x47, 0x1c, + 0x7c, 0xa3, 0xf8, 0x24, 0xfe, 0x25, 0x57, 0x37, 0xbb, 0x0b, 0xe2, 0x11, 0xb2, 0xec, 0x5f, 0xa9, + 0x33, 0x2f, 0x66, 0xe8, 0x18, 0xb4, 0x1d, 0x44, 0x61, 0xca, 0x91, 0x89, 0x5f, 0xa2, 0x0f, 0x01, + 0x88, 0x97, 0xed, 0xe8, 0xc8, 0x39, 0x71, 0x89, 0x93, 0x7d, 0x35, 0xc2, 0xce, 0xcb, 0x6b, 0xbb, + 0xe0, 0x3f, 0xe5, 0xde, 0x6e, 0x3b, 0x17, 0x68, 0x91, 0xbb, 0xe9 +]; + +const SERVER_HELLO: [u8; 0x9B] = [ + 0x02, 0x00, 0x00, 0x97, 0x03, 0x03, 0x5a, 0x7a, 0x25, 0x58, 0x0a, 0x34, 0x9c, 0x66, 0x08, 0x1f, + 0xbf, 0x98, 0x03, 0xd3, 0x55, 0x37, 0x14, 0xe9, 0xdb, 0xfb, 0x12, 0xf3, 0x8c, 0x69, 0x1e, 0xc1, + 0xd4, 0xfc, 0x67, 0x4b, 0x06, 0x47, 0x20, 0x81, 0x52, 0xe7, 0x4f, 0x58, 0x54, 0x5a, 0x9f, 0x89, + 0xc1, 0x2b, 0xd5, 0x40, 0x61, 0x53, 0xeb, 0x50, 0x8e, 0x77, 0x3a, 0xa9, 0x44, 0x07, 0x0c, 0x2c, + 0xab, 0xeb, 0xf5, 0x6b, 0x3d, 0x91, 0x6e, 0x13, 0x02, 0x00, 0x00, 0x4f, 0x00, 0x2b, 0x00, 0x02, + 0x03, 0x04, 0x00, 0x33, 0x00, 0x45, 0x00, 0x17, 0x00, 0x41, 0x04, 0xb9, 0x93, 0x81, 0xfd, 0xa5, + 0xdc, 0x6d, 0xe2, 0x64, 0x44, 0xbe, 0xa6, 0xd4, 0x7f, 0x8c, 0x0e, 0xb3, 0x6f, 0x4a, 0xcf, 0xa1, + 0x73, 0x1b, 0x3c, 0x93, 0x41, 0xef, 0x97, 0x2c, 0x3a, 0x2a, 0xd4, 0xb1, 0xe8, 0xc3, 0x06, 0x3a, + 0xf8, 0x2e, 0x8a, 0xf3, 0x35, 0x0a, 0x47, 0x98, 0x47, 0x67, 0x28, 0xab, 0x9d, 0xd2, 0xb4, 0x98, + 0x33, 0xc6, 0xa5, 0x3d, 0x99, 0x7e, 0x28, 0x89, 0x2d, 0x9d, 0xd9 +]; + +const CIPHERTEXT: [u8; 39] = [ + 0xf6, 0xa9, 0x89, 0x64, 0x69, 0xf7, 0x87, 0x96, 0x61, 0xf6, 0xc9, 0xf8, 0x02, 0xfb, 0xfa, 0xa0, + 0xae, 0xca, 0x4f, 0x59, 0x9b, 0xb4, 0x26, 0x2b, 0x06, 0x54, 0x4b, 0xce, 0xbc, 0xa4, 0x27, 0x55, + 0xc0, 0xe4, 0x69, 0x33, 0x25, 0x46, 0x7f ]; \ No newline at end of file diff --git a/src/parse.rs b/src/parse.rs index 67d4efd..47566ae 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,5 +1,6 @@ use nom::IResult; use nom::bytes::complete::take; +use nom::bytes::complete::tag; use nom::combinator::complete; use nom::sequence::tuple; use nom::error::ErrorKind; @@ -53,7 +54,7 @@ pub(crate) fn parse_tls_repr(bytes: &[u8]) -> IResult<&[u8], TlsRepr> { Ok((rest, repr)) } -fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> { +pub(crate) fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> { let handshake_type = take(1_usize); let length = take(3_usize); @@ -73,6 +74,30 @@ fn parse_handshake(bytes: &[u8]) -> IResult<&[u8], HandshakeRepr> { repr.handshake_data = data; Ok((rest, repr)) }, + EncryptedExtensions => { + // Split data into EE and the last TLS content byte + let (tls_content_byte, ee_data) = take(repr.length)(rest)?; + + // Process TLS content byte. + complete( + tag(&[0x16]) + )(tls_content_byte)?; + + // Process EE + let (rest, handshake_data) = parse_encrypted_extensions( + ee_data + )?; + repr.handshake_data = HandshakeData::EncryptedExtensions( + handshake_data + ); + + // Verify that all bytes are comsumed + complete( + take(0_usize) + )(rest)?; + + Ok((&[], repr)) + } _ => todo!() } } @@ -126,27 +151,42 @@ fn parse_server_hello(bytes: &[u8]) -> IResult<&[u8], HandshakeData> { Ok((rest, HandshakeData::ServerHello(server_hello))) } -pub(crate) fn parse_encrypted_extensions(bytes: &[u8]) -> IResult<&[u8], EncryptedExtensions> { - let (mut rest, extension_length) = take(2_usize)(bytes)?; - let mut extension_length: i32 = NetworkEndian::read_u16(extension_length).into(); - let mut extension_vec: Vec = Vec::new(); - while extension_length > 0 { - let (rem, extension) = parse_extension(rest, HandshakeType::EncryptedExtensions)?; - rest = rem; - extension_length -= i32::try_from(extension.get_length()).unwrap(); +fn parse_encrypted_extensions(bytes: &[u8]) -> IResult<&[u8], EncryptedExtensions> { + let (mut rest, extension_length) = take(2_usize)(bytes)?; + let extension_length: u16 = NetworkEndian::read_u16(extension_length); + let mut extension_length_counter: i32 = extension_length.into(); + let mut extension_vec: Vec = Vec::new(); + + // Split the data into "extensions" and the rest + let (rest, mut encypted_extension_data) = + take(usize::try_from(extension_length).unwrap())(rest)?; + + while extension_length_counter > 0 { + let (rem, extension) = parse_extension( + encypted_extension_data, + HandshakeType::EncryptedExtensions + )?; + encypted_extension_data = rem; + extension_length_counter -= i32::try_from(extension.get_length()).unwrap(); // Todo:: Proper error - if extension_length < 0 { + if extension_length_counter < 0 { todo!() } extension_vec.push(extension); - } + } let encrypted_extensions = EncryptedExtensions { - length: u16::try_from(extension_length).unwrap(), + length: extension_length, extensions: extension_vec - }; + }; + + // Force completeness. The entire slice is meant to be processed. + complete( + take(0_usize) + )(rest)?; + Ok((rest, encrypted_extensions)) } @@ -190,6 +230,38 @@ fn parse_extension(bytes: &[u8], handshake_type: HandshakeType) -> IResult<&[u8] _ => todo!() } }, + SupportedGroups => { // NamedGroupList + let (rest, length) = take(2_usize)(rest)?; + let length = NetworkEndian::read_u16(length); + + // Isolate contents, for easier error handling + let (rest, mut rem_data) = take(length)(rest)?; + + let mut named_group_extension = NamedGroupList { + length, + named_group_list: Vec::new(), + }; + + for index in 0..(length/2) { + let (rem, named_group) = take(2_usize)(rem_data)?; + rem_data = rem; + let named_group = NamedGroup::try_from( + NetworkEndian::read_u16(named_group) + ).unwrap(); + named_group_extension.named_group_list.push(named_group); + + // Assure completeness + if index == (length/2) { + complete(take(0_usize))(rem_data)?; + } + } + ( + rest, + ExtensionData::NegotiatedGroups( + named_group_extension + ) + ) + } KeyShare => { match handshake_type { HandshakeType::ClientHello => { diff --git a/src/session.rs b/src/session.rs index 39c31f5..ef50cfe 100644 --- a/src/session.rs +++ b/src/session.rs @@ -106,6 +106,8 @@ impl Session { .diffie_hellman(&encoded_point) .unwrap(); + log::info!("Shared secret: {:?}", ecdhe_shared_secret.as_bytes()); + // Generate Handshake secret match cipher_suite { CipherSuite::TLS_AES_128_GCM_SHA256 | @@ -287,7 +289,7 @@ impl Session { }, _ => unreachable!() } - } + }, CipherSuite::TLS_AES_256_GCM_SHA384 => { // Select 1 hash function, then update the hash self.hash = Hash::select_sha384(self.hash.clone()); @@ -376,7 +378,7 @@ impl Session { let server_handshake_iv: Vec = { let mut server_handshake_iv_holder = Vec::from_slice(&[0; 12]).unwrap(); hkdf_expand_label( - &client_handshake_traffic_secret_hkdf, + &server_handshake_traffic_secret_hkdf, "iv", "", &mut server_handshake_iv_holder @@ -405,11 +407,11 @@ impl Session { } ); - } + }, CipherSuite::TLS_AES_128_CCM_8_SHA256 => { unreachable!() } - } + }; self.state = TlsState::WAIT_EE; } @@ -465,11 +467,11 @@ impl Session { buffer: &mut dyn Buffer ) -> Result<(), Error> { let (nonce, cipher): (&Vec, &Cipher) = match self.role { - TlsRole::Client => {( + TlsRole::Server => {( self.client_nonce.as_ref().unwrap(), self.client_cipher.as_ref().unwrap() )}, - TlsRole::Server => {( + TlsRole::Client => {( self.server_nonce.as_ref().unwrap(), self.server_cipher.as_ref().unwrap() )}, diff --git a/src/tls.rs b/src/tls.rs index 2bc51dd..2e4f368 100644 --- a/src/tls.rs +++ b/src/tls.rs @@ -34,7 +34,7 @@ use alloc::vec::{ self, Vec }; use crate::Error as TlsError; use crate::tls_packet::*; -use crate::parse::{ parse_tls_repr, parse_encrypted_extensions }; +use crate::parse::{ parse_tls_repr, parse_handshake }; use crate::buffer::TlsBuffer; use crate::session::{Session, TlsRole}; @@ -117,7 +117,10 @@ impl TlsSocket { } // Handle TLS handshake through TLS states - match self.session.borrow().get_tls_state() { + let tls_state = { + self.session.borrow().get_tls_state() + }; + match tls_state { // Initiate TLS handshake TlsState::START => { // Prepare field that is randomised, @@ -131,7 +134,7 @@ impl TlsSocket { .client_hello(&ecdh_secret, random, session_id.clone()); // Update hash function with client hello handshake - let mut array = [0; 2048]; + let mut array = [0; 512]; let mut buffer = TlsBuffer::new(&mut array); buffer.enqueue_tls_repr(repr)?; let slice: &[u8] = buffer.into(); @@ -157,6 +160,10 @@ impl TlsSocket { // TLS client should jump from WAIT_SH directly to WAIT_CERT_CR directly. TlsState::WAIT_EE => {}, + // TLS Client wait for server's certificate + // No need to send anything + TlsState::WAIT_CERT_CR => {}, + _ => todo!() } @@ -191,7 +198,10 @@ impl TlsSocket { return Ok(()) } - match self.session.borrow().get_tls_state() { + let tls_state = { + self.session.borrow().get_tls_state() + }; + match tls_state { // During WAIT_SH for a TLS client, client should wait for ServerHello TlsState::WAIT_SH => { // Legacy_protocol must be TLS 1.2 @@ -302,11 +312,12 @@ impl TlsSocket { // This is indeed a desirable ServerHello TLS repr // Reprocess ServerHello into a slice // Update session with required parameter - let mut array = [0; 2048]; + let mut array = [0; 512]; let mut buffer = TlsBuffer::new(&mut array); - buffer.enqueue_tls_repr(repr); + buffer.enqueue_tls_repr(repr)?; let slice: &[u8] = buffer.into(); - self.session.borrow_mut().client_update_for_sh( + let mut session = self.session.borrow_mut(); + session.client_update_for_sh( selected_cipher.unwrap(), server_public.unwrap(), &slice[5..] @@ -331,21 +342,26 @@ impl TlsSocket { buffer.write_u16(repr.version.into())?; buffer.write_u16(repr.length)?; let associated_data: &[u8] = buffer.into(); - self.session.borrow().encrypt_in_place( - associated_data, - &mut payload - ); + { + self.session.borrow().decrypt_in_place( + associated_data, + &mut payload + ); + } + log::info!("Decrypted payload {:?}", payload); // TODO: Parse payload of EE - let (_, encrypted_extensions) = - parse_encrypted_extensions(&payload) - .map_err(|_| Error::Unrecognized)?; + let parse_result = parse_handshake(&payload); + let (_, encrypted_extensions_handshake) = parse_result + .map_err(|_| Error::Unrecognized)?; // TODO: Process payload // Practically, nothing will be done about cookies/server name // Extension processing is therefore skipped + log::info!("EE handshake: {:?}", encrypted_extensions_handshake); self.session.borrow_mut().client_update_for_ee(); + log::info!("Transition to WAIT_CERT_CR"); }, // In this stage, wait for a certificate from server diff --git a/src/tls_packet.rs b/src/tls_packet.rs index f89a214..45dd7fc 100644 --- a/src/tls_packet.rs +++ b/src/tls_packet.rs @@ -188,7 +188,7 @@ pub(crate) enum HandshakeData<'a> { Uninitialized, ClientHello(ClientHello<'a>), ServerHello(ServerHello<'a>), - ExcryptedExtensions(EncryptedExtensions), + EncryptedExtensions(EncryptedExtensions), } impl<'a> HandshakeData<'a> { @@ -558,6 +558,9 @@ impl SignatureSchemeList { #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)] #[repr(u16)] pub(crate) enum NamedGroup { + #[num_enum(default)] + UNKNOWN = 0x0000, + /* Elliptic Curve Groups (ECDHE) */ secp256r1 = 0x0017, secp384r1 = 0x0018,