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