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}