client_hello.rs
1 use crate::{ChExtension, ClientHello, eprintln_red, println_cyan, println_green}; 2 use crate::HandshakeProtocol; 3 4 pub(crate) fn client_hello_handler(buffer: Vec<u8>) -> ClientHello { 5 let mut client_hello = ClientHello { 6 content_type: buffer[0], 7 version: u16::from_be_bytes([buffer[1], buffer[2]]), 8 length: u16::from_be_bytes([buffer[3], buffer[4]]), 9 handshake: Box::new(HandshakeProtocol { 10 handshake_type: buffer[5], 11 length: u32::from_be_bytes([0x0, buffer[6], buffer[7], buffer[8]]), 12 version: u16::from_be_bytes([buffer[9], buffer[10]]), 13 random: vec![], 14 session_id_length: buffer[43], 15 legacy_session_id: vec![], 16 cipher_suites_length: 0, 17 cipher_suites: vec![], 18 compression_methods_length: 0, 19 legacy_compression_methods: vec![], 20 extensions_length: 0, 21 extensions: vec![], 22 }), 23 }; 24 25 // modify any non-directly assignable values :3 26 if let ClientHello { ref mut handshake, .. } = &mut client_hello { 27 { 28 let mut temp_bytes: Vec<u8> = vec![]; 29 30 for byte in buffer[11..=42].iter() { 31 temp_bytes.push(*byte); 32 } 33 34 handshake.random = temp_bytes; 35 } 36 println_cyan!("{:?}", handshake.random); 37 38 let relative_start = 44 + handshake.session_id_length as usize; 39 40 { 41 let mut temp_bytes: Vec<u8> = vec![]; 42 43 for byte in buffer[44..relative_start].iter() { 44 temp_bytes.push(*byte); 45 } 46 47 handshake.legacy_session_id = temp_bytes; 48 } 49 50 println_cyan!("{:?}", handshake.legacy_session_id); 51 { 52 println_cyan!("{} || {}", buffer[relative_start], buffer[relative_start + 1]); 53 handshake.cipher_suites_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); // todo: fix this mf 54 55 for i in (relative_start + 2..=relative_start + (handshake.cipher_suites_length as usize)).step_by(2) { 56 let cipher = u16::from_be_bytes([buffer[i], buffer[i + 1]]); 57 handshake.cipher_suites.push(cipher); 58 59 println_cyan!("supported cipher: {:02x}{:02x} || index: {}", buffer[i], buffer[i + 1], i+1); 60 } 61 } 62 63 let relative_start = relative_start + 2 + (handshake.cipher_suites_length as usize); 64 65 { 66 let methods_length = buffer[relative_start] as usize; 67 handshake.compression_methods_length = buffer[relative_start]; 68 println_cyan!("{} = {} is this good?", relative_start, handshake.compression_methods_length); 69 70 for i in relative_start + 1..(relative_start + 1 + methods_length) { 71 handshake.legacy_compression_methods.push(buffer[i]); 72 73 println_cyan!("support compression: {:02x}", buffer[i]); 74 } 75 } 76 77 let relative_start = relative_start + 1 + (handshake.compression_methods_length as usize); 78 79 println_green!("{:?}", &handshake); 80 81 { 82 handshake.extensions_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 83 84 let mut relative_start = relative_start + 2; 85 println_green!("extension_length:{} current:{}, left over:{}", handshake.extensions_length, relative_start, handshake.length as usize - relative_start); 86 87 while relative_start < handshake.extensions_length as usize { 88 let extension_type = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 89 90 relative_start += 2; 91 let extension_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 92 relative_start += 2; 93 94 //let extension_data: &[u8] = if (relative_start + (extension_length as usize)) < (handshake.length as usize) { 95 // &buffer[relative_start..(relative_start + (extension_length as usize))] 96 //} else { 97 // //relative_extension_start = handshake_extension_length as usize; 98 // print!("[TRUNCATED] "); 99 // &buffer[relative_start..=(handshake.length as usize)] 100 //}; 101 102 let extension: Option<ChExtension> = match extension_type { 103 0 => { 104 println_cyan!("Server Name!"); 105 let mut server_name_indication_extension: Vec<(u16, u8, u16, Vec<u8>)> = vec![]; 106 107 let mut extensions_start = relative_start; 108 let mut current_length: usize = 0; 109 110 while current_length < extension_length as usize { 111 let server_name_list_length = u16::from_be_bytes([buffer[extensions_start], buffer[extensions_start + 1]]); 112 let server_name_type = buffer[extensions_start + 2]; 113 let server_name_length = u16::from_be_bytes([buffer[extensions_start + 3], buffer[extensions_start + 4]]); 114 115 let mut server_name: Vec<u8> = vec![]; 116 117 for byte in buffer[(extensions_start + 5)..=(extensions_start + 4 + (server_name_length as usize))].iter() { 118 server_name.push(*byte); 119 } 120 121 extensions_start = extensions_start + (server_name_length as usize) + 5; 122 current_length = current_length + (server_name_length as usize) + 5; 123 server_name_indication_extension.push((server_name_list_length, server_name_type, server_name_length, server_name)); 124 } 125 126 Some(ChExtension::ServerName { 127 extension_type, 128 length: extension_length, 129 server_name_indication_extension, 130 }) 131 } 132 1 => { 133 eprintln_red!("Max Fragment Length Isn't Supported!"); 134 None 135 } 136 5 => { 137 eprintln_red!("Status Request Isn't Supported!"); 138 None 139 } 140 10 => { 141 println_cyan!("Supported Groups!"); 142 143 let mut supported_groups: Vec<u16> = vec![]; 144 145 let supported_groups_list_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 146 147 for i in (0..(supported_groups_list_length as usize)).step_by(2) { 148 let group = u16::from_be_bytes([buffer[relative_start + 2 + i], buffer[relative_start + 3 + i]]); 149 150 supported_groups.push(group); 151 } 152 153 Some(ChExtension::SupportedGroups { 154 extension_type, 155 length: extension_length, 156 supported_groups_list_length, 157 supported_groups, 158 }) 159 } 160 13 => { 161 println_cyan!("Signature algorithms!"); 162 let mut signature_hash_algorithms: Vec<(u8, u8)> = vec![]; 163 164 let signature_hash_algorithms_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 165 166 for i in 0..=(signature_hash_algorithms_length as usize / 2) { 167 let hash = buffer[relative_start + 2 + i]; 168 let signature = buffer[relative_start + 3 + i]; 169 170 signature_hash_algorithms.push((hash, signature)); 171 } 172 173 Some(ChExtension::SignatureAlgorithms { 174 extension_type, 175 length: extension_length, 176 signature_hash_algorithms_length: 0, 177 signature_hash_algorithms, 178 }) 179 } 180 14 => { 181 eprintln_red!("Use Srtp Isn't Supported!"); 182 None 183 } 184 15 => { 185 eprintln_red!("Heartbeat Isn't Supported!"); 186 None 187 } 188 16 => { 189 println_cyan!("Application Layer Protocol Negotiation!"); 190 191 let mut alpn_protocol: Vec<(u8, String)> = vec![]; 192 let alpn_extension_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 193 194 let mut extensions_start = relative_start + 2; 195 let mut current_length: usize = 0; 196 197 while current_length < alpn_extension_length as usize { 198 let alpn_string_length = buffer[extensions_start]; 199 let alpn_next_protocol: String = String::from_utf8(buffer[(extensions_start + 1)..((extensions_start + 1) + alpn_string_length as usize)].to_owned()).unwrap_or_default(); 200 201 extensions_start = (extensions_start + 1) + alpn_string_length as usize; 202 current_length = (current_length + 1) + (alpn_string_length as usize); 203 alpn_protocol.push((alpn_string_length, alpn_next_protocol)); 204 } 205 206 Some(ChExtension::ApplicationLayerProtocolNegotiation { 207 extension_type, 208 length: extension_length, 209 alpn_extension_length, 210 alpn_protocol, 211 }) 212 } 213 18 => { 214 eprintln_red!("Signed Certificate Timestamp Isn't Supported!"); 215 None 216 } 217 19 => { 218 eprintln_red!("Client Certificate Type Isn't Supported!"); 219 None 220 } 221 20 => { 222 eprintln_red!("Server Certificate Type Isn't Supported!"); 223 None 224 } 225 21 => { 226 eprintln_red!("Padding Isn't Supported!"); 227 None 228 } 229 42 => { 230 eprintln_red!("Early Data Isn't Supported!"); 231 None 232 } 233 43 => { 234 println_cyan!("Supported Versions!"); 235 236 let mut supported_versions: Vec<u16> = vec![]; 237 let supported_versions_length = buffer[relative_start]; 238 239 for i in (0..(supported_versions_length as usize)).step_by(2) { 240 let version = u16::from_be_bytes([buffer[relative_start + 1 + i], buffer[relative_start + 2 + i]]); 241 242 supported_versions.push(version); 243 } 244 245 Some(ChExtension::SupportedVersions { 246 extension_type, 247 length: extension_length, 248 supported_versions_length, 249 supported_versions, 250 }) 251 } 252 44 => { 253 eprintln_red!("Cookie Isn't Supported!"); 254 None 255 } 256 45 => { 257 println_cyan!("Psk Key Exchange Modes!"); 258 let psk_key_exchange_modes_length = buffer[relative_start]; 259 let psk_key_exchange_mode = buffer[(relative_start + 1)..((relative_start + 1) + psk_key_exchange_modes_length as usize)].to_owned(); 260 261 Some(ChExtension::PskKeyExchangeModes { 262 extension_type, 263 length: extension_length, 264 psk_key_exchange_modes_length, 265 psk_key_exchange_mode, 266 }) 267 } 268 47 => { 269 eprintln_red!("Certificate Authorities Isn't Supported!"); 270 None 271 } 272 48 => { 273 eprintln_red!("Oid Filters Isn't Supported!"); 274 None 275 } 276 49 => { 277 eprintln_red!("Post Handshake Auth Isn't Supported!"); 278 None 279 } 280 50 => { 281 eprintln_red!("Signature Algorithms Cert Isn't Supported!"); 282 None 283 } 284 51 => { 285 println_cyan!("Key Share!"); 286 287 let mut key_share_extensions: Vec<(u16, u16, Vec<u8>)> = vec![]; 288 let client_key_share_length = u16::from_be_bytes([buffer[relative_start], buffer[relative_start + 1]]); 289 290 let mut extensions_start = relative_start + 2; 291 let mut current_length: usize = 0; 292 293 while current_length < client_key_share_length as usize { 294 let group = u16::from_be_bytes([buffer[extensions_start], buffer[extensions_start + 1]]); 295 let key_exchange_length = u16::from_be_bytes([buffer[extensions_start + 2], buffer[extensions_start + 3]]); 296 297 let mut key_exchange: Vec<u8> = vec![]; 298 299 for byte in buffer[(extensions_start + 4)..((extensions_start + 4) + key_exchange_length as usize)].iter() { 300 key_exchange.push(*byte); 301 } 302 303 extensions_start = (extensions_start + 3) + (key_exchange_length as usize) + 1; 304 current_length = (current_length + 3) + (key_exchange_length as usize) + 1; 305 key_share_extensions.push((group, key_exchange_length, key_exchange)); 306 } 307 308 Some(ChExtension::KeyShare { 309 extension_type, 310 length: extension_length, 311 client_key_share_length, 312 key_share_extensions, 313 }) 314 } 315 _ => { 316 eprintln_red!("Unsupported extension! || Type: {}", extension_type); 317 None 318 } 319 }; 320 321 // if there is an extension, then push it :3 322 if let Some(value) = extension { 323 handshake.extensions.push(value); 324 } 325 326 relative_start += extension_length as usize; 327 //println_green!("Extension found! Type: {} || Length: {} || Extension_data: {:?}", extension_type,extension_length,extension_data); 328 } 329 //println_cyan!("{:?}", handshake); 330 } 331 332 println_green!("{:?}", &handshake); 333 } 334 return client_hello; 335 }