From 38bf1d3c3b02cb0f96afe44b53360de901ba510d Mon Sep 17 00:00:00 2001 From: occheung Date: Sun, 18 Oct 2020 20:02:40 +0800 Subject: [PATCH] parse: init ee --- Cargo.toml | 14 +++++++-- src/buffer.rs | 2 +- src/encrypted.rs | 2 ++ src/lib.rs | 1 + src/main.rs | 43 ++++++++++++++++++++++++++-- src/parse.rs | 29 ++++++++++++++++++- src/session.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++- src/tls.rs | 40 +++++++++++++++++++++++--- src/tls_packet.rs | 17 +++++++---- 9 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 src/encrypted.rs diff --git a/Cargo.toml b/Cargo.toml index 06b8358..d99dfd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,8 +5,6 @@ authors = ["occheung"] edition = "2018" [dependencies] -aes-gcm = "0.7.0" -ccm = "0.2.0" hkdf = "0.9.0" sha2 = { version = "0.9.1", default-features = false } byteorder = { version = "1.3.4", default-features = false } @@ -15,6 +13,16 @@ log = "0.4.11" generic-array = "0.14.4" heapless = "0.5.6" +[dependencies.aes-gcm] +version = "0.8.0" +default-features = true +features = [ "heapless" ] + +[dependencies.ccm] +version = "0.3.0" +default-features = true +features = [ "heapless" ] + [dependencies.smoltcp] version = "0.6.0" default-features = false @@ -28,7 +36,7 @@ features = [] [dependencies.chacha20poly1305] version = "0.6.0" default-features = false -features = [ "alloc", "chacha20" ] +features = [ "alloc", "chacha20", "heapless" ] [dependencies.p256] version = "0.5.0" diff --git a/src/buffer.rs b/src/buffer.rs index 59596a7..8060622 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -86,7 +86,7 @@ impl<'a> TlsBuffer<'a> { self.write_u16(tls_repr.version.into())?; self.write_u16(tls_repr.length)?; if let Some(app_data) = tls_repr.payload { - self.write(app_data)?; + self.write(app_data.as_slice())?; } else if let Some(handshake_repr) = tls_repr.handshake { // Queue handshake_repr into buffer self.enqueue_handshake_repr(handshake_repr)?; diff --git a/src/encrypted.rs b/src/encrypted.rs new file mode 100644 index 0000000..44211e3 --- /dev/null +++ b/src/encrypted.rs @@ -0,0 +1,2 @@ +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/lib.rs b/src/lib.rs index 224df61..c239d62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,5 +16,6 @@ pub enum Error { PropagatedError(smoltcp::Error), ParsingError, EncryptionError, + DecryptionError, CapacityError, } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 09bb89b..6a4033c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,9 @@ use hkdf::Hkdf; use smoltcp_tls::key::*; use smoltcp_tls::buffer::TlsBuffer; +mod encrypted; +use encrypted::ENCRYPTED_DATA; + struct CountingRng(u64); impl RngCore for CountingRng { @@ -120,7 +123,7 @@ fn main() { handshake_secret_hkdf.expand(info, &mut okm).unwrap(); okm }; - let client_handshake_write_key = { + let server_handshake_write_key = { let hkdf_label = HkdfLabel { length: 16, label_length: 9, @@ -135,15 +138,49 @@ fn main() { // Define output key material (OKM), dynamically sized by hash let mut okm: GenericArray = GenericArray::default(); - Hkdf::::from_prk(&client_handshake_traffic_secret) + Hkdf::::from_prk(&server_handshake_traffic_secret) .unwrap() .expand(info, &mut okm); okm }; + let server_handshake_write_iv = { + let hkdf_label = HkdfLabel { + length: 12, + label_length: 8, + label: b"tls13 iv", + context_length: 0, + context: b"", + }; + let mut array = [0; 100]; + let mut buffer = TlsBuffer::new(&mut array); + 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) + .unwrap() + .expand(info, &mut okm); + okm + }; + let cipher: Aes128Gcm = Aes128Gcm::new(&server_handshake_write_key); + let decrypted_data = { + let mut vec: Vec = Vec::from_slice(&ENCRYPTED_DATA).unwrap(); + cipher.decrypt_in_place( + &server_handshake_write_iv, + &[ + 0x17, 0x03, 0x03, 0x04, 0x75 + ], + &mut vec + ).unwrap(); + vec + }; println!("{:x?}", client_handshake_traffic_secret); println!("{:x?}", server_handshake_traffic_secret); - println!("{:x?}", client_handshake_write_key); + println!("{:x?}", server_handshake_write_key); + println!("{:x?}", server_handshake_write_iv); + println!("{:x?}", decrypted_data); } diff --git a/src/parse.rs b/src/parse.rs index 5fe603f..67d4efd 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -43,7 +43,9 @@ pub(crate) fn parse_tls_repr(bytes: &[u8]) -> IResult<&[u8], TlsRepr> { repr.handshake = Some(handshake); }, ChangeCipherSpec | ApplicationData => { - repr.payload = Some(bytes); + let mut vec: Vec = Vec::new(); + vec.extend_from_slice(bytes); + repr.payload = Some(vec); }, _ => todo!() } @@ -124,6 +126,30 @@ 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(); + + // Todo:: Proper error + if extension_length < 0 { + todo!() + } + + extension_vec.push(extension); + } + + let encrypted_extensions = EncryptedExtensions { + length: u16::try_from(extension_length).unwrap(), + extensions: extension_vec + }; + Ok((rest, encrypted_extensions)) +} + fn parse_extension(bytes: &[u8], handshake_type: HandshakeType) -> IResult<&[u8], Extension> { let extension_type = take(2_usize); let length = take(2_usize); @@ -139,6 +165,7 @@ fn parse_extension(bytes: &[u8], handshake_type: HandshakeType) -> IResult<&[u8] // Process extension data according to extension_type // TODO: Deal with HelloRetryRequest let (rest, extension_data) = { + // TODO: Handle all mandatory extension types use ExtensionType::*; match extension_type { SupportedVersions => { diff --git a/src/session.rs b/src/session.rs index 85d1409..39c31f5 100644 --- a/src/session.rs +++ b/src/session.rs @@ -27,6 +27,7 @@ pub(crate) struct Session { changed_cipher_spec: bool, // Handshake secret, Master secret // Early secret is computed right before HS + // TLS standard: Secrets should not be stored unnecessarily latest_secret: Option>, // Hash functions needed hash: Hash, @@ -412,6 +413,10 @@ impl Session { self.state = TlsState::WAIT_EE; } + pub(crate) fn client_update_for_ee(&mut self) { + self.state = TlsState::WAIT_CERT_CR; + } + pub(crate) fn verify_session_id_echo(&self, session_id_echo: &[u8]) -> bool { if let Some(session_id_inner) = self.session_id { session_id_inner == session_id_echo @@ -431,6 +436,50 @@ impl Session { pub(crate) fn receive_change_cipher_spec(&mut self) { self.changed_cipher_spec = true; } + + pub(crate) fn encrypt_in_place( + &self, + associated_data: &[u8], + buffer: &mut dyn Buffer + ) -> Result<(), Error> { + let (nonce, cipher): (&Vec, &Cipher) = match self.role { + TlsRole::Client => {( + self.client_nonce.as_ref().unwrap(), + self.client_cipher.as_ref().unwrap() + )}, + TlsRole::Server => {( + self.server_nonce.as_ref().unwrap(), + self.server_cipher.as_ref().unwrap() + )}, + }; + cipher.encrypt_in_place( + &GenericArray::from_slice(nonce), + associated_data, + buffer + ) + } + + pub(crate) fn decrypt_in_place( + &self, + associated_data: &[u8], + buffer: &mut dyn Buffer + ) -> Result<(), Error> { + let (nonce, cipher): (&Vec, &Cipher) = match self.role { + TlsRole::Client => {( + self.client_nonce.as_ref().unwrap(), + self.client_cipher.as_ref().unwrap() + )}, + TlsRole::Server => {( + self.server_nonce.as_ref().unwrap(), + self.server_cipher.as_ref().unwrap() + )}, + }; + cipher.decrypt_in_place( + &GenericArray::from_slice(nonce), + associated_data, + buffer + ) + } } #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -525,7 +574,7 @@ pub(crate) enum Cipher { impl Cipher { pub(crate) fn encrypt_in_place( - &mut self, + &self, nonce: &GenericArray, associated_data: &[u8], buffer: &mut dyn Buffer @@ -545,4 +594,26 @@ impl Cipher { } }.map_err(|_| Error::EncryptionError) } + + pub(crate) fn decrypt_in_place( + &self, + nonce: &GenericArray, + associated_data: &[u8], + buffer: &mut dyn Buffer + ) -> Result<(), Error> { + match self { + Cipher::Aes128Gcm { aes128gcm } => { + aes128gcm.decrypt_in_place(nonce, associated_data, buffer) + }, + Cipher::Aes256Gcm { aes256gcm } => { + aes256gcm.decrypt_in_place(nonce, associated_data, buffer) + }, + Cipher::Chacha20poly1305 { chacha20poly1305 } => { + chacha20poly1305.decrypt_in_place(nonce, associated_data, buffer) + }, + Cipher::Ccm { ccm } => { + ccm.decrypt_in_place(nonce, associated_data, buffer) + } + }.map_err(|_| Error::DecryptionError) + } } \ No newline at end of file diff --git a/src/tls.rs b/src/tls.rs index d3534f7..2bc51dd 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; +use crate::parse::{ parse_tls_repr, parse_encrypted_extensions }; use crate::buffer::TlsBuffer; use crate::session::{Session, TlsRole}; @@ -179,7 +179,7 @@ impl TlsSocket { } // Process TLS ingress during handshake - fn process(&self, repr: TlsRepr) -> Result<()> { + fn process(&self, mut repr: TlsRepr) -> Result<()> { // Change_cipher_spec check: // Must receive CCS before recv peer's FINISH message // i.e. Must happen after START and before CONNECTED @@ -316,8 +316,42 @@ impl TlsSocket { // Expect encrypted extensions after receiving SH TlsState::WAIT_EE => { + // Check that the packet is classified as application data + if !repr.is_application_data() { + // Abort communication, this affect IV calculation + todo!() + } + // ExcepytedExtensions are disguised as ApplicationData // Pull out the `payload` from TlsRepr, decrypt as EE + let mut payload = repr.payload.take().unwrap(); + let mut array: [u8; 5] = [0; 5]; + let mut buffer = TlsBuffer::new(&mut array); + buffer.write_u8(repr.content_type.into())?; + 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 + ); + + // TODO: Parse payload of EE + let (_, encrypted_extensions) = + parse_encrypted_extensions(&payload) + .map_err(|_| Error::Unrecognized)?; + + // TODO: Process payload + // Practically, nothing will be done about cookies/server name + // Extension processing is therefore skipped + + self.session.borrow_mut().client_update_for_ee(); + }, + + // In this stage, wait for a certificate from server + // Parse the certificate and check its content + TlsState::WAIT_CERT_CR => { + }, _ => {}, @@ -370,10 +404,8 @@ impl TlsSocket { if !tcp_socket.can_recv() { return Ok((Vec::new())); } - let array_size = tcp_socket.recv_slice(byte_array)?; let mut vec: Vec = Vec::new(); - let mut bytes: &[u8] = &byte_array[..array_size]; loop { match parse_tls_repr(bytes) { diff --git a/src/tls_packet.rs b/src/tls_packet.rs index 553749e..f89a214 100644 --- a/src/tls_packet.rs +++ b/src/tls_packet.rs @@ -46,7 +46,7 @@ pub(crate) struct TlsRepr<'a> { pub(crate) content_type: TlsContentType, pub(crate) version: TlsVersion, pub(crate) length: u16, - pub(crate) payload: Option<&'a[u8]>, + pub(crate) payload: Option>, pub(crate) handshake: Option> } @@ -96,14 +96,21 @@ impl<'a> TlsRepr<'a> { self.handshake.is_none() && self.payload.is_some() && { - if let Some(data) = self.payload { - [0x01] == data + if let Some(data) = &self.payload { + data[0] == 0x01 && + data.len() == 1 } else { false } } } + pub(crate) fn is_application_data(&self) -> bool { + self.content_type == TlsContentType::ApplicationData && + self.handshake.is_none() && + self.payload.is_some() + } + pub(crate) fn decrypt_ee(&self, shared_secret: &SharedSecret) -> HandshakeRepr { todo!() } @@ -405,8 +412,8 @@ pub(crate) struct ServerHello<'a> { #[derive(Debug, Clone)] pub(crate) struct EncryptedExtensions { - length: u16, - extensions: Vec, + pub(crate) length: u16, + pub(crate) extensions: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]