Skip to main content

rustls/server/
connection.rs

1use alloc::borrow::Cow;
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4use core::fmt;
5use core::fmt::{Debug, Formatter};
6use core::ops::Deref;
7use std::io;
8
9use pki_types::{DnsName, FipsStatus};
10
11use super::config::{ClientHello, ServerConfig};
12use crate::common_state::{CommonState, ConnectionOutputs, EarlyDataEvent, Event, Protocol, Side};
13use crate::conn::private::SideOutput;
14use crate::conn::{
15    Connection, ConnectionCommon, ConnectionCore, KeyingMaterialExporter, Reader, SendPath,
16    SideCommonOutput, Writer,
17};
18#[cfg(doc)]
19use crate::crypto;
20use crate::crypto::cipher::Payload;
21use crate::error::{ApiMisuse, Error, ErrorWithAlert};
22use crate::log::trace;
23use crate::msgs::{ServerExtensionsInput, ServerNamePayload};
24use crate::server::hs::{ChooseConfig, ExpectClientHello, ReadClientHello, ServerState};
25use crate::suites::ExtractedSecrets;
26use crate::sync::Arc;
27use crate::vecbuf::ChunkVecBuffer;
28
29/// This represents a single TLS server connection.
30///
31/// Send TLS-protected data to the peer using the `io::Write` trait implementation.
32/// Read data from the peer using the `io::Read` trait implementation.
33pub struct ServerConnection {
34    pub(super) inner: ConnectionCommon<ServerSide>,
35}
36
37impl ServerConnection {
38    /// Make a new ServerConnection.  `config` controls how
39    /// we behave in the TLS protocol.
40    pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
41        let fips = config.fips();
42        Ok(Self {
43            inner: ConnectionCommon::new(
44                ConnectionCore::for_server(
45                    config,
46                    ServerExtensionsInput::default(),
47                    Protocol::Tcp,
48                )?,
49                fips,
50            ),
51        })
52    }
53
54    /// Retrieves the server name, if any, used to select the certificate and
55    /// private key.
56    ///
57    /// This returns `None` until some time after the client's server name indication
58    /// (SNI) extension value is processed during the handshake. It will never be
59    /// `None` when the connection is ready to send or process application data,
60    /// unless the client does not support SNI.
61    ///
62    /// This is useful for application protocols that need to enforce that the
63    /// server name matches an application layer protocol hostname. For
64    /// example, HTTP/1.1 servers commonly expect the `Host:` header field of
65    /// every request on a connection to match the hostname in the SNI extension
66    /// when the client provides the SNI extension.
67    ///
68    /// The server name is also used to match sessions during session resumption.
69    pub fn server_name(&self) -> Option<&DnsName<'_>> {
70        self.inner.core.side.server_name()
71    }
72
73    /// Application-controlled portion of the resumption ticket supplied by the client, if any.
74    ///
75    /// Recovered from the prior session's `set_resumption_data`. Integrity is guaranteed by rustls.
76    ///
77    /// Returns `Some` if and only if a valid resumption ticket has been received from the client.
78    pub fn received_resumption_data(&self) -> Option<&[u8]> {
79        self.inner
80            .core
81            .side
82            .received_resumption_data()
83    }
84
85    /// Set the resumption data to embed in future resumption tickets supplied to the client.
86    ///
87    /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
88    /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
89    /// resumption tickets are affected.
90    ///
91    /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
92    /// from the client is desired, encrypt the data separately.
93    pub fn set_resumption_data(&mut self, data: &[u8]) -> Result<(), Error> {
94        assert!(data.len() < 2usize.pow(15));
95        match &mut self.inner.core.state {
96            Ok(st) => st.set_resumption_data(data),
97            Err(e) => Err(e.clone()),
98        }
99    }
100
101    /// Returns an `io::Read` implementer you can read bytes from that are
102    /// received from a client as TLS1.3 0RTT/"early" data, during the handshake.
103    ///
104    /// This returns `None` in many circumstances, such as :
105    ///
106    /// - Early data is disabled if [`ServerConfig::max_early_data_size`] is zero (the default).
107    /// - The session negotiated with the client is not TLS1.3.
108    /// - The client just doesn't support early data.
109    /// - The connection doesn't resume an existing session.
110    /// - The client hasn't sent a full ClientHello yet.
111    pub fn early_data(&mut self) -> Option<ReadEarlyData<'_>> {
112        if self
113            .inner
114            .core
115            .side
116            .early_data
117            .was_accepted()
118        {
119            Some(ReadEarlyData::new(&mut self.inner))
120        } else {
121            None
122        }
123    }
124
125    /// Extract secrets, so they can be used when configuring kTLS, for example.
126    /// Should be used with care as it exposes secret key material.
127    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
128        self.inner.dangerous_extract_secrets()
129    }
130}
131
132impl Connection for ServerConnection {
133    fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
134        self.inner.read_tls(rd)
135    }
136
137    fn write_tls(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
138        self.inner.write_tls(wr)
139    }
140
141    fn wants_read(&self) -> bool {
142        self.inner.wants_read()
143    }
144
145    fn wants_write(&self) -> bool {
146        self.inner.wants_write()
147    }
148
149    fn reader(&mut self) -> Reader<'_> {
150        self.inner.reader()
151    }
152
153    fn writer(&mut self) -> Writer<'_> {
154        self.inner.writer()
155    }
156
157    fn process_new_packets(&mut self) -> Result<crate::IoState, Error> {
158        self.inner.process_new_packets()
159    }
160
161    fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
162        self.inner.exporter()
163    }
164
165    fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
166        self.inner.dangerous_extract_secrets()
167    }
168
169    fn set_buffer_limit(&mut self, limit: Option<usize>) {
170        self.inner.set_buffer_limit(limit)
171    }
172
173    fn set_plaintext_buffer_limit(&mut self, limit: Option<usize>) {
174        self.inner
175            .set_plaintext_buffer_limit(limit)
176    }
177
178    fn refresh_traffic_keys(&mut self) -> Result<(), Error> {
179        self.inner.refresh_traffic_keys()
180    }
181
182    fn send_close_notify(&mut self) {
183        self.inner.send_close_notify();
184    }
185
186    fn is_handshaking(&self) -> bool {
187        self.inner.is_handshaking()
188    }
189
190    fn fips(&self) -> FipsStatus {
191        self.inner.fips
192    }
193}
194
195impl Deref for ServerConnection {
196    type Target = ConnectionOutputs;
197
198    fn deref(&self) -> &Self::Target {
199        &self.inner
200    }
201}
202
203impl Debug for ServerConnection {
204    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
205        f.debug_struct("ServerConnection")
206            .finish_non_exhaustive()
207    }
208}
209
210/// Handle a server-side connection before configuration is available.
211///
212/// `Acceptor` allows the caller to choose a [`ServerConfig`] after reading
213/// the [`ClientHello`] of an incoming connection. This is useful for
214/// servers that choose different certificates or cipher suites based on the
215/// characteristics of the `ClientHello`. In particular it is useful for
216/// servers that need to do some I/O to load a certificate and its private key
217/// and don't want to use the blocking interface provided by
218/// [`ServerCredentialResolver`][crate::server::ServerCredentialResolver].
219///
220/// Create an Acceptor with [`Acceptor::default()`].
221///
222/// # Example
223///
224/// ```no_run
225/// # #[cfg(feature = "aws-lc-rs")] {
226/// # fn choose_server_config(
227/// #     _: rustls::server::ClientHello,
228/// # ) -> std::sync::Arc<rustls::ServerConfig> {
229/// #     unimplemented!();
230/// # }
231/// # #[allow(unused_variables)]
232/// # fn main() {
233/// use rustls::server::{Acceptor, ServerConfig};
234/// let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
235/// for stream in listener.incoming() {
236///     let mut stream = stream.unwrap();
237///     let mut acceptor = Acceptor::default();
238///     let accepted = loop {
239///         acceptor.read_tls(&mut stream).unwrap();
240///         if let Some(accepted) = acceptor.accept().unwrap() {
241///             break accepted;
242///         }
243///     };
244///
245///     // For some user-defined choose_server_config:
246///     let config = choose_server_config(accepted.client_hello());
247///     let conn = accepted
248///         .into_connection(config)
249///         .unwrap();
250///
251///     // Proceed with handling the ServerConnection.
252/// }
253/// # }
254/// # }
255/// ```
256pub struct Acceptor {
257    inner: Option<ConnectionCommon<ServerSide>>,
258}
259
260impl Default for Acceptor {
261    /// Return an empty Acceptor, ready to receive bytes from a new client connection.
262    fn default() -> Self {
263        Self {
264            inner: Some(ConnectionCommon::new(
265                ConnectionCore::for_acceptor(Protocol::Tcp),
266                FipsStatus::Unvalidated,
267            )),
268        }
269    }
270}
271
272impl Acceptor {
273    /// Read TLS content from `rd`.
274    ///
275    /// Returns an error if this `Acceptor` has already yielded an [`Accepted`]. For more details,
276    /// refer to [`Connection::read_tls()`].
277    ///
278    /// [`Connection::read_tls()`]: crate::Connection::read_tls
279    pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
280        match &mut self.inner {
281            Some(conn) => conn.read_tls(rd),
282            None => Err(io::Error::other(
283                "acceptor cannot read after successful acceptance",
284            )),
285        }
286    }
287
288    /// Check if a `ClientHello` message has been received.
289    ///
290    /// Returns `Ok(None)` if the complete `ClientHello` has not yet been received.
291    /// Do more I/O and then call this function again.
292    ///
293    /// Returns `Ok(Some(accepted))` if the connection has been accepted. Call
294    /// `accepted.into_connection()` to continue. Do not call this function again.
295    ///
296    /// Returns `Err((err, alert))` if an error occurred. If an alert is returned, the
297    /// application should call `alert.write()` to send the alert to the client. It should
298    /// not call `accept()` again.
299    pub fn accept(&mut self) -> Result<Option<Accepted>, (Error, AcceptedAlert)> {
300        let Some(mut connection) = self.inner.take() else {
301            return Err((
302                ApiMisuse::AcceptorPolledAfterCompletion.into(),
303                AcceptedAlert::empty(),
304            ));
305        };
306
307        if let Err(e) = connection.process_new_packets() {
308            return Err(AcceptedAlert::from_error(e, connection.core.common.send));
309        }
310
311        let Ok(ServerState::ChooseConfig(_)) = connection.core.state else {
312            self.inner = Some(connection);
313            return Ok(None);
314        };
315
316        let Ok(ServerState::ChooseConfig(choose_config)) = core::mem::replace(
317            &mut connection.core.state,
318            Err(Error::Unreachable("Accepted misused state")),
319        ) else {
320            unreachable!(); // checked in previous block
321        };
322
323        Ok(Some(Accepted {
324            connection,
325            choose_config,
326        }))
327    }
328}
329
330/// Represents a TLS alert resulting from handling the client's `ClientHello` message.
331///
332/// When [`Acceptor::accept()`] returns an error, it yields an `AcceptedAlert` such that the
333/// application can communicate failure to the client via [`AcceptedAlert::write()`].
334pub struct AcceptedAlert(ChunkVecBuffer);
335
336impl AcceptedAlert {
337    pub(super) fn from_error(error: Error, mut send: SendPath) -> (Error, Self) {
338        let ErrorWithAlert { error, data } = ErrorWithAlert::new(error, &mut send);
339        let mut output = ChunkVecBuffer::new(None);
340        output.append(data);
341        (error, Self(output))
342    }
343
344    pub(super) fn empty() -> Self {
345        Self(ChunkVecBuffer::new(None))
346    }
347
348    /// Send the alert to the client.
349    ///
350    /// To account for short writes this function should be called repeatedly until it
351    /// returns `Ok(0)` or an error.
352    pub fn write(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
353        self.0.write_to(wr)
354    }
355
356    /// Send the alert to the client.
357    ///
358    /// This function will invoke the writer until the buffer is empty.
359    pub fn write_all(&mut self, wr: &mut dyn io::Write) -> Result<(), io::Error> {
360        while self.write(wr)? != 0 {}
361        Ok(())
362    }
363}
364
365impl Debug for AcceptedAlert {
366    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
367        f.debug_struct("AcceptedAlert")
368            .finish_non_exhaustive()
369    }
370}
371
372/// Allows reading of early data in resumed TLS1.3 connections.
373///
374/// "Early data" is also known as "0-RTT data".
375///
376/// This type implements [`io::Read`].
377pub struct ReadEarlyData<'a> {
378    common: &'a mut ConnectionCommon<ServerSide>,
379}
380
381impl<'a> ReadEarlyData<'a> {
382    fn new(common: &'a mut ConnectionCommon<ServerSide>) -> Self {
383        ReadEarlyData { common }
384    }
385
386    /// Returns the "early" exporter that can derive key material for use in early data
387    ///
388    /// See [RFC5705][] for general details on what exporters are, and [RFC8446 S7.5][] for
389    /// specific details on the "early" exporter.
390    ///
391    /// **Beware** that the early exporter requires care, as it is subject to the same
392    /// potential for replay as early data itself.  See [RFC8446 appendix E.5.1][] for
393    /// more detail.
394    ///
395    /// This function can be called at most once per connection. This function will error:
396    /// if called more than once per connection.
397    ///
398    /// If you are looking for the normal exporter, this is available from
399    /// [`Connection::exporter()`].
400    ///
401    /// [RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705
402    /// [RFC8446 S7.5]: https://datatracker.ietf.org/doc/html/rfc8446#section-7.5
403    /// [RFC8446 appendix E.5.1]: https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.5.1
404    /// [`Connection::exporter()`]: crate::conn::Connection::exporter()
405    pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
406        self.common.core.early_exporter()
407    }
408}
409
410impl io::Read for ReadEarlyData<'_> {
411    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
412        self.common
413            .core
414            .side
415            .early_data
416            .read(buf)
417    }
418}
419
420/// Represents a `ClientHello` message received through the [`Acceptor`].
421///
422/// Contains the state required to resume the connection through [`Accepted::into_connection()`].
423pub struct Accepted {
424    // invariant: `connection.core.state` is `Err(_)` and requires restoring
425    connection: ConnectionCommon<ServerSide>,
426    choose_config: Box<ChooseConfig>,
427}
428
429impl Accepted {
430    /// Get the [`ClientHello`] for this connection.
431    pub fn client_hello(&self) -> ClientHello<'_> {
432        let client_hello = self.choose_config.client_hello();
433        let server_name = client_hello
434            .server_name
435            .as_ref()
436            .and_then(ServerNamePayload::to_dns_name_normalized)
437            .map(Cow::Owned);
438        let ch = ClientHello {
439            server_name,
440            signature_schemes: client_hello
441                .signature_schemes
442                .as_deref()
443                .unwrap_or_default(),
444            alpn: client_hello.protocols.as_ref(),
445            server_cert_types: client_hello
446                .server_certificate_types
447                .as_deref(),
448            client_cert_types: client_hello
449                .client_certificate_types
450                .as_deref(),
451            cipher_suites: &client_hello.cipher_suites,
452            certificate_authorities: client_hello
453                .certificate_authority_names
454                .as_deref(),
455            named_groups: client_hello.named_groups.as_deref(),
456        };
457
458        trace!("Accepted::client_hello(): {ch:#?}");
459        ch
460    }
461
462    /// Convert the [`Accepted`] into a [`ServerConnection`].
463    ///
464    /// Takes the state returned from [`Acceptor::accept()`] as well as the [`ServerConfig`] that
465    /// should be used for the session. Returns an error if configuration-dependent validation of
466    /// the received `ClientHello` message fails.
467    pub fn into_connection(
468        mut self,
469        config: Arc<ServerConfig>,
470    ) -> Result<ServerConnection, (Error, AcceptedAlert)> {
471        if let Err(err) = self
472            .connection
473            .send
474            .set_max_fragment_size(config.max_fragment_size)
475        {
476            // We have a connection here, but it won't contain an alert since the error
477            // is with the fragment size configured in the `ServerConfig`.
478            return Err((err, AcceptedAlert::empty()));
479        }
480        self.connection.fips = config.fips();
481
482        let mut output = SideCommonOutput {
483            side: &mut self.connection.core.side,
484            quic: None,
485            common: &mut self.connection.core.common,
486        };
487
488        let state = match self.choose_config.use_config(
489            config,
490            ServerExtensionsInput::default(),
491            &mut output,
492        ) {
493            Ok(state) => state,
494            Err(err) => {
495                return Err(AcceptedAlert::from_error(
496                    err,
497                    self.connection.core.common.send,
498                ));
499            }
500        };
501        self.connection.core.state = Ok(state);
502
503        Ok(ServerConnection {
504            inner: self.connection,
505        })
506    }
507}
508
509impl Debug for Accepted {
510    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
511        f.debug_struct("Accepted")
512            .finish_non_exhaustive()
513    }
514}
515
516#[derive(Default)]
517pub(super) enum EarlyDataState {
518    #[default]
519    New,
520    Accepted {
521        received: ChunkVecBuffer,
522    },
523}
524
525impl EarlyDataState {
526    fn accept(&mut self) {
527        *self = Self::Accepted {
528            received: ChunkVecBuffer::new(None),
529        };
530    }
531
532    fn was_accepted(&self) -> bool {
533        matches!(self, Self::Accepted { .. })
534    }
535
536    #[expect(dead_code)]
537    fn peek(&self) -> Option<&[u8]> {
538        match self {
539            Self::Accepted { received, .. } => received.peek(),
540            _ => None,
541        }
542    }
543
544    #[expect(dead_code)]
545    fn pop(&mut self) -> Option<Vec<u8>> {
546        match self {
547            Self::Accepted { received, .. } => received.pop(),
548            _ => None,
549        }
550    }
551
552    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
553        match self {
554            Self::Accepted { received, .. } => received.read(buf),
555            _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
556        }
557    }
558
559    fn take_received_plaintext(&mut self, bytes: Payload<'_>) {
560        let Self::Accepted { received } = self else {
561            return;
562        };
563
564        received.append(bytes.into_vec());
565    }
566}
567
568impl ConnectionCore<ServerSide> {
569    pub(crate) fn for_server(
570        config: Arc<ServerConfig>,
571        extra_exts: ServerExtensionsInput,
572        protocol: Protocol,
573    ) -> Result<Self, Error> {
574        let mut common = CommonState::new(Side::Server);
575        common
576            .send
577            .set_max_fragment_size(config.max_fragment_size)?;
578        Ok(Self::new(
579            Box::new(ExpectClientHello::new(
580                config,
581                extra_exts,
582                Vec::new(),
583                protocol,
584            ))
585            .into(),
586            ServerConnectionData::default(),
587            common,
588        ))
589    }
590
591    pub(crate) fn for_acceptor(protocol: Protocol) -> Self {
592        Self::new(
593            ReadClientHello::new(protocol).into(),
594            ServerConnectionData::default(),
595            CommonState::new(Side::Server),
596        )
597    }
598}
599
600/// State associated with a server connection.
601#[derive(Default)]
602pub(crate) struct ServerConnectionData {
603    sni: Option<DnsName<'static>>,
604    received_resumption_data: Option<Vec<u8>>,
605    early_data: EarlyDataState,
606}
607
608impl ServerConnectionData {
609    pub(crate) fn received_resumption_data(&self) -> Option<&[u8]> {
610        self.received_resumption_data.as_deref()
611    }
612
613    pub(crate) fn server_name(&self) -> Option<&DnsName<'static>> {
614        self.sni.as_ref()
615    }
616}
617
618impl SideOutput for ServerConnectionData {
619    fn emit(&mut self, ev: Event<'_>) {
620        match ev {
621            Event::EarlyApplicationData(data) => self
622                .early_data
623                .take_received_plaintext(data),
624            Event::EarlyData(EarlyDataEvent::Accepted) => self.early_data.accept(),
625            Event::ReceivedServerName(sni) => self.sni = sni,
626            Event::ResumptionData(data) => self.received_resumption_data = Some(data),
627            _ => unreachable!(),
628        }
629    }
630}
631
632/// State associated with a server connection.
633#[expect(clippy::exhaustive_structs)]
634#[derive(Debug)]
635pub struct ServerSide;
636
637impl crate::conn::SideData for ServerSide {}
638
639impl crate::conn::private::Side for ServerSide {
640    type Data = ServerConnectionData;
641    type State = ServerState;
642}
643
644#[cfg(test)]
645mod tests {
646    use std::format;
647
648    use super::*;
649
650    // these branches not reachable externally, unless something else goes wrong.
651    #[test]
652    fn test_read_in_new_state() {
653        assert_eq!(
654            format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
655            "Err(Kind(BrokenPipe))"
656        );
657    }
658}