ytls_record/record/handshake/
extensions.rs

1//! Extensions parsing
2
3use ytls_traits::ClientHelloProcessor;
4
5use crate::error::ExtensionsError;
6
7use zerocopy::byteorder::network_endian::U16 as N16;
8
9pub struct Extensions {}
10
11impl Extensions {
12    pub fn parse_client_extensions<P: ClientHelloProcessor>(
13        prc: &mut P,
14        bytes: &[u8],
15    ) -> Result<(), ExtensionsError> {
16        let mut remaining = bytes;
17
18        let mut parsed_total = 0;
19        let to_parse = bytes.len();
20
21        loop {
22            if remaining.len() < 4 {
23                break;
24            }
25            let extension_id: usize = N16::from_bytes([remaining[0], remaining[1]]).into();
26            let extension_len = N16::from_bytes([remaining[2], remaining[3]]);
27            remaining = &remaining[4..];
28
29            parsed_total += 4;
30
31            let extension_len_usize: usize = extension_len.into();
32
33            parsed_total += extension_len_usize;
34
35            if extension_len_usize > remaining.len() {
36                return Err(ExtensionsError::OverflowExtensionLen);
37            }
38
39            let extension_data = if extension_len_usize == remaining.len() {
40                remaining
41            } else {
42                let (extension_data, remaining_next) = remaining.split_at(extension_len.into());
43                remaining = &remaining_next;
44                extension_data
45            };
46
47            prc.handle_extension(extension_id as u16, extension_data);
48
49            if parsed_total == to_parse {
50                break;
51            }
52        }
53        Ok(())
54    }
55}