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;