/ src / artic_tls / src / client_hello.rs
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  }