Skip to main content

rustls/conn/
mod.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt::{self, Debug};
4use core::ops::{Deref, DerefMut};
5use std::io::{self, BufRead, Read};
6
7use kernel::KernelConnection;
8use pki_types::FipsStatus;
9
10use crate::common_state::{
11    CommonState, ConnectionOutput, ConnectionOutputs, Event, Output, OutputEvent,
12};
13use crate::error::{ApiMisuse, Error};
14use crate::kernel::KernelState;
15use crate::msgs::{Delocator, Message, Random, ServerExtensionsInput};
16use crate::quic::QuicOutput;
17use crate::server::{ChooseConfig, ServerConfig, ServerSide};
18use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
19use crate::sync::Arc;
20use crate::tls13::key_schedule::KeyScheduleTrafficSend;
21use crate::vecbuf::ChunkVecBuffer;
22
23// pub so that it can be re-exported from the crate root
24pub mod kernel;
25
26mod receive;
27pub(crate) use receive::{Input, MessageIter, ReceivePath, TrafficTemperCounters};
28pub use receive::{SliceInput, TlsInputBuffer, VecInput};
29
30mod send;
31use send::DEFAULT_BUFFER_LIMIT;
32pub(crate) use send::{SendOutput, SendPath};
33
34pub(crate) mod split;
35use split::SplitConnection;
36
37use crate::crypto::cipher::OutboundPlain;
38
39/// A trait generalizing over buffered client or server connections.
40pub trait Connection: Debug + Deref<Target = ConnectionOutputs> {
41    /// Writes TLS messages to `wr`.
42    ///
43    /// On success, this function returns `Ok(n)` where `n` is a number of bytes written to `wr`
44    /// (after encoding and encryption).
45    ///
46    /// After this function returns, the connection buffer may not yet be fully flushed. The
47    /// [`Self::wants_write()`] function can be used to check if the output buffer is
48    /// empty.
49    fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error>;
50
51    /// Returns true if the caller should call [`Self::process_new_packets()`] as soon as possible.
52    ///
53    /// If there is pending plaintext data to read with [`Self::reader()`],
54    /// this returns false.  If your application respects this mechanism,
55    /// only one full TLS message will be buffered by rustls.
56    fn wants_read(&self) -> bool;
57
58    /// Returns true if the caller should call [`Self::write_tls()`] as soon as possible.
59    fn wants_write(&self) -> bool;
60
61    /// Returns an object that allows reading plaintext.
62    fn reader(&mut self) -> Reader<'_>;
63
64    /// Returns an object that allows writing plaintext.
65    fn writer(&mut self) -> Writer<'_>;
66
67    /// Processes any new packets from the buffer supplied in `buf`.
68    ///
69    /// Errors from this function relate to TLS protocol errors, and
70    /// are fatal to the connection.  Future calls after an error will do
71    /// no new work and will return the same error. After an error is
72    /// received from this function, you should not continue to fill up the buffer.
73    /// However, you may call the other methods on the connection, including [`Self::writer()`],
74    /// [`Self::send_close_notify()`], and [`Self::write_tls()`]. Most likely you will want to
75    /// call [`Self::write_tls()`] to send any alerts queued by the error and then
76    /// close the underlying connection.
77    ///
78    /// Success from this function comes with some sundry state data
79    /// about the connection.
80    fn process_new_packets(&mut self, input: &mut dyn TlsInputBuffer) -> Result<IoState, Error>;
81
82    /// Returns an object that can derive key material from the agreed connection secrets.
83    ///
84    /// See [RFC5705][] for more details on what this is for.
85    ///
86    /// This function can be called at most once per connection.
87    ///
88    /// This function will error:
89    ///
90    /// - if called prior to the handshake completing; (check with
91    ///   [`Self::is_handshaking()`] first).
92    /// - if called more than once per connection.
93    ///
94    /// [RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705
95    fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error>;
96
97    /// Extract secrets, so they can be used when configuring kTLS, for example.
98    ///
99    /// Should be used with care as it exposes secret key material.
100    fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error>;
101
102    /// Sets a limit on the internal buffers used to buffer
103    /// unsent plaintext (prior to completing the TLS handshake)
104    /// and unsent TLS records.  This limit acts only on application
105    /// data written through [`Self::writer()`].
106    ///
107    /// By default the limit is 64KB.  The limit can be set
108    /// at any time, even if the current buffer use is higher.
109    ///
110    /// [`None`] means no limit applies, and will mean that written
111    /// data is buffered without bound -- it is up to the application
112    /// to appropriately schedule its plaintext and TLS writes to bound
113    /// memory usage.
114    ///
115    /// For illustration: `Some(1)` means a limit of one byte applies:
116    /// [`Self::writer()`] will accept only one byte, encrypt it and
117    /// add a TLS header.  Once this is sent via [`Self::write_tls()`],
118    /// another byte may be sent.
119    ///
120    /// # Internal write-direction buffering
121    /// rustls has two buffers whose size are bounded by this setting:
122    ///
123    /// ## Buffering of unsent plaintext data prior to handshake completion
124    ///
125    /// Calls to [`Self::writer()`] before or during the handshake
126    /// are buffered (up to the limit specified here).  Once the
127    /// handshake completes this data is encrypted and the resulting
128    /// TLS records are added to the outgoing buffer.
129    ///
130    /// ## Buffering of outgoing TLS records
131    ///
132    /// This buffer is used to store TLS records that rustls needs to
133    /// send to the peer.  It is used in these two circumstances:
134    ///
135    /// - by [`Self::process_new_packets()`] when a handshake or alert
136    ///   TLS record needs to be sent.
137    /// - by [`Self::writer()`] post-handshake: the plaintext is
138    ///   encrypted and the resulting TLS record is buffered.
139    ///
140    /// This buffer is emptied by [`Self::write_tls()`].
141    fn set_buffer_limit(&mut self, limit: Option<usize>);
142
143    /// Sets a limit on the internal buffers used to buffer decoded plaintext.
144    ///
145    /// See [`Self::set_buffer_limit()`] for more information on how limits are applied.
146    fn set_plaintext_buffer_limit(&mut self, limit: Option<usize>);
147
148    /// Sends a TLS1.3 `key_update` message to refresh a connection's keys.
149    ///
150    /// This call refreshes our encryption keys. Once the peer receives the message,
151    /// it refreshes _its_ encryption and decryption keys and sends a response.
152    /// Once we receive that response, we refresh our decryption keys to match.
153    /// At the end of this process, keys in both directions have been refreshed.
154    ///
155    /// Note that this process does not happen synchronously: this call just
156    /// arranges that the `key_update` message will be included in the next
157    /// [`Self::write_tls()`] output.
158    ///
159    /// This fails with [`Error::HandshakeNotComplete`] if called before the initial
160    /// handshake is complete, or if a version prior to TLS1.3 is negotiated.
161    ///
162    /// # Usage advice
163    /// Note that other implementations (including rustls) may enforce limits on
164    /// the number of `key_update` messages allowed on a given connection to prevent
165    /// denial of service.  Therefore, this should be called sparingly.
166    ///
167    /// rustls implicitly and automatically refreshes traffic keys when needed
168    /// according to the selected cipher suite's cryptographic constraints.  There
169    /// is therefore no need to call this manually to avoid cryptographic keys
170    /// "wearing out".
171    ///
172    /// The main reason to call this manually is to roll keys when it is known
173    /// a connection will be idle for a long period.
174    fn refresh_traffic_keys(&mut self) -> Result<(), Error>;
175
176    /// Queues a `close_notify` warning alert to be sent in the next [`Self::write_tls`] call.
177    ///
178    /// This informs the peer that the connection is being closed.
179    ///
180    /// Does nothing if any `close_notify` or fatal alert was already sent.
181    fn send_close_notify(&mut self);
182
183    /// Returns true if the connection is currently performing the TLS handshake.
184    ///
185    /// During this time plaintext written to the connection is buffered in memory. After
186    /// [`Self::process_new_packets()`] has been called, this might start to return `false`
187    /// while the final handshake packets still need to be extracted from the connection's buffers.
188    fn is_handshaking(&self) -> bool;
189
190    /// Return the FIPS validation status of the connection.
191    ///
192    /// This is different from [`CryptoProvider::fips()`][]:
193    /// it is concerned only with cryptography, whereas this _also_ covers TLS-level
194    /// configuration that NIST recommends, as well as ECH HPKE suites if applicable.
195    ///
196    /// [`CryptoProvider::fips()`]: crate::crypto::CryptoProvider::fips()
197    fn fips(&self) -> FipsStatus;
198}
199
200/// TLS connection state with side-specific data (`Side`).
201///
202/// This is one of the core abstractions of the rustls API. It represents a single connection
203/// to a peer, and holds all the state associated with that connection. Note that it does
204/// not hold any IO objects: the application is responsible for reading and writing TLS records.
205/// If you want an object that does hold IO objects, see `rustls_util::Stream` and
206/// `rustls_util::StreamOwned`.
207///
208/// This object is generic over the `Side` type parameter, which must implement the marker trait
209/// [`SideData`]. This is used to store side-specific data.
210pub(crate) struct ConnectionCommon<Side: SideData> {
211    pub(crate) core: ConnectionCore<Side>,
212    buffers: Buffers,
213}
214
215impl<Side: SideData> ConnectionCommon<Side> {
216    pub(crate) fn new(core: ConnectionCore<Side>) -> Self {
217        Self {
218            core,
219            buffers: Buffers::new(),
220        }
221    }
222
223    #[inline]
224    pub(crate) fn process_new_packets(
225        &mut self,
226        input: &mut dyn TlsInputBuffer,
227    ) -> Result<IoState, Error> {
228        if input.has_seen_eof() {
229            self.buffers.has_seen_eof = true;
230        } else if self
231            .buffers
232            .received_plaintext
233            .is_full()
234        {
235            return Err(ApiMisuse::ReceivedPlaintextBufferFull.into());
236        }
237
238        let mut iter = MessageIter::new(input, None, &mut self.core);
239        while let Some(result) = iter.next() {
240            let payload = result?.reborrow(&Delocator::new(iter.input().slice_mut()));
241            self.buffers
242                .received_plaintext
243                .append(payload.into_vec());
244        }
245
246        input.discard(
247            self.core
248                .common
249                .recv
250                .deframer
251                .take_discard(),
252        );
253
254        // Release unsent buffered plaintext.
255        if self.send.may_send_application_data
256            && !self
257                .buffers
258                .sendable_plaintext
259                .is_empty()
260        {
261            self.core
262                .common
263                .send
264                .send_buffered_plaintext(&mut self.buffers.sendable_plaintext);
265        }
266
267        Ok(IoState::new(
268            &self.core.common.send,
269            &self.core.common.recv,
270            &self.buffers,
271        ))
272    }
273
274    pub(crate) fn wants_read(&self) -> bool {
275        // We want to read more data all the time, except when we have unprocessed plaintext.
276        // This provides back-pressure to the TCP buffers. We also don't want to read more after
277        // the peer has sent us a close notification.
278        //
279        // In the handshake case we don't have readable plaintext before the handshake has
280        // completed, but also don't want to read if we still have sendable tls.
281        self.buffers
282            .received_plaintext
283            .is_empty()
284            && !self.recv.has_received_close_notify
285            && (self.send.may_send_application_data || self.send.sendable_tls.is_empty())
286    }
287
288    pub(crate) fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
289        self.core.exporter()
290    }
291
292    /// Extract secrets, so they can be used when configuring kTLS, for example.
293    /// Should be used with care as it exposes secret key material.
294    pub(crate) fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
295        self.core.dangerous_extract_secrets()
296    }
297
298    pub(crate) fn set_buffer_limit(&mut self, limit: Option<usize>) {
299        self.buffers
300            .sendable_plaintext
301            .set_limit(limit);
302        self.send.sendable_tls.set_limit(limit);
303    }
304
305    pub(crate) fn set_plaintext_buffer_limit(&mut self, limit: Option<usize>) {
306        self.buffers
307            .received_plaintext
308            .set_limit(limit);
309    }
310
311    pub(crate) fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
312        self.core
313            .common
314            .send
315            .refresh_traffic_keys()
316    }
317
318    pub(crate) fn split(self) -> Result<SplitConnection<Side>, Error> {
319        // `SplitConnection` cannot be used to progress a handshake.
320        if self.is_handshaking() {
321            return Err(ApiMisuse::SplitDuringHandshake.into());
322        }
323
324        // We are about to drop `Buffers`
325        if !self.buffers.is_empty() {
326            return Err(ApiMisuse::SplitWithPendingBuffers.into());
327        }
328
329        SplitConnection::try_from(self.core)
330    }
331}
332
333impl<Side: SideData> ConnectionCommon<Side> {
334    /// Returns an object that allows reading plaintext.
335    pub(crate) fn reader(&mut self) -> Reader<'_> {
336        let common = &mut self.core.common;
337        let has_received_close_notify = common.recv.has_received_close_notify;
338        Reader {
339            received_plaintext: &mut self.buffers.received_plaintext,
340            // Are we done? i.e., have we processed all received messages, and received a
341            // close_notify to indicate that no new messages will arrive?
342            has_received_close_notify,
343            has_seen_eof: self.buffers.has_seen_eof,
344        }
345    }
346
347    /// Returns an object that allows writing plaintext.
348    pub(crate) fn writer(&mut self) -> Writer<'_> {
349        Writer::new(self)
350    }
351
352    pub(crate) fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
353        self.send.sendable_tls.write_to(wr)
354    }
355}
356
357impl<Side: SideData> Deref for ConnectionCommon<Side> {
358    type Target = CommonState;
359
360    fn deref(&self) -> &Self::Target {
361        &self.core.common
362    }
363}
364
365impl<Side: SideData> DerefMut for ConnectionCommon<Side> {
366    fn deref_mut(&mut self) -> &mut Self::Target {
367        &mut self.core.common
368    }
369}
370
371pub(crate) struct ConnectionCore<Side: SideData> {
372    pub(crate) state: Result<Side::State, Error>,
373    pub(crate) side: Side::Data,
374    pub(crate) common: CommonState,
375}
376
377impl<Side: SideData> ConnectionCore<Side> {
378    pub(crate) fn new(state: Side::State, side: Side::Data, common: CommonState) -> Self {
379        Self {
380            state: Ok(state),
381            side,
382            common,
383        }
384    }
385
386    pub(crate) fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
387        Ok(self
388            .dangerous_into_kernel_connection()?
389            .0)
390    }
391
392    pub(crate) fn dangerous_into_kernel_connection(
393        mut self,
394    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
395        if self.common.is_handshaking() {
396            return Err(Error::HandshakeNotComplete);
397        }
398        Self::from_parts_into_kernel_connection(
399            &mut self.common.send,
400            self.common.recv,
401            self.common.outputs,
402            self.state?,
403        )
404    }
405
406    pub(crate) fn from_parts_into_kernel_connection(
407        send: &mut SendPath,
408        recv: ReceivePath,
409        outputs: ConnectionOutputs,
410        state: Side::State,
411    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
412        if !send.sendable_tls.is_empty() {
413            return Err(ApiMisuse::SecretExtractionWithPendingSendableData.into());
414        }
415
416        let read_seq = recv.decrypt_state.read_seq();
417        let write_seq = send.encrypt_state.write_seq();
418
419        let tls13_key_schedule = send.tls13_key_schedule.take();
420
421        let (secrets, state) = state.into_external_state(&tls13_key_schedule)?;
422        let secrets = ExtractedSecrets {
423            tx: (write_seq, secrets.tx),
424            rx: (read_seq, secrets.rx),
425        };
426        let external = KernelConnection::new(state, outputs, tls13_key_schedule)?;
427
428        Ok((secrets, external))
429    }
430
431    pub(crate) fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
432        match self.common.exporter.take() {
433            Some(inner) => Ok(KeyingMaterialExporter { inner }),
434            None if self.common.is_handshaking() => Err(Error::HandshakeNotComplete),
435            None => Err(ApiMisuse::ExporterAlreadyUsed.into()),
436        }
437    }
438
439    pub(crate) fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
440        match self.common.early_exporter.take() {
441            Some(inner) => Ok(KeyingMaterialExporter { inner }),
442            None => Err(ApiMisuse::ExporterAlreadyUsed.into()),
443        }
444    }
445}
446
447impl ConnectionCore<ServerSide> {
448    pub(crate) fn accepted(
449        &mut self,
450        choose: Box<ChooseConfig>,
451        exts: ServerExtensionsInput,
452        quic: Option<&mut dyn QuicOutput>,
453        config: Arc<ServerConfig>,
454    ) -> Result<(), Error> {
455        self.common
456            .send
457            .set_max_fragment_size(config.max_fragment_size)?;
458        self.common.fips = config.fips();
459
460        let mut output = SideCommonOutput {
461            side: &mut self.side,
462            quic,
463            common: &mut self.common,
464        };
465
466        self.state = Ok(choose.use_config(config, exts, &mut output)?);
467        Ok(())
468    }
469}
470
471/// Common items for buffered, std::io-using connections.
472pub(crate) struct Buffers {
473    pub(crate) received_plaintext: ChunkVecBuffer,
474    pub(crate) sendable_plaintext: ChunkVecBuffer,
475    pub(crate) has_seen_eof: bool,
476}
477
478impl Buffers {
479    fn new() -> Self {
480        Self {
481            received_plaintext: ChunkVecBuffer::new(Some(DEFAULT_RECEIVED_PLAINTEXT_LIMIT)),
482            sendable_plaintext: ChunkVecBuffer::new(Some(DEFAULT_BUFFER_LIMIT)),
483            has_seen_eof: false,
484        }
485    }
486
487    fn is_empty(&self) -> bool {
488        self.received_plaintext.is_empty() && self.sendable_plaintext.is_empty()
489    }
490}
491
492/// A structure that implements [`std::io::Read`] for reading plaintext.
493pub struct Reader<'a> {
494    pub(super) received_plaintext: &'a mut ChunkVecBuffer,
495    pub(super) has_received_close_notify: bool,
496    pub(super) has_seen_eof: bool,
497}
498
499impl<'a> Reader<'a> {
500    /// Check the connection's state if no bytes are available for reading.
501    fn check_no_bytes_state(&self) -> io::Result<()> {
502        match (self.has_received_close_notify, self.has_seen_eof) {
503            // cleanly closed; don't care about TCP EOF: express this as Ok(0)
504            (true, _) => Ok(()),
505            // unclean closure
506            (false, true) => Err(io::Error::new(
507                io::ErrorKind::UnexpectedEof,
508                UNEXPECTED_EOF_MESSAGE,
509            )),
510            // connection still going, but needs more data: signal `WouldBlock` so that
511            // the caller knows this
512            (false, false) => Err(io::ErrorKind::WouldBlock.into()),
513        }
514    }
515
516    /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
517    ///
518    /// This method consumes `self` so that it can return a slice whose lifetime is bounded by
519    /// the [`Connection`] that created this [`Reader`].
520    pub fn into_first_chunk(self) -> io::Result<&'a [u8]> {
521        match self.received_plaintext.chunk() {
522            Some(chunk) => Ok(chunk),
523            None => {
524                self.check_no_bytes_state()?;
525                Ok(&[])
526            }
527        }
528    }
529}
530
531impl Read for Reader<'_> {
532    /// Obtain plaintext data received from the peer over this TLS connection.
533    ///
534    /// If the peer closes the TLS session cleanly, this returns `Ok(0)`  once all
535    /// the pending data has been read. No further data can be received on that
536    /// connection, so the underlying TCP connection should be half-closed too.
537    ///
538    /// If the peer closes the TLS session uncleanly (a TCP EOF without sending a
539    /// `close_notify` alert) this function returns a `std::io::Error` of type
540    /// `ErrorKind::UnexpectedEof` once any pending data has been read.
541    ///
542    /// Note that support for `close_notify` varies in peer TLS libraries: many do not
543    /// support it and uncleanly close the TCP connection (this might be
544    /// vulnerable to truncation attacks depending on the application protocol).
545    /// This means applications using rustls must both handle EOF
546    /// from this function, *and* unexpected EOF of the underlying TCP connection.
547    ///
548    /// If there are no bytes to read, this returns `Err(ErrorKind::WouldBlock.into())`.
549    ///
550    /// You may learn the number of bytes available at any time by inspecting
551    /// the return of [`Connection::process_new_packets()`].
552    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
553        let len = self.received_plaintext.read(buf)?;
554        if len > 0 || buf.is_empty() {
555            return Ok(len);
556        }
557
558        self.check_no_bytes_state()
559            .map(|()| len)
560    }
561}
562
563impl BufRead for Reader<'_> {
564    /// Obtain a chunk of plaintext data received from the peer over this TLS connection.
565    /// This reads the same data as [`Reader::read()`], but returns a reference instead of
566    /// copying the data.
567    ///
568    /// The caller should call [`Reader::consume()`] afterward to advance the buffer.
569    ///
570    /// See [`Reader::into_first_chunk()`] for a version of this function that returns a
571    /// buffer with a longer lifetime.
572    fn fill_buf(&mut self) -> io::Result<&[u8]> {
573        Reader {
574            // reborrow
575            received_plaintext: self.received_plaintext,
576            ..*self
577        }
578        .into_first_chunk()
579    }
580
581    fn consume(&mut self, amt: usize) {
582        self.received_plaintext
583            .consume_first_chunk(amt)
584    }
585}
586
587const UNEXPECTED_EOF_MESSAGE: &str = "peer closed connection without sending TLS close_notify: \
588https://docs.rs/rustls/latest/rustls/manual/_03_howto/index.html#unexpected-eof";
589
590/// A structure that implements [`std::io::Write`] for writing plaintext.
591pub struct Writer<'a> {
592    sink: &'a mut dyn PlaintextSink,
593}
594
595impl<'a> Writer<'a> {
596    /// Create a new Writer.
597    ///
598    /// This is not an external interface.  Get one of these objects
599    /// from [`Connection::writer()`].
600    pub(crate) fn new(sink: &'a mut dyn PlaintextSink) -> Self {
601        Writer { sink }
602    }
603}
604
605impl io::Write for Writer<'_> {
606    /// Send the plaintext `buf` to the peer, encrypting and authenticating it.
607    ///
608    /// Once this function succeeds you should call [`Connection::write_tls()`] which will output
609    /// the corresponding TLS records.
610    ///
611    /// This function buffers plaintext sent before the TLS handshake completes, and sends it as soon
612    /// as it can.  See [`Connection::set_buffer_limit()`] to control the size of this buffer.
613    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
614        self.sink.write(buf)
615    }
616
617    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
618        self.sink.write_vectored(bufs)
619    }
620
621    fn flush(&mut self) -> io::Result<()> {
622        self.sink.flush()
623    }
624}
625
626/// Internal trait implemented by the [`ServerConnection`]/[`ClientConnection`]
627/// allowing them to be the subject of a [`Writer`].
628///
629/// [`ServerConnection`]: crate::ServerConnection
630/// [`ClientConnection`]: crate::ClientConnection
631pub(crate) trait PlaintextSink {
632    fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
633    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>;
634    fn flush(&mut self) -> io::Result<()>;
635}
636
637impl<Side: SideData> PlaintextSink for ConnectionCommon<Side> {
638    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
639        let len = self
640            .core
641            .common
642            .send
643            .buffer_plaintext(buf.into(), &mut self.buffers.sendable_plaintext);
644        self.send.maybe_refresh_traffic_keys();
645        Ok(len)
646    }
647
648    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
649        let payload_owner: Vec<&[u8]>;
650        let payload = match bufs.len() {
651            0 => return Ok(0),
652            1 => OutboundPlain::Single(bufs[0].deref()),
653            _ => {
654                payload_owner = bufs
655                    .iter()
656                    .map(|io_slice| io_slice.deref())
657                    .collect();
658
659                OutboundPlain::new(&payload_owner)
660            }
661        };
662        let len = self
663            .core
664            .common
665            .send
666            .buffer_plaintext(payload, &mut self.buffers.sendable_plaintext);
667        self.send.maybe_refresh_traffic_keys();
668        Ok(len)
669    }
670
671    fn flush(&mut self) -> io::Result<()> {
672        Ok(())
673    }
674}
675
676/// An object of this type can export keying material.
677pub struct KeyingMaterialExporter {
678    pub(crate) inner: Box<dyn Exporter>,
679}
680
681impl KeyingMaterialExporter {
682    /// Derives key material from the agreed connection secrets.
683    ///
684    /// This function fills in `output` with `output.len()` bytes of key
685    /// material derived from a master connection secret using `label`
686    /// and `context` for diversification. Ownership of the buffer is taken
687    /// by the function and returned via the Ok result to ensure no key
688    /// material leaks if the function fails.
689    ///
690    /// See [RFC5705][] for more details on what this does and is for.  In
691    /// other libraries this is often named `SSL_export_keying_material()`
692    /// or `SslExportKeyingMaterial()`.
693    ///
694    /// This function is not meaningful if `output.len()` is zero and will
695    /// return an error in that case.
696    ///
697    /// [RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705
698    pub fn derive<T: AsMut<[u8]>>(
699        &self,
700        label: &[u8],
701        context: Option<&[u8]>,
702        mut output: T,
703    ) -> Result<T, Error> {
704        if output.as_mut().is_empty() {
705            return Err(ApiMisuse::ExporterOutputZeroLength.into());
706        }
707
708        self.inner
709            .derive(label, context, output.as_mut())
710            .map(|_| output)
711    }
712}
713
714impl Debug for KeyingMaterialExporter {
715    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
716        f.debug_struct("KeyingMaterialExporter")
717            .finish_non_exhaustive()
718    }
719}
720
721/// This trait is for any object that can export keying material.
722///
723/// The terminology comes from [RFC5705](https://datatracker.ietf.org/doc/html/rfc5705)
724/// but doesn't really involve "exporting" key material (in the usual meaning of "export"
725/// -- of moving an artifact from one domain to another) but is best thought of as key
726/// diversification using an existing secret.  That secret is implicit in this interface,
727/// so is assumed to be held by `self`. The secret should be zeroized in `drop()`.
728///
729/// There are several such internal implementations, depending on the context
730/// and protocol version.
731pub(crate) trait Exporter: Send + Sync {
732    /// Fills in `output` with derived keying material.
733    ///
734    /// This is deterministic depending on a base secret (implicit in `self`),
735    /// plus the `label` and `context` values.
736    ///
737    /// Must fill in `output` entirely, or return an error.
738    fn derive(&self, label: &[u8], context: Option<&[u8]>, output: &mut [u8]) -> Result<(), Error>;
739}
740
741#[derive(Debug)]
742pub(crate) struct ConnectionRandoms {
743    pub(crate) client: [u8; 32],
744    pub(crate) server: [u8; 32],
745}
746
747impl ConnectionRandoms {
748    pub(crate) fn new(client: Random, server: Random) -> Self {
749        Self {
750            client: client.0,
751            server: server.0,
752        }
753    }
754}
755
756/// Values of this structure are returned from [`Connection::process_new_packets()`]
757/// and tell the caller the current I/O state of the TLS connection.
758#[derive(Debug, Eq, PartialEq)]
759pub struct IoState {
760    tls_bytes_to_write: usize,
761    plaintext_bytes_to_read: usize,
762    peer_has_closed: bool,
763}
764
765impl IoState {
766    pub(crate) fn new(send: &SendPath, recv: &ReceivePath, buffers: &Buffers) -> Self {
767        Self {
768            tls_bytes_to_write: send.sendable_tls.len(),
769            plaintext_bytes_to_read: buffers.received_plaintext.len(),
770            peer_has_closed: recv.has_received_close_notify,
771        }
772    }
773
774    /// How many bytes could be written by [`Connection::write_tls()`] if called right now.
775    ///
776    /// A non-zero value implies [`CommonState::wants_write()`].
777    pub fn tls_bytes_to_write(&self) -> usize {
778        self.tls_bytes_to_write
779    }
780
781    /// How many plaintext bytes could be obtained via [`std::io::Read`] without further I/O.
782    pub fn plaintext_bytes_to_read(&self) -> usize {
783        self.plaintext_bytes_to_read
784    }
785
786    /// True if the peer has sent us a close_notify alert.
787    ///
788    /// This is the TLS mechanism to securely half-close a TLS connection, and signifies that
789    /// the peer will not send any further data on this connection.
790    ///
791    /// This is also signalled via returning `Ok(0)` from [`std::io::Read`], after all the
792    /// received bytes have been retrieved.
793    pub fn peer_has_closed(&self) -> bool {
794        self.peer_has_closed
795    }
796}
797
798pub(crate) struct SideCommonOutput<'a, 'q> {
799    pub(crate) side: &'a mut dyn SideOutput,
800    pub(crate) quic: Option<&'q mut dyn QuicOutput>,
801    pub(crate) common: &'a mut CommonState,
802}
803
804impl<'q> Output<'_> for SideCommonOutput<'_, 'q> {
805    fn emit(&mut self, ev: Event<'_>) {
806        self.side.emit(ev);
807    }
808
809    fn output(&mut self, ev: OutputEvent<'_>) {
810        if let OutputEvent::ProtocolVersion(ver) = ev {
811            self.common.recv.negotiated_version = Some(ver);
812            self.common.send.negotiated_version(ver);
813        }
814        self.common.outputs.handle(ev);
815    }
816
817    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) {
818        match self.quic() {
819            Some(quic) => quic.send_msg(m, must_encrypt),
820            None => self
821                .common
822                .send
823                .send_msg(m, must_encrypt),
824        }
825    }
826
827    fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
828        match self.quic.as_mut() {
829            Some(q) => Some(&mut **q),
830            None => None,
831        }
832    }
833
834    fn start_traffic(&mut self) {
835        self.common
836            .recv
837            .may_receive_application_data = true;
838        self.common
839            .send
840            .start_outgoing_traffic();
841    }
842
843    fn receive(&mut self) -> &mut ReceivePath {
844        &mut self.common.recv
845    }
846
847    fn send(&mut self) -> &mut dyn SendOutput {
848        &mut self.common.send
849    }
850}
851
852/// Data specific to the peer's side (client or server).
853#[expect(private_bounds)]
854pub trait SideData: private::Side {}
855
856pub(crate) mod private {
857    use super::*;
858
859    pub(crate) trait Side: Debug {
860        /// Data storage type.
861        type Data: SideOutput;
862        /// State machine type.
863        type State: StateMachine;
864    }
865
866    pub(crate) trait SideOutput {
867        fn emit(&mut self, ev: Event<'_>);
868    }
869}
870
871use private::SideOutput;
872
873pub(crate) trait StateMachine: Sized {
874    fn handle<'m>(self, input: Input<'m>, output: &mut dyn Output<'m>) -> Result<Self, Error>;
875    fn wants_input(&self) -> bool;
876    fn is_traffic(&self) -> bool;
877    fn handle_decrypt_error(&mut self);
878    fn into_external_state(
879        self,
880        send_keys: &Option<Box<KeyScheduleTrafficSend>>,
881    ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error>;
882}
883
884const DEFAULT_RECEIVED_PLAINTEXT_LIMIT: usize = 16 * 1024;