mls_spec/
tlspl.rs

1#![allow(dead_code)]
2
3fn vlvec_overhead(data_len: usize) -> usize {
4    const MLS_VLBYTES_MAX_LEN: usize = (1 << 30) - 1;
5    debug_assert!(
6        data_len <= MLS_VLBYTES_MAX_LEN,
7        "The serialized size is above the MLS-defined limits of Variable-Length vectors [actual = {data_len}, max = {MLS_VLBYTES_MAX_LEN}]"
8    );
9
10    if data_len <= 0x3f {
11        1
12    } else if data_len <= 0x3fff {
13        2
14    } else if data_len <= 0x3fff_ffff {
15        4
16    } else {
17        8
18    }
19}
20
21#[inline]
22pub fn tls_serialized_len_as_vlvec(data_len: usize) -> usize {
23    vlvec_overhead(data_len) + data_len
24}
25
26pub fn write_vlvec_prefix<W: std::io::Write>(
27    data_len: usize,
28    writer: &mut W,
29) -> Result<usize, tls_codec::Error> {
30    let overhead = vlvec_overhead(data_len);
31    let prefix: u8 = match overhead {
32        1 => 0x00,
33        2 => 0x40,
34        4 => 0x80,
35        8 => 0xC0,
36        _ => unreachable!(),
37    };
38    let mut data_len_mix = data_len;
39
40    for i in 0..overhead {
41        let base = if i == 0 { prefix } else { 0x00 };
42        let byte = base | (data_len_mix & 0xFF) as u8;
43        writer.write_all(&[byte])?;
44        data_len_mix >>= 8;
45    }
46
47    Ok(overhead)
48}
49
50pub mod bytes {
51    use tls_codec::{Deserialize as _, Serialize as _, Size as _, VLByteSlice, VLBytes};
52
53    pub fn tls_serialized_len(v: &[u8]) -> usize {
54        VLByteSlice(v).tls_serialized_len()
55    }
56
57    pub fn tls_serialize<W: std::io::Write>(
58        v: &[u8],
59        writer: &mut W,
60    ) -> Result<usize, tls_codec::Error> {
61        VLByteSlice(v).tls_serialize(writer)
62    }
63
64    pub fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<Vec<u8>, tls_codec::Error> {
65        Ok(VLBytes::tls_deserialize(bytes)?.into())
66    }
67}
68
69pub mod optbytes {
70    use tls_codec::{Deserialize as _, Serialize as _, Size as _, VLByteSlice, VLBytes};
71
72    pub fn tls_serialized_len<B: AsRef<[u8]>>(v: &Option<B>) -> usize {
73        v.as_ref()
74            .map(|v| VLByteSlice(v.as_ref()))
75            .tls_serialized_len()
76    }
77
78    pub fn tls_serialize<W: std::io::Write, B: AsRef<[u8]>>(
79        v: &Option<B>,
80        writer: &mut W,
81    ) -> Result<usize, tls_codec::Error> {
82        v.as_ref()
83            .map(|v| VLByteSlice(v.as_ref()))
84            .tls_serialize(writer)
85    }
86
87    pub fn tls_deserialize<R: std::io::Read>(
88        bytes: &mut R,
89    ) -> Result<Option<Vec<u8>>, tls_codec::Error> {
90        Ok(Option::<VLBytes>::tls_deserialize(bytes)?.map(Into::into))
91    }
92}
93
94pub mod string {
95    pub fn tls_serialized_len(v: &str) -> usize {
96        super::bytes::tls_serialized_len(v.as_bytes())
97    }
98
99    pub fn tls_serialize<W: std::io::Write>(
100        v: &str,
101        writer: &mut W,
102    ) -> Result<usize, tls_codec::Error> {
103        super::bytes::tls_serialize(v.as_bytes(), writer)
104    }
105
106    #[allow(dead_code)]
107    pub fn tls_deserialize<R: std::io::Read>(bytes: &mut R) -> Result<String, tls_codec::Error> {
108        super::bytes::tls_deserialize(bytes).and_then(|bytes| {
109            String::from_utf8(bytes).map_err(|e| {
110                tls_codec::Error::DecodingError(format!("Could not decode utf8 string: {e:?}"))
111            })
112        })
113    }
114}