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