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
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!(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}