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