rustls/msgs/deframer/
mod.rs
1use core::mem;
2
3use crate::error::{Error, InvalidMessage};
4use crate::msgs::codec::Reader;
5use crate::msgs::message::{
6 HEADER_SIZE, InboundOpaqueMessage, MessageError, read_opaque_message_header,
7};
8
9pub(crate) mod buffers;
10pub(crate) mod handshake;
11
12pub(crate) struct DeframerIter<'a> {
28 buf: &'a mut [u8],
29 consumed: usize,
30}
31
32impl<'a> DeframerIter<'a> {
33 pub(crate) fn new(buf: &'a mut [u8]) -> Self {
35 Self { buf, consumed: 0 }
36 }
37
38 pub(crate) fn bytes_consumed(&self) -> usize {
41 self.consumed
42 }
43}
44
45impl<'a> Iterator for DeframerIter<'a> {
46 type Item = Result<InboundOpaqueMessage<'a>, Error>;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 let mut reader = Reader::init(self.buf);
50
51 let (typ, version, len) = match read_opaque_message_header(&mut reader) {
52 Ok(header) => header,
53 Err(err) => {
54 let err = match err {
55 MessageError::TooShortForHeader | MessageError::TooShortForLength => {
56 return None;
57 }
58 MessageError::InvalidEmptyPayload => InvalidMessage::InvalidEmptyPayload,
59 MessageError::MessageTooLarge => InvalidMessage::MessageTooLarge,
60 MessageError::InvalidContentType => InvalidMessage::InvalidContentType,
61 MessageError::UnknownProtocolVersion => InvalidMessage::UnknownProtocolVersion,
62 };
63 return Some(Err(err.into()));
64 }
65 };
66
67 let end = HEADER_SIZE + len as usize;
68
69 self.buf.get(HEADER_SIZE..end)?;
70
71 let (consumed, remainder) = mem::take(&mut self.buf).split_at_mut(end);
74 self.buf = remainder;
75 self.consumed += end;
76
77 Some(Ok(InboundOpaqueMessage::new(
78 typ,
79 version,
80 &mut consumed[HEADER_SIZE..],
81 )))
82 }
83}
84
85pub fn fuzz_deframer(data: &[u8]) {
86 let mut buf = data.to_vec();
87 let mut iter = DeframerIter::new(&mut buf);
88
89 for message in iter.by_ref() {
90 if message.is_err() {
91 break;
92 }
93 }
94
95 assert!(iter.bytes_consumed() <= buf.len());
96}
97
98#[cfg(feature = "std")]
99#[cfg(test)]
100mod tests {
101 use alloc::vec::Vec;
102 use std::prelude::v1::*;
103
104 use super::*;
105 use crate::ContentType;
106
107 #[test]
108 fn iterator_empty_before_header_received() {
109 assert!(
110 DeframerIter::new(&mut [])
111 .next()
112 .is_none()
113 );
114 assert!(
115 DeframerIter::new(&mut [0x16])
116 .next()
117 .is_none()
118 );
119 assert!(
120 DeframerIter::new(&mut [0x16, 0x03])
121 .next()
122 .is_none()
123 );
124 assert!(
125 DeframerIter::new(&mut [0x16, 0x03, 0x03])
126 .next()
127 .is_none()
128 );
129 assert!(
130 DeframerIter::new(&mut [0x16, 0x03, 0x03, 0x00])
131 .next()
132 .is_none()
133 );
134 assert!(
135 DeframerIter::new(&mut [0x16, 0x03, 0x03, 0x00, 0x01])
136 .next()
137 .is_none()
138 );
139 }
140
141 #[test]
142 fn iterate_one_message() {
143 let mut buffer = [0x17, 0x03, 0x03, 0x00, 0x01, 0x00];
144 let mut iter = DeframerIter::new(&mut buffer);
145 assert_eq!(
146 iter.next().unwrap().unwrap().typ,
147 ContentType::ApplicationData
148 );
149 assert_eq!(iter.bytes_consumed(), 6);
150 assert!(iter.next().is_none());
151 }
152
153 #[test]
154 fn iterate_two_messages() {
155 let mut buffer = [
156 0x16, 0x03, 0x03, 0x00, 0x01, 0x00, 0x17, 0x03, 0x03, 0x00, 0x01, 0x00,
157 ];
158 let mut iter = DeframerIter::new(&mut buffer);
159 assert_eq!(iter.next().unwrap().unwrap().typ, ContentType::Handshake);
160 assert_eq!(iter.bytes_consumed(), 6);
161 assert_eq!(
162 iter.next().unwrap().unwrap().typ,
163 ContentType::ApplicationData
164 );
165 assert_eq!(iter.bytes_consumed(), 12);
166 assert!(iter.next().is_none());
167 }
168
169 #[test]
170 fn iterator_invalid_protocol_version_rejected() {
171 let mut buffer = include_bytes!("../../testdata/deframer-invalid-version.bin").to_vec();
172 let mut iter = DeframerIter::new(&mut buffer);
173 assert_eq!(
174 iter.next().unwrap().err(),
175 Some(Error::InvalidMessage(
176 InvalidMessage::UnknownProtocolVersion
177 ))
178 );
179 }
180
181 #[test]
182 fn iterator_invalid_content_type_rejected() {
183 let mut buffer = include_bytes!("../../testdata/deframer-invalid-contenttype.bin").to_vec();
184 let mut iter = DeframerIter::new(&mut buffer);
185 assert_eq!(
186 iter.next().unwrap().err(),
187 Some(Error::InvalidMessage(InvalidMessage::InvalidContentType))
188 );
189 }
190
191 #[test]
192 fn iterator_excess_message_length_rejected() {
193 let mut buffer = include_bytes!("../../testdata/deframer-invalid-length.bin").to_vec();
194 let mut iter = DeframerIter::new(&mut buffer);
195 assert_eq!(
196 iter.next().unwrap().err(),
197 Some(Error::InvalidMessage(InvalidMessage::MessageTooLarge))
198 );
199 }
200
201 #[test]
202 fn iterator_zero_message_length_rejected() {
203 let mut buffer = include_bytes!("../../testdata/deframer-invalid-empty.bin").to_vec();
204 let mut iter = DeframerIter::new(&mut buffer);
205 assert_eq!(
206 iter.next().unwrap().err(),
207 Some(Error::InvalidMessage(InvalidMessage::InvalidEmptyPayload))
208 );
209 }
210
211 #[test]
212 fn iterator_over_many_messages() {
213 let client_hello = include_bytes!("../../testdata/deframer-test.1.bin");
214 let mut buffer = Vec::with_capacity(3 * client_hello.len());
215 buffer.extend(client_hello);
216 buffer.extend(client_hello);
217 buffer.extend(client_hello);
218 let mut iter = DeframerIter::new(&mut buffer);
219 let mut count = 0;
220
221 for message in iter.by_ref() {
222 let message = message.unwrap();
223 assert_eq!(ContentType::Handshake, message.typ);
224 count += 1;
225 }
226
227 assert_eq!(count, 3);
228 assert_eq!(client_hello.len() * 3, iter.bytes_consumed());
229 }
230
231 #[test]
232 fn exercise_fuzz_deframer() {
233 fuzz_deframer(&[0xff, 0xff, 0xff, 0xff, 0xff]);
234 for prefix in 0..7 {
235 fuzz_deframer(&[0x16, 0x03, 0x03, 0x00, 0x01, 0xff][..prefix]);
236 }
237 }
238}