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 {}