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, DerefMut};
7use std::io;
8
9use pki_types::{DnsName, FipsStatus};
10
11use super::config::{ClientHello, ServerConfig};
12use crate::common_state::{
13    CommonState, ConnectionOutputs, EarlyDataEvent, Event, Output, Protocol, SendPath, Side,
14};
15use crate::conn::{
16    Connection, ConnectionCommon, ConnectionCore, KeyingMaterialExporter, Reader, 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 DerefMut for ServerConnection {
204    fn deref_mut(&mut self) -> &mut Self::Target {
205        &mut self.inner
206    }
207}
208
209impl Debug for ServerConnection {
210    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
211        f.debug_struct("ServerConnection")
212            .finish_non_exhaustive()
213    }
214}
215
216/// Handle a server-side connection before configuration is available.
217///
218/// `Acceptor` allows the caller to choose a [`ServerConfig`] after reading
219/// the [`ClientHello`] of an incoming connection. This is useful for
220/// servers that choose different certificates or cipher suites based on the
221/// characteristics of the `ClientHello`. In particular it is useful for
222/// servers that need to do some I/O to load a certificate and its private key
223/// and don't want to use the blocking interface provided by
224/// [`ServerCredentialResolver`][crate::server::ServerCredentialResolver].
225///
226/// Create an Acceptor with [`Acceptor::default()`].
227///
228/// # Example
229///
230/// ```no_run
231/// # #[cfg(feature = "aws-lc-rs")] {
232/// # fn choose_server_config(
233/// #     _: rustls::server::ClientHello,
234/// # ) -> std::sync::Arc<rustls::ServerConfig> {
235/// #     unimplemented!();
236/// # }
237/// # #[allow(unused_variables)]
238/// # fn main() {
239/// use rustls::server::{Acceptor, ServerConfig};
240/// let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
241/// for stream in listener.incoming() {
242///     let mut stream = stream.unwrap();
243///     let mut acceptor = Acceptor::default();
244///     let accepted = loop {
245///         acceptor.read_tls(&mut stream).unwrap();
246///         if let Some(accepted) = acceptor.accept().unwrap() {
247///             break accepted;
248///         }
249///     };
250///
251///     // For some user-defined choose_server_config:
252///     let config = choose_server_config(accepted.client_hello());
253///     let conn = accepted
254///         .into_connection(config)
255///         .unwrap();
256///
257///     // Proceed with handling the ServerConnection.
258/// }
259/// # }
260/// # }
261/// ```
262pub struct Acceptor {
263    inner: Option<ConnectionCommon<ServerSide>>,
264}
265
266impl Default for Acceptor {
267    /// Return an empty Acceptor, ready to receive bytes from a new client connection.
268    fn default() -> Self {
269        Self {
270            inner: Some(ConnectionCommon::new(
271                ConnectionCore::for_acceptor(Protocol::Tcp),
272                FipsStatus::Unvalidated,
273            )),
274        }
275    }
276}
277
278impl Acceptor {
279    /// Read TLS content from `rd`.
280    ///
281    /// Returns an error if this `Acceptor` has already yielded an [`Accepted`]. For more details,
282    /// refer to [`Connection::read_tls()`].
283    ///
284    /// [`Connection::read_tls()`]: crate::Connection::read_tls
285    pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
286        match &mut self.inner {
287            Some(conn) => conn.read_tls(rd),
288            None => Err(io::Error::other(
289                "acceptor cannot read after successful acceptance",
290            )),
291        }
292    }
293
294    /// Check if a `ClientHello` message has been received.
295    ///
296    /// Returns `Ok(None)` if the complete `ClientHello` has not yet been received.
297    /// Do more I/O and then call this function again.
298    ///
299    /// Returns `Ok(Some(accepted))` if the connection has been accepted. Call
300    /// `accepted.into_connection()` to continue. Do not call this function again.
301    ///
302    /// Returns `Err((err, alert))` if an error occurred. If an alert is returned, the
303    /// application should call `alert.write()` to send the alert to the client. It should
304    /// not call `accept()` again.
305    pub fn accept(&mut self) -> Result<Option<Accepted>, (Error, AcceptedAlert)> {
306        let Some(mut connection) = self.inner.take() else {
307            return Err((
308                ApiMisuse::AcceptorPolledAfterCompletion.into(),
309                AcceptedAlert::empty(),
310            ));
311        };
312
313        if let Err(e) = connection.process_new_packets() {
314            return Err(AcceptedAlert::from_error(e, connection.core.common.send));
315        }
316
317        let Ok(ServerState::ChooseConfig(_)) = connection.core.state else {
318            self.inner = Some(connection);
319            return Ok(None);
320        };
321
322        let Ok(ServerState::ChooseConfig(choose_config)) = core::mem::replace(
323            &mut connection.core.state,
324            Err(Error::Unreachable("Accepted misused state")),
325        ) else {
326            unreachable!(); // checked in previous block
327        };
328
329        Ok(Some(Accepted {
330            connection,
331            choose_config,
332        }))
333    }
334}
335
336/// Represents a TLS alert resulting from handling the client's `ClientHello` message.
337///
338/// When [`Acceptor::accept()`] returns an error, it yields an `AcceptedAlert` such that the
339/// application can communicate failure to the client via [`AcceptedAlert::write()`].
340pub struct AcceptedAlert(ChunkVecBuffer);
341
342impl AcceptedAlert {
343    pub(super) fn from_error(error: Error, mut send: SendPath) -> (Error, Self) {
344        let ErrorWithAlert { error, data } = ErrorWithAlert::new(error, &mut send);
345        let mut output = ChunkVecBuffer::new(None);
346        output.append(data);
347        (error, Self(output))
348    }
349
350    pub(super) fn empty() -> Self {
351        Self(ChunkVecBuffer::new(None))
352    }
353
354    /// Send the alert to the client.
355    ///
356    /// To account for short writes this function should be called repeatedly until it
357    /// returns `Ok(0)` or an error.
358    pub fn write(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
359        self.0.write_to(wr)
360    }
361
362    /// Send the alert to the client.
363    ///
364    /// This function will invoke the writer until the buffer is empty.
365    pub fn write_all(&mut self, wr: &mut dyn io::Write) -> Result<(), io::Error> {
366        while self.write(wr)? != 0 {}
367        Ok(())
368    }
369}
370
371impl Debug for AcceptedAlert {
372    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
373        f.debug_struct("AcceptedAlert")
374            .finish_non_exhaustive()
375    }
376}
377
378/// Allows reading of early data in resumed TLS1.3 connections.
379///
380/// "Early data" is also known as "0-RTT data".
381///
382/// This type implements [`io::Read`].
383pub struct ReadEarlyData<'a> {
384    common: &'a mut ConnectionCommon<ServerSide>,
385}
386
387impl<'a> ReadEarlyData<'a> {
388    fn new(common: &'a mut ConnectionCommon<ServerSide>) -> Self {
389        ReadEarlyData { common }
390    }
391
392    /// Returns the "early" exporter that can derive key material for use in early data
393    ///
394    /// See [RFC5705][] for general details on what exporters are, and [RFC8446 S7.5][] for
395    /// specific details on the "early" exporter.
396    ///
397    /// **Beware** that the early exporter requires care, as it is subject to the same
398    /// potential for replay as early data itself.  See [RFC8446 appendix E.5.1][] for
399    /// more detail.
400    ///
401    /// This function can be called at most once per connection. This function will error:
402    /// if called more than once per connection.
403    ///
404    /// If you are looking for the normal exporter, this is available from
405    /// [`Connection::exporter()`].
406    ///
407    /// [RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705
408    /// [RFC8446 S7.5]: https://datatracker.ietf.org/doc/html/rfc8446#section-7.5
409    /// [RFC8446 appendix E.5.1]: https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.5.1
410    /// [`Connection::exporter()`]: crate::conn::Connection::exporter()
411    pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
412        self.common.core.early_exporter()
413    }
414}
415
416impl io::Read for ReadEarlyData<'_> {
417    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
418        self.common
419            .core
420            .side
421            .early_data
422            .read(buf)
423    }
424}
425
426/// Represents a `ClientHello` message received through the [`Acceptor`].
427///
428/// Contains the state required to resume the connection through [`Accepted::into_connection()`].
429pub struct Accepted {
430    // invariant: `connection.core.state` is `Err(_)` and requires restoring
431    connection: ConnectionCommon<ServerSide>,
432    choose_config: ChooseConfig,
433}
434
435impl Accepted {
436    /// Get the [`ClientHello`] for this connection.
437    pub fn client_hello(&self) -> ClientHello<'_> {
438        let client_hello = self.choose_config.client_hello();
439        let server_name = client_hello
440            .server_name
441            .as_ref()
442            .and_then(ServerNamePayload::to_dns_name_normalized)
443            .map(Cow::Owned);
444        let ch = ClientHello {
445            server_name,
446            signature_schemes: client_hello
447                .signature_schemes
448                .as_deref()
449                .unwrap_or_default(),
450            alpn: client_hello.protocols.as_ref(),
451            server_cert_types: client_hello
452                .server_certificate_types
453                .as_deref(),
454            client_cert_types: client_hello
455                .client_certificate_types
456                .as_deref(),
457            cipher_suites: &client_hello.cipher_suites,
458            certificate_authorities: client_hello
459                .certificate_authority_names
460                .as_deref(),
461            named_groups: client_hello.named_groups.as_deref(),
462        };
463
464        trace!("Accepted::client_hello(): {ch:#?}");
465        ch
466    }
467
468    /// Convert the [`Accepted`] into a [`ServerConnection`].
469    ///
470    /// Takes the state returned from [`Acceptor::accept()`] as well as the [`ServerConfig`] that
471    /// should be used for the session. Returns an error if configuration-dependent validation of
472    /// the received `ClientHello` message fails.
473    pub fn into_connection(
474        mut self,
475        config: Arc<ServerConfig>,
476    ) -> Result<ServerConnection, (Error, AcceptedAlert)> {
477        if let Err(err) = self
478            .connection
479            .send
480            .set_max_fragment_size(config.max_fragment_size)
481        {
482            // We have a connection here, but it won't contain an alert since the error
483            // is with the fragment size configured in the `ServerConfig`.
484            return Err((err, AcceptedAlert::empty()));
485        }
486        self.connection.fips = config.fips();
487
488        let state = match self.choose_config.use_config(
489            config,
490            ServerExtensionsInput::default(),
491            &mut self.connection.core.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 Debug for EarlyDataState {
569    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
570        match self {
571            Self::New => write!(f, "EarlyDataState::New"),
572            Self::Accepted { received } => write!(
573                f,
574                "EarlyDataState::Accepted {{ received: {} }}",
575                received.len(),
576            ),
577        }
578    }
579}
580
581impl ConnectionCore<ServerSide> {
582    pub(crate) fn for_server(
583        config: Arc<ServerConfig>,
584        extra_exts: ServerExtensionsInput,
585        protocol: Protocol,
586    ) -> Result<Self, Error> {
587        let mut common = CommonState::new(Side::Server, protocol);
588        common
589            .send
590            .set_max_fragment_size(config.max_fragment_size)?;
591        Ok(Self::new(
592            Box::new(ExpectClientHello::new(
593                config,
594                extra_exts,
595                Vec::new(),
596                protocol,
597            ))
598            .into(),
599            ServerConnectionData::default(),
600            common,
601        ))
602    }
603
604    pub(crate) fn for_acceptor(protocol: Protocol) -> Self {
605        Self::new(
606            ReadClientHello::new(protocol).into(),
607            ServerConnectionData::default(),
608            CommonState::new(Side::Server, protocol),
609        )
610    }
611}
612
613/// State associated with a server connection.
614#[derive(Debug, Default)]
615pub(crate) struct ServerConnectionData {
616    sni: Option<DnsName<'static>>,
617    received_resumption_data: Option<Vec<u8>>,
618    early_data: EarlyDataState,
619}
620
621impl ServerConnectionData {
622    pub(crate) fn received_resumption_data(&self) -> Option<&[u8]> {
623        self.received_resumption_data.as_deref()
624    }
625
626    pub(crate) fn server_name(&self) -> Option<&DnsName<'static>> {
627        self.sni.as_ref()
628    }
629}
630
631impl Output for ServerConnectionData {
632    fn emit(&mut self, ev: Event<'_>) {
633        match ev {
634            Event::EarlyApplicationData(data) => self
635                .early_data
636                .take_received_plaintext(data),
637            Event::EarlyData(EarlyDataEvent::Accepted) => self.early_data.accept(),
638            Event::ReceivedServerName(sni) => self.sni = sni,
639            Event::ResumptionData(data) => self.received_resumption_data = Some(data),
640            _ => unreachable!(),
641        }
642    }
643}
644
645/// State associated with a server connection.
646#[expect(clippy::exhaustive_structs)]
647#[derive(Debug)]
648pub struct ServerSide;
649
650impl crate::conn::SideData for ServerSide {}
651
652impl crate::conn::private::Side for ServerSide {
653    type Data = ServerConnectionData;
654    type State = ServerState;
655}
656
657#[cfg(test)]
658mod tests {
659    use std::format;
660
661    use super::*;
662
663    // these branches not reachable externally, unless something else goes wrong.
664    #[test]
665    fn test_read_in_new_state() {
666        assert_eq!(
667            format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
668            "Err(Kind(BrokenPipe))"
669        );
670    }
671}