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}