rustls/
conn.rs

1use alloc::boxed::Box;
2use core::fmt::Debug;
3use core::mem;
4use core::ops::{Deref, DerefMut, Range};
5#[cfg(feature = "std")]
6use std::io;
7
8use crate::common_state::{CommonState, Context, DEFAULT_BUFFER_LIMIT, IoState, State};
9use crate::enums::{AlertDescription, ContentType, ProtocolVersion};
10use crate::error::{Error, PeerMisbehaved};
11use crate::log::trace;
12use crate::msgs::deframer::DeframerIter;
13use crate::msgs::deframer::buffers::{BufferProgress, DeframerVecBuffer, Delocator, Locator};
14use crate::msgs::deframer::handshake::HandshakeDeframer;
15use crate::msgs::handshake::Random;
16use crate::msgs::message::{InboundPlainMessage, Message, MessagePayload};
17use crate::record_layer::Decrypted;
18use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
19use crate::vecbuf::ChunkVecBuffer;
20
21pub(crate) mod unbuffered;
22
23#[cfg(feature = "std")]
24mod connection {
25    use alloc::vec::Vec;
26    use core::fmt::Debug;
27    use core::ops::{Deref, DerefMut};
28    use std::io::{self, BufRead, Read};
29
30    use crate::ConnectionCommon;
31    use crate::common_state::{CommonState, IoState};
32    use crate::error::Error;
33    use crate::msgs::message::OutboundChunks;
34    use crate::suites::ExtractedSecrets;
35    use crate::vecbuf::ChunkVecBuffer;
36
37    /// A client or server connection.
38    #[derive(Debug)]
39    pub enum Connection {
40        /// A client connection
41        Client(crate::client::ClientConnection),
42        /// A server connection
43        Server(crate::server::ServerConnection),
44    }
45
46    impl Connection {
47        /// Read TLS content from `rd`.
48        ///
49        /// See [`ConnectionCommon::read_tls()`] for more information.
50        pub fn read_tls(&mut self, rd: &mut dyn Read) -> Result<usize, io::Error> {
51            match self {
52                Self::Client(conn) => conn.read_tls(rd),
53                Self::Server(conn) => conn.read_tls(rd),
54            }
55        }
56
57        /// Writes TLS messages to `wr`.
58        ///
59        /// See [`ConnectionCommon::write_tls()`] for more information.
60        pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
61            self.sendable_tls.write_to(wr)
62        }
63
64        /// Returns an object that allows reading plaintext.
65        pub fn reader(&mut self) -> Reader<'_> {
66            match self {
67                Self::Client(conn) => conn.reader(),
68                Self::Server(conn) => conn.reader(),
69            }
70        }
71
72        /// Returns an object that allows writing plaintext.
73        pub fn writer(&mut self) -> Writer<'_> {
74            match self {
75                Self::Client(conn) => Writer::new(&mut **conn),
76                Self::Server(conn) => Writer::new(&mut **conn),
77            }
78        }
79
80        /// Processes any new packets read by a previous call to [`Connection::read_tls`].
81        ///
82        /// See [`ConnectionCommon::process_new_packets()`] for more information.
83        pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
84            match self {
85                Self::Client(conn) => conn.process_new_packets(),
86                Self::Server(conn) => conn.process_new_packets(),
87            }
88        }
89
90        /// Derives key material from the agreed connection secrets.
91        ///
92        /// See [`ConnectionCommon::export_keying_material()`] for more information.
93        pub fn export_keying_material<T: AsMut<[u8]>>(
94            &self,
95            output: T,
96            label: &[u8],
97            context: Option<&[u8]>,
98        ) -> Result<T, Error> {
99            match self {
100                Self::Client(conn) => conn.export_keying_material(output, label, context),
101                Self::Server(conn) => conn.export_keying_material(output, label, context),
102            }
103        }
104
105        /// This function uses `io` to complete any outstanding IO for this connection.
106        ///
107        /// See [`ConnectionCommon::complete_io()`] for more information.
108        pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
109        where
110            Self: Sized,
111            T: Read + io::Write,
112        {
113            match self {
114                Self::Client(conn) => conn.complete_io(io),
115                Self::Server(conn) => conn.complete_io(io),
116            }
117        }
118
119        /// Extract secrets, so they can be used when configuring kTLS, for example.
120        /// Should be used with care as it exposes secret key material.
121        pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
122            match self {
123                Self::Client(client) => client.dangerous_extract_secrets(),
124                Self::Server(server) => server.dangerous_extract_secrets(),
125            }
126        }
127
128        /// Sets a limit on the internal buffers
129        ///
130        /// See [`ConnectionCommon::set_buffer_limit()`] for more information.
131        pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
132            match self {
133                Self::Client(client) => client.set_buffer_limit(limit),
134                Self::Server(server) => server.set_buffer_limit(limit),
135            }
136        }
137
138        /// Sends a TLS1.3 `key_update` message to refresh a connection's keys
139        ///
140        /// See [`ConnectionCommon::refresh_traffic_keys()`] for more information.
141        pub fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
142            match self {
143                Self::Client(client) => client.refresh_traffic_keys(),
144                Self::Server(server) => server.refresh_traffic_keys(),
145            }
146        }
147    }
148
149    impl Deref for Connection {
150        type Target = CommonState;
151
152        fn deref(&self) -> &Self::Target {
153            match self {
154                Self::Client(conn) => &conn.core.common_state,
155                Self::Server(conn) => &conn.core.common_state,
156            }
157        }
158    }
159
160    impl DerefMut for Connection {
161        fn deref_mut(&mut self) -> &mut Self::Target {
162            match self {
163                Self::Client(conn) => &mut conn.core.common_state,
164                Self::Server(conn) => &mut conn.core.common_state,
165            }
166        }
167    }
168
169    /// A structure that implements [`std::io::Read`] for reading plaintext.
170    pub struct Reader<'a> {
171        pub(super) received_plaintext: &'a mut ChunkVecBuffer,
172        pub(super) has_received_close_notify: bool,
173        pub(super) has_seen_eof: bool,
174    }
175
176    impl<'a> Reader<'a> {
177        /// Check the connection's state if no bytes are available for reading.
178        fn check_no_bytes_state(&self) -> io::Result<()> {
179            match (self.has_received_close_notify, self.has_seen_eof) {
180                // cleanly closed; don't care about TCP EOF: express this as Ok(0)
181                (true, _) => Ok(()),
182                // unclean closure
183                (false, true) => Err(io::Error::new(
184                    io::ErrorKind::UnexpectedEof,
185                    UNEXPECTED_EOF_MESSAGE,
186                )),
187                // connection still going, but needs more data: signal `WouldBlock` so that
188                // the caller knows this
189                (false, false) => Err(io::ErrorKind::WouldBlock.into()),
190            }
191        }
192
193        /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
194        ///
195        /// This method consumes `self` so that it can return a slice whose lifetime is bounded by
196        /// the [`ConnectionCommon`] that created this `Reader`.
197        pub fn into_first_chunk(self) -> io::Result<&'a [u8]> {
198            match self.received_plaintext.chunk() {
199                Some(chunk) => Ok(chunk),
200                None => {
201                    self.check_no_bytes_state()?;
202                    Ok(&[])
203                }
204            }
205        }
206    }
207
208    impl Read for Reader<'_> {
209        /// Obtain plaintext data received from the peer over this TLS connection.
210        ///
211        /// If the peer closes the TLS session cleanly, this returns `Ok(0)`  once all
212        /// the pending data has been read. No further data can be received on that
213        /// connection, so the underlying TCP connection should be half-closed too.
214        ///
215        /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
216        /// `close_notify` alert) this function returns a `std::io::Error` of type
217        /// `ErrorKind::UnexpectedEof` once any pending data has been read.
218        ///
219        /// Note that support for `close_notify` varies in peer TLS libraries: many do not
220        /// support it and uncleanly close the TCP connection (this might be
221        /// vulnerable to truncation attacks depending on the application protocol).
222        /// This means applications using rustls must both handle EOF
223        /// from this function, *and* unexpected EOF of the underlying TCP connection.
224        ///
225        /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
226        ///
227        /// You may learn the number of bytes available at any time by inspecting
228        /// the return of [`Connection::process_new_packets`].
229        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
230            let len = self.received_plaintext.read(buf)?;
231            if len > 0 || buf.is_empty() {
232                return Ok(len);
233            }
234
235            self.check_no_bytes_state()
236                .map(|()| len)
237        }
238
239        /// Obtain plaintext data received from the peer over this TLS connection.
240        ///
241        /// If the peer closes the TLS session, this returns `Ok(())` without filling
242        /// any more of the buffer once all the pending data has been read. No further
243        /// data can be received on that connection, so the underlying TCP connection
244        /// should be half-closed too.
245        ///
246        /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
247        /// `close_notify` alert) this function returns a `std::io::Error` of type
248        /// `ErrorKind::UnexpectedEof` once any pending data has been read.
249        ///
250        /// Note that support for `close_notify` varies in peer TLS libraries: many do not
251        /// support it and uncleanly close the TCP connection (this might be
252        /// vulnerable to truncation attacks depending on the application protocol).
253        /// This means applications using rustls must both handle EOF
254        /// from this function, *and* unexpected EOF of the underlying TCP connection.
255        ///
256        /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
257        ///
258        /// You may learn the number of bytes available at any time by inspecting
259        /// the return of [`Connection::process_new_packets`].
260        #[cfg(read_buf)]
261        fn read_buf(&mut self, mut cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
262            let before = cursor.written();
263            self.received_plaintext
264                .read_buf(cursor.reborrow())?;
265            let len = cursor.written() - before;
266            if len > 0 || cursor.capacity() == 0 {
267                return Ok(());
268            }
269
270            self.check_no_bytes_state()
271        }
272    }
273
274    impl BufRead for Reader<'_> {
275        /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
276        /// This reads the same data as [`Reader::read()`], but returns a reference instead of
277        /// copying the data.
278        ///
279        /// The caller should call [`Reader::consume()`] afterward to advance the buffer.
280        ///
281        /// See [`Reader::into_first_chunk()`] for a version of this function that returns a
282        /// buffer with a longer lifetime.
283        fn fill_buf(&mut self) -> io::Result<&[u8]> {
284            Reader {
285                // reborrow
286                received_plaintext: self.received_plaintext,
287                ..*self
288            }
289            .into_first_chunk()
290        }
291
292        fn consume(&mut self, amt: usize) {
293            self.received_plaintext
294                .consume_first_chunk(amt)
295        }
296    }
297
298    const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sending TLS close_notify: \
299https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";
300
301    /// A structure that implements [`std::io::Write`] for writing plaintext.
302    pub struct Writer<'a> {
303        sink: &'a mut dyn PlaintextSink,
304    }
305
306    impl<'a> Writer<'a> {
307        /// Create a new Writer.
308        ///
309        /// This is not an external interface.  Get one of these objects
310        /// from [`Connection::writer`].
311        pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
312            Writer { sink }
313        }
314    }
315
316    impl io::Write for Writer<'_> {
317        /// Send the plaintext `buf` to the peer, encrypting
318        /// and authenticating it.  Once this function succeeds
319        /// you should call [`Connection::write_tls`] which will output the
320        /// corresponding TLS records.
321        ///
322        /// This function buffers plaintext sent before the
323        /// TLS handshake completes, and sends it as soon
324        /// as it can.  See [`ConnectionCommon::set_buffer_limit`] to control
325        /// the size of this buffer.
326        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
327            self.sink.write(buf)
328        }
329
330        fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
331            self.sink.write_vectored(bufs)
332        }
333
334        fn flush(&mut self) -> io::Result<()> {
335            self.sink.flush()
336        }
337    }
338
339    /// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
340    /// allowing them to be the subject of a [`Writer`].
341    ///
342    /// [`ServerConnection`]: crate::ServerConnection
343    /// [`ClientConnection`]: crate::ClientConnection
344    pub(crate) trait PlaintextSink {
345        fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
346        fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
347        fn flush(&mut self) -> io::Result<()>;
348    }
349
350    impl<T> PlaintextSink for ConnectionCommon<T> {
351        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
352            let len = self
353                .core
354                .common_state
355                .buffer_plaintext(buf.into(), &mut self.sendable_plaintext);
356            self.core.maybe_refresh_traffic_keys();
357            Ok(len)
358        }
359
360        fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
361            let payload_owner: Vec<&[u8]>;
362            let payload = match bufs.len() {
363                0 => return Ok(0),
364                1 => OutboundChunks::Single(bufs[0].deref()),
365                _ => {
366                    payload_owner = bufs
367                        .iter()
368                        .map(|io_slice| io_slice.deref())
369                        .collect();
370
371                    OutboundChunks::new(&payload_owner)
372                }
373            };
374            let len = self
375                .core
376                .common_state
377                .buffer_plaintext(payload, &mut self.sendable_plaintext);
378            self.core.maybe_refresh_traffic_keys();
379            Ok(len)
380        }
381
382        fn flush(&mut self) -> io::Result<()> {
383            Ok(())
384        }
385    }
386}
387
388#[cfg(feature = "std")]
389pub use connection::{Connection, Reader, Writer};
390
391#[derive(Debug)]
392pub(crate) struct ConnectionRandoms {
393    pub(crate) client: [u8; 32],
394    pub(crate) server: [u8; 32],
395}
396
397impl ConnectionRandoms {
398    pub(crate) fn new(client: Random, server: Random) -> Self {
399        Self {
400            client: client.0,
401            server: server.0,
402        }
403    }
404}
405
406/// Interface shared by client and server connections.
407pub struct ConnectionCommon<Data> {
408    pub(crate) core: ConnectionCore<Data>,
409    deframer_buffer: DeframerVecBuffer,
410    sendable_plaintext: ChunkVecBuffer,
411}
412
413impl<Data> ConnectionCommon<Data> {
414    /// Processes any new packets read by a previous call to
415    /// [`Connection::read_tls`].
416    ///
417    /// Errors from this function relate to TLS protocol errors, and
418    /// are fatal to the connection.  Future calls after an error will do
419    /// no new work and will return the same error. After an error is
420    /// received from [`process_new_packets`], you should not call [`read_tls`]
421    /// any more (it will fill up buffers to no purpose). However, you
422    /// may call the other methods on the connection, including `write`,
423    /// `send_close_notify`, and `write_tls`. Most likely you will want to
424    /// call `write_tls` to send any alerts queued by the error and then
425    /// close the underlying connection.
426    ///
427    /// Success from this function comes with some sundry state data
428    /// about the connection.
429    ///
430    /// [`read_tls`]: Connection::read_tls
431    /// [`process_new_packets`]: Connection::process_new_packets
432    #[inline]
433    pub fn process_new_packets(&mut self) -> Result<IoState, Error> {
434        self.core
435            .process_new_packets(&mut self.deframer_buffer, &mut self.sendable_plaintext)
436    }
437
438    /// Derives key material from the agreed connection secrets.
439    ///
440    /// This function fills in `output` with `output.len()` bytes of key
441    /// material derived from the master session secret using `label`
442    /// and `context` for diversification. Ownership of the buffer is taken
443    /// by the function and returned via the Ok result to ensure no key
444    /// material leaks if the function fails.
445    ///
446    /// See RFC5705 for more details on what this does and is for.
447    ///
448    /// For TLS1.3 connections, this function does not use the
449    /// "early" exporter at any point.
450    ///
451    /// This function fails if called prior to the handshake completing;
452    /// check with [`CommonState::is_handshaking`] first.
453    ///
454    /// This function fails if `output.len()` is zero.
455    #[inline]
456    pub fn export_keying_material<T: AsMut<[u8]>>(
457        &self,
458        output: T,
459        label: &[u8],
460        context: Option<&[u8]>,
461    ) -> Result<T, Error> {
462        self.core
463            .export_keying_material(output, label, context)
464    }
465
466    /// Extract secrets, so they can be used when configuring kTLS, for example.
467    /// Should be used with care as it exposes secret key material.
468    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
469        self.core.dangerous_extract_secrets()
470    }
471
472    /// Sets a limit on the internal buffers used to buffer
473    /// unsent plaintext (prior to completing the TLS handshake)
474    /// and unsent TLS records.  This limit acts only on application
475    /// data written through [`Connection::writer`].
476    ///
477    /// By default the limit is 64KB.  The limit can be set
478    /// at any time, even if the current buffer use is higher.
479    ///
480    /// [`None`] means no limit applies, and will mean that written
481    /// data is buffered without bound -- it is up to the application
482    /// to appropriately schedule its plaintext and TLS writes to bound
483    /// memory usage.
484    ///
485    /// For illustration: `Some(1)` means a limit of one byte applies:
486    /// [`Connection::writer`] will accept only one byte, encrypt it and
487    /// add a TLS header.  Once this is sent via [`Connection::write_tls`],
488    /// another byte may be sent.
489    ///
490    /// # Internal write-direction buffering
491    /// rustls has two buffers whose size are bounded by this setting:
492    ///
493    /// ## Buffering of unsent plaintext data prior to handshake completion
494    ///
495    /// Calls to [`Connection::writer`] before or during the handshake
496    /// are buffered (up to the limit specified here).  Once the
497    /// handshake completes this data is encrypted and the resulting
498    /// TLS records are added to the outgoing buffer.
499    ///
500    /// ## Buffering of outgoing TLS records
501    ///
502    /// This buffer is used to store TLS records that rustls needs to
503    /// send to the peer.  It is used in these two circumstances:
504    ///
505    /// - by [`Connection::process_new_packets`] when a handshake or alert
506    ///   TLS record needs to be sent.
507    /// - by [`Connection::writer`] post-handshake: the plaintext is
508    ///   encrypted and the resulting TLS record is buffered.
509    ///
510    /// This buffer is emptied by [`Connection::write_tls`].
511    ///
512    /// [`Connection::writer`]: crate::Connection::writer
513    /// [`Connection::write_tls`]: crate::Connection::write_tls
514    /// [`Connection::process_new_packets`]: crate::Connection::process_new_packets
515    pub fn set_buffer_limit(&mut self, limit: Option<usize>) {
516        self.sendable_plaintext.set_limit(limit);
517        self.sendable_tls.set_limit(limit);
518    }
519
520    /// Sends a TLS1.3 `key_update` message to refresh a connection's keys.
521    ///
522    /// This call refreshes our encryption keys. Once the peer receives the message,
523    /// it refreshes _its_ encryption and decryption keys and sends a response.
524    /// Once we receive that response, we refresh our decryption keys to match.
525    /// At the end of this process, keys in both directions have been refreshed.
526    ///
527    /// Note that this process does not happen synchronously: this call just
528    /// arranges that the `key_update` message will be included in the next
529    /// `write_tls` output.
530    ///
531    /// This fails with `Error::HandshakeNotComplete` if called before the initial
532    /// handshake is complete, or if a version prior to TLS1.3 is negotiated.
533    ///
534    /// # Usage advice
535    /// Note that other implementations (including rustls) may enforce limits on
536    /// the number of `key_update` messages allowed on a given connection to prevent
537    /// denial of service.  Therefore, this should be called sparingly.
538    ///
539    /// rustls implicitly and automatically refreshes traffic keys when needed
540    /// according to the selected cipher suite's cryptographic constraints.  There
541    /// is therefore no need to call this manually to avoid cryptographic keys
542    /// "wearing out".
543    ///
544    /// The main reason to call this manually is to roll keys when it is known
545    /// a connection will be idle for a long period.
546    pub fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
547        self.core.refresh_traffic_keys()
548    }
549}
550
551#[cfg(feature = "std")]
552impl<Data> ConnectionCommon<Data> {
553    /// Returns an object that allows reading plaintext.
554    pub fn reader(&mut self) -> Reader<'_> {
555        let common = &mut self.core.common_state;
556        Reader {
557            received_plaintext: &mut common.received_plaintext,
558            // Are we done? i.e., have we processed all received messages, and received a
559            // close_notify to indicate that no new messages will arrive?
560            has_received_close_notify: common.has_received_close_notify,
561            has_seen_eof: common.has_seen_eof,
562        }
563    }
564
565    /// Returns an object that allows writing plaintext.
566    pub fn writer(&mut self) -> Writer<'_> {
567        Writer::new(self)
568    }
569
570    /// This function uses `io` to complete any outstanding IO for
571    /// this connection.
572    ///
573    /// This is a convenience function which solely uses other parts
574    /// of the public API.
575    ///
576    /// What this means depends on the connection  state:
577    ///
578    /// - If the connection [`is_handshaking`], then IO is performed until
579    ///   the handshake is complete.
580    /// - Otherwise, if [`wants_write`] is true, [`write_tls`] is invoked
581    ///   until it is all written.
582    /// - Otherwise, if [`wants_read`] is true, [`read_tls`] is invoked
583    ///   once.
584    ///
585    /// The return value is the number of bytes read from and written
586    /// to `io`, respectively.
587    ///
588    /// This function will block if `io` blocks.
589    ///
590    /// Errors from TLS record handling (i.e., from [`process_new_packets`])
591    /// are wrapped in an `io::ErrorKind::InvalidData`-kind error.
592    ///
593    /// [`is_handshaking`]: CommonState::is_handshaking
594    /// [`wants_read`]: CommonState::wants_read
595    /// [`wants_write`]: CommonState::wants_write
596    /// [`write_tls`]: ConnectionCommon::write_tls
597    /// [`read_tls`]: ConnectionCommon::read_tls
598    /// [`process_new_packets`]: ConnectionCommon::process_new_packets
599    pub fn complete_io<T>(&mut self, io: &mut T) -> Result<(usize, usize), io::Error>
600    where
601        Self: Sized,
602        T: io::Read + io::Write,
603    {
604        let mut eof = false;
605        let mut wrlen = 0;
606        let mut rdlen = 0;
607
608        loop {
609            let until_handshaked = self.is_handshaking();
610
611            if !self.wants_write() && !self.wants_read() {
612                // We will make no further progress.
613                return Ok((rdlen, wrlen));
614            }
615
616            while self.wants_write() {
617                match self.write_tls(io)? {
618                    0 => {
619                        io.flush()?;
620                        return Ok((rdlen, wrlen)); // EOF.
621                    }
622                    n => wrlen += n,
623                }
624            }
625            io.flush()?;
626
627            if !until_handshaked && wrlen > 0 {
628                return Ok((rdlen, wrlen));
629            }
630
631            while !eof && self.wants_read() {
632                let read_size = match self.read_tls(io) {
633                    Ok(0) => {
634                        eof = true;
635                        Some(0)
636                    }
637                    Ok(n) => {
638                        rdlen += n;
639                        Some(n)
640                    }
641                    Err(err) if err.kind() == io::ErrorKind::Interrupted => None, // nothing to do
642                    Err(err) => return Err(err),
643                };
644                if read_size.is_some() {
645                    break;
646                }
647            }
648
649            match self.process_new_packets() {
650                Ok(_) => {}
651                Err(e) => {
652                    // In case we have an alert to send describing this error,
653                    // try a last-gasp write -- but don't predate the primary
654                    // error.
655                    let _ignored = self.write_tls(io);
656                    let _ignored = io.flush();
657
658                    return Err(io::Error::new(io::ErrorKind::InvalidData, e));
659                }
660            };
661
662            // if we're doing IO until handshaked, and we believe we've finished handshaking,
663            // but process_new_packets() has queued TLS data to send, loop around again to write
664            // the queued messages.
665            if until_handshaked && !self.is_handshaking() && self.wants_write() {
666                continue;
667            }
668
669            match (eof, until_handshaked, self.is_handshaking()) {
670                (_, true, false) => return Ok((rdlen, wrlen)),
671                (_, false, _) => return Ok((rdlen, wrlen)),
672                (true, true, true) => return Err(io::Error::from(io::ErrorKind::UnexpectedEof)),
673                (..) => {}
674            }
675        }
676    }
677
678    /// Extract the first handshake message.
679    ///
680    /// This is a shortcut to the `process_new_packets()` -> `process_msg()` ->
681    /// `process_handshake_messages()` path, specialized for the first handshake message.
682    pub(crate) fn first_handshake_message(&mut self) -> Result<Option<Message<'static>>, Error> {
683        let mut buffer_progress = self.core.hs_deframer.progress();
684
685        let res = self
686            .core
687            .deframe(
688                None,
689                self.deframer_buffer.filled_mut(),
690                &mut buffer_progress,
691            )
692            .map(|opt| opt.map(|pm| Message::try_from(pm).map(|m| m.into_owned())));
693
694        match res? {
695            Some(Ok(msg)) => {
696                self.deframer_buffer
697                    .discard(buffer_progress.take_discard());
698                Ok(Some(msg))
699            }
700            Some(Err(err)) => Err(self.send_fatal_alert(AlertDescription::DecodeError, err)),
701            None => Ok(None),
702        }
703    }
704
705    pub(crate) fn replace_state(&mut self, new: Box<dyn State<Data>>) {
706        self.core.state = Ok(new);
707    }
708
709    /// Read TLS content from `rd` into the internal buffer.
710    ///
711    /// Due to the internal buffering, `rd` can supply TLS messages in arbitrary-sized chunks (like
712    /// a socket or pipe might).
713    ///
714    /// You should call [`process_new_packets()`] each time a call to this function succeeds in order
715    /// to empty the incoming TLS data buffer.
716    ///
717    /// This function returns `Ok(0)` when the underlying `rd` does so. This typically happens when
718    /// a socket is cleanly closed, or a file is at EOF. Errors may result from the IO done through
719    /// `rd`; additionally, errors of `ErrorKind::Other` are emitted to signal backpressure:
720    ///
721    /// * In order to empty the incoming TLS data buffer, you should call [`process_new_packets()`]
722    ///   each time a call to this function succeeds.
723    /// * In order to empty the incoming plaintext data buffer, you should empty it through
724    ///   the [`reader()`] after the call to [`process_new_packets()`].
725    ///
726    /// This function also returns `Ok(0)` once a `close_notify` alert has been successfully
727    /// received.  No additional data is ever read in this state.
728    ///
729    /// [`process_new_packets()`]: ConnectionCommon::process_new_packets
730    /// [`reader()`]: ConnectionCommon::reader
731    pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
732        if self.received_plaintext.is_full() {
733            return Err(io::Error::new(
734                io::ErrorKind::Other,
735                "received plaintext buffer full",
736            ));
737        }
738
739        if self.has_received_close_notify {
740            return Ok(0);
741        }
742
743        let res = self
744            .deframer_buffer
745            .read(rd, self.core.hs_deframer.is_active());
746        if let Ok(0) = res {
747            self.has_seen_eof = true;
748        }
749        res
750    }
751
752    /// Writes TLS messages to `wr`.
753    ///
754    /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
755    /// (after encoding and encryption).
756    ///
757    /// After this function returns, the connection buffer may not yet be fully flushed. The
758    /// [`CommonState::wants_write`] function can be used to check if the output buffer is empty.
759    pub fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
760        self.sendable_tls.write_to(wr)
761    }
762}
763
764impl<'a, Data> From<&'a mut ConnectionCommon<Data>> for Context<'a, Data> {
765    fn from(conn: &'a mut ConnectionCommon<Data>) -> Self {
766        Self {
767            common: &mut conn.core.common_state,
768            data: &mut conn.core.data,
769            sendable_plaintext: Some(&mut conn.sendable_plaintext),
770        }
771    }
772}
773
774impl<T> Deref for ConnectionCommon<T> {
775    type Target = CommonState;
776
777    fn deref(&self) -> &Self::Target {
778        &self.core.common_state
779    }
780}
781
782impl<T> DerefMut for ConnectionCommon<T> {
783    fn deref_mut(&mut self) -> &mut Self::Target {
784        &mut self.core.common_state
785    }
786}
787
788impl<Data> From<ConnectionCore<Data>> for ConnectionCommon<Data> {
789    fn from(core: ConnectionCore<Data>) -> Self {
790        Self {
791            core,
792            deframer_buffer: DeframerVecBuffer::default(),
793            sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
794        }
795    }
796}
797
798/// Interface shared by unbuffered client and server connections.
799pub struct UnbufferedConnectionCommon<Data> {
800    pub(crate) core: ConnectionCore<Data>,
801    wants_write: bool,
802    emitted_peer_closed_state: bool,
803}
804
805impl<Data> From<ConnectionCore<Data>> for UnbufferedConnectionCommon<Data> {
806    fn from(core: ConnectionCore<Data>) -> Self {
807        Self {
808            core,
809            wants_write: false,
810            emitted_peer_closed_state: false,
811        }
812    }
813}
814
815impl<Data> UnbufferedConnectionCommon<Data> {
816    /// Extract secrets, so they can be used when configuring kTLS, for example.
817    /// Should be used with care as it exposes secret key material.
818    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
819        self.core.dangerous_extract_secrets()
820    }
821}
822
823impl<T> Deref for UnbufferedConnectionCommon<T> {
824    type Target = CommonState;
825
826    fn deref(&self) -> &Self::Target {
827        &self.core.common_state
828    }
829}
830
831pub(crate) struct ConnectionCore<Data> {
832    pub(crate) state: Result<Box<dyn State<Data>>, Error>,
833    pub(crate) data: Data,
834    pub(crate) common_state: CommonState,
835    pub(crate) hs_deframer: HandshakeDeframer,
836
837    /// We limit consecutive empty fragments to avoid a route for the peer to send
838    /// us significant but fruitless traffic.
839    seen_consecutive_empty_fragments: u8,
840}
841
842impl<Data> ConnectionCore<Data> {
843    pub(crate) fn new(state: Box<dyn State<Data>>, data: Data, common_state: CommonState) -> Self {
844        Self {
845            state: Ok(state),
846            data,
847            common_state,
848            hs_deframer: HandshakeDeframer::default(),
849            seen_consecutive_empty_fragments: 0,
850        }
851    }
852
853    pub(crate) fn process_new_packets(
854        &mut self,
855        deframer_buffer: &mut DeframerVecBuffer,
856        sendable_plaintext: &mut ChunkVecBuffer,
857    ) -> Result<IoState, Error> {
858        let mut state = match mem::replace(&mut self.state, Err(Error::HandshakeNotComplete)) {
859            Ok(state) => state,
860            Err(e) => {
861                self.state = Err(e.clone());
862                return Err(e);
863            }
864        };
865
866        let mut buffer_progress = self.hs_deframer.progress();
867
868        loop {
869            let res = self.deframe(
870                Some(&*state),
871                deframer_buffer.filled_mut(),
872                &mut buffer_progress,
873            );
874
875            let opt_msg = match res {
876                Ok(opt_msg) => opt_msg,
877                Err(e) => {
878                    self.state = Err(e.clone());
879                    deframer_buffer.discard(buffer_progress.take_discard());
880                    return Err(e);
881                }
882            };
883
884            let Some(msg) = opt_msg else {
885                break;
886            };
887
888            match self.process_msg(msg, state, Some(sendable_plaintext)) {
889                Ok(new) => state = new,
890                Err(e) => {
891                    self.state = Err(e.clone());
892                    deframer_buffer.discard(buffer_progress.take_discard());
893                    return Err(e);
894                }
895            }
896
897            if self
898                .common_state
899                .has_received_close_notify
900            {
901                // "Any data received after a closure alert has been received MUST be ignored."
902                // -- <https://datatracker.ietf.org/doc/html/rfc8446#section-6.1>
903                // This is data that has already been accepted in `read_tls`.
904                buffer_progress.add_discard(deframer_buffer.filled().len());
905                break;
906            }
907
908            deframer_buffer.discard(buffer_progress.take_discard());
909        }
910
911        deframer_buffer.discard(buffer_progress.take_discard());
912        self.state = Ok(state);
913        Ok(self.common_state.current_io_state())
914    }
915
916    /// Pull a message out of the deframer and send any messages that need to be sent as a result.
917    fn deframe<'b>(
918        &mut self,
919        state: Option<&dyn State<Data>>,
920        buffer: &'b mut [u8],
921        buffer_progress: &mut BufferProgress,
922    ) -> Result<Option<InboundPlainMessage<'b>>, Error> {
923        // before processing any more of `buffer`, return any extant messages from `hs_deframer`
924        if self.hs_deframer.has_message_ready() {
925            Ok(self.take_handshake_message(buffer, buffer_progress))
926        } else {
927            self.process_more_input(state, buffer, buffer_progress)
928        }
929    }
930
931    fn take_handshake_message<'b>(
932        &mut self,
933        buffer: &'b mut [u8],
934        buffer_progress: &mut BufferProgress,
935    ) -> Option<InboundPlainMessage<'b>> {
936        self.hs_deframer
937            .iter(buffer)
938            .next()
939            .map(|(message, discard)| {
940                buffer_progress.add_discard(discard);
941                message
942            })
943    }
944
945    fn process_more_input<'b>(
946        &mut self,
947        state: Option<&dyn State<Data>>,
948        buffer: &'b mut [u8],
949        buffer_progress: &mut BufferProgress,
950    ) -> Result<Option<InboundPlainMessage<'b>>, Error> {
951        let version_is_tls13 = matches!(
952            self.common_state.negotiated_version,
953            Some(ProtocolVersion::TLSv1_3)
954        );
955
956        let locator = Locator::new(buffer);
957
958        loop {
959            let mut iter = DeframerIter::new(&mut buffer[buffer_progress.processed()..]);
960
961            let (message, processed) = loop {
962                let message = match iter.next().transpose() {
963                    Ok(Some(message)) => message,
964                    Ok(None) => return Ok(None),
965                    Err(err) => return Err(self.handle_deframe_error(err, state)),
966                };
967
968                let allowed_plaintext = match message.typ {
969                    // CCS messages are always plaintext.
970                    ContentType::ChangeCipherSpec => true,
971                    // Alerts are allowed to be plaintext if-and-only-if:
972                    // * The negotiated protocol version is TLS 1.3. - In TLS 1.2 it is unambiguous when
973                    //   keying changes based on the CCS message. Only TLS 1.3 requires these heuristics.
974                    // * We have not yet decrypted any messages from the peer - if we have we don't
975                    //   expect any plaintext.
976                    // * The payload size is indicative of a plaintext alert message.
977                    ContentType::Alert
978                        if version_is_tls13
979                            && !self
980                                .common_state
981                                .record_layer
982                                .has_decrypted()
983                            && message.payload.len() <= 2 =>
984                    {
985                        true
986                    }
987                    // In other circumstances, we expect all messages to be encrypted.
988                    _ => false,
989                };
990
991                if allowed_plaintext && !self.hs_deframer.is_active() {
992                    break (message.into_plain_message(), iter.bytes_consumed());
993                }
994
995                let message = match self
996                    .common_state
997                    .record_layer
998                    .decrypt_incoming(message)
999                {
1000                    // failed decryption during trial decryption is not allowed to be
1001                    // interleaved with partial handshake data.
1002                    Ok(None) if !self.hs_deframer.is_aligned() => {
1003                        return Err(
1004                            PeerMisbehaved::RejectedEarlyDataInterleavedWithHandshakeMessage.into(),
1005                        );
1006                    }
1007
1008                    // failed decryption during trial decryption.
1009                    Ok(None) => continue,
1010
1011                    Ok(Some(message)) => message,
1012
1013                    Err(err) => return Err(self.handle_deframe_error(err, state)),
1014                };
1015
1016                let Decrypted {
1017                    want_close_before_decrypt,
1018                    plaintext,
1019                } = message;
1020
1021                if want_close_before_decrypt {
1022                    self.common_state.send_close_notify();
1023                }
1024
1025                break (plaintext, iter.bytes_consumed());
1026            };
1027
1028            if !self.hs_deframer.is_aligned() && message.typ != ContentType::Handshake {
1029                // "Handshake messages MUST NOT be interleaved with other record
1030                // types.  That is, if a handshake message is split over two or more
1031                // records, there MUST NOT be any other records between them."
1032                // https://www.rfc-editor.org/rfc/rfc8446#section-5.1
1033                return Err(PeerMisbehaved::MessageInterleavedWithHandshakeMessage.into());
1034            }
1035
1036            match message.payload.len() {
1037                0 => {
1038                    if self.seen_consecutive_empty_fragments
1039                        == ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX
1040                    {
1041                        return Err(PeerMisbehaved::TooManyEmptyFragments.into());
1042                    }
1043                    self.seen_consecutive_empty_fragments += 1;
1044                }
1045                _ => {
1046                    self.seen_consecutive_empty_fragments = 0;
1047                }
1048            };
1049
1050            buffer_progress.add_processed(processed);
1051
1052            // do an end-run around the borrow checker, converting `message` (containing
1053            // a borrowed slice) to an unborrowed one (containing a `Range` into the
1054            // same buffer).  the reborrow happens inside the branch that returns the
1055            // message.
1056            //
1057            // is fixed by -Zpolonius
1058            // https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md#problem-case-3-conditional-control-flow-across-functions
1059            let unborrowed = InboundUnborrowedMessage::unborrow(&locator, message);
1060
1061            if unborrowed.typ != ContentType::Handshake {
1062                let message = unborrowed.reborrow(&Delocator::new(buffer));
1063                buffer_progress.add_discard(processed);
1064                return Ok(Some(message));
1065            }
1066
1067            let message = unborrowed.reborrow(&Delocator::new(buffer));
1068            self.hs_deframer
1069                .input_message(message, &locator, buffer_progress.processed());
1070            self.hs_deframer.coalesce(buffer)?;
1071
1072            self.common_state.aligned_handshake = self.hs_deframer.is_aligned();
1073
1074            if self.hs_deframer.has_message_ready() {
1075                // trial decryption finishes with the first handshake message after it started.
1076                self.common_state
1077                    .record_layer
1078                    .finish_trial_decryption();
1079
1080                return Ok(self.take_handshake_message(buffer, buffer_progress));
1081            }
1082        }
1083    }
1084
1085    fn handle_deframe_error(&mut self, error: Error, state: Option<&dyn State<Data>>) -> Error {
1086        match error {
1087            error @ Error::InvalidMessage(_) => {
1088                if self.common_state.is_quic() {
1089                    self.common_state.quic.alert = Some(AlertDescription::DecodeError);
1090                    error
1091                } else {
1092                    self.common_state
1093                        .send_fatal_alert(AlertDescription::DecodeError, error)
1094                }
1095            }
1096            Error::PeerSentOversizedRecord => self
1097                .common_state
1098                .send_fatal_alert(AlertDescription::RecordOverflow, error),
1099            Error::DecryptError => {
1100                if let Some(state) = state {
1101                    state.handle_decrypt_error();
1102                }
1103                self.common_state
1104                    .send_fatal_alert(AlertDescription::BadRecordMac, error)
1105            }
1106
1107            error => error,
1108        }
1109    }
1110
1111    fn process_msg(
1112        &mut self,
1113        msg: InboundPlainMessage<'_>,
1114        state: Box<dyn State<Data>>,
1115        sendable_plaintext: Option<&mut ChunkVecBuffer>,
1116    ) -> Result<Box<dyn State<Data>>, Error> {
1117        // Drop CCS messages during handshake in TLS1.3
1118        if msg.typ == ContentType::ChangeCipherSpec
1119            && !self
1120                .common_state
1121                .may_receive_application_data
1122            && self.common_state.is_tls13()
1123        {
1124            if !msg.is_valid_ccs() {
1125                // "An implementation which receives any other change_cipher_spec value or
1126                //  which receives a protected change_cipher_spec record MUST abort the
1127                //  handshake with an "unexpected_message" alert."
1128                return Err(self.common_state.send_fatal_alert(
1129                    AlertDescription::UnexpectedMessage,
1130                    PeerMisbehaved::IllegalMiddleboxChangeCipherSpec,
1131                ));
1132            }
1133
1134            self.common_state
1135                .received_tls13_change_cipher_spec()?;
1136            trace!("Dropping CCS");
1137            return Ok(state);
1138        }
1139
1140        // Now we can fully parse the message payload.
1141        let msg = match Message::try_from(msg) {
1142            Ok(msg) => msg,
1143            Err(err) => {
1144                return Err(self
1145                    .common_state
1146                    .send_fatal_alert(AlertDescription::DecodeError, err));
1147            }
1148        };
1149
1150        // For alerts, we have separate logic.
1151        if let MessagePayload::Alert(alert) = &msg.payload {
1152            self.common_state.process_alert(alert)?;
1153            return Ok(state);
1154        }
1155
1156        self.common_state
1157            .process_main_protocol(msg, state, &mut self.data, sendable_plaintext)
1158    }
1159
1160    pub(crate) fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
1161        if !self
1162            .common_state
1163            .enable_secret_extraction
1164        {
1165            return Err(Error::General("Secret extraction is disabled".into()));
1166        }
1167
1168        let st = self.state?;
1169
1170        let record_layer = self.common_state.record_layer;
1171        let PartiallyExtractedSecrets { tx, rx } = st.extract_secrets()?;
1172        Ok(ExtractedSecrets {
1173            tx: (record_layer.write_seq(), tx),
1174            rx: (record_layer.read_seq(), rx),
1175        })
1176    }
1177
1178    pub(crate) fn export_keying_material<T: AsMut<[u8]>>(
1179        &self,
1180        mut output: T,
1181        label: &[u8],
1182        context: Option<&[u8]>,
1183    ) -> Result<T, Error> {
1184        if output.as_mut().is_empty() {
1185            return Err(Error::General(
1186                "export_keying_material with zero-length output".into(),
1187            ));
1188        }
1189
1190        match self.state.as_ref() {
1191            Ok(st) => st
1192                .export_keying_material(output.as_mut(), label, context)
1193                .map(|_| output),
1194            Err(e) => Err(e.clone()),
1195        }
1196    }
1197
1198    /// Trigger a `refresh_traffic_keys` if required by `CommonState`.
1199    fn maybe_refresh_traffic_keys(&mut self) {
1200        if mem::take(
1201            &mut self
1202                .common_state
1203                .refresh_traffic_keys_pending,
1204        ) {
1205            let _ = self.refresh_traffic_keys();
1206        }
1207    }
1208
1209    fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
1210        match &mut self.state {
1211            Ok(st) => st.send_key_update_request(&mut self.common_state),
1212            Err(e) => Err(e.clone()),
1213        }
1214    }
1215}
1216
1217/// Data specific to the peer's side (client or server).
1218pub trait SideData: Debug {}
1219
1220/// An InboundPlainMessage which does not borrow its payload, but
1221/// references a range that can later be borrowed.
1222struct InboundUnborrowedMessage {
1223    typ: ContentType,
1224    version: ProtocolVersion,
1225    bounds: Range<usize>,
1226}
1227
1228impl InboundUnborrowedMessage {
1229    fn unborrow(locator: &Locator, msg: InboundPlainMessage<'_>) -> Self {
1230        Self {
1231            typ: msg.typ,
1232            version: msg.version,
1233            bounds: locator.locate(msg.payload),
1234        }
1235    }
1236
1237    fn reborrow<'b>(self, delocator: &Delocator<'b>) -> InboundPlainMessage<'b> {
1238        InboundPlainMessage {
1239            typ: self.typ,
1240            version: self.version,
1241            payload: delocator.slice_from_range(&self.bounds),
1242        }
1243    }
1244}
1245
1246/// cf. BoringSSL's `kMaxEmptyRecords`
1247/// <https://github.com/google/boringssl/blob/dec5989b793c56ad4dd32173bd2d8595ca78b398/ssl/tls_record.cc#L124-L128>
1248const ALLOWED_CONSECUTIVE_EMPTY_FRAGMENTS_MAX: u8 = 32;