Skip to main content

rustls/server/
connection.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::ops::Deref;
4use core::{fmt, mem};
5use std::io;
6
7use pki_types::{DnsName, FipsStatus};
8
9use super::config::{ClientHello, ServerConfig};
10use crate::common_state::{
11    CommonState, ConnectionOutputs, EarlyDataEvent, Event, Protocol, Side, maybe_send_fatal_alert,
12};
13use crate::conn::private::SideOutput;
14use crate::conn::split::SplitConnection;
15use crate::conn::{
16    Connection, ConnectionCommon, KeyingMaterialExporter, MessageHandler, MessageIter, SideData,
17    StateMachine, TlsInputBuffer,
18};
19#[cfg(doc)]
20use crate::crypto;
21use crate::crypto::cipher::{OutboundPlain, Payload};
22use crate::error::Error;
23use crate::msgs::ServerExtensionsInput;
24use crate::server::hs::{ChooseConfig, ExpectClientHello, ReadClientHello, ServerState};
25use crate::suites::ExtractedSecrets;
26use crate::sync::Arc;
27use crate::tracing::trace;
28use crate::vecbuf::ChunkVecBuffer;
29
30/// This represents a single TLS server connection.
31///
32/// Send TLS-protected data to the peer using the `io::Write` trait implementation.
33/// Read data from the peer using the `io::Read` trait implementation.
34pub struct ServerConnection {
35    pub(super) inner: ConnectionCommon<ServerSide>,
36}
37
38impl ServerConnection {
39    /// Make a new ServerConnection.  `config` controls how
40    /// we behave in the TLS protocol.
41    pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
42        Ok(Self {
43            inner: ConnectionCommon::for_server(
44                config,
45                ServerExtensionsInput::default(),
46                Protocol::Tcp,
47            )?,
48        })
49    }
50
51    /// Split a post-handshake connection into a [`SplitConnection`].
52    ///
53    /// This allows the two directions (transmit and receive) of the connection to be progressed
54    /// separately (including by different threads, which would allow dedicating a CPU core for each
55    /// direction rather than one per connection; this can dramatically improve performance for
56    /// full-duplex protocols).
57    ///
58    /// It also separates out the [`ConnectionOutputs`] which gives the application direct control
59    /// of how long this is kept.
60    ///
61    /// This fails if:
62    ///
63    /// - the handshake is not complete. Check with [`Connection::is_handshaking()`].
64    /// - there is any buffered TLS data to send.  Obtain it first with [`Connection::write_tls()`].
65    pub fn split(self) -> Result<SplitConnection<ServerSide>, Error> {
66        self.inner.split()
67    }
68
69    /// Retrieves the server name, if any, used to select the certificate and
70    /// private key.
71    ///
72    /// This returns `None` until some time after the client's server name indication
73    /// (SNI) extension value is processed during the handshake. It will never be
74    /// `None` when the connection is ready to send or process application data,
75    /// unless the client does not support SNI.
76    ///
77    /// This is useful for application protocols that need to enforce that the
78    /// server name matches an application layer protocol hostname. For
79    /// example, HTTP/1.1 servers commonly expect the `Host:` header field of
80    /// every request on a connection to match the hostname in the SNI extension
81    /// when the client provides the SNI extension.
82    ///
83    /// The server name is also used to match sessions during session resumption.
84    pub fn server_name(&self) -> Option<&DnsName<'_>> {
85        self.inner.side.server_name()
86    }
87
88    /// Application-controlled portion of the resumption ticket supplied by the client, if any.
89    ///
90    /// Recovered from the prior session's `set_resumption_data`. Integrity is guaranteed by rustls.
91    ///
92    /// Returns `Some` if and only if a valid resumption ticket has been received from the client.
93    pub fn received_resumption_data(&self) -> Option<&[u8]> {
94        self.inner
95            .side
96            .received_resumption_data()
97    }
98
99    /// Set the resumption data to embed in future resumption tickets supplied to the client.
100    ///
101    /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
102    /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
103    /// resumption tickets are affected.
104    ///
105    /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
106    /// from the client is desired, encrypt the data separately.
107    pub fn set_resumption_data(&mut self, data: &[u8]) -> Result<(), Error> {
108        assert!(data.len() < 2usize.pow(15));
109        match &mut self.inner.state {
110            Ok(st) => st.set_resumption_data(data),
111            Err(e) => Err(e.clone()),
112        }
113    }
114
115    /// Returns an `io::Read` implementer you can read bytes from that are
116    /// received from a client as TLS1.3 0RTT/"early" data, during the handshake.
117    ///
118    /// This returns `None` in many circumstances, such as :
119    ///
120    /// - Early data is disabled if [`ServerConfig::max_early_data_size`] is zero (the default).
121    /// - The session negotiated with the client is not TLS1.3.
122    /// - The client just doesn't support early data.
123    /// - The connection doesn't resume an existing session.
124    /// - The client hasn't sent a full ClientHello yet.
125    pub fn early_data(&mut self) -> Option<ReadEarlyData<'_>> {
126        if self
127            .inner
128            .side
129            .early_data
130            .was_accepted()
131        {
132            Some(ReadEarlyData::new(&mut self.inner))
133        } else {
134            None
135        }
136    }
137}
138
139impl Connection for ServerConnection {
140    type Side = ServerSide;
141
142    fn write_tls(&mut self, plaintext: OutboundPlain<'_>, tls: &mut Vec<u8>) -> Result<(), Error> {
143        self.inner.write_tls(plaintext, tls)
144    }
145
146    fn wants_read(&self) -> bool {
147        self.inner.wants_read()
148    }
149
150    fn process_new_packets<'a, 'm>(
151        &'a mut self,
152        input: &'m mut dyn TlsInputBuffer,
153        tls: &'a mut Vec<u8>,
154    ) -> MessageHandler<'a, 'm, ServerSide> {
155        self.inner
156            .process_new_packets(input, tls)
157    }
158
159    fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
160        self.inner.exporter()
161    }
162
163    fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
164        self.inner.dangerous_extract_secrets()
165    }
166
167    fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error> {
168        self.inner.refresh_traffic_keys(tls)
169    }
170
171    fn send_close_notify(&mut self, tls: &mut Vec<u8>) {
172        self.inner.send_close_notify(tls);
173    }
174
175    fn is_handshaking(&self) -> bool {
176        self.inner.is_handshaking()
177    }
178
179    fn fips(&self) -> FipsStatus {
180        self.inner.fips
181    }
182}
183
184impl Deref for ServerConnection {
185    type Target = ConnectionOutputs;
186
187    fn deref(&self) -> &Self::Target {
188        &self.inner
189    }
190}
191
192impl fmt::Debug for ServerConnection {
193    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194        f.debug_struct("ServerConnection")
195            .finish_non_exhaustive()
196    }
197}
198
199/// An in-progress TLS server handshake.
200#[non_exhaustive]
201#[derive(Debug)]
202pub enum ServerHandshake {
203    /// More data needs to be received to make progress.
204    NeedsInput(NeedsInput),
205
206    /// A complete `ClientHello` has been received.
207    ///
208    /// The handshake can be progressed by choosing a [`ServerConfig`] based on
209    /// [`Accepted::client_hello()`] and providing it to [`Accepted::choose_config()`].
210    Accepted(Accepted),
211
212    /// The handshake is complete.
213    ///
214    /// Now see [`SplitConnection`] to continue the connection.
215    Complete(SplitConnection<ServerSide>),
216}
217
218impl ServerHandshake {
219    /// Creates a new [`ServerHandshake`] via the payload of the [`ServerHandshake::NeedsInput`] variant.
220    ///
221    /// It is a fundamental fact of server TLS connections that the server reads first; this is reflected
222    /// in the returned type.
223    ///
224    /// You may wrap this in the [`ServerHandshake::NeedsInput`] variant to generalise the type to a
225    /// [`ServerHandshake`].
226    ///
227    /// The returned object should be fed data from a single potential client.
228    pub fn start() -> NeedsInput {
229        NeedsInput {
230            inner: ConnectionCommon::for_acceptor(Protocol::Tcp),
231        }
232    }
233}
234
235impl TryFrom<ConnectionCommon<ServerSide>> for ServerHandshake {
236    type Error = Error;
237
238    fn try_from(mut inner: ConnectionCommon<ServerSide>) -> Result<Self, Error> {
239        const MISUSED: Error = Error::Unreachable("forgot to restore state");
240
241        Ok(match mem::replace(&mut inner.state, Err(MISUSED))? {
242            ServerState::ChooseConfig(choose_config) => Self::Accepted(Accepted {
243                inner,
244                choose_config,
245            }),
246
247            state if state.is_traffic() => {
248                inner.state = Ok(state);
249                Self::Complete(SplitConnection::try_from(inner)?)
250            }
251
252            state => {
253                inner.state = Ok(state);
254                Self::NeedsInput(NeedsInput { inner })
255            }
256        })
257    }
258}
259
260/// More data needs to be received to make progress.
261///
262/// Provide the data to [`Self::process()`].
263pub struct NeedsInput {
264    inner: ConnectionCommon<ServerSide>,
265}
266
267impl NeedsInput {
268    /// Progress the handshake by receiving further data.
269    ///
270    /// The data is obtained via `input`.  Any output produced is appended to `output` and
271    /// should be sent to the peer (including if this function returns an error, because
272    /// the `output` may contain an alert.)
273    ///
274    /// An error from this function is otherwise fatal to the connection, as it consumes
275    /// the [`NeedsInput`] object.
276    ///
277    /// On success, this returns:
278    ///
279    /// - a [`ServerHandshake::NeedsInput`] if more data is required.
280    /// - a [`ServerHandshake::Accepted`] if a whole `ClientHello` has been received, requiring
281    ///   and a choice of [`ServerConfig`] is required to continue.
282    /// - a [`ServerHandshake::Complete`] if the handshake is complete.
283    pub fn process(
284        mut self,
285        input: &mut dyn TlsInputBuffer,
286        tls: &mut Vec<u8>,
287    ) -> Result<ServerHandshake, Error> {
288        let mut iter = MessageIter::new(input, tls, None, &mut self.inner);
289        let r = loop {
290            match iter.next() {
291                Some(Ok(_)) => {}
292                Some(Err(e)) => break Err(e),
293                None => break Ok(()),
294            };
295
296            // end loop as soon as traffic state is entered, as the above loop drops
297            // incoming appdata.
298            if iter
299                .state()
300                .as_ref()
301                .map(|st| st.is_traffic())
302                .unwrap_or_default()
303            {
304                break Ok(());
305            }
306        };
307
308        input.discard(
309            self.inner
310                .common
311                .recv
312                .deframer
313                .take_discard(),
314        );
315
316        r?;
317        ServerHandshake::try_from(self.inner)
318    }
319
320    /// Temporary escape hatch during migration to new API.
321    pub fn into_buffered_connection(self) -> ServerConnection {
322        ServerConnection { inner: self.inner }
323    }
324}
325
326impl fmt::Debug for NeedsInput {
327    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328        f.debug_struct("NeedsInput")
329            .finish_non_exhaustive()
330    }
331}
332
333/// Represents a `ClientHello` message.
334///
335/// The handshake can be progressed by choosing a [`ServerConfig`] based on
336/// [`Accepted::client_hello()`] and providing it to [`Accepted::choose_config()`].
337pub struct Accepted {
338    // invariant: `inner.state` is `Err(_)` and requires restoring
339    inner: ConnectionCommon<ServerSide>,
340    choose_config: Box<ChooseConfig>,
341}
342
343impl Accepted {
344    /// Get the [`ClientHello`] for this connection.
345    pub fn client_hello(&self) -> ClientHello<'_> {
346        let ch = self.choose_config.client_hello();
347        trace!("Accepted::client_hello(): {ch:#?}");
348        ch
349    }
350
351    /// Choose a [`ServerConfig`] to progress the handshake.
352    ///
353    /// Output to send to the peer is appended to `output`.  Typically, this is the `ServerHello`,
354    /// but it may also be an `Alert` if an error is returned.
355    ///
356    /// Returns an error if configuration-dependent validation of the received `ClientHello` message fails.
357    pub fn choose_config(
358        mut self,
359        config: Arc<ServerConfig>,
360        tls: &mut Vec<u8>,
361    ) -> Result<ServerHandshake, Error> {
362        let result = self.inner.accepted(
363            self.choose_config,
364            ServerExtensionsInput::default(),
365            None,
366            config,
367            tls,
368        );
369
370        let send_path = &mut self.inner.common.send;
371
372        if let Err(err) = &result {
373            maybe_send_fatal_alert(send_path, err, tls);
374        }
375
376        result?;
377
378        Ok(ServerHandshake::NeedsInput(NeedsInput {
379            inner: self.inner,
380        }))
381    }
382}
383
384impl fmt::Debug for Accepted {
385    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386        f.debug_struct("Accepted")
387            .finish_non_exhaustive()
388    }
389}
390
391/// Allows reading of early data in resumed TLS1.3 connections.
392///
393/// "Early data" is also known as "0-RTT data".
394///
395/// This type implements [`io::Read`].
396pub struct ReadEarlyData<'a> {
397    common: &'a mut ConnectionCommon<ServerSide>,
398}
399
400impl<'a> ReadEarlyData<'a> {
401    fn new(common: &'a mut ConnectionCommon<ServerSide>) -> Self {
402        ReadEarlyData { common }
403    }
404
405    /// Returns the "early" exporter that can derive key material for use in early data
406    ///
407    /// See [RFC 5705][] for general details on what exporters are, and [RFC 9846 S7.5][] for
408    /// specific details on the "early" exporter.
409    ///
410    /// **Beware** that the early exporter requires care, as it is subject to the same
411    /// potential for replay as early data itself.  See [RFC 9846 appendix F.5.1][] for
412    /// more detail.
413    ///
414    /// This function can be called at most once per connection. This function will error:
415    /// if called more than once per connection.
416    ///
417    /// If you are looking for the normal exporter, this is available from
418    /// [`Connection::exporter()`].
419    ///
420    /// [RFC 5705]: https://datatracker.ietf.org/doc/html/rfc5705
421    /// [RFC 9846 S7.5]: https://datatracker.ietf.org/doc/html/rfc9846#section-7.5
422    /// [RFC 9846 appendix F.5.1]: https://datatracker.ietf.org/doc/html/rfc9846#appendix-F.5.1
423    /// [`Connection::exporter()`]: crate::conn::Connection::exporter()
424    pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
425        self.common.common.early_exporter()
426    }
427}
428
429impl io::Read for ReadEarlyData<'_> {
430    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
431        self.common.side.early_data.read(buf)
432    }
433}
434
435#[derive(Default)]
436pub(super) enum EarlyDataState {
437    #[default]
438    New,
439    Accepted {
440        received: ChunkVecBuffer,
441    },
442}
443
444impl EarlyDataState {
445    fn accept(&mut self) {
446        *self = Self::Accepted {
447            received: ChunkVecBuffer::new(),
448        };
449    }
450
451    fn was_accepted(&self) -> bool {
452        matches!(self, Self::Accepted { .. })
453    }
454
455    #[expect(dead_code)]
456    fn peek(&self) -> Option<&[u8]> {
457        match self {
458            Self::Accepted { received, .. } => received.peek(),
459            _ => None,
460        }
461    }
462
463    #[expect(dead_code)]
464    fn pop(&mut self) -> Option<Vec<u8>> {
465        match self {
466            Self::Accepted { received, .. } => received.pop(),
467            _ => None,
468        }
469    }
470
471    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
472        match self {
473            Self::Accepted { received, .. } => Ok(received.read(buf)),
474            _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
475        }
476    }
477
478    fn take_received_plaintext(&mut self, bytes: Payload<'_>) {
479        let Self::Accepted { received } = self else {
480            return;
481        };
482
483        received.append(bytes.into_vec());
484    }
485}
486
487impl ConnectionCommon<ServerSide> {
488    pub(crate) fn for_server(
489        config: Arc<ServerConfig>,
490        extra_exts: ServerExtensionsInput,
491        protocol: Protocol,
492    ) -> Result<Self, Error> {
493        let mut common = CommonState::new(Side::Server, config.fips());
494        common
495            .send
496            .set_max_fragment_size(config.max_fragment_size)?;
497        Ok(Self::new(
498            Box::new(ExpectClientHello::new(
499                config,
500                extra_exts,
501                Vec::new(),
502                protocol,
503            ))
504            .into(),
505            ServerConnectionData::default(),
506            common,
507        ))
508    }
509
510    pub(crate) fn for_acceptor(protocol: Protocol) -> Self {
511        Self::new(
512            ReadClientHello::new(protocol).into(),
513            ServerConnectionData::default(),
514            CommonState::new(Side::Server, FipsStatus::Unvalidated),
515        )
516    }
517}
518
519/// State associated with a server connection.
520#[derive(Default)]
521pub(crate) struct ServerConnectionData {
522    sni: Option<DnsName<'static>>,
523    received_resumption_data: Option<Vec<u8>>,
524    early_data: EarlyDataState,
525}
526
527impl ServerConnectionData {
528    pub(crate) fn received_resumption_data(&self) -> Option<&[u8]> {
529        self.received_resumption_data.as_deref()
530    }
531
532    pub(crate) fn server_name(&self) -> Option<&DnsName<'static>> {
533        self.sni.as_ref()
534    }
535}
536
537impl SideOutput for ServerConnectionData {
538    fn emit(&mut self, ev: Event<'_>) {
539        match ev {
540            Event::EarlyApplicationData(data) => self
541                .early_data
542                .take_received_plaintext(data),
543            Event::EarlyData(EarlyDataEvent::Accepted) => self.early_data.accept(),
544            Event::ReceivedServerName(sni) => self.sni = sni,
545            Event::ResumptionData(data) => self.received_resumption_data = Some(data),
546            _ => unreachable!(),
547        }
548    }
549}
550
551/// State associated with a server connection.
552#[expect(clippy::exhaustive_structs)]
553#[derive(Debug)]
554pub struct ServerSide;
555
556impl SideData for ServerSide {}
557
558impl crate::conn::private::Side for ServerSide {
559    type Data = ServerConnectionData;
560    type State = ServerState;
561}
562
563#[cfg(test)]
564mod tests {
565    use std::format;
566
567    use super::*;
568
569    // these branches not reachable externally, unless something else goes wrong.
570    #[test]
571    fn test_read_in_new_state() {
572        assert_eq!(
573            format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
574            "Err(Kind(BrokenPipe))"
575        );
576    }
577}