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;