Skip to main content

rustls/conn/
mod.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt;
4use core::ops::Deref;
5
6use kernel::KernelConnection;
7use pki_types::FipsStatus;
8
9use crate::client::ClientSide;
10use crate::common_state::{
11    CommonState, ConnectionOutput, ConnectionOutputs, Event, Output, OutputEvent,
12};
13use crate::crypto::VerifiedIdentity;
14use crate::crypto::cipher::{OutboundPlain, Payload};
15use crate::error::{ApiMisuse, Error};
16use crate::kernel::KernelState;
17use crate::msgs::{Delocator, Message, Random, ServerExtensionsInput};
18use crate::quic::{self, QuicOutput};
19use crate::server::{ChooseConfig, ServerConfig, ServerSide};
20use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
21use crate::sync::Arc;
22use crate::tls13::key_schedule::KeyScheduleTrafficSend;
23
24// pub so that it can be re-exported from the crate root
25pub mod kernel;
26
27mod handshake;
28pub use handshake::{Accepted, Tcp, Transport, VerifyPeerIdentity};
29pub(crate) use handshake::{ClientNext, ServerNext, sealed};
30
31mod receive;
32pub(crate) use receive::{
33    DataKind, Input, MessageIter, MessageIterMode, ReceivePath, TrafficTemperCounters,
34};
35pub use receive::{SliceInput, TlsInputBuffer, VecInput};
36
37mod send;
38pub(crate) use send::{Encrypter, SendOutput, SendPath};
39
40pub(crate) mod split;
41use split::SplitConnection;
42
43/// A TLS connection, parametrized by the side ([`ClientSide`] or [`ServerSide`]).
44///
45/// This is one of the core abstractions of the rustls API. It represents a single connection
46/// to a peer, and holds all the state associated with that connection. Note that it does
47/// not hold any IO objects: the application is responsible for reading and writing TLS records.
48///
49/// This object is generic over the `Side` type parameter, which must be either [`ClientSide`]
50/// or [`ServerSide`]. While most of the API for a connection is shared between both types, some
51/// API is asymmetric, which is reflected by the type parameter. As such, some methods
52/// (including constructors) are specific on the `Side` type. See the implementations
53/// for [`ClientSide`](#impl-Connection<ClientSide>) and [`ServerSide`](#impl-Connection<ServerSide>) below.
54///
55/// [`ClientSide`]: crate::client::ClientSide
56/// [`ServerSide`]: crate::server::ServerSide
57pub struct Connection<Side: SideData, T: Transport> {
58    pub(crate) state: Result<Side::State, Error>,
59    pub(crate) side: Side,
60    pub(crate) common: CommonState,
61    pub(crate) transport: T,
62}
63
64impl<Side: SideData, T: Transport> Connection<Side, T> {
65    pub(crate) fn process(
66        &mut self,
67        input: &mut dyn TlsInputBuffer,
68        tls: &mut Vec<u8>,
69    ) -> Result<(), Error> {
70        let mut iter = MessageIter::new(input, tls, self, MessageIterMode::Handshake);
71        let result = loop {
72            match iter.next(false) {
73                Some(Ok(_)) => {}
74                Some(Err(e)) => break Err(e),
75                None => break Ok(()),
76            };
77        };
78
79        input.discard(self.common.recv.deframer.take_discard());
80
81        result?;
82        Ok(())
83    }
84
85    #[doc = include_str!("../doc/exporter.md")]
86    pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
87        match self.common.is_handshaking() {
88            true => Err(Error::HandshakeNotComplete),
89            false => self.common.outputs.exporter(),
90        }
91    }
92
93    /// Returns data learned during the connection.
94    pub fn side(&self) -> &Side {
95        &self.side
96    }
97
98    /// Return the FIPS validation status of the connection.
99    ///
100    /// This is different from [`CryptoProvider::fips()`][]:
101    /// it is concerned only with cryptography, whereas this _also_ covers TLS-level
102    /// configuration that NIST recommends, as well as ECH HPKE suites if applicable.
103    ///
104    /// [`CryptoProvider::fips()`]: crate::crypto::CryptoProvider::fips()
105    pub fn fips(&self) -> FipsStatus {
106        self.common.fips
107    }
108
109    /// Returns true if the connection is currently performing the TLS handshake.
110    ///
111    /// During this time, [`Self::write()`] will return an error.
112    pub fn is_handshaking(&self) -> bool {
113        self.common.is_handshaking()
114    }
115}
116
117impl<Side: SideData> Connection<Side, Tcp> {
118    /// Build a [`MessageHandler`] to process messages from the `input` buffer.
119    ///
120    /// Any data appended to `tls` should be sent to the peer.
121    pub fn read_tls<'a, 'm>(
122        &'a mut self,
123        input: &'m mut dyn TlsInputBuffer,
124        tls: &'a mut Vec<u8>,
125    ) -> MessageHandler<'a, 'm, Side> {
126        MessageHandler::new(input, tls, self)
127    }
128
129    /// Writes the application data from `plaintext` into TLS records and appends them to `tls`.
130    ///
131    /// Any data appended to `tls` should be sent to the peer.
132    ///
133    /// This will fail if either the handshake is not complete yet (because we don't yet have the
134    /// keys to encrypt application data) or if the send path has been closed by sending a
135    /// `close_notify` alert.
136    ///
137    /// For TLS 1.2, this also fails with [`Error::EncryptError`] if encrypting `plaintext` would
138    /// exceed the negotiated cipher suite's
139    /// [`confidentiality_limit`][crate::crypto::CipherSuiteCommon::confidentiality_limit]. In that
140    /// case, none of `plaintext` is sent; a `close_notify` alert is appended to `tls` instead.
141    ///
142    /// If the connection previously encountered a fatal error (for example, while processing
143    /// received data in [`Self::read_tls()`]), this returns that error, even if `plaintext`
144    /// is empty.
145    pub fn write(&mut self, plaintext: OutboundPlain<'_>, tls: &mut Vec<u8>) -> Result<(), Error> {
146        if let Err(err) = &self.state {
147            return Err(err.clone());
148        } else if plaintext.is_empty() {
149            return Ok(());
150        }
151
152        self.common
153            .send
154            .send_appdata_encrypt(DataKind::Traffic(plaintext), tls)?;
155
156        Ok(())
157    }
158
159    /// Sends a TLS1.3 `key_update` message into `tls` to refresh a connection's keys.
160    ///
161    /// The main reason to call this manually is to roll keys when it is known
162    /// a connection will be idle for a long period.
163    ///
164    /// rustls implicitly and automatically refreshes traffic keys when needed
165    /// according to the selected cipher suite's cryptographic constraints.  There
166    /// is therefore no need to call this manually to avoid cryptographic keys
167    /// "wearing out".
168    ///
169    /// This call refreshes our encryption keys. Once the peer receives the message,
170    /// it refreshes _its_ encryption and decryption keys and sends a response.
171    /// Once we receive that response, we refresh our decryption keys to match.
172    /// At the end of this process, keys in both directions have been refreshed.
173    ///
174    /// This fails with [`Error::HandshakeNotComplete`] if called before the initial
175    /// handshake is complete, or if a version prior to TLS1.3 is negotiated.
176    ///
177    /// # Usage advice
178    /// Note that other implementations (including rustls) may enforce limits on
179    /// the number of `key_update` messages allowed on a given connection to prevent
180    /// denial of service.  Therefore, this should be called sparingly.
181    ///
182    /// rustls only allows one outstanding request at a time; this function succeeds
183    /// but sends nothing if a request is already in-flight.
184    pub fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
185        self.common
186            .send
187            .refresh_traffic_keys(tls)
188    }
189
190    /// Split a post-handshake connection into a [`SplitConnection`].
191    ///
192    /// This allows the two directions (transmit and receive) of the connection to be progressed
193    /// separately (including by different threads, which would allow dedicating a CPU core for each
194    /// direction rather than one per connection; this can dramatically improve performance for
195    /// full-duplex protocols).
196    ///
197    /// It also separates out the [`ConnectionOutputs`] which gives the application direct control
198    /// of how long this is kept.
199    ///
200    /// This fails if:
201    ///
202    /// - the handshake is not complete. Check with [`Connection::is_handshaking()`].
203    /// - there is any buffered TLS data to send.  Obtain it first with [`Connection::write()`].
204    pub fn split(self) -> Result<SplitConnection<Side>, Error> {
205        SplitConnection::try_from(self)
206    }
207
208    #[doc = include_str!("../doc/early_exporter.md")]
209    pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
210        self.common.early_exporter()
211    }
212
213    /// Extract secrets, so they can be used when configuring kTLS, for example.
214    ///
215    /// Should be used with care as it exposes secret key material.
216    ///
217    /// All TLS data previously written into caller-provided buffers must be sent to the peer before
218    /// calling this function.
219    ///
220    /// This fails with [`ApiMisuse::KernelConnectionWithPendingSendData`] if the
221    /// connection has pending data to send, which would otherwise be lost.
222    /// Write out that pending data before calling this function.
223    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
224        Ok(self
225            .dangerous_into_kernel_connection()?
226            .0)
227    }
228
229    pub(crate) fn dangerous_into_kernel_connection(
230        self,
231    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
232        if self.common.is_handshaking() {
233            return Err(Error::HandshakeNotComplete);
234        }
235        Self::from_parts_into_kernel_connection(
236            self.common.send,
237            self.common.recv,
238            self.common.outputs,
239            self.state?,
240        )
241    }
242
243    pub(crate) fn from_parts_into_kernel_connection(
244        send: SendPath,
245        recv: ReceivePath,
246        outputs: ConnectionOutputs,
247        state: Side::State,
248    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
249        // a queued key_update response has consumed a send sequence number so
250        // discarding it would leave the extracted secrets ahead of what the
251        // peer receives.
252        if send.has_queued_key_update() {
253            return Err(ApiMisuse::KernelConnectionWithPendingSendData.into());
254        }
255
256        let read_seq = recv.decrypt_state.read_seq();
257        let (write_seq, tls13_key_schedule) = send.export()?;
258
259        let (secrets, state) = state.into_external_state(&tls13_key_schedule)?;
260        let secrets = ExtractedSecrets {
261            tx: (write_seq, secrets.tx),
262            rx: (read_seq, secrets.rx),
263        };
264        let external = KernelConnection::new(state, outputs, tls13_key_schedule)?;
265
266        Ok((secrets, external))
267    }
268
269    /// Writes a `close_notify` warning alert into `tls`.
270    ///
271    /// This informs the peer that the connection is being closed.
272    ///
273    /// Does nothing if any `close_notify` or fatal alert was already sent.
274    pub fn send_close_notify(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
275        self.common.send_close_notify(tls)
276    }
277}
278
279impl<T: Transport> Connection<ClientSide, T> {
280    /// Returns the number of TLS1.3 tickets that have been received.
281    pub fn tls13_tickets_received(&self) -> u32 {
282        self.common.recv.tls13_tickets_received
283    }
284}
285
286impl<T: Transport> Connection<ServerSide, T> {
287    pub(crate) fn accepted(
288        &mut self,
289        choose: Box<ChooseConfig>,
290        exts: ServerExtensionsInput,
291        config: Arc<ServerConfig>,
292        tls: &mut Vec<u8>,
293    ) -> Result<(), Error> {
294        self.common
295            .send
296            .set_max_fragment_size(config.max_fragment_size)?;
297        self.common.fips = config.fips();
298
299        let mut output = SideCommonOutput {
300            side: &mut self.side,
301            quic: self.transport.quic(),
302            common: &mut self.common,
303            tls,
304        };
305
306        self.state = Ok(choose.use_config(config, exts, &mut output)?);
307        Ok(())
308    }
309
310    /// Set the resumption data to embed in future resumption tickets supplied to the client.
311    ///
312    /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
313    /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
314    /// resumption tickets are affected.
315    ///
316    /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
317    /// from the client is desired, encrypt the data separately.
318    pub fn set_resumption_data(&mut self, data: &[u8]) -> Result<(), Error> {
319        assert!(data.len() < 2usize.pow(15));
320        match &mut self.state {
321            Ok(st) => st.set_resumption_data(data),
322            Err(e) => Err(e.clone()),
323        }
324    }
325}
326
327impl<Side: SideData> Connection<Side, Tcp> {
328    fn into_handshake(self) -> Result<Side::Handshake, Error> {
329        Side::Handshake::try_from(self)
330    }
331}
332
333impl<S: SideData, T: Transport> fmt::Debug for Connection<S, T> {
334    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
335        let Self {
336            state: _,
337            side,
338            common,
339            transport: _,
340        } = self;
341
342        f.debug_struct("Connection")
343            .field("side", side)
344            .field("common", common)
345            .finish_non_exhaustive()
346    }
347}
348
349impl<Side: SideData, T: Transport> Deref for Connection<Side, T> {
350    type Target = CommonState;
351
352    fn deref(&self) -> &Self::Target {
353        &self.common
354    }
355}
356
357/// Driver for handling messages from the [`TlsInputBuffer`].
358///
359/// Must be driven to completion to make progress, by calling either [`Self::handle_all()`] or
360/// repeatedly calling [`Self::next_payload()`] until it returns `None`.
361///
362/// Backpressure is provided by the [`TlsInputBuffer`] implementation. When using a [`VecInput`]
363/// buffer, [`VecInput::read()`] will not ingest more data once the internal buffer is full.
364#[must_use]
365pub struct MessageHandler<'a, 'm, Side: SideData> {
366    iter: MessageIter<'a, 'm, Side, SendPath>,
367    done: bool,
368}
369
370impl<'a, 'm, Side: SideData> MessageHandler<'a, 'm, Side> {
371    pub(crate) fn new(
372        input: &'m mut dyn TlsInputBuffer,
373        tls: &'a mut Vec<u8>,
374        conn: &'a mut Connection<Side, impl Transport>,
375    ) -> Self {
376        Self {
377            iter: MessageIter::new(input, tls, conn, MessageIterMode::All),
378            done: false,
379        }
380    }
381}
382
383impl<'a, 'm, Side: SideData> MessageHandler<'a, 'm, Side> {
384    /// Handles all complete messages from the input buffer.
385    ///
386    /// Writes any plaintext application data from the input into `buf`, and returns the I/O
387    /// state of the connection after processing the last message. If an error is returned,
388    /// the connection is in a fatal error state and no further progress can be made. After
389    /// an error is received from this function, you should not continue to fill up the buffer.
390    ///
391    /// However, you may call the other methods on the connection, including
392    /// [`Connection::send_close_notify()`]. Any alert produced by the error will have
393    /// been appended to the `tls` buffer; most likely you will want to send that data
394    /// to the peer and then close the underlying connection.
395    pub fn handle_all(mut self, buf: &mut Vec<u8>) -> Result<IoState, Error> {
396        while let Some(result) = self.next_payload() {
397            buf.extend_from_slice(result?.bytes());
398        }
399
400        Ok(self.state())
401    }
402
403    /// Yields the first payload of plaintext application data from the input buffer.
404    ///
405    /// Should be called repeatedly until it returns `None`, at which point the input buffer no
406    /// longer contains any complete messages and should be refilled by the application.
407    ///
408    /// Early ("0-RTT") data received by a server while the handshake is still in progress
409    /// is not yielded here; it is only available from
410    /// [`next_early_data()`][MessageHandler::next_early_data] and is dropped if
411    /// encountered by this method.
412    pub fn next_payload(&mut self) -> Option<Result<Payload<'_>, Error>> {
413        if self.done {
414            return None;
415        }
416
417        let Some(result) = self.iter.next(false) else {
418            self.done = true;
419            return None;
420        };
421
422        let payload = match result {
423            Ok(payload) => payload,
424            Err(err) => {
425                self.done = true;
426                return Some(Err(err));
427            }
428        };
429
430        Some(Ok(
431            payload.reborrow(&Delocator::new(self.iter.input.slice_mut()))
432        ))
433    }
434
435    /// The I/O state of the connection after processing the last message.
436    pub fn state(self) -> IoState {
437        IoState::new(self.iter.recv)
438    }
439}
440
441impl<'a, 'm> MessageHandler<'a, 'm, ServerSide> {
442    /// Yields the next payload application data received from the client.
443    ///
444    /// Early data is only received during the handshake, from clients resuming an earlier
445    /// session, and only if the connection was configured with a non-zero
446    /// [`ServerConfig::max_early_data_size`][crate::ServerConfig::max_early_data_size].
447    ///
448    /// **Beware** that early data is subject to replay by an attacker; see [RFC 8446
449    /// appendix E.5][] for more detail.
450    ///
451    /// Call this until it returns `None` before processing regular application data with
452    /// [`next_payload()`][MessageHandler::next_payload] or
453    /// [`handle_all()`][MessageHandler::handle_all]: early data encountered by those
454    /// methods is dropped.
455    ///
456    /// `None` means no early data is currently available: the early data phase may have
457    /// ended, or processing may require further input.
458    ///
459    /// If this yields an error, stop calling it: the same error will also be reported by
460    /// [`next_payload()`][MessageHandler::next_payload] and
461    /// [`handle_all()`][MessageHandler::handle_all], so it can be ignored here.
462    ///
463    /// [RFC 8446 appendix E.5]: https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.5
464    pub fn next_early_data(&mut self) -> Option<Result<Payload<'_>, Error>> {
465        if self.done {
466            return None;
467        }
468
469        if let Ok(state) = &self.iter.state {
470            if state.is_traffic() {
471                return None; // early data phase has ended
472            }
473        }
474
475        // Not marking the handler as done: traffic data may still follow in the input buffer.
476        let result = self.iter.next(true)?;
477        let payload = match result {
478            Ok(payload) => payload,
479            Err(err) => return Some(Err(err)),
480        };
481
482        Some(Ok(
483            payload.reborrow(&Delocator::new(self.iter.input.slice_mut()))
484        ))
485    }
486}
487
488impl<'a, 'm, Side: SideData + private::Side> Drop for MessageHandler<'a, 'm, Side> {
489    fn drop(&mut self) {
490        let MessageIter { input, recv, .. } = &mut self.iter;
491        input.discard(recv.deframer.take_discard());
492    }
493}
494
495impl<S: SideData> fmt::Debug for MessageHandler<'_, '_, S> {
496    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
497        f.debug_struct("MessageHandler")
498            .field("done", &self.done)
499            .finish_non_exhaustive()
500    }
501}
502
503/// More data needs to be supplied to make progress.
504///
505/// Provide the data to [`Self::process()`].
506pub struct NeedsInput<Side: SideData>(pub(crate) Connection<Side, Tcp>);
507
508impl<Side: SideData> NeedsInput<Side> {
509    pub(crate) fn new(inner: Connection<Side, Tcp>) -> Self {
510        Self(inner)
511    }
512
513    /// Progress the handshake by receiving further data.
514    ///
515    /// The data is obtained via `input`.  Any output produced is appended to `tls` and
516    /// should be sent to the peer (including if this function returns an error, because
517    /// `tls` may contain an alert.)
518    ///
519    /// An error from this function is otherwise fatal to the connection, as it consumes
520    /// the [`NeedsInput`] object.
521    ///
522    /// On success, this returns a handshake object specifying what to do to progress
523    /// the connection.  If this contains another [`NeedsInput`] object then obtaining more
524    /// input (eg, from a socket or other source) is certainly necessary.
525    pub fn process(
526        mut self,
527        input: &mut dyn TlsInputBuffer,
528        tls: &mut Vec<u8>,
529    ) -> Result<Side::Handshake, Error> {
530        self.0.process(input, tls)?;
531        self.0.into_handshake()
532    }
533
534    #[doc = include_str!("../doc/early_exporter.md")]
535    pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
536        self.0.common.early_exporter()
537    }
538}
539
540impl<S: SideData> fmt::Debug for NeedsInput<S> {
541    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542        f.debug_struct("NeedsInput")
543            .finish_non_exhaustive()
544    }
545}
546
547/// Dynamically-dispatched state machine, to maintain static unreachability of
548/// per-protocol-version code.
549pub(crate) trait State<Side: SideData>: Send + Sync {
550    /// Advance the state machine using `input` and emitting data to `output`.
551    fn handle<'m>(
552        self: Box<Self>,
553        input: Input<'m>,
554        output: &mut dyn Output<'m>,
555    ) -> Result<Side::State, Error>;
556
557    fn is_traffic(&self) -> bool {
558        false
559    }
560
561    fn handle_decrypt_error(&mut self) {}
562
563    fn into_external_state(
564        self: Box<Self>,
565        _send_keys: &Option<Box<KeyScheduleTrafficSend>>,
566    ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error> {
567        Err(Error::HandshakeNotComplete)
568    }
569}
570
571/// Trait to maintain static unreachablity of per-protocol-version code.
572pub(crate) trait VerifySidePeerIdentity<Side: SideData>: Send + Sync {
573    fn presented_identity(&self) -> Result<Side::PeerIdentity<'_>, Error>;
574    fn verify_with_config(&self) -> Result<VerifiedIdentity<'static>, Error>;
575    fn continue_with(
576        self: Box<Self>,
577        verified: VerifiedIdentity<'static>,
578        output: &mut dyn Output<'_>,
579    ) -> Result<Side::State, Error>;
580}
581
582/// An object of this type can export keying material.
583pub struct KeyingMaterialExporter {
584    pub(crate) inner: Box<dyn Exporter>,
585}
586
587impl KeyingMaterialExporter {
588    /// Derives key material from the agreed connection secrets.
589    ///
590    /// This function fills in `output` with `output.len()` bytes of key
591    /// material derived from a master connection secret using `label`
592    /// and `context` for diversification. Ownership of the buffer is taken
593    /// by the function and returned via the Ok result to ensure no key
594    /// material leaks if the function fails.
595    ///
596    /// See [RFC 5705][] for more details on what this does and is for.  In
597    /// other libraries this is often named `SSL_export_keying_material()`
598    /// or `SslExportKeyingMaterial()`.
599    ///
600    /// This function is not meaningful if `output.len()` is zero and will
601    /// return an error in that case.
602    ///
603    /// [RFC 5705]: https://datatracker.ietf.org/doc/html/rfc5705
604    pub fn derive<T: AsMut<[u8]>>(
605        &self,
606        label: &[u8],
607        context: Option<&[u8]>,
608        mut output: T,
609    ) -> Result<T, Error> {
610        if output.as_mut().is_empty() {
611            return Err(ApiMisuse::ExporterOutputZeroLength.into());
612        }
613
614        self.inner
615            .derive(label, context, output.as_mut())
616            .map(|_| output)
617    }
618}
619
620impl fmt::Debug for KeyingMaterialExporter {
621    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622        f.debug_struct("KeyingMaterialExporter")
623            .finish_non_exhaustive()
624    }
625}
626
627/// This trait is for any object that can export keying material.
628///
629/// The terminology comes from [RFC 5705](https://datatracker.ietf.org/doc/html/rfc5705)
630/// but doesn't really involve "exporting" key material (in the usual meaning of "export"
631/// -- of moving an artifact from one domain to another) but is best thought of as key
632/// diversification using an existing secret.  That secret is implicit in this interface,
633/// so is assumed to be held by `self`. The secret should be zeroized in `drop()`.
634///
635/// There are several such internal implementations, depending on the context
636/// and protocol version.
637pub(crate) trait Exporter: Send + Sync {
638    /// Fills in `output` with derived keying material.
639    ///
640    /// This is deterministic depending on a base secret (implicit in `self`),
641    /// plus the `label` and `context` values.
642    ///
643    /// Must fill in `output` entirely, or return an error.
644    fn derive(&self, label: &[u8], context: Option<&[u8]>, output: &mut [u8]) -> Result<(), Error>;
645}
646
647#[derive(Debug)]
648pub(crate) struct ConnectionRandoms {
649    pub(crate) client: [u8; 32],
650    pub(crate) server: [u8; 32],
651}
652
653impl ConnectionRandoms {
654    pub(crate) fn new(client: Random, server: Random) -> Self {
655        Self {
656            client: client.0,
657            server: server.0,
658        }
659    }
660}
661
662/// Describes the current I/O state of a TLS connection.
663///
664/// Values of this structure are returned from operations on [`MessageHandler`]s.
665#[derive(Debug, Eq, PartialEq)]
666pub struct IoState {
667    peer_has_closed: bool,
668}
669
670impl IoState {
671    pub(crate) fn new(recv: &ReceivePath) -> Self {
672        Self {
673            peer_has_closed: recv.has_received_close_notify,
674        }
675    }
676
677    /// True if the peer has sent us a close_notify alert.
678    ///
679    /// This is the TLS mechanism to securely half-close a TLS connection, and signifies that
680    /// the peer will not send any further data on this connection.
681    pub fn peer_has_closed(&self) -> bool {
682        self.peer_has_closed
683    }
684}
685
686pub(crate) struct SideCommonOutput<'a, 'q> {
687    pub(crate) side: &'a mut dyn SideOutput,
688    pub(crate) quic: Option<&'q mut dyn QuicOutput>,
689    pub(crate) common: &'a mut CommonState,
690    pub(crate) tls: &'a mut Vec<u8>,
691}
692
693impl<'q> Output<'_> for SideCommonOutput<'_, 'q> {
694    fn emit(&mut self, ev: Event) {
695        self.side.emit(ev);
696    }
697
698    fn output(&mut self, ev: OutputEvent<'_>) {
699        if let OutputEvent::ProtocolVersion(ver) = ev {
700            self.common.recv.negotiated_version = Some(ver);
701            self.common.send.negotiated_version(ver);
702        }
703        self.common.outputs.handle(ev);
704    }
705
706    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) -> Result<(), Error> {
707        match self.quic() {
708            Some(quic) => {
709                quic.send_msg(m, must_encrypt);
710                Ok(())
711            }
712            None => self
713                .common
714                .send
715                .send_msg(m, must_encrypt, self.tls),
716        }
717    }
718
719    fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
720        match self.quic.as_mut() {
721            Some(q) => Some(&mut **q),
722            None => None,
723        }
724    }
725
726    fn start_traffic(&mut self) {
727        self.common
728            .recv
729            .may_receive_application_data = true;
730        self.common
731            .send
732            .start_outgoing_traffic();
733    }
734
735    fn receive(&mut self) -> &mut ReceivePath {
736        &mut self.common.recv
737    }
738
739    fn send(&mut self) -> &mut dyn SendOutput {
740        &mut self.common.send
741    }
742}
743
744/// Data specific to the peer's side (client or server).
745#[expect(private_bounds)]
746pub trait SideData: SideOutput + fmt::Debug + private::Side + Sized + 'static {
747    /// Type representing an in-progress TCP handshake.
748    type Handshake: TryFrom<Connection<Self, Tcp>, Error = Error>;
749    /// Type representing an in-progress QUIC handshake.
750    type QuicHandshake: quic::FromConn<Self>;
751
752    /// Type representing the peer's identity.
753    type PeerIdentity<'a>;
754}
755
756pub(crate) mod private {
757    use super::*;
758
759    pub(crate) trait Side: fmt::Debug {
760        /// State machine type.
761        type State: StateMachine;
762    }
763
764    pub(crate) trait SideOutput {
765        fn emit(&mut self, ev: Event);
766    }
767}
768
769use private::SideOutput;
770
771pub(crate) trait StateMachine: Sized {
772    /// Advance the state machine using `input` and emitting data to `output`.
773    fn handle<'m>(self, input: Input<'m>, output: &mut dyn Output<'m>) -> Result<Self, Error>;
774
775    /// Return true if the current state requires input to be provided via `handle()`.
776    fn wants_input(&self) -> bool;
777
778    /// Advance the state machine using no input, emitting data to `output`.
779    ///
780    /// This should return `Ok(self)` if the current state requires input.
781    fn handle_without_input(self, output: &mut dyn Output<'_>) -> Result<Self, Error>;
782
783    fn is_traffic(&self) -> bool;
784    fn handle_decrypt_error(&mut self);
785    fn into_external_state(
786        self,
787        send_keys: &Option<Box<KeyScheduleTrafficSend>>,
788    ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error>;
789}
790
791/// When to take action to avoid sequence space exhaustion.
792///
793/// This gives a margin in which any action can have an effect, prior to `SEQ_HARD_LIMIT`
794/// being reached.
795const SEQ_SOFT_LIMIT: u64 = u64::MAX - 0xffff;
796
797/// When to refuse further encryptions.
798const SEQ_HARD_LIMIT: u64 = u64::MAX - 1;