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;
7
8use crate::client::ClientSide;
9use crate::common_state::{
10    CommonState, ConnectionOutput, ConnectionOutputs, Event, Output, OutputEvent, UnborrowedPayload,
11};
12use crate::crypto::VerifiedIdentity;
13use crate::crypto::cipher::{OutboundPlain, Payload};
14use crate::error::{ApiMisuse, Error};
15use crate::kernel::KernelState;
16use crate::msgs::{Delocator, Message, Random, ServerExtensionsInput};
17use crate::quic::{self, QuicOutput};
18use crate::server::{ChooseConfig, ServerConfig, ServerSide};
19use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
20use crate::sync::Arc;
21use crate::tls13::key_schedule::KeyScheduleTrafficSend;
22
23// pub so that it can be re-exported from the crate root
24pub mod kernel;
25
26mod handshake;
27pub use handshake::{Accepted, Tcp, Transport, VerifyPeerIdentity};
28pub(crate) use handshake::{ClientNext, Processed, ServerNext, sealed};
29
30mod receive;
31pub(crate) use receive::{
32    DataKind, Input, MessageIter, MessageIterMode, ReceivePath, TrafficTemperCounters,
33};
34pub use receive::{SliceInput, TlsInputBuffer, VecInput};
35
36mod send;
37pub(crate) use send::{Encrypter, SendOutput, SendPath};
38
39#[cfg(feature = "std")]
40pub(crate) mod split;
41#[cfg(feature = "std")]
42use split::SplitConnection;
43
44/// A TLS connection, parametrized by the side ([`ClientSide`] or [`ServerSide`]).
45///
46/// This is one of the core abstractions of the rustls API. It represents a single connection
47/// to a peer, and holds all the state associated with that connection. Note that it does
48/// not hold any IO objects: the application is responsible for reading and writing TLS records.
49///
50/// This object is generic over the `Side` type parameter, which must be either [`ClientSide`]
51/// or [`ServerSide`]. While most of the API for a connection is shared between both types, some
52/// API is asymmetric, which is reflected by the type parameter. As such, some methods
53/// (including constructors) are specific on the `Side` type. See the implementations
54/// for [`ClientSide`](#impl-Connection<ClientSide>) and [`ServerSide`](#impl-Connection<ServerSide>) below.
55///
56/// [`ClientSide`]: crate::client::ClientSide
57/// [`ServerSide`]: crate::server::ServerSide
58pub struct Connection<Side: SideData, T: Transport> {
59    pub(crate) state: Result<Side::State, Error>,
60    pub(crate) side: Side,
61    pub(crate) common: CommonState,
62    pub(crate) transport: T,
63}
64
65impl<Side: SideData, T: Transport> Connection<Side, T> {
66    pub(crate) fn process(
67        mut self,
68        input: &mut dyn TlsInputBuffer,
69        tls: &mut Vec<u8>,
70    ) -> Result<Processed<Side, T>, Error> {
71        let mut iter = MessageIter::new(input, tls, &mut self, MessageIterMode::Handshake);
72        let early_data = match iter.next(true) {
73            Some(Ok(UnborrowedPayload::Unborrowed(range))) => Ok(Some(
74                Delocator::new(input.slice_mut())
75                    .slice_from_range(&range)
76                    .to_vec(),
77            )),
78            Some(Ok(UnborrowedPayload::Owned(_))) => Err(Error::Unreachable(
79                "decrypted early data should be borrowed",
80            )),
81            Some(Err(e)) => Err(e),
82            None => Ok(None),
83        };
84
85        input.discard(self.common.recv.deframer.take_discard());
86
87        Ok(match early_data? {
88            Some(data) => Processed::EarlyData { conn: self, data },
89            None => Processed::Progress(self),
90        })
91    }
92
93    #[doc = include_str!("../doc/exporter.md")]
94    pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
95        match self.common.is_handshaking() {
96            true => Err(Error::HandshakeNotComplete),
97            false => self.common.outputs.exporter(),
98        }
99    }
100
101    /// Returns data learned during the connection.
102    pub fn side(&self) -> &Side {
103        &self.side
104    }
105
106    /// Returns true if the connection is currently performing the TLS handshake.
107    ///
108    /// During this time, [`Self::write()`] will return an error.
109    pub fn is_handshaking(&self) -> bool {
110        self.common.is_handshaking()
111    }
112}
113
114impl<Side: SideData> Connection<Side, Tcp> {
115    /// Build a [`MessageHandler`] to process messages from the `input` buffer.
116    ///
117    /// Any data appended to `tls` should be sent to the peer.
118    pub fn read_tls<'a, 'm>(
119        &'a mut self,
120        input: &'m mut dyn TlsInputBuffer,
121        tls: &'a mut Vec<u8>,
122    ) -> MessageHandler<'a, 'm, Side> {
123        MessageHandler::new(input, tls, self)
124    }
125
126    /// Writes the application data from `plaintext` into TLS records and appends them to `tls`.
127    ///
128    /// Any data appended to `tls` should be sent to the peer.
129    ///
130    /// This will fail if either the handshake is not complete yet (because we don't yet have the
131    /// keys to encrypt application data) or if the send path has been closed by sending a
132    /// `close_notify` alert.
133    ///
134    /// For TLS 1.2, this also fails with [`Error::EncryptError`] if encrypting `plaintext` would
135    /// exceed the negotiated cipher suite's
136    /// [`confidentiality_limit`][crate::crypto::CipherSuiteCommon::confidentiality_limit]. In that
137    /// case, none of `plaintext` is sent; a `close_notify` alert is appended to `tls` instead.
138    ///
139    /// If the connection previously encountered a fatal error (for example, while processing
140    /// received data in [`Self::read_tls()`]), this returns that error, even if `plaintext`
141    /// is empty.
142    pub fn write(&mut self, plaintext: OutboundPlain<'_>, tls: &mut Vec<u8>) -> Result<(), Error> {
143        if let Err(err) = &self.state {
144            return Err(err.clone());
145        } else if plaintext.is_empty() {
146            return Ok(());
147        }
148
149        self.common
150            .send
151            .send_appdata_encrypt(DataKind::Traffic(plaintext), tls)?;
152
153        Ok(())
154    }
155
156    /// Sends a TLS1.3 `key_update` message into `tls` to refresh a connection's keys.
157    ///
158    /// The main reason to call this manually is to roll keys when it is known
159    /// a connection will be idle for a long period.
160    ///
161    /// rustls implicitly and automatically refreshes traffic keys when needed
162    /// according to the selected cipher suite's cryptographic constraints.  There
163    /// is therefore no need to call this manually to avoid cryptographic keys
164    /// "wearing out".
165    ///
166    /// This call refreshes our encryption keys. Once the peer receives the message,
167    /// it refreshes _its_ encryption and decryption keys and sends a response.
168    /// Once we receive that response, we refresh our decryption keys to match.
169    /// At the end of this process, keys in both directions have been refreshed.
170    ///
171    /// This fails with [`Error::HandshakeNotComplete`] if called before the initial
172    /// handshake is complete, or if a version prior to TLS1.3 is negotiated.
173    ///
174    /// # Usage advice
175    /// Note that other implementations (including rustls) may enforce limits on
176    /// the number of `key_update` messages allowed on a given connection to prevent
177    /// denial of service.  Therefore, this should be called sparingly.
178    ///
179    /// rustls only allows one outstanding request at a time; this function succeeds
180    /// but sends nothing if a request is already in-flight.
181    pub fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
182        self.common
183            .send
184            .refresh_traffic_keys(tls)
185    }
186
187    /// Split a post-handshake connection into a [`SplitConnection`].
188    ///
189    /// This allows the two directions (transmit and receive) of the connection to be progressed
190    /// separately (including by different threads, which would allow dedicating a CPU core for each
191    /// direction rather than one per connection; this can dramatically improve performance for
192    /// full-duplex protocols).
193    ///
194    /// It also separates out the [`ConnectionOutputs`] which gives the application direct control
195    /// of how long this is kept.
196    ///
197    /// This fails if:
198    ///
199    /// - the handshake is not complete. Check with [`Connection::is_handshaking()`].
200    /// - there is any buffered TLS data to send.  Obtain it first with [`Connection::write()`].
201    #[cfg(feature = "std")]
202    pub fn split(self) -> Result<SplitConnection<Side>, Error> {
203        SplitConnection::try_from(self)
204    }
205
206    #[doc = include_str!("../doc/early_exporter.md")]
207    pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
208        self.common.early_exporter()
209    }
210
211    /// Extract secrets, so they can be used when configuring kTLS, for example.
212    ///
213    /// Should be used with care as it exposes secret key material.
214    ///
215    /// All TLS data previously written into caller-provided buffers must be sent to the peer before
216    /// calling this function.
217    ///
218    /// This fails with [`ApiMisuse::KernelConnectionWithPendingSendData`] if the
219    /// connection has pending data to send, which would otherwise be lost.
220    /// Write out that pending data before calling this function.
221    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
222        Ok(self
223            .dangerous_into_kernel_connection()?
224            .0)
225    }
226
227    pub(crate) fn dangerous_into_kernel_connection(
228        self,
229    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
230        if self.common.is_handshaking() {
231            return Err(Error::HandshakeNotComplete);
232        }
233        Self::from_parts_into_kernel_connection(
234            self.common.send,
235            self.common.recv,
236            self.common.outputs,
237            self.state?,
238        )
239    }
240
241    pub(crate) fn from_parts_into_kernel_connection(
242        send: SendPath,
243        recv: ReceivePath,
244        outputs: ConnectionOutputs,
245        state: Side::State,
246    ) -> Result<(ExtractedSecrets, KernelConnection<Side>), Error> {
247        // a queued key_update response has consumed a send sequence number so
248        // discarding it would leave the extracted secrets ahead of what the
249        // peer receives.
250        if send.has_queued_key_update() {
251            return Err(ApiMisuse::KernelConnectionWithPendingSendData.into());
252        }
253
254        let read_seq = recv.decrypt_state.read_seq();
255        let (write_seq, tls13_key_schedule) = send.export()?;
256
257        let (secrets, state) = state.into_external_state(&tls13_key_schedule)?;
258        let secrets = ExtractedSecrets {
259            tx: (write_seq, secrets.tx),
260            rx: (read_seq, secrets.rx),
261        };
262        let external = KernelConnection::new(state, outputs, tls13_key_schedule)?;
263
264        Ok((secrets, external))
265    }
266
267    /// Writes a `close_notify` warning alert into `tls`.
268    ///
269    /// This informs the peer that the connection is being closed.
270    ///
271    /// Does nothing if any `close_notify` or fatal alert was already sent.
272    pub fn send_close_notify(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
273        self.common.send_close_notify(tls)
274    }
275}
276
277impl<T: Transport> Connection<ClientSide, T> {
278    /// Returns the number of TLS1.3 tickets that have been received.
279    pub fn tls13_tickets_received(&self) -> u32 {
280        self.common.recv.tls13_tickets_received
281    }
282}
283
284impl<T: Transport> Connection<ServerSide, T> {
285    pub(crate) fn accepted(
286        &mut self,
287        choose: Box<ChooseConfig>,
288        exts: ServerExtensionsInput,
289        config: Arc<ServerConfig>,
290        tls: &mut Vec<u8>,
291    ) -> Result<(), Error> {
292        self.common
293            .send
294            .set_max_fragment_size(config.max_fragment_size)?;
295        self.common.outputs.fips = config.fips();
296
297        let mut output = SideCommonOutput {
298            side: &mut self.side,
299            quic: self.transport.quic(),
300            common: &mut self.common,
301            tls,
302        };
303
304        self.state = Ok(choose.use_config(config, exts, &mut output)?);
305        Ok(())
306    }
307
308    /// Set the resumption data to embed in future resumption tickets supplied to the client.
309    ///
310    /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
311    /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
312    /// resumption tickets are affected.
313    ///
314    /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
315    /// from the client is desired, encrypt the data separately.
316    pub fn set_resumption_data(&mut self, data: &[u8]) -> Result<(), Error> {
317        if data.len() >= (1 << 15) {
318            return Err(ApiMisuse::ResumptionDataTooLarge.into());
319        }
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(Processed::Progress(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        self,
527        input: &mut dyn TlsInputBuffer,
528        tls: &mut Vec<u8>,
529    ) -> Result<Side::Handshake, Error> {
530        Side::Handshake::try_from(self.0.process(input, tls)?)
531    }
532
533    #[doc = include_str!("../doc/early_exporter.md")]
534    pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
535        self.0.common.early_exporter()
536    }
537}
538
539impl<S: SideData> fmt::Debug for NeedsInput<S> {
540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
541        f.debug_struct("NeedsInput")
542            .finish_non_exhaustive()
543    }
544}
545
546/// Dynamically-dispatched state machine, to maintain static unreachability of
547/// per-protocol-version code.
548pub(crate) trait State<Side: SideData>: Send + Sync {
549    /// Advance the state machine using `input` and emitting data to `output`.
550    fn handle<'m>(
551        self: Box<Self>,
552        input: Input<'m>,
553        output: &mut dyn Output<'m>,
554    ) -> Result<Side::State, Error>;
555
556    fn is_traffic(&self) -> bool {
557        false
558    }
559
560    fn handle_decrypt_error(&mut self) {}
561
562    fn into_external_state(
563        self: Box<Self>,
564        _send_keys: &Option<Box<KeyScheduleTrafficSend>>,
565    ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error> {
566        Err(Error::HandshakeNotComplete)
567    }
568}
569
570/// Trait to maintain static unreachablity of per-protocol-version code.
571pub(crate) trait VerifySidePeerIdentity<Side: SideData>: Send + Sync {
572    fn presented_identity(&self) -> Result<Side::PeerIdentity<'_>, Error>;
573    fn verify_with_config(&self) -> Result<VerifiedIdentity<'static>, Error>;
574    fn continue_with(
575        self: Box<Self>,
576        verified: VerifiedIdentity<'static>,
577        output: &mut dyn Output<'_>,
578    ) -> Result<Side::State, Error>;
579}
580
581/// An object of this type can export keying material.
582pub struct KeyingMaterialExporter {
583    pub(crate) inner: Box<dyn Exporter>,
584}
585
586impl KeyingMaterialExporter {
587    /// Derives key material from the agreed connection secrets.
588    ///
589    /// This function fills in `output` with `output.len()` bytes of key
590    /// material derived from a master connection secret using `label`
591    /// and `context` for diversification. Ownership of the buffer is taken
592    /// by the function and returned via the Ok result to ensure no key
593    /// material leaks if the function fails.
594    ///
595    /// See [RFC 5705][] for more details on what this does and is for.  In
596    /// other libraries this is often named `SSL_export_keying_material()`
597    /// or `SslExportKeyingMaterial()`.
598    ///
599    /// This function is not meaningful if `output.len()` is zero and will
600    /// return an error in that case.
601    ///
602    /// [RFC 5705]: https://datatracker.ietf.org/doc/html/rfc5705
603    pub fn derive<T: AsMut<[u8]>>(
604        &self,
605        label: &[u8],
606        context: Option<&[u8]>,
607        mut output: T,
608    ) -> Result<T, Error> {
609        if output.as_mut().is_empty() {
610            return Err(ApiMisuse::ExporterOutputZeroLength.into());
611        }
612
613        self.inner
614            .derive(label, context, output.as_mut())
615            .map(|_| output)
616    }
617}
618
619impl fmt::Debug for KeyingMaterialExporter {
620    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
621        f.debug_struct("KeyingMaterialExporter")
622            .finish_non_exhaustive()
623    }
624}
625
626/// This trait is for any object that can export keying material.
627///
628/// The terminology comes from [RFC 5705](https://datatracker.ietf.org/doc/html/rfc5705)
629/// but doesn't really involve "exporting" key material (in the usual meaning of "export"
630/// -- of moving an artifact from one domain to another) but is best thought of as key
631/// diversification using an existing secret.  That secret is implicit in this interface,
632/// so is assumed to be held by `self`. The secret should be zeroized in `drop()`.
633///
634/// There are several such internal implementations, depending on the context
635/// and protocol version.
636pub(crate) trait Exporter: Send + Sync {
637    /// Fills in `output` with derived keying material.
638    ///
639    /// This is deterministic depending on a base secret (implicit in `self`),
640    /// plus the `label` and `context` values.
641    ///
642    /// Must fill in `output` entirely, or return an error.
643    fn derive(&self, label: &[u8], context: Option<&[u8]>, output: &mut [u8]) -> Result<(), Error>;
644}
645
646#[derive(Debug)]
647pub(crate) struct ConnectionRandoms {
648    pub(crate) client: [u8; 32],
649    pub(crate) server: [u8; 32],
650}
651
652impl ConnectionRandoms {
653    pub(crate) fn new(client: Random, server: Random) -> Self {
654        Self {
655            client: client.0,
656            server: server.0,
657        }
658    }
659}
660
661/// Describes the current I/O state of a TLS connection.
662///
663/// Values of this structure are returned from operations on [`MessageHandler`]s.
664#[derive(Debug, Eq, PartialEq)]
665pub struct IoState {
666    peer_has_closed: bool,
667}
668
669impl IoState {
670    pub(crate) fn new(recv: &ReceivePath) -> Self {
671        Self {
672            peer_has_closed: recv.has_received_close_notify,
673        }
674    }
675
676    /// True if the peer has sent us a close_notify alert.
677    ///
678    /// This is the TLS mechanism to securely half-close a TLS connection, and signifies that
679    /// the peer will not send any further data on this connection.
680    pub fn peer_has_closed(&self) -> bool {
681        self.peer_has_closed
682    }
683}
684
685pub(crate) struct SideCommonOutput<'a, 'q> {
686    pub(crate) side: &'a mut dyn SideOutput,
687    pub(crate) quic: Option<&'q mut dyn QuicOutput>,
688    pub(crate) common: &'a mut CommonState,
689    pub(crate) tls: &'a mut Vec<u8>,
690}
691
692impl<'q> Output<'_> for SideCommonOutput<'_, 'q> {
693    fn emit(&mut self, ev: Event) {
694        self.side.emit(ev);
695    }
696
697    fn output(&mut self, ev: OutputEvent<'_>) {
698        if let OutputEvent::ProtocolVersion(ver) = ev {
699            self.common.recv.negotiated_version = Some(ver);
700            self.common.send.negotiated_version(ver);
701        }
702        self.common.outputs.handle(ev);
703    }
704
705    fn send_msg(&mut self, m: Message<'_>, must_encrypt: bool) -> Result<(), Error> {
706        match self.quic() {
707            Some(quic) => {
708                quic.send_msg(m, must_encrypt);
709                Ok(())
710            }
711            None => self
712                .common
713                .send
714                .send_msg(m, must_encrypt, self.tls),
715        }
716    }
717
718    fn quic(&mut self) -> Option<&mut dyn QuicOutput> {
719        match self.quic.as_mut() {
720            Some(q) => Some(&mut **q),
721            None => None,
722        }
723    }
724
725    fn start_traffic(&mut self) {
726        self.common
727            .recv
728            .may_receive_application_data = true;
729        self.common
730            .send
731            .start_outgoing_traffic();
732    }
733
734    fn receive(&mut self) -> &mut ReceivePath {
735        &mut self.common.recv
736    }
737
738    fn send(&mut self) -> &mut dyn SendOutput {
739        &mut self.common.send
740    }
741}
742
743/// Data specific to the peer's side (client or server).
744#[expect(private_bounds)]
745pub trait SideData: SideOutput + fmt::Debug + private::Side + Sized + 'static {
746    /// Type representing an in-progress TCP handshake.
747    type Handshake: TryFrom<Processed<Self, Tcp>, Error = Error>;
748    /// Type representing an in-progress QUIC handshake.
749    type QuicHandshake: quic::FromConn<Self>;
750
751    /// Type representing the peer's identity.
752    type PeerIdentity<'a>;
753}
754
755pub(crate) mod private {
756    use super::*;
757
758    pub(crate) trait Side: fmt::Debug {
759        /// State machine type.
760        type State: StateMachine;
761    }
762
763    pub(crate) trait SideOutput {
764        fn emit(&mut self, ev: Event);
765    }
766}
767
768use private::SideOutput;
769
770pub(crate) trait StateMachine: Sized {
771    /// Advance the state machine using `input` and emitting data to `output`.
772    fn handle<'m>(self, input: Input<'m>, output: &mut dyn Output<'m>) -> Result<Self, Error>;
773
774    /// Return true if the current state requires input to be provided via `handle()`.
775    fn wants_input(&self) -> bool;
776
777    /// Advance the state machine using no input, emitting data to `output`.
778    ///
779    /// This should return `Ok(self)` if the current state requires input.
780    fn handle_without_input(self, output: &mut dyn Output<'_>) -> Result<Self, Error>;
781
782    fn is_traffic(&self) -> bool;
783    fn handle_decrypt_error(&mut self);
784    fn into_external_state(
785        self,
786        send_keys: &Option<Box<KeyScheduleTrafficSend>>,
787    ) -> Result<(PartiallyExtractedSecrets, Box<dyn KernelState + 'static>), Error>;
788}
789
790/// When to take action to avoid sequence space exhaustion.
791///
792/// This gives a margin in which any action can have an effect, prior to `SEQ_HARD_LIMIT`
793/// being reached.
794const SEQ_SOFT_LIMIT: u64 = u64::MAX - 0xffff;
795
796/// When to refuse further encryptions.
797const SEQ_HARD_LIMIT: u64 = u64::MAX - 1;