rustls/
conn.rs

1use crate::common_state::{CommonState, Context, IoState, State};
2use crate::enums::{AlertDescription, ContentType};
3use crate::error::{Error, PeerMisbehaved};
4#[cfg(feature = "logging")]
5use crate::log::trace;
6use crate::msgs::deframer::{Deframed, DeframerSliceBuffer, DeframerVecBuffer, MessageDeframer};
7use crate::msgs::handshake::Random;
8use crate::msgs::message::{Message, MessagePayload, PlainMessage};
9use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
10use crate::vecbuf::ChunkVecBuffer;
11
12use alloc::boxed::Box;
13use core::fmt::Debug;
14use core::mem;
15use core::ops::{Deref, DerefMut};
16use std::io;
17
18/// A client or server connection.
19#[derive(Debug)]
20pub enum Connection {
21    /// A client connection
22    Client(crate::client::ClientConnection),
23    /// A server connection
24    Server(crate::server::ServerConnection),
25}
26
27impl Connection {
28    /// Read TLS content from `rd`.
29    ///
30    /// See [`ConnectionCommon::read_tls()`] for more information.
31    pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
32        match self {
33            Self::Client(conn) => conn.read_tls(rd),
34            Self::Server(conn) => conn.read_tls(rd),
35        }
36    }
37
38    /// Writes TLS messages to `wr`.
39    ///
40    /// See [`ConnectionCommon::write_tls()`] for more information.
41    pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
42        self.sendable_tls.write_to(wr)
43    }
44
45    /// Returns an object that allows reading plaintext.
46    pub fn reader(&mut self) -> Reader {
47        match self {
48            Self::Client(conn) => conn.reader(),
49            Self::Server(conn) => conn.reader(),
50        }
51    }
52
53    /// Returns an object that allows writing plaintext.
54    pub fn writer(&mut self) -> Writer {
55        match self {
56            Self::Client(conn) => Writer::new(&mut **conn),
57            Self::Server(conn) => Writer::new(&mut **conn),
58        }
59    }
60
61    /// Processes any new packets read by a previous call to [`Connection::read_tls`].
62    ///
63    /// See [`ConnectionCommon::process_new_packets()`] for more information.
64    pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
65        match self {
66            Self::Client(conn) => conn.process_new_packets(),
67            Self::Server(conn) => conn.process_new_packets(),
68        }
69    }
70
71    /// Derives key material from the agreed connection secrets.
72    ///
73    /// See [`ConnectionCommon::export_keying_material()`] for more information.
74    pub fn export_keying_material<T: AsMut<[u8]>>(
75        &self,
76        output: T,
77        label: &[u8],
78        context: Option<&[u8]>,
79    ) -> Result<T, Error> {
80        match self {
81            Self::Client(conn) => conn.export_keying_material(output, label, context),
82            Self::Server(conn) => conn.export_keying_material(output, label, context),
83        }
84    }
85
86    /// This function uses `io` to complete any outstanding IO for this connection.
87    ///
88    /// See [`ConnectionCommon::complete_io()`] for more information.
89    pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
90    where
91        Self: Sized,
92        T: io::Read + io::Write,
93    {
94        match self {
95            Self::Client(conn) => conn.complete_io(io),
96            Self::Server(conn) => conn.complete_io(io),
97        }
98    }
99
100    /// Extract secrets, so they can be used when configuring kTLS, for example.
101    /// Should be used with care as it exposes secret key material.
102    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
103        match self {
104            Self::Client(client) => client.dangerous_extract_secrets(),
105            Self::Server(server) => server.dangerous_extract_secrets(),
106        }
107    }
108}
109
110impl Deref for Connection {
111    type Target = CommonState;
112
113    fn deref(&self) -> &Self::Target {
114        match self {
115            Self::Client(conn) => &conn.core.common_state,
116            Self::Server(conn) => &conn.core.common_state,
117        }
118    }
119}
120
121impl DerefMut for Connection {
122    fn deref_mut(&mut self) -> &mut Self::Target {
123        match self {
124            Self::Client(conn) => &mut conn.core.common_state,
125            Self::Server(conn) => &mut conn.core.common_state,
126        }
127    }
128}
129
130/// A structure that implements [`std::io::Read`] for reading plaintext.
131pub struct Reader<'a> {
132    received_plaintext: &'a mut ChunkVecBuffer,
133    peer_cleanly_closed: bool,
134    has_seen_eof: bool,
135}
136
137impl<'a> io::Read for Reader<'a> {
138    /// Obtain plaintext data received from the peer over this TLS connection.
139    ///
140    /// If the peer closes the TLS session cleanly, this returns `Ok(0)`  once all
141    /// the pending data has been read. No further data can be received on that
142    /// connection, so the underlying TCP connection should be half-closed too.
143    ///
144    /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
145    /// `close_notify` alert) this function returns a `std::io::Error` of type
146    /// `ErrorKind::UnexpectedEof` once any pending data has been read.
147    ///
148    /// Note that support for `close_notify` varies in peer TLS libraries: many do not
149    /// support it and uncleanly close the TCP connection (this might be
150    /// vulnerable to truncation attacks depending on the application protocol).
151    /// This means applications using rustls must both handle EOF
152    /// from this function, *and* unexpected EOF of the underlying TCP connection.
153    ///
154    /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
155    ///
156    /// You may learn the number of bytes available at any time by inspecting
157    /// the return of [`Connection::process_new_packets`].
158    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
159        let len = self.received_plaintext.read(buf)?;
160
161        if len == 0 && !buf.is_empty() {
162            // No bytes available:
163            match (self.peer_cleanly_closed, self.has_seen_eof) {
164                // cleanly closed; don't care about TCP EOF: express this as Ok(0)
165                (true, _) => {}
166                // unclean closure
167                (false, true) => {
168                    return Err(io::Error::new(
169                        io::ErrorKind::UnexpectedEof,
170                        UNEXPECTED_EOF_MESSAGE,
171                    ))
172                }
173                // connection still going, but needs more data: signal `WouldBlock` so that
174                // the caller knows this
175                (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
176            }
177        }
178
179        Ok(len)
180    }
181
182    /// Obtain plaintext data received from the peer over this TLS connection.
183    ///
184    /// If the peer closes the TLS session, this returns `Ok(())` without filling
185    /// any more of the buffer once all the pending data has been read. No further
186    /// data can be received on that connection, so the underlying TCP connection
187    /// should be half-closed too.
188    ///
189    /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
190    /// `close_notify` alert) this function returns a `std::io::Error` of type
191    /// `ErrorKind::UnexpectedEof` once any pending data has been read.
192    ///
193    /// Note that support for `close_notify` varies in peer TLS libraries: many do not
194    /// support it and uncleanly close the TCP connection (this might be
195    /// vulnerable to truncation attacks depending on the application protocol).
196    /// This means applications using rustls must both handle EOF
197    /// from this function, *and* unexpected EOF of the underlying TCP connection.
198    ///
199    /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
200    ///
201    /// You may learn the number of bytes available at any time by inspecting
202    /// the return of [`Connection::process_new_packets`].
203    #[cfg(read_buf)]
204    fn read_buf(&mut self, mut cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
205        let before = cursor.written();
206        self.received_plaintext
207            .read_buf(cursor.reborrow())?;
208        let len = cursor.written() - before;
209
210        if len == 0 && cursor.capacity() > 0 {
211            // No bytes available:
212            match (self.peer_cleanly_closed, self.has_seen_eof) {
213                // cleanly closed; don't care about TCP EOF: express this as Ok(0)
214                (true, _) => {}
215                // unclean closure
216                (false, true) => {
217                    return Err(io::Error::new(
218                        io::ErrorKind::UnexpectedEof,
219                        UNEXPECTED_EOF_MESSAGE,
220                    ));
221                }
222                // connection still going, but need more data: signal `WouldBlock` so that
223                // the caller knows this
224                (false, false) => return Err(io::ErrorKind::WouldBlock.into()),
225            }
226        }
227
228        Ok(())
229    }
230}
231
232/// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
233/// allowing them to be the subject of a [`Writer`].
234///
235/// [`ServerConnection`]: crate::ServerConnection
236/// [`ClientConnection`]: crate::ClientConnection
237pub(crate) trait PlaintextSink {
238    fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
239    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
240    fn flush(&mut self) -> io::Result<()>;
241}
242
243impl<T> PlaintextSink for ConnectionCommon<T> {
244    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
245        Ok(self.send_some_plaintext(buf))
246    }
247
248    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
249        let mut sz = 0;
250        for buf in bufs {
251            sz += self.send_some_plaintext(buf);
252        }
253        Ok(sz)
254    }
255
256    fn flush(&mut self) -> io::Result<()> {
257        Ok(())
258    }
259}
260
261/// A structure that implements [`std::io::Write`] for writing plaintext.
262pub struct Writer<'a> {
263    sink: &'a mut dyn PlaintextSink,
264}
265
266impl<'a> Writer<'a> {
267    /// Create a new Writer.
268    ///
269    /// This is not an external interface.  Get one of these objects
270    /// from [`Connection::writer`].
271    pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
272        Writer { sink }
273    }
274}
275
276impl<'a> io::Write for Writer<'a> {
277    /// Send the plaintext `buf` to the peer, encrypting
278    /// and authenticating it.  Once this function succeeds
279    /// you should call [`Connection::write_tls`] which will output the
280    /// corresponding TLS records.
281    ///
282    /// This function buffers plaintext sent before the
283    /// TLS handshake completes, and sends it as soon
284    /// as it can.  See [`CommonState::set_buffer_limit`] to control
285    /// the size of this buffer.
286    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
287        self.sink.write(buf)
288    }
289
290    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
291        self.sink.write_vectored(bufs)
292    }
293
294    fn flush(&mut self) -> io::Result<()> {
295        self.sink.flush()
296    }
297}
298
299#[derive(Debug)]
300pub(crate) struct ConnectionRandoms {
301    pub(crate) client: [u8; 32],
302    pub(crate) server: [u8; 32],
303}
304
305/// How many ChangeCipherSpec messages we accept and drop in TLS1.3 handshakes.
306/// The spec says 1, but implementations (namely the boringssl test suite) get
307/// this wrong.  BoringSSL itself accepts up to 32.
308static TLS13_MAX_DROPPED_CCS: u8 = 2u8;
309
310impl ConnectionRandoms {
311    pub(crate) fn new(client: Random, server: Random) -> Self {
312        Self {
313            client: client.0,
314            server: server.0,
315        }
316    }
317}
318
319// --- Common (to client and server) connection functions ---
320
321fn is_valid_ccs(msg: &PlainMessage) -> bool {
322    // We passthrough ChangeCipherSpec messages in the deframer without decrypting them.
323    // Note: this is prior to the record layer, so is unencrypted. See
324    // third paragraph of section 5 in RFC8446.
325    msg.typ == ContentType::ChangeCipherSpec && msg.payload.0 == [0x01]
326}
327
328/// Interface shared by client and server connections.
329pub struct ConnectionCommon<Data> {
330    pub(crate) core: ConnectionCore<Data>,
331    deframer_buffer: DeframerVecBuffer,
332}
333
334impl<Data> ConnectionCommon<Data> {
335    /// Returns an object that allows reading plaintext.
336    pub fn reader(&mut self) -> Reader {
337        let common = &mut self.core.common_state;
338        Reader {
339            received_plaintext: &mut common.received_plaintext,
340            // Are we done? i.e., have we processed all received messages, and received a
341            // close_notify to indicate that no new messages will arrive?
342            peer_cleanly_closed: common.has_received_close_notify
343                && !self.deframer_buffer.has_pending(),
344            has_seen_eof: common.has_seen_eof,
345        }
346    }
347
348    /// Returns an object that allows writing plaintext.
349    pub fn writer(&mut self) -> Writer {
350        Writer::new(self)
351    }
352
353    /// This function uses `io` to complete any outstanding IO for
354    /// this connection.
355    ///
356    /// This is a convenience function which solely uses other parts
357    /// of the public API.
358    ///
359    /// What this means depends on the connection  state:
360    ///
361    /// - If the connection [`is_handshaking`], then IO is performed until
362    ///   the handshake is complete.
363    /// - Otherwise, if [`wants_write`] is true, [`write_tls`] is invoked
364    ///   until it is all written.
365    /// - Otherwise, if [`wants_read`] is true, [`read_tls`] is invoked
366    ///   once.
367    ///
368    /// The return value is the number of bytes read from and written
369    /// to `io`, respectively.
370    ///
371    /// This function will block if `io` blocks.
372    ///
373    /// Errors from TLS record handling (i.e., from [`process_new_packets`])
374    /// are wrapped in an `io::ErrorKind::InvalidData`-kind error.
375    ///
376    /// [`is_handshaking`]: CommonState::is_handshaking
377    /// [`wants_read`]: CommonState::wants_read
378    /// [`wants_write`]: CommonState::wants_write
379    /// [`write_tls`]: ConnectionCommon::write_tls
380    /// [`read_tls`]: ConnectionCommon::read_tls
381    /// [`process_new_packets`]: ConnectionCommon::process_new_packets
382    pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
383    where
384        Self: Sized,
385        T: io::Read + io::Write,
386    {
387        let mut eof = false;
388        let mut wrlen = 0;
389        let mut rdlen = 0;
390
391        loop {
392            let until_handshaked = self.is_handshaking();
393
394            if !self.wants_write() && !self.wants_read() {
395                // We will make no further progress.
396                return Ok((rdlen, wrlen));
397            }
398
399            while self.wants_write() {
400                wrlen += self.write_tls(io)?;
401            }
402            io.flush()?;
403
404            if !until_handshaked && wrlen > 0 {
405                return Ok((rdlen, wrlen));
406            }
407
408            while !eof && self.wants_read() {
409                let read_size = match self.read_tls(io) {
410                    Ok(0) => {
411                        eof = true;
412                        Some(0)
413                    }
414                    Ok(n) => {
415                        rdlen += n;
416                        Some(n)
417                    }
418                    Err(ref err) if err.kind() == io::ErrorKind::Interrupted => None, // nothing to do
419                    Err(err) => return Err(err),
420                };
421                if read_size.is_some() {
422                    break;
423                }
424            }
425
426            match self.process_new_packets() {
427                Ok(_) => {}
428                Err(e) => {
429                    // In case we have an alert to send describing this error,
430                    // try a last-gasp write -- but don't predate the primary
431                    // error.
432                    let _ignored = self.write_tls(io);
433                    let _ignored = io.flush();
434
435                    return Err(io::Error::new(io::ErrorKind::InvalidData, e));
436                }
437            };
438
439            // if we're doing IO until handshaked, and we believe we've finished handshaking,
440            // but process_new_packets() has queued TLS data to send, loop around again to write
441            // the queued messages.
442            if until_handshaked && !self.is_handshaking() && self.wants_write() {
443                continue;
444            }
445
446            match (eof, until_handshaked, self.is_handshaking()) {
447                (_, true, false) => return Ok((rdlen, wrlen)),
448                (_, false, _) => return Ok((rdlen, wrlen)),
449                (true, true, true) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
450                (..) => {}
451            }
452        }
453    }
454
455    /// Extract the first handshake message.
456    ///
457    /// This is a shortcut to the `process_new_packets()` -> `process_msg()` ->
458    /// `process_handshake_messages()` path, specialized for the first handshake message.
459    pub(crate) fn first_handshake_message(&mut self) -> Result<Option<Message>, Error> {
460        let mut deframer_buffer = self.deframer_buffer.borrow();
461        let res = self
462            .core
463            .deframe(None, &mut deframer_buffer);
464        let discard = deframer_buffer.pending_discard();
465        self.deframer_buffer.discard(discard);
466
467        match res?.map(Message::try_from) {
468            Some(Ok(msg)) => Ok(Some(msg)),
469            Some(Err(err)) => Err(self.send_fatal_alert(AlertDescription::DecodeError, err)),
470            None => Ok(None),
471        }
472    }
473
474    pub(crate) fn replace_state(&mut self, new: Box<dyn State<Data>>) {
475        self.core.state = Ok(new);
476    }
477
478    /// Processes any new packets read by a previous call to
479    /// [`Connection::read_tls`].
480    ///
481    /// Errors from this function relate to TLS protocol errors, and
482    /// are fatal to the connection.  Future calls after an error will do
483    /// no new work and will return the same error. After an error is
484    /// received from [`process_new_packets`], you should not call [`read_tls`]
485    /// any more (it will fill up buffers to no purpose). However, you
486    /// may call the other methods on the connection, including `write`,
487    /// `send_close_notify`, and `write_tls`. Most likely you will want to
488    /// call `write_tls` to send any alerts queued by the error and then
489    /// close the underlying connection.
490    ///
491    /// Success from this function comes with some sundry state data
492    /// about the connection.
493    ///
494    /// [`read_tls`]: Connection::read_tls
495    /// [`process_new_packets`]: Connection::process_new_packets
496    #[inline]
497    pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
498        self.core
499            .process_new_packets(&mut self.deframer_buffer)
500    }
501
502    /// Read TLS content from `rd` into the internal buffer.
503    ///
504    /// Due to the internal buffering, `rd` can supply TLS messages in arbitrary-sized chunks (like
505    /// a socket or pipe might).
506    ///
507    /// You should call [`process_new_packets()`] each time a call to this function succeeds in order
508    /// to empty the incoming TLS data buffer.
509    ///
510    /// This function returns `Ok(0)` when the underlying `rd` does so. This typically happens when
511    /// a socket is cleanly closed, or a file is at EOF. Errors may result from the IO done through
512    /// `rd`; additionally, errors of `ErrorKind::Other` are emitted to signal backpressure:
513    ///
514    /// * In order to empty the incoming TLS data buffer, you should call [`process_new_packets()`]
515    ///   each time a call to this function succeeds.
516    /// * In order to empty the incoming plaintext data buffer, you should empty it through
517    ///   the [`reader()`] after the call to [`process_new_packets()`].
518    ///
519    /// [`process_new_packets()`]: ConnectionCommon::process_new_packets
520    /// [`reader()`]: ConnectionCommon::reader
521    pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
522        if self.received_plaintext.is_full() {
523            return Err(io::Error::new(
524                io::ErrorKind::Other,
525                "received plaintext buffer full",
526            ));
527        }
528
529        let res = self
530            .core
531            .message_deframer
532            .read(rd, &mut self.deframer_buffer);
533        if let Ok(0) = res {
534            self.has_seen_eof = true;
535        }
536        res
537    }
538
539    /// Writes TLS messages to `wr`.
540    ///
541    /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
542    /// (after encoding and encryption).
543    ///
544    /// After this function returns, the connection buffer may not yet be fully flushed. The
545    /// [`CommonState::wants_write`] function can be used to check if the output buffer is empty.
546    pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
547        self.sendable_tls.write_to(wr)
548    }
549
550    /// Derives key material from the agreed connection secrets.
551    ///
552    /// This function fills in `output` with `output.len()` bytes of key
553    /// material derived from the master session secret using `label`
554    /// and `context` for diversification. Ownership of the buffer is taken
555    /// by the function and returned via the Ok result to ensure no key
556    /// material leaks if the function fails.
557    ///
558    /// See RFC5705 for more details on what this does and is for.
559    ///
560    /// For TLS1.3 connections, this function does not use the
561    /// "early" exporter at any point.
562    ///
563    /// This function fails if called prior to the handshake completing;
564    /// check with [`CommonState::is_handshaking`] first.
565    ///
566    /// This function fails if `output.len()` is zero.
567    #[inline]
568    pub fn export_keying_material<T: AsMut<[u8]>>(
569        &self,
570        output: T,
571        label: &[u8],
572        context: Option<&[u8]>,
573    ) -> Result<T, Error> {
574        self.core
575            .export_keying_material(output, label, context)
576    }
577
578    /// Extract secrets, so they can be used when configuring kTLS, for example.
579    /// Should be used with care as it exposes secret key material.
580    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
581        if !self.enable_secret_extraction {
582            return Err(Error::General("Secret extraction is disabled".into()));
583        }
584
585        let st = self.core.state?;
586
587        let record_layer = self.core.common_state.record_layer;
588        let PartiallyExtractedSecrets { tx, rx } = st.extract_secrets()?;
589        Ok(ExtractedSecrets {
590            tx: (record_layer.write_seq(), tx),
591            rx: (record_layer.read_seq(), rx),
592        })
593    }
594}
595
596impl<'a, Data> From<&'a mut ConnectionCommon<Data>> for Context<'a, Data> {
597    fn from(conn: &'a mut ConnectionCommon<Data>) -> Self {
598        Self {
599            common: &mut conn.core.common_state,
600            data: &mut conn.core.data,
601        }
602    }
603}
604
605impl<T> Deref for ConnectionCommon<T> {
606    type Target = CommonState;
607
608    fn deref(&self) -> &Self::Target {
609        &self.core.common_state
610    }
611}
612
613impl<T> DerefMut for ConnectionCommon<T> {
614    fn deref_mut(&mut self) -> &mut Self::Target {
615        &mut self.core.common_state
616    }
617}
618
619impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
620    fn from(core: ConnectionCore<Data>) -> Self {
621        Self {
622            core,
623            deframer_buffer: DeframerVecBuffer::default(),
624        }
625    }
626}
627
628pub(crate) struct ConnectionCore<Data> {
629    pub(crate) state: Result<Box<dyn State<Data>>, Error>,
630    pub(crate) data: Data,
631    pub(crate) common_state: CommonState,
632    pub(crate) message_deframer: MessageDeframer,
633}
634
635impl<Data> ConnectionCore<Data> {
636    pub(crate) fn new(state: Box<dyn State<Data>>, data: Data, common_state: CommonState) -> Self {
637        Self {
638            state: Ok(state),
639            data,
640            common_state,
641            message_deframer: MessageDeframer::default(),
642        }
643    }
644
645    pub(crate) fn process_new_packets(
646        &mut self,
647        deframer_buffer: &mut DeframerVecBuffer,
648    ) -> Result<IoState, Error> {
649        let mut state = match mem::replace(&mut self.state, Err(Error::HandshakeNotComplete)) {
650            Ok(state) => state,
651            Err(e) => {
652                self.state = Err(e.clone());
653                return Err(e);
654            }
655        };
656
657        let mut borrowed_buffer = deframer_buffer.borrow();
658        while let Some(msg) = self.deframe(Some(&*state), &mut borrowed_buffer)? {
659            match self.process_msg(msg, state) {
660                Ok(new) => state = new,
661                Err(e) => {
662                    self.state = Err(e.clone());
663                    let discard = borrowed_buffer.pending_discard();
664                    deframer_buffer.discard(discard);
665                    return Err(e);
666                }
667            }
668        }
669
670        let discard = borrowed_buffer.pending_discard();
671        deframer_buffer.discard(discard);
672        self.state = Ok(state);
673        Ok(self.common_state.current_io_state())
674    }
675
676    /// Pull a message out of the deframer and send any messages that need to be sent as a result.
677    fn deframe(
678        &mut self,
679        state: Option<&dyn State<Data>>,
680        deframer_buffer: &mut DeframerSliceBuffer,
681    ) -> Result<Option<PlainMessage>, Error> {
682        match self.message_deframer.pop(
683            &mut self.common_state.record_layer,
684            self.common_state.negotiated_version,
685            deframer_buffer,
686        ) {
687            Ok(Some(Deframed {
688                want_close_before_decrypt,
689                aligned,
690                trial_decryption_finished,
691                message,
692            })) => {
693                if want_close_before_decrypt {
694                    self.common_state.send_close_notify();
695                }
696
697                if trial_decryption_finished {
698                    self.common_state
699                        .record_layer
700                        .finish_trial_decryption();
701                }
702
703                self.common_state.aligned_handshake = aligned;
704                Ok(Some(message))
705            }
706            Ok(None) => Ok(None),
707            Err(err @ Error::InvalidMessage(_)) => {
708                if self.common_state.is_quic() {
709                    self.common_state.quic.alert = Some(AlertDescription::DecodeError);
710                }
711
712                Err(if !self.common_state.is_quic() {
713                    self.common_state
714                        .send_fatal_alert(AlertDescription::DecodeError, err)
715                } else {
716                    err
717                })
718            }
719            Err(err @ Error::PeerSentOversizedRecord) => Err(self
720                .common_state
721                .send_fatal_alert(AlertDescription::RecordOverflow, err)),
722            Err(err @ Error::DecryptError) => {
723                if let Some(state) = state {
724                    state.handle_decrypt_error();
725                }
726                Err(self
727                    .common_state
728                    .send_fatal_alert(AlertDescription::BadRecordMac, err))
729            }
730            Err(e) => Err(e),
731        }
732    }
733
734    fn process_msg(
735        &mut self,
736        msg: PlainMessage,
737        state: Box<dyn State<Data>>,
738    ) -> Result<Box<dyn State<Data>>, Error> {
739        // Drop CCS messages during handshake in TLS1.3
740        if msg.typ == ContentType::ChangeCipherSpec
741            && !self
742                .common_state
743                .may_receive_application_data
744            && self.common_state.is_tls13()
745        {
746            if !is_valid_ccs(&msg)
747                || self.common_state.received_middlebox_ccs > TLS13_MAX_DROPPED_CCS
748            {
749                // "An implementation which receives any other change_cipher_spec value or
750                //  which receives a protected change_cipher_spec record MUST abort the
751                //  handshake with an "unexpected_message" alert."
752                return Err(self.common_state.send_fatal_alert(
753                    AlertDescription::UnexpectedMessage,
754                    PeerMisbehaved::IllegalMiddleboxChangeCipherSpec,
755                ));
756            } else {
757                self.common_state.received_middlebox_ccs += 1;
758                trace!("Dropping CCS");
759                return Ok(state);
760            }
761        }
762
763        // Now we can fully parse the message payload.
764        let msg = match Message::try_from(msg) {
765            Ok(msg) => msg,
766            Err(err) => {
767                return Err(self
768                    .common_state
769                    .send_fatal_alert(AlertDescription::DecodeError, err));
770            }
771        };
772
773        // For alerts, we have separate logic.
774        if let MessagePayload::Alert(alert) = &msg.payload {
775            self.common_state.process_alert(alert)?;
776            return Ok(state);
777        }
778
779        self.common_state
780            .process_main_protocol(msg, state, &mut self.data)
781    }
782
783    pub(crate) fn export_keying_material<T: AsMut<[u8]>>(
784        &self,
785        mut output: T,
786        label: &[u8],
787        context: Option<&[u8]>,
788    ) -> Result<T, Error> {
789        if output.as_mut().is_empty() {
790            return Err(Error::General(
791                "export_keying_material with zero-length output".into(),
792            ));
793        }
794
795        match self.state.as_ref() {
796            Ok(st) => st
797                .export_keying_material(output.as_mut(), label, context)
798                .map(|_| output),
799            Err(e) => Err(e.clone()),
800        }
801    }
802}
803
804/// Data specific to the peer's side (client or server).
805pub trait SideData: Debug {}
806
807const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sending TLS close_notify: \
808https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";