Skip to main content

rustls/conn/
mod.rs

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