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