embedded_tls/
parse_buffer.rs1use crate::TlsError;
2use heapless::{CapacityError, Vec};
3
4#[derive(Debug, Copy, Clone)]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub enum ParseError {
7 InsufficientBytes,
8 InsufficientSpace,
9 InvalidData,
10}
11
12pub struct ParseBuffer<'b> {
13 pos: usize,
14 buffer: &'b [u8],
15}
16
17impl<'b> From<&'b [u8]> for ParseBuffer<'b> {
18 fn from(val: &'b [u8]) -> Self {
19 ParseBuffer::new(val)
20 }
21}
22
23impl<'b, const N: usize> From<ParseBuffer<'b>> for Result<Vec<u8, N>, CapacityError> {
24 fn from(val: ParseBuffer<'b>) -> Self {
25 Vec::from_slice(&val.buffer[val.pos..])
26 }
27}
28
29impl<'b> ParseBuffer<'b> {
30 pub fn new(buffer: &'b [u8]) -> Self {
31 Self { pos: 0, buffer }
32 }
33
34 pub fn is_empty(&self) -> bool {
35 self.pos == self.buffer.len()
36 }
37
38 pub fn remaining(&self) -> usize {
39 self.buffer.len() - self.pos
40 }
41
42 pub fn offset(&self) -> usize {
43 self.pos
44 }
45
46 pub fn as_slice(&self) -> &'b [u8] {
47 self.buffer
48 }
49
50 pub fn slice(&mut self, len: usize) -> Result<ParseBuffer<'b>, ParseError> {
51 if self.pos + len <= self.buffer.len() {
52 let slice = ParseBuffer::new(&self.buffer[self.pos..self.pos + len]);
53 self.pos += len;
54 Ok(slice)
55 } else {
56 Err(ParseError::InsufficientBytes)
57 }
58 }
59
60 pub fn read_u8(&mut self) -> Result<u8, ParseError> {
61 if self.pos < self.buffer.len() {
62 let value = self.buffer[self.pos];
63 self.pos += 1;
64 Ok(value)
65 } else {
66 Err(ParseError::InsufficientBytes)
67 }
68 }
69
70 pub fn read_u16(&mut self) -> Result<u16, ParseError> {
71 if self.pos + 2 <= self.buffer.len() {
73 let value = u16::from_be_bytes([self.buffer[self.pos], self.buffer[self.pos + 1]]);
74 self.pos += 2;
75 Ok(value)
76 } else {
77 Err(ParseError::InsufficientBytes)
78 }
79 }
80
81 pub fn read_u24(&mut self) -> Result<u32, ParseError> {
82 if self.pos + 3 <= self.buffer.len() {
83 let value = u32::from_be_bytes([
84 0,
85 self.buffer[self.pos],
86 self.buffer[self.pos + 1],
87 self.buffer[self.pos + 2],
88 ]);
89 self.pos += 3;
90 Ok(value)
91 } else {
92 Err(ParseError::InsufficientBytes)
93 }
94 }
95
96 pub fn read_u32(&mut self) -> Result<u32, ParseError> {
97 if self.pos + 4 <= self.buffer.len() {
98 let value = u32::from_be_bytes([
99 self.buffer[self.pos],
100 self.buffer[self.pos + 1],
101 self.buffer[self.pos + 2],
102 self.buffer[self.pos + 3],
103 ]);
104 self.pos += 4;
105 Ok(value)
106 } else {
107 Err(ParseError::InsufficientBytes)
108 }
109 }
110
111 pub fn fill(&mut self, dest: &mut [u8]) -> Result<(), ParseError> {
112 if self.pos + dest.len() <= self.buffer.len() {
113 dest.copy_from_slice(&self.buffer[self.pos..self.pos + dest.len()]);
114 self.pos += dest.len();
115 Ok(())
117 } else {
118 Err(ParseError::InsufficientBytes)
119 }
120 }
121
122 pub fn copy<const N: usize>(
123 &mut self,
124 dest: &mut Vec<u8, N>,
125 num_bytes: usize,
126 ) -> Result<(), ParseError> {
127 let space = dest.capacity() - dest.len();
128 if space < num_bytes {
129 error!(
130 "Insufficient space in destination buffer. Space: {} required: {}",
131 space, num_bytes
132 );
133 Err(ParseError::InsufficientSpace)
134 } else if self.pos + num_bytes <= self.buffer.len() {
135 dest.extend_from_slice(&self.buffer[self.pos..self.pos + num_bytes])
136 .map_err(|_| {
137 error!(
138 "Failed to extend destination buffer. Space: {} required: {}",
139 space, num_bytes
140 );
141 ParseError::InsufficientSpace
142 })?;
143 self.pos += num_bytes;
144 Ok(())
145 } else {
146 Err(ParseError::InsufficientBytes)
147 }
148 }
149
150 pub fn read_list<T, const N: usize>(
151 &mut self,
152 data_length: usize,
153 read: impl Fn(&mut ParseBuffer<'b>) -> Result<T, ParseError>,
154 ) -> Result<Vec<T, N>, ParseError> {
155 let mut result = Vec::new();
156
157 let mut data = self.slice(data_length)?;
158 while !data.is_empty() {
159 result.push(read(&mut data)?).map_err(|_| {
160 error!("Failed to store parse result");
161 ParseError::InsufficientSpace
162 })?;
163 }
164
165 Ok(result)
166 }
167}
168
169impl From<ParseError> for TlsError {
170 fn from(e: ParseError) -> Self {
171 TlsError::ParseError(e)
172 }
173}