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
12/// A deframer of TLS wire messages.
13///
14/// Returns `Some(Ok(_))` containing each `InboundOpaqueMessage` deframed
15/// from the buffer.
16///
17/// Returns `None` if no further messages can be deframed from the
18/// buffer.  More data is required for further progress.
19///
20/// Returns `Some(Err(_))` if the peer is not talking TLS, but some
21/// other protocol.  The caller should abort the connection, because
22/// the deframer cannot recover.
23///
24/// Call `bytes_consumed()` to learn how many bytes the iterator has
25/// processed from the front of the original buffer.  This is only updated
26/// when a message is successfully deframed (ie. `Some(Ok(_))` is returned).
27pub(crate) struct DeframerIter<'a> {
28    buf: &'a mut [u8],
29    consumed: usize,
30}
31
32impl<'a> DeframerIter<'a> {
33    /// Make a new `DeframerIter`
34    pub(crate) fn new(buf: &'a mut [u8]) -> Self {
35        Self { buf, consumed: 0 }
36    }
37
38    /// How many bytes were processed successfully from the front
39    /// of the buffer passed to `new()`?
40    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        // we now have a TLS header and body on the front of `self.buf`.  remove
72        // it from the front.
73        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}