rustls/server/
connection.rs

1#[cfg(feature = "std")]
2use alloc::borrow::Cow;
3use alloc::boxed::Box;
4use alloc::vec::Vec;
5use core::fmt;
6use core::fmt::{Debug, Formatter};
7use core::ops::{Deref, DerefMut};
8#[cfg(feature = "std")]
9use std::io;
10
11use pki_types::DnsName;
12
13#[cfg(feature = "std")]
14use super::config::ClientHello;
15use super::config::ServerConfig;
16use super::hs;
17#[cfg(feature = "std")]
18use super::hs::ClientHelloInput;
19#[cfg(feature = "std")]
20use crate::common_state::State;
21use crate::common_state::{CommonState, Side};
22#[cfg(feature = "std")]
23use crate::conn::ConnectionCommon;
24use crate::conn::{ConnectionCore, UnbufferedConnectionCommon};
25#[cfg(doc)]
26use crate::crypto;
27#[cfg(feature = "std")]
28use crate::crypto::SignatureScheme;
29use crate::crypto::cipher::Payload;
30use crate::error::Error;
31use crate::kernel::KernelConnection;
32#[cfg(feature = "std")]
33use crate::log::trace;
34#[cfg(feature = "std")]
35use crate::msgs::deframer::Locator;
36#[cfg(feature = "std")]
37use crate::msgs::handshake::ClientHelloPayload;
38use crate::msgs::handshake::ServerExtensionsInput;
39#[cfg(feature = "std")]
40use crate::msgs::handshake::ServerNamePayload;
41#[cfg(feature = "std")]
42use crate::msgs::message::Message;
43use crate::suites::ExtractedSecrets;
44use crate::sync::Arc;
45use crate::vecbuf::ChunkVecBuffer;
46
47#[cfg(feature = "std")]
48mod buffered {
49    use alloc::boxed::Box;
50    use core::fmt;
51    use core::fmt::{Debug, Formatter};
52    use core::ops::{Deref, DerefMut};
53    use std::io;
54
55    use pki_types::DnsName;
56
57    use super::{Accepted, Accepting, ServerConfig, ServerConnectionData, ServerExtensionsInput};
58    use crate::KeyingMaterialExporter;
59    use crate::common_state::{CommonState, Side};
60    use crate::conn::{ConnectionCommon, ConnectionCore};
61    use crate::error::{ApiMisuse, Error};
62    use crate::msgs::deframer::Locator;
63    use crate::server::hs::{ClientHelloInput, ServerContext};
64    use crate::suites::ExtractedSecrets;
65    use crate::sync::Arc;
66    use crate::vecbuf::ChunkVecBuffer;
67
68    /// This represents a single TLS server connection.
69    ///
70    /// Send TLS-protected data to the peer using the `io::Write` trait implementation.
71    /// Read data from the peer using the `io::Read` trait implementation.
72    pub struct ServerConnection {
73        pub(super) inner: ConnectionCommon<ServerConnectionData>,
74    }
75
76    impl ServerConnection {
77        /// Make a new ServerConnection.  `config` controls how
78        /// we behave in the TLS protocol.
79        pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
80            Ok(Self {
81                inner: ConnectionCommon::from(ConnectionCore::for_server(
82                    config,
83                    ServerExtensionsInput::default(),
84                )?),
85            })
86        }
87
88        /// Retrieves the server name, if any, used to select the certificate and
89        /// private key.
90        ///
91        /// This returns `None` until some time after the client's server name indication
92        /// (SNI) extension value is processed during the handshake. It will never be
93        /// `None` when the connection is ready to send or process application data,
94        /// unless the client does not support SNI.
95        ///
96        /// This is useful for application protocols that need to enforce that the
97        /// server name matches an application layer protocol hostname. For
98        /// example, HTTP/1.1 servers commonly expect the `Host:` header field of
99        /// every request on a connection to match the hostname in the SNI extension
100        /// when the client provides the SNI extension.
101        ///
102        /// The server name is also used to match sessions during session resumption.
103        pub fn server_name(&self) -> Option<&DnsName<'_>> {
104            self.inner.core.side.sni.as_ref()
105        }
106
107        /// Application-controlled portion of the resumption ticket supplied by the client, if any.
108        ///
109        /// Recovered from the prior session's `set_resumption_data`. Integrity is guaranteed by rustls.
110        ///
111        /// Returns `Some` if and only if a valid resumption ticket has been received from the client.
112        pub fn received_resumption_data(&self) -> Option<&[u8]> {
113            self.inner
114                .core
115                .side
116                .received_resumption_data
117                .as_ref()
118                .map(|x| &x[..])
119        }
120
121        /// Set the resumption data to embed in future resumption tickets supplied to the client.
122        ///
123        /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
124        /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
125        /// resumption tickets are affected.
126        ///
127        /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
128        /// from the client is desired, encrypt the data separately.
129        pub fn set_resumption_data(&mut self, data: &[u8]) {
130            assert!(data.len() < 2usize.pow(15));
131            self.inner.core.side.resumption_data = data.into();
132        }
133
134        /// Explicitly discard early data, notifying the client
135        ///
136        /// Useful if invariants encoded in `received_resumption_data()` cannot be respected.
137        ///
138        /// Must be called while `is_handshaking` is true.
139        pub fn reject_early_data(&mut self) {
140            self.inner.core.reject_early_data()
141        }
142
143        /// Returns an `io::Read` implementer you can read bytes from that are
144        /// received from a client as TLS1.3 0RTT/"early" data, during the handshake.
145        ///
146        /// This returns `None` in many circumstances, such as :
147        ///
148        /// - Early data is disabled if [`ServerConfig::max_early_data_size`] is zero (the default).
149        /// - The session negotiated with the client is not TLS1.3.
150        /// - The client just doesn't support early data.
151        /// - The connection doesn't resume an existing session.
152        /// - The client hasn't sent a full ClientHello yet.
153        pub fn early_data(&mut self) -> Option<ReadEarlyData<'_>> {
154            if self
155                .inner
156                .core
157                .side
158                .early_data
159                .was_accepted()
160            {
161                Some(ReadEarlyData::new(&mut self.inner))
162            } else {
163                None
164            }
165        }
166
167        /// Return true if the connection was made with a `ServerConfig` that is FIPS compatible.
168        ///
169        /// This is different from [`crate::crypto::CryptoProvider::fips()`]:
170        /// it is concerned only with cryptography, whereas this _also_ covers TLS-level
171        /// configuration that NIST recommends, as well as ECH HPKE suites if applicable.
172        pub fn fips(&self) -> bool {
173            self.inner.core.common_state.fips
174        }
175
176        /// Extract secrets, so they can be used when configuring kTLS, for example.
177        /// Should be used with care as it exposes secret key material.
178        pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
179            self.inner.dangerous_extract_secrets()
180        }
181    }
182
183    impl Debug for ServerConnection {
184        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
185            f.debug_struct("ServerConnection")
186                .finish()
187        }
188    }
189
190    impl Deref for ServerConnection {
191        type Target = ConnectionCommon<ServerConnectionData>;
192
193        fn deref(&self) -> &Self::Target {
194            &self.inner
195        }
196    }
197
198    impl DerefMut for ServerConnection {
199        fn deref_mut(&mut self) -> &mut Self::Target {
200            &mut self.inner
201        }
202    }
203
204    impl From<ServerConnection> for crate::Connection {
205        fn from(conn: ServerConnection) -> Self {
206            Self::Server(conn)
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`][super::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    /// ```
256    pub struct Acceptor {
257        inner: Option<ConnectionCommon<ServerConnectionData>>,
258    }
259
260    impl 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(
265                    ConnectionCore::new(
266                        Box::new(Accepting),
267                        ServerConnectionData::default(),
268                        CommonState::new(Side::Server),
269                    )
270                    .into(),
271                ),
272            }
273        }
274    }
275
276    impl Acceptor {
277        /// Read TLS content from `rd`.
278        ///
279        /// Returns an error if this `Acceptor` has already yielded an [`Accepted`]. For more details,
280        /// refer to [`Connection::read_tls()`].
281        ///
282        /// [`Connection::read_tls()`]: crate::Connection::read_tls
283        pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
284            match &mut self.inner {
285                Some(conn) => conn.read_tls(rd),
286                None => Err(io::Error::other(
287                    "acceptor cannot read after successful acceptance",
288                )),
289            }
290        }
291
292        /// Check if a `ClientHello` message has been received.
293        ///
294        /// Returns `Ok(None)` if the complete `ClientHello` has not yet been received.
295        /// Do more I/O and then call this function again.
296        ///
297        /// Returns `Ok(Some(accepted))` if the connection has been accepted. Call
298        /// `accepted.into_connection()` to continue. Do not call this function again.
299        ///
300        /// Returns `Err((err, alert))` if an error occurred. If an alert is returned, the
301        /// application should call `alert.write()` to send the alert to the client. It should
302        /// not call `accept()` again.
303        pub fn accept(&mut self) -> Result<Option<Accepted>, (Error, AcceptedAlert)> {
304            let Some(mut connection) = self.inner.take() else {
305                return Err((
306                    ApiMisuse::AcceptorPolledAfterCompletion.into(),
307                    AcceptedAlert::empty(),
308                ));
309            };
310
311            let message = match connection.first_handshake_message() {
312                Ok(Some(msg)) => msg,
313                Ok(None) => {
314                    self.inner = Some(connection);
315                    return Ok(None);
316                }
317                Err(err) => return Err(AcceptedAlert::from_error(err, connection)),
318            };
319
320            let mut cx = ServerContext {
321                common: &mut connection.core.common_state,
322                data: &mut connection.core.side,
323                // `ClientHelloInput::from_message` won't read borrowed plaintext
324                plaintext_locator: &Locator::new(&[]),
325                received_plaintext: &mut None,
326                sendable_plaintext: Some(&mut connection.sendable_plaintext),
327            };
328
329            let sig_schemes = match ClientHelloInput::from_message(&message, false, &mut cx) {
330                Ok(ClientHelloInput { sig_schemes, .. }) => sig_schemes,
331                Err(err) => {
332                    return Err(AcceptedAlert::from_error(err, connection));
333                }
334            };
335            debug_assert!(cx.received_plaintext.is_none(), "read plaintext");
336
337            Ok(Some(Accepted {
338                connection,
339                message,
340                sig_schemes,
341            }))
342        }
343    }
344
345    /// Represents a TLS alert resulting from handling the client's `ClientHello` message.
346    ///
347    /// When [`Acceptor::accept()`] returns an error, it yields an `AcceptedAlert` such that the
348    /// application can communicate failure to the client via [`AcceptedAlert::write()`].
349    pub struct AcceptedAlert(ChunkVecBuffer);
350
351    impl AcceptedAlert {
352        pub(super) fn from_error(
353            error: Error,
354            mut conn: ConnectionCommon<ServerConnectionData>,
355        ) -> (Error, Self) {
356            conn.core
357                .common_state
358                .maybe_send_fatal_alert(&error);
359            (error, Self(conn.core.common_state.sendable_tls))
360        }
361
362        pub(super) fn empty() -> Self {
363            Self(ChunkVecBuffer::new(None))
364        }
365
366        /// Send the alert to the client.
367        ///
368        /// To account for short writes this function should be called repeatedly until it
369        /// returns `Ok(0)` or an error.
370        pub fn write(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
371            self.0.write_to(wr)
372        }
373
374        /// Send the alert to the client.
375        ///
376        /// This function will invoke the writer until the buffer is empty.
377        pub fn write_all(&mut self, wr: &mut dyn io::Write) -> Result<(), io::Error> {
378            while self.write(wr)? != 0 {}
379            Ok(())
380        }
381    }
382
383    impl Debug for AcceptedAlert {
384        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
385            f.debug_struct("AcceptedAlert").finish()
386        }
387    }
388
389    /// Allows reading of early data in resumed TLS1.3 connections.
390    ///
391    /// "Early data" is also known as "0-RTT data".
392    ///
393    /// This type implements [`io::Read`].
394    pub struct ReadEarlyData<'a> {
395        common: &'a mut ConnectionCommon<ServerConnectionData>,
396    }
397
398    impl<'a> ReadEarlyData<'a> {
399        fn new(common: &'a mut ConnectionCommon<ServerConnectionData>) -> Self {
400            ReadEarlyData { common }
401        }
402
403        /// Returns the "early" exporter that can derive key material for use in early data
404        ///
405        /// See [RFC5705][] for general details on what exporters are, and [RFC8446 S7.5][] for
406        /// specific details on the "early" exporter.
407        ///
408        /// **Beware** that the early exporter requires care, as it is subject to the same
409        /// potential for replay as early data itself.  See [RFC8446 appendix E.5.1][] for
410        /// more detail.
411        ///
412        /// This function can be called at most once per connection. This function will error:
413        /// if called more than once per connection.
414        ///
415        /// If you are looking for the normal exporter, this is available from
416        /// [`ConnectionCommon::exporter()`].
417        ///
418        /// [RFC5705]: https://datatracker.ietf.org/doc/html/rfc5705
419        /// [RFC8446 S7.5]: https://datatracker.ietf.org/doc/html/rfc8446#section-7.5
420        /// [RFC8446 appendix E.5.1]: https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.5.1
421        /// [`ConnectionCommon::exporter()`]: crate::conn::ConnectionCommon::exporter()
422        pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error> {
423            self.common.core.early_exporter()
424        }
425    }
426
427    impl io::Read for ReadEarlyData<'_> {
428        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
429            self.common
430                .core
431                .side
432                .early_data
433                .read(buf)
434        }
435    }
436}
437#[cfg(feature = "std")]
438pub use buffered::{AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection};
439
440/// Unbuffered version of `ServerConnection`
441///
442/// See the [`crate::unbuffered`] module docs for more details
443pub struct UnbufferedServerConnection {
444    inner: UnbufferedConnectionCommon<ServerConnectionData>,
445}
446
447impl UnbufferedServerConnection {
448    /// Make a new ServerConnection. `config` controls how we behave in the TLS protocol.
449    pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
450        Ok(Self {
451            inner: UnbufferedConnectionCommon::from(ConnectionCore::for_server(
452                config,
453                ServerExtensionsInput::default(),
454            )?),
455        })
456    }
457
458    /// Extract secrets, so they can be used when configuring kTLS, for example.
459    /// Should be used with care as it exposes secret key material.
460    #[deprecated = "dangerous_extract_secrets() does not support session tickets or \
461                    key updates, use dangerous_into_kernel_connection() instead"]
462    pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
463        self.inner.dangerous_extract_secrets()
464    }
465
466    /// Extract secrets and an [`KernelConnection`] object.
467    ///
468    /// This allows you use rustls to manage keys and then manage encryption and
469    /// decryption yourself (e.g. for kTLS).
470    ///
471    /// Should be used with care as it exposes secret key material.
472    ///
473    /// See the [`crate::kernel`] documentations for details on prerequisites
474    /// for calling this method.
475    pub fn dangerous_into_kernel_connection(
476        self,
477    ) -> Result<(ExtractedSecrets, KernelConnection<ServerConnectionData>), Error> {
478        self.inner
479            .core
480            .dangerous_into_kernel_connection()
481    }
482}
483
484impl Deref for UnbufferedServerConnection {
485    type Target = UnbufferedConnectionCommon<ServerConnectionData>;
486
487    fn deref(&self) -> &Self::Target {
488        &self.inner
489    }
490}
491
492impl DerefMut for UnbufferedServerConnection {
493    fn deref_mut(&mut self) -> &mut Self::Target {
494        &mut self.inner
495    }
496}
497
498impl UnbufferedConnectionCommon<ServerConnectionData> {
499    pub(crate) fn pop_early_data(&mut self) -> Option<Vec<u8>> {
500        self.core.side.early_data.pop()
501    }
502
503    pub(crate) fn peek_early_data(&self) -> Option<&[u8]> {
504        self.core.side.early_data.peek()
505    }
506}
507
508/// Represents a `ClientHello` message received through the [`Acceptor`].
509///
510/// Contains the state required to resume the connection through [`Accepted::into_connection()`].
511#[cfg(feature = "std")]
512pub struct Accepted {
513    connection: ConnectionCommon<ServerConnectionData>,
514    message: Message<'static>,
515    sig_schemes: Vec<SignatureScheme>,
516}
517
518#[cfg(feature = "std")]
519impl Accepted {
520    /// Get the [`ClientHello`] for this connection.
521    pub fn client_hello(&self) -> ClientHello<'_> {
522        let payload = Self::client_hello_payload(&self.message);
523        let server_name = payload
524            .server_name
525            .as_ref()
526            .and_then(ServerNamePayload::to_dns_name_normalized)
527            .map(Cow::Owned);
528        let ch = ClientHello {
529            server_name,
530            signature_schemes: &self.sig_schemes,
531            alpn: payload.protocols.as_ref(),
532            server_cert_types: payload
533                .server_certificate_types
534                .as_deref(),
535            client_cert_types: payload
536                .client_certificate_types
537                .as_deref(),
538            cipher_suites: &payload.cipher_suites,
539            certificate_authorities: payload
540                .certificate_authority_names
541                .as_deref(),
542            named_groups: payload.named_groups.as_deref(),
543        };
544
545        trace!("Accepted::client_hello(): {ch:#?}");
546        ch
547    }
548
549    /// Convert the [`Accepted`] into a [`ServerConnection`].
550    ///
551    /// Takes the state returned from [`Acceptor::accept()`] as well as the [`ServerConfig`] that
552    /// should be used for the session. Returns an error if configuration-dependent validation of
553    /// the received `ClientHello` message fails.
554    pub fn into_connection(
555        mut self,
556        config: Arc<ServerConfig>,
557    ) -> Result<ServerConnection, (Error, AcceptedAlert)> {
558        if let Err(err) = self
559            .connection
560            .set_max_fragment_size(config.max_fragment_size)
561        {
562            // We have a connection here, but it won't contain an alert since the error
563            // is with the fragment size configured in the `ServerConfig`.
564            return Err((err, AcceptedAlert::empty()));
565        }
566
567        self.connection.enable_secret_extraction = config.enable_secret_extraction;
568
569        let state = hs::ExpectClientHello::new(config, ServerExtensionsInput::default());
570        let proof = match self
571            .connection
572            .core
573            .common_state
574            .check_aligned_handshake()
575        {
576            Ok(proof) => proof,
577            Err(err) => return Err(AcceptedAlert::from_error(err, self.connection)),
578        };
579        let mut cx = hs::ServerContext {
580            common: &mut self.connection.core.common_state,
581            data: &mut self.connection.core.side,
582            // `ExpectClientHello::with_input` won't read borrowed plaintext
583            plaintext_locator: &Locator::new(&[]),
584            received_plaintext: &mut None,
585            sendable_plaintext: Some(&mut self.connection.sendable_plaintext),
586        };
587
588        let input = ClientHelloInput {
589            client_hello: Self::client_hello_payload(&self.message),
590            message: &self.message,
591            sig_schemes: self.sig_schemes,
592            proof,
593        };
594
595        let new = match state.with_input(input, &mut cx) {
596            Ok(new) => new,
597            Err(err) => return Err(AcceptedAlert::from_error(err, self.connection)),
598        };
599        debug_assert!(cx.received_plaintext.is_none(), "read plaintext");
600
601        self.connection.replace_state(new);
602        Ok(ServerConnection {
603            inner: self.connection,
604        })
605    }
606
607    fn client_hello_payload<'a>(message: &'a Message<'_>) -> &'a ClientHelloPayload {
608        match &message.payload {
609            crate::msgs::message::MessagePayload::Handshake { parsed, .. } => match &parsed.0 {
610                crate::msgs::handshake::HandshakePayload::ClientHello(ch) => ch,
611                _ => unreachable!(),
612            },
613            _ => unreachable!(),
614        }
615    }
616}
617
618#[cfg(feature = "std")]
619impl Debug for Accepted {
620    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
621        f.debug_struct("Accepted").finish()
622    }
623}
624
625#[cfg(feature = "std")]
626struct Accepting;
627
628#[cfg(feature = "std")]
629impl State<ServerConnectionData> for Accepting {
630    #[cfg_attr(coverage_nightly, coverage(off))]
631    fn handle<'m>(
632        self: Box<Self>,
633        _cx: &mut hs::ServerContext<'_>,
634        _m: Message<'m>,
635    ) -> Result<Box<dyn State<ServerConnectionData>>, Error> {
636        Err(Error::Unreachable("unreachable state"))
637    }
638}
639
640#[derive(Default)]
641pub(super) enum EarlyDataState {
642    #[default]
643    New,
644    Accepted {
645        received: ChunkVecBuffer,
646        left: usize,
647    },
648    Rejected,
649}
650
651impl EarlyDataState {
652    pub(super) fn reject(&mut self) {
653        *self = Self::Rejected;
654    }
655
656    pub(super) fn accept(&mut self, max_size: usize) {
657        *self = Self::Accepted {
658            received: ChunkVecBuffer::new(Some(max_size)),
659            left: max_size,
660        };
661    }
662
663    #[cfg(feature = "std")]
664    fn was_accepted(&self) -> bool {
665        matches!(self, Self::Accepted { .. })
666    }
667
668    pub(super) fn was_rejected(&self) -> bool {
669        matches!(self, Self::Rejected)
670    }
671
672    fn peek(&self) -> Option<&[u8]> {
673        match self {
674            Self::Accepted { received, .. } => received.peek(),
675            _ => None,
676        }
677    }
678
679    fn pop(&mut self) -> Option<Vec<u8>> {
680        match self {
681            Self::Accepted { received, .. } => received.pop(),
682            _ => None,
683        }
684    }
685
686    #[cfg(feature = "std")]
687    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
688        match self {
689            Self::Accepted { received, .. } => received.read(buf),
690            _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
691        }
692    }
693
694    pub(super) fn take_received_plaintext(&mut self, bytes: Payload<'_>) -> bool {
695        let available = bytes.bytes().len();
696        let Self::Accepted { received, left } = self else {
697            return false;
698        };
699
700        if received.apply_limit(available) != available || available > *left {
701            return false;
702        }
703
704        received.append(bytes.into_vec());
705        *left -= available;
706        true
707    }
708}
709
710impl Debug for EarlyDataState {
711    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
712        match self {
713            Self::New => write!(f, "EarlyDataState::New"),
714            Self::Accepted { received, left } => write!(
715                f,
716                "EarlyDataState::Accepted {{ received: {}, left: {} }}",
717                received.len(),
718                left
719            ),
720            Self::Rejected => write!(f, "EarlyDataState::Rejected"),
721        }
722    }
723}
724
725impl ConnectionCore<ServerConnectionData> {
726    pub(crate) fn for_server(
727        config: Arc<ServerConfig>,
728        extra_exts: ServerExtensionsInput<'static>,
729    ) -> Result<Self, Error> {
730        let mut common = CommonState::new(Side::Server);
731        common.set_max_fragment_size(config.max_fragment_size)?;
732        common.enable_secret_extraction = config.enable_secret_extraction;
733        common.fips = config.fips();
734        Ok(Self::new(
735            Box::new(hs::ExpectClientHello::new(config, extra_exts)),
736            ServerConnectionData::default(),
737            common,
738        ))
739    }
740
741    #[cfg(feature = "std")]
742    pub(crate) fn reject_early_data(&mut self) {
743        assert!(
744            self.common_state.is_handshaking(),
745            "cannot retroactively reject early data"
746        );
747        self.side.early_data.reject();
748    }
749}
750
751/// State associated with a server connection.
752#[derive(Default, Debug)]
753pub struct ServerConnectionData {
754    pub(crate) sni: Option<DnsName<'static>>,
755    pub(crate) received_resumption_data: Option<Vec<u8>>,
756    pub(crate) resumption_data: Vec<u8>,
757    pub(super) early_data: EarlyDataState,
758}
759
760impl crate::conn::SideData for ServerConnectionData {}
761
762#[cfg(feature = "std")]
763#[cfg(test)]
764mod tests {
765    use std::format;
766
767    use super::*;
768
769    // these branches not reachable externally, unless something else goes wrong.
770    #[test]
771    fn test_read_in_new_state() {
772        assert_eq!(
773            format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
774            "Err(Kind(BrokenPipe))"
775        );
776    }
777}