rustls/msgs/deframer/
mod.rs
1use core::mem;
2
3use crate::error::{Error, InvalidMessage};
4use crate::msgs::codec::Reader;
5use crate::msgs::message::{
6 read_opaque_message_header, InboundOpaqueMessage, MessageError, HEADER_SIZE,
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!(DeframerIter::new(&mut [])
110 .next()
111 .is_none());
112 assert!(DeframerIter::new(&mut [0x16])
113 .next()
114 .is_none());
115 assert!(DeframerIter::new(&mut [0x16, 0x03])
116 .next()
117 .is_none());
118 assert!(DeframerIter::new(&mut [0x16, 0x03, 0x03])
119 .next()
120 .is_none());
121 assert!(DeframerIter::new(&mut [0x16, 0x03, 0x03, 0x00])
122 .next()
123 .is_none());
124 assert!(DeframerIter::new(&mut [0x16, 0x03, 0x03, 0x00, 0x01])
125 .next()
126 .is_none());
127 }
128
129 #[test]
130 fn iterate_one_message() {
131 let mut buffer = [0x17, 0x03, 0x03, 0x00, 0x01, 0x00];
132 let mut iter = DeframerIter::new(&mut buffer);
133 assert_eq!(
134 iter.next().unwrap().unwrap().typ,
135 ContentType::ApplicationData
136 );
137 assert_eq!(iter.bytes_consumed(), 6);
138 assert!(iter.next().is_none());
139 }
140
141 #[test]
142 fn iterate_two_messages() {
143 let mut buffer = [
144 0x16, 0x03, 0x03, 0x00, 0x01, 0x00, 0x17, 0x03, 0x03, 0x00, 0x01, 0x00,
145 ];
146 let mut iter = DeframerIter::new(&mut buffer);
147 assert_eq!(iter.next().unwrap().unwrap().typ, ContentType::Handshake);
148 assert_eq!(iter.bytes_consumed(), 6);
149 assert_eq!(
150 iter.next().unwrap().unwrap().typ,
151 ContentType::ApplicationData
152 );
153 assert_eq!(iter.bytes_consumed(), 12);
154 assert!(iter.next().is_none());
155 }
156
157 #[test]
158 fn iterator_invalid_protocol_version_rejected() {
159 let mut buffer = include_bytes!("../../testdata/deframer-invalid-version.bin").to_vec();
160 let mut iter = DeframerIter::new(&mut buffer);
161 assert_eq!(
162 iter.next().unwrap().err(),
163 Some(Error::InvalidMessage(
164 InvalidMessage::UnknownProtocolVersion
165 ))
166 );
167 }
168
169 #[test]
170 fn iterator_invalid_content_type_rejected() {
171 let mut buffer = include_bytes!("../../testdata/deframer-invalid-contenttype.bin").to_vec();
172 let mut iter = DeframerIter::new(&mut buffer);
173 assert_eq!(
174 iter.next().unwrap().err(),
175 Some(Error::InvalidMessage(InvalidMessage::InvalidContentType))
176 );
177 }
178
179 #[test]
180 fn iterator_excess_message_length_rejected() {
181 let mut buffer = include_bytes!("../../testdata/deframer-invalid-length.bin").to_vec();
182 let mut iter = DeframerIter::new(&mut buffer);
183 assert_eq!(
184 iter.next().unwrap().err(),
185 Some(Error::InvalidMessage(InvalidMessage::MessageTooLarge))
186 );
187 }
188
189 #[test]
190 fn iterator_zero_message_length_rejected() {
191 let mut buffer = include_bytes!("../../testdata/deframer-invalid-empty.bin").to_vec();
192 let mut iter = DeframerIter::new(&mut buffer);
193 assert_eq!(
194 iter.next().unwrap().err(),
195 Some(Error::InvalidMessage(InvalidMessage::InvalidEmptyPayload))
196 );
197 }
198
199 #[test]
200 fn iterator_over_many_messages() {
201 let client_hello = include_bytes!("../../testdata/deframer-test.1.bin");
202 let mut buffer = Vec::with_capacity(3 * client_hello.len());
203 buffer.extend(client_hello);
204 buffer.extend(client_hello);
205 buffer.extend(client_hello);
206 let mut iter = DeframerIter::new(&mut buffer);
207 let mut count = 0;
208
209 for message in iter.by_ref() {
210 let message = message.unwrap();
211 assert_eq!(ContentType::Handshake, message.typ);
212 count += 1;
213 }
214
215 assert_eq!(count, 3);
216 assert_eq!(client_hello.len() * 3, iter.bytes_consumed());
217 }
218
219 #[test]
220 fn exercise_fuzz_deframer() {
221 fuzz_deframer(&[0xff, 0xff, 0xff, 0xff, 0xff]);
222 for prefix in 0..7 {
223 fuzz_deframer(&[0x16, 0x03, 0x03, 0x00, 0x01, 0xff][..prefix]);
224 }
225 }
226}