Skip to main content

rustls/server/
connection.rs

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