Skip to main content

rustls/conn/
mod.rs

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