rustls/server/server_conn.rs
1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt;
4use core::fmt::{Debug, Formatter};
5use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut};
7#[cfg(feature = "std")]
8use std::io;
9
10use pki_types::{DnsName, UnixTime};
11
12use super::hs;
13#[cfg(feature = "std")]
14use crate::WantsVerifier;
15use crate::builder::ConfigBuilder;
16use crate::common_state::{CommonState, Side};
17#[cfg(feature = "std")]
18use crate::common_state::{Protocol, State};
19use crate::conn::{ConnectionCommon, ConnectionCore, UnbufferedConnectionCommon};
20#[cfg(doc)]
21use crate::crypto;
22use crate::crypto::CryptoProvider;
23use crate::enums::{CertificateType, CipherSuite, ProtocolVersion, SignatureScheme};
24use crate::error::Error;
25use crate::kernel::KernelConnection;
26use crate::log::trace;
27use crate::msgs::base::Payload;
28use crate::msgs::handshake::{ClientHelloPayload, ProtocolName, ServerExtensionsInput};
29use crate::msgs::message::Message;
30use crate::suites::ExtractedSecrets;
31use crate::sync::Arc;
32#[cfg(feature = "std")]
33use crate::time_provider::DefaultTimeProvider;
34use crate::time_provider::TimeProvider;
35use crate::vecbuf::ChunkVecBuffer;
36use crate::{
37 DistinguishedName, KeyLog, NamedGroup, WantsVersions, compress, sign, verify, versions,
38};
39
40/// A trait for the ability to store server session data.
41///
42/// The keys and values are opaque.
43///
44/// Inserted keys are randomly chosen by the library and have
45/// no internal structure (in other words, you may rely on all
46/// bits being uniformly random). Queried keys are untrusted data.
47///
48/// Both the keys and values should be treated as
49/// **highly sensitive data**, containing enough key material
50/// to break all security of the corresponding sessions.
51///
52/// Implementations can be lossy (in other words, forgetting
53/// key/value pairs) without any negative security consequences.
54///
55/// However, note that `take` **must** reliably delete a returned
56/// value. If it does not, there may be security consequences.
57///
58/// `put` and `take` are mutating operations; this isn't expressed
59/// in the type system to allow implementations freedom in
60/// how to achieve interior mutability. `Mutex` is a common
61/// choice.
62pub trait StoresServerSessions: Debug + Send + Sync {
63 /// Store session secrets encoded in `value` against `key`,
64 /// overwrites any existing value against `key`. Returns `true`
65 /// if the value was stored.
66 fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool;
67
68 /// Find a value with the given `key`. Return it, or None
69 /// if it doesn't exist.
70 fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
71
72 /// Find a value with the given `key`. Return it and delete it;
73 /// or None if it doesn't exist.
74 fn take(&self, key: &[u8]) -> Option<Vec<u8>>;
75
76 /// Whether the store can cache another session. This is used to indicate to clients
77 /// whether their session can be resumed; the implementation is not required to remember
78 /// a session even if it returns `true` here.
79 fn can_cache(&self) -> bool;
80}
81
82/// A trait for the ability to encrypt and decrypt tickets.
83pub trait ProducesTickets: Debug + Send + Sync {
84 /// Returns true if this implementation will encrypt/decrypt
85 /// tickets. Should return false if this is a dummy
86 /// implementation: the server will not send the SessionTicket
87 /// extension and will not call the other functions.
88 fn enabled(&self) -> bool;
89
90 /// Returns the lifetime in seconds of tickets produced now.
91 /// The lifetime is provided as a hint to clients that the
92 /// ticket will not be useful after the given time.
93 ///
94 /// This lifetime must be implemented by key rolling and
95 /// erasure, *not* by storing a lifetime in the ticket.
96 ///
97 /// The objective is to limit damage to forward secrecy caused
98 /// by tickets, not just limiting their lifetime.
99 fn lifetime(&self) -> u32;
100
101 /// Encrypt and authenticate `plain`, returning the resulting
102 /// ticket. Return None if `plain` cannot be encrypted for
103 /// some reason: an empty ticket will be sent and the connection
104 /// will continue.
105 fn encrypt(&self, plain: &[u8]) -> Option<Vec<u8>>;
106
107 /// Decrypt `cipher`, validating its authenticity protection
108 /// and recovering the plaintext. `cipher` is fully attacker
109 /// controlled, so this decryption must be side-channel free,
110 /// panic-proof, and otherwise bullet-proof. If the decryption
111 /// fails, return None.
112 fn decrypt(&self, cipher: &[u8]) -> Option<Vec<u8>>;
113}
114
115/// How to choose a certificate chain and signing key for use
116/// in server authentication.
117///
118/// This is suitable when selecting a certificate does not require
119/// I/O or when the application is using blocking I/O anyhow.
120///
121/// For applications that use async I/O and need to do I/O to choose
122/// a certificate (for instance, fetching a certificate from a data store),
123/// the [`Acceptor`] interface is more suitable.
124pub trait ResolvesServerCert: Debug + Send + Sync {
125 /// Choose a certificate chain and matching key given simplified
126 /// ClientHello information.
127 ///
128 /// Return `None` to abort the handshake.
129 fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<sign::CertifiedKey>>;
130
131 /// Return true when the server only supports raw public keys.
132 fn only_raw_public_keys(&self) -> bool {
133 false
134 }
135}
136
137/// A struct representing the received Client Hello
138#[derive(Debug)]
139pub struct ClientHello<'a> {
140 pub(super) server_name: &'a Option<DnsName<'a>>,
141 pub(super) signature_schemes: &'a [SignatureScheme],
142 pub(super) alpn: Option<&'a Vec<ProtocolName>>,
143 pub(super) server_cert_types: Option<&'a [CertificateType]>,
144 pub(super) client_cert_types: Option<&'a [CertificateType]>,
145 pub(super) cipher_suites: &'a [CipherSuite],
146 /// The [certificate_authorities] extension, if it was sent by the client.
147 ///
148 /// [certificate_authorities]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
149 pub(super) certificate_authorities: Option<&'a [DistinguishedName]>,
150 pub(super) named_groups: Option<&'a [NamedGroup]>,
151}
152
153impl<'a> ClientHello<'a> {
154 /// Get the server name indicator.
155 ///
156 /// Returns `None` if the client did not supply a SNI.
157 pub fn server_name(&self) -> Option<&str> {
158 self.server_name
159 .as_ref()
160 .map(<DnsName<'_> as AsRef<str>>::as_ref)
161 }
162
163 /// Get the compatible signature schemes.
164 ///
165 /// Returns standard-specified default if the client omitted this extension.
166 pub fn signature_schemes(&self) -> &[SignatureScheme] {
167 self.signature_schemes
168 }
169
170 /// Get the ALPN protocol identifiers submitted by the client.
171 ///
172 /// Returns `None` if the client did not include an ALPN extension.
173 ///
174 /// Application Layer Protocol Negotiation (ALPN) is a TLS extension that lets a client
175 /// submit a set of identifiers that each a represent an application-layer protocol.
176 /// The server will then pick its preferred protocol from the set submitted by the client.
177 /// Each identifier is represented as a byte array, although common values are often ASCII-encoded.
178 /// See the official RFC-7301 specifications at <https://datatracker.ietf.org/doc/html/rfc7301>
179 /// for more information on ALPN.
180 ///
181 /// For example, a HTTP client might specify "http/1.1" and/or "h2". Other well-known values
182 /// are listed in the at IANA registry at
183 /// <https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>.
184 ///
185 /// The server can specify supported ALPN protocols by setting [`ServerConfig::alpn_protocols`].
186 /// During the handshake, the server will select the first protocol configured that the client supports.
187 pub fn alpn(&self) -> Option<impl Iterator<Item = &'a [u8]>> {
188 self.alpn.map(|protocols| {
189 protocols
190 .iter()
191 .map(|proto| proto.as_ref())
192 })
193 }
194
195 /// Get cipher suites.
196 pub fn cipher_suites(&self) -> &[CipherSuite] {
197 self.cipher_suites
198 }
199
200 /// Get the server certificate types offered in the ClientHello.
201 ///
202 /// Returns `None` if the client did not include a certificate type extension.
203 pub fn server_cert_types(&self) -> Option<&'a [CertificateType]> {
204 self.server_cert_types
205 }
206
207 /// Get the client certificate types offered in the ClientHello.
208 ///
209 /// Returns `None` if the client did not include a certificate type extension.
210 pub fn client_cert_types(&self) -> Option<&'a [CertificateType]> {
211 self.client_cert_types
212 }
213
214 /// Get the [certificate_authorities] extension sent by the client.
215 ///
216 /// Returns `None` if the client did not send this extension.
217 ///
218 /// [certificate_authorities]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.4
219 pub fn certificate_authorities(&self) -> Option<&'a [DistinguishedName]> {
220 self.certificate_authorities
221 }
222
223 /// Get the [`named_groups`] extension sent by the client.
224 ///
225 /// This means different things in different versions of TLS:
226 ///
227 /// Originally it was introduced as the "[`elliptic_curves`]" extension for TLS1.2.
228 /// It described the elliptic curves supported by a client for all purposes: key
229 /// exchange, signature verification (for server authentication), and signing (for
230 /// client auth). Later [RFC7919] extended this to include FFDHE "named groups",
231 /// but FFDHE groups in this context only relate to key exchange.
232 ///
233 /// In TLS1.3 it was renamed to "[`named_groups`]" and now describes all types
234 /// of key exchange mechanisms, and does not relate at all to elliptic curves
235 /// used for signatures.
236 ///
237 /// [`elliptic_curves`]: https://datatracker.ietf.org/doc/html/rfc4492#section-5.1.1
238 /// [RFC7919]: https://datatracker.ietf.org/doc/html/rfc7919#section-2
239 /// [`named_groups`]:https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.7
240 pub fn named_groups(&self) -> Option<&'a [NamedGroup]> {
241 self.named_groups
242 }
243}
244
245/// Common configuration for a set of server sessions.
246///
247/// Making one of these is cheap, though one of the inputs may be expensive: gathering trust roots
248/// from the operating system to add to the [`RootCertStore`] passed to a `ClientCertVerifier`
249/// builder may take on the order of a few hundred milliseconds.
250///
251/// These must be created via the [`ServerConfig::builder()`] or [`ServerConfig::builder_with_provider()`]
252/// function.
253///
254/// # Defaults
255///
256/// * [`ServerConfig::max_fragment_size`]: the default is `None` (meaning 16kB).
257/// * [`ServerConfig::session_storage`]: if the `std` feature is enabled, the default stores 256
258/// sessions in memory. If the `std` feature is not enabled, the default is to not store any
259/// sessions. In a no-std context, by enabling the `hashbrown` feature you may provide your
260/// own `session_storage` using [`ServerSessionMemoryCache`] and a `crate::lock::MakeMutex`
261/// implementation.
262/// * [`ServerConfig::alpn_protocols`]: the default is empty -- no ALPN protocol is negotiated.
263/// * [`ServerConfig::key_log`]: key material is not logged.
264/// * [`ServerConfig::send_tls13_tickets`]: 2 tickets are sent.
265/// * [`ServerConfig::cert_compressors`]: depends on the crate features, see [`compress::default_cert_compressors()`].
266/// * [`ServerConfig::cert_compression_cache`]: caches the most recently used 4 compressions
267/// * [`ServerConfig::cert_decompressors`]: depends on the crate features, see [`compress::default_cert_decompressors()`].
268///
269/// # Sharing resumption storage between `ServerConfig`s
270///
271/// In a program using many `ServerConfig`s it may improve resumption rates
272/// (which has a significant impact on connection performance) if those
273/// configs share [`ServerConfig::session_storage`] or [`ServerConfig::ticketer`].
274///
275/// However, caution is needed: other fields influence the security of a session
276/// and resumption between them can be surprising. If sharing
277/// [`ServerConfig::session_storage`] or [`ServerConfig::ticketer`] between two
278/// `ServerConfig`s, you should also evaluate the following fields and ensure
279/// they are equivalent:
280///
281/// * `ServerConfig::verifier` -- client authentication requirements,
282/// * [`ServerConfig::cert_resolver`] -- server identities.
283///
284/// To illustrate, imagine two `ServerConfig`s `A` and `B`. `A` requires
285/// client authentication, `B` does not. If `A` and `B` shared a resumption store,
286/// it would be possible for a session originated by `B` (that is, an unauthenticated client)
287/// to be inserted into the store, and then resumed by `A`. This would give a false
288/// impression to the user of `A` that the client was authenticated. This is possible
289/// whether the resumption is performed statefully (via [`ServerConfig::session_storage`])
290/// or statelessly (via [`ServerConfig::ticketer`]).
291///
292/// _Unlike_ `ClientConfig`, rustls does not enforce any policy here.
293///
294/// [`RootCertStore`]: crate::RootCertStore
295/// [`ServerSessionMemoryCache`]: crate::server::handy::ServerSessionMemoryCache
296#[derive(Clone, Debug)]
297pub struct ServerConfig {
298 /// Source of randomness and other crypto.
299 pub(super) provider: Arc<CryptoProvider>,
300
301 /// Ignore the client's ciphersuite order. Instead,
302 /// choose the top ciphersuite in the server list
303 /// which is supported by the client.
304 pub ignore_client_order: bool,
305
306 /// The maximum size of plaintext input to be emitted in a single TLS record.
307 /// A value of None is equivalent to the [TLS maximum] of 16 kB.
308 ///
309 /// rustls enforces an arbitrary minimum of 32 bytes for this field.
310 /// Out of range values are reported as errors from [ServerConnection::new].
311 ///
312 /// Setting this value to a little less than the TCP MSS may improve latency
313 /// for stream-y workloads.
314 ///
315 /// [TLS maximum]: https://datatracker.ietf.org/doc/html/rfc8446#section-5.1
316 /// [ServerConnection::new]: crate::server::ServerConnection::new
317 pub max_fragment_size: Option<usize>,
318
319 /// How to store client sessions.
320 ///
321 /// See [ServerConfig#sharing-resumption-storage-between-serverconfigs]
322 /// for a warning related to this field.
323 pub session_storage: Arc<dyn StoresServerSessions>,
324
325 /// How to produce tickets.
326 ///
327 /// See [ServerConfig#sharing-resumption-storage-between-serverconfigs]
328 /// for a warning related to this field.
329 pub ticketer: Arc<dyn ProducesTickets>,
330
331 /// How to choose a server cert and key. This is usually set by
332 /// [ConfigBuilder::with_single_cert] or [ConfigBuilder::with_cert_resolver].
333 /// For async applications, see also [Acceptor].
334 pub cert_resolver: Arc<dyn ResolvesServerCert>,
335
336 /// Protocol names we support, most preferred first.
337 /// If empty we don't do ALPN at all.
338 pub alpn_protocols: Vec<Vec<u8>>,
339
340 /// Supported protocol versions, in no particular order.
341 /// The default is all supported versions.
342 pub(super) versions: versions::EnabledVersions,
343
344 /// How to verify client certificates.
345 pub(super) verifier: Arc<dyn verify::ClientCertVerifier>,
346
347 /// How to output key material for debugging. The default
348 /// does nothing.
349 pub key_log: Arc<dyn KeyLog>,
350
351 /// Allows traffic secrets to be extracted after the handshake,
352 /// e.g. for kTLS setup.
353 pub enable_secret_extraction: bool,
354
355 /// Amount of early data to accept for sessions created by
356 /// this config. Specify 0 to disable early data. The
357 /// default is 0.
358 ///
359 /// Read the early data via [`ServerConnection::early_data`].
360 ///
361 /// The units for this are _both_ plaintext bytes, _and_ ciphertext
362 /// bytes, depending on whether the server accepts a client's early_data
363 /// or not. It is therefore recommended to include some slop in
364 /// this value to account for the unknown amount of ciphertext
365 /// expansion in the latter case.
366 pub max_early_data_size: u32,
367
368 /// Whether the server should send "0.5RTT" data. This means the server
369 /// sends data after its first flight of handshake messages, without
370 /// waiting for the client to complete the handshake.
371 ///
372 /// This can improve TTFB latency for either server-speaks-first protocols,
373 /// or client-speaks-first protocols when paired with "0RTT" data. This
374 /// comes at the cost of a subtle weakening of the normal handshake
375 /// integrity guarantees that TLS provides. Note that the initial
376 /// `ClientHello` is indirectly authenticated because it is included
377 /// in the transcript used to derive the keys used to encrypt the data.
378 ///
379 /// This only applies to TLS1.3 connections. TLS1.2 connections cannot
380 /// do this optimisation and this setting is ignored for them. It is
381 /// also ignored for TLS1.3 connections that even attempt client
382 /// authentication.
383 ///
384 /// This defaults to false. This means the first application data
385 /// sent by the server comes after receiving and validating the client's
386 /// handshake up to the `Finished` message. This is the safest option.
387 pub send_half_rtt_data: bool,
388
389 /// How many TLS1.3 tickets to send immediately after a successful
390 /// handshake.
391 ///
392 /// Because TLS1.3 tickets are single-use, this allows
393 /// a client to perform multiple resumptions.
394 ///
395 /// The default is 2.
396 ///
397 /// If this is 0, no tickets are sent and clients will not be able to
398 /// do any resumption.
399 pub send_tls13_tickets: usize,
400
401 /// If set to `true`, requires the client to support the extended
402 /// master secret extraction method defined in [RFC 7627].
403 ///
404 /// The default is `true` if the "fips" crate feature is enabled,
405 /// `false` otherwise.
406 ///
407 /// It must be set to `true` to meet FIPS requirement mentioned in section
408 /// **D.Q Transition of the TLS 1.2 KDF to Support the Extended Master
409 /// Secret** from [FIPS 140-3 IG.pdf].
410 ///
411 /// [RFC 7627]: https://datatracker.ietf.org/doc/html/rfc7627
412 /// [FIPS 140-3 IG.pdf]: https://csrc.nist.gov/csrc/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf
413 #[cfg(feature = "tls12")]
414 pub require_ems: bool,
415
416 /// Provides the current system time
417 pub time_provider: Arc<dyn TimeProvider>,
418
419 /// How to compress the server's certificate chain.
420 ///
421 /// If a client supports this extension, and advertises support
422 /// for one of the compression algorithms included here, the
423 /// server certificate will be compressed according to [RFC8779].
424 ///
425 /// This only applies to TLS1.3 connections. It is ignored for
426 /// TLS1.2 connections.
427 ///
428 /// [RFC8779]: https://datatracker.ietf.org/doc/rfc8879/
429 pub cert_compressors: Vec<&'static dyn compress::CertCompressor>,
430
431 /// Caching for compressed certificates.
432 ///
433 /// This is optional: [`compress::CompressionCache::Disabled`] gives
434 /// a cache that does no caching.
435 pub cert_compression_cache: Arc<compress::CompressionCache>,
436
437 /// How to decompress the clients's certificate chain.
438 ///
439 /// If this is non-empty, the [RFC8779] certificate compression
440 /// extension is offered when requesting client authentication,
441 /// and any compressed certificates are transparently decompressed
442 /// during the handshake.
443 ///
444 /// This only applies to TLS1.3 connections. It is ignored for
445 /// TLS1.2 connections.
446 ///
447 /// [RFC8779]: https://datatracker.ietf.org/doc/rfc8879/
448 pub cert_decompressors: Vec<&'static dyn compress::CertDecompressor>,
449}
450
451impl ServerConfig {
452 /// Create a builder for a server configuration with
453 /// [the process-default `CryptoProvider`][CryptoProvider#using-the-per-process-default-cryptoprovider]
454 /// and safe protocol version defaults.
455 ///
456 /// For more information, see the [`ConfigBuilder`] documentation.
457 #[cfg(feature = "std")]
458 pub fn builder() -> ConfigBuilder<Self, WantsVerifier> {
459 Self::builder_with_protocol_versions(versions::DEFAULT_VERSIONS)
460 }
461
462 /// Create a builder for a server configuration with
463 /// [the process-default `CryptoProvider`][CryptoProvider#using-the-per-process-default-cryptoprovider]
464 /// and the provided protocol versions.
465 ///
466 /// Panics if
467 /// - the supported versions are not compatible with the provider (eg.
468 /// the combination of ciphersuites supported by the provider and supported
469 /// versions lead to zero cipher suites being usable),
470 /// - if a `CryptoProvider` cannot be resolved using a combination of
471 /// the crate features and process default.
472 ///
473 /// For more information, see the [`ConfigBuilder`] documentation.
474 #[cfg(feature = "std")]
475 pub fn builder_with_protocol_versions(
476 versions: &[&'static versions::SupportedProtocolVersion],
477 ) -> ConfigBuilder<Self, WantsVerifier> {
478 // Safety assumptions:
479 // 1. that the provider has been installed (explicitly or implicitly)
480 // 2. that the process-level default provider is usable with the supplied protocol versions.
481 Self::builder_with_provider(
482 CryptoProvider::get_default_or_install_from_crate_features().clone(),
483 )
484 .with_protocol_versions(versions)
485 .unwrap()
486 }
487
488 /// Create a builder for a server configuration with a specific [`CryptoProvider`].
489 ///
490 /// This will use the provider's configured ciphersuites. You must additionally choose
491 /// which protocol versions to enable, using `with_protocol_versions` or
492 /// `with_safe_default_protocol_versions` and handling the `Result` in case a protocol
493 /// version is not supported by the provider's ciphersuites.
494 ///
495 /// For more information, see the [`ConfigBuilder`] documentation.
496 #[cfg(feature = "std")]
497 pub fn builder_with_provider(
498 provider: Arc<CryptoProvider>,
499 ) -> ConfigBuilder<Self, WantsVersions> {
500 ConfigBuilder {
501 state: WantsVersions {},
502 provider,
503 time_provider: Arc::new(DefaultTimeProvider),
504 side: PhantomData,
505 }
506 }
507
508 /// Create a builder for a server configuration with no default implementation details.
509 ///
510 /// This API must be used by `no_std` users.
511 ///
512 /// You must provide a specific [`TimeProvider`].
513 ///
514 /// You must provide a specific [`CryptoProvider`].
515 ///
516 /// This will use the provider's configured ciphersuites. You must additionally choose
517 /// which protocol versions to enable, using `with_protocol_versions` or
518 /// `with_safe_default_protocol_versions` and handling the `Result` in case a protocol
519 /// version is not supported by the provider's ciphersuites.
520 ///
521 /// For more information, see the [`ConfigBuilder`] documentation.
522 pub fn builder_with_details(
523 provider: Arc<CryptoProvider>,
524 time_provider: Arc<dyn TimeProvider>,
525 ) -> ConfigBuilder<Self, WantsVersions> {
526 ConfigBuilder {
527 state: WantsVersions {},
528 provider,
529 time_provider,
530 side: PhantomData,
531 }
532 }
533
534 /// Return `true` if connections made with this `ServerConfig` will
535 /// operate in FIPS mode.
536 ///
537 /// This is different from [`CryptoProvider::fips()`]: [`CryptoProvider::fips()`]
538 /// is concerned only with cryptography, whereas this _also_ covers TLS-level
539 /// configuration that NIST recommends.
540 pub fn fips(&self) -> bool {
541 #[cfg(feature = "tls12")]
542 {
543 self.provider.fips() && self.require_ems
544 }
545
546 #[cfg(not(feature = "tls12"))]
547 {
548 self.provider.fips()
549 }
550 }
551
552 /// Return the crypto provider used to construct this client configuration.
553 pub fn crypto_provider(&self) -> &Arc<CryptoProvider> {
554 &self.provider
555 }
556
557 /// We support a given TLS version if it's quoted in the configured
558 /// versions *and* at least one ciphersuite for this version is
559 /// also configured.
560 pub(crate) fn supports_version(&self, v: ProtocolVersion) -> bool {
561 self.versions.contains(v)
562 && self
563 .provider
564 .cipher_suites
565 .iter()
566 .any(|cs| cs.version().version == v)
567 }
568
569 #[cfg(feature = "std")]
570 pub(crate) fn supports_protocol(&self, proto: Protocol) -> bool {
571 self.provider
572 .cipher_suites
573 .iter()
574 .any(|cs| cs.usable_for_protocol(proto))
575 }
576
577 pub(super) fn current_time(&self) -> Result<UnixTime, Error> {
578 self.time_provider
579 .current_time()
580 .ok_or(Error::FailedToGetCurrentTime)
581 }
582}
583
584#[cfg(feature = "std")]
585mod connection {
586 use alloc::boxed::Box;
587 use core::fmt;
588 use core::fmt::{Debug, Formatter};
589 use core::ops::{Deref, DerefMut};
590 use std::io;
591
592 use super::{
593 Accepted, Accepting, EarlyDataState, ServerConfig, ServerConnectionData,
594 ServerExtensionsInput,
595 };
596 use crate::common_state::{CommonState, Context, Side};
597 use crate::conn::{ConnectionCommon, ConnectionCore};
598 use crate::error::Error;
599 use crate::server::hs;
600 use crate::suites::ExtractedSecrets;
601 use crate::sync::Arc;
602 use crate::vecbuf::ChunkVecBuffer;
603
604 /// Allows reading of early data in resumed TLS1.3 connections.
605 ///
606 /// "Early data" is also known as "0-RTT data".
607 ///
608 /// This structure implements [`std::io::Read`].
609 pub struct ReadEarlyData<'a> {
610 early_data: &'a mut EarlyDataState,
611 }
612
613 impl<'a> ReadEarlyData<'a> {
614 fn new(early_data: &'a mut EarlyDataState) -> Self {
615 ReadEarlyData { early_data }
616 }
617 }
618
619 impl io::Read for ReadEarlyData<'_> {
620 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
621 self.early_data.read(buf)
622 }
623
624 #[cfg(read_buf)]
625 fn read_buf(&mut self, cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
626 self.early_data.read_buf(cursor)
627 }
628 }
629
630 /// This represents a single TLS server connection.
631 ///
632 /// Send TLS-protected data to the peer using the `io::Write` trait implementation.
633 /// Read data from the peer using the `io::Read` trait implementation.
634 pub struct ServerConnection {
635 pub(super) inner: ConnectionCommon<ServerConnectionData>,
636 }
637
638 impl ServerConnection {
639 /// Make a new ServerConnection. `config` controls how
640 /// we behave in the TLS protocol.
641 pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
642 Ok(Self {
643 inner: ConnectionCommon::from(ConnectionCore::for_server(
644 config,
645 ServerExtensionsInput::default(),
646 )?),
647 })
648 }
649
650 /// Retrieves the server name, if any, used to select the certificate and
651 /// private key.
652 ///
653 /// This returns `None` until some time after the client's server name indication
654 /// (SNI) extension value is processed during the handshake. It will never be
655 /// `None` when the connection is ready to send or process application data,
656 /// unless the client does not support SNI.
657 ///
658 /// This is useful for application protocols that need to enforce that the
659 /// server name matches an application layer protocol hostname. For
660 /// example, HTTP/1.1 servers commonly expect the `Host:` header field of
661 /// every request on a connection to match the hostname in the SNI extension
662 /// when the client provides the SNI extension.
663 ///
664 /// The server name is also used to match sessions during session resumption.
665 pub fn server_name(&self) -> Option<&str> {
666 self.inner.core.get_sni_str()
667 }
668
669 /// Application-controlled portion of the resumption ticket supplied by the client, if any.
670 ///
671 /// Recovered from the prior session's `set_resumption_data`. Integrity is guaranteed by rustls.
672 ///
673 /// Returns `Some` if and only if a valid resumption ticket has been received from the client.
674 pub fn received_resumption_data(&self) -> Option<&[u8]> {
675 self.inner
676 .core
677 .data
678 .received_resumption_data
679 .as_ref()
680 .map(|x| &x[..])
681 }
682
683 /// Set the resumption data to embed in future resumption tickets supplied to the client.
684 ///
685 /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other
686 /// data. Should be called while `is_handshaking` returns true to ensure all transmitted
687 /// resumption tickets are affected.
688 ///
689 /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy
690 /// from the client is desired, encrypt the data separately.
691 pub fn set_resumption_data(&mut self, data: &[u8]) {
692 assert!(data.len() < 2usize.pow(15));
693 self.inner.core.data.resumption_data = data.into();
694 }
695
696 /// Explicitly discard early data, notifying the client
697 ///
698 /// Useful if invariants encoded in `received_resumption_data()` cannot be respected.
699 ///
700 /// Must be called while `is_handshaking` is true.
701 pub fn reject_early_data(&mut self) {
702 self.inner.core.reject_early_data()
703 }
704
705 /// Returns an `io::Read` implementer you can read bytes from that are
706 /// received from a client as TLS1.3 0RTT/"early" data, during the handshake.
707 ///
708 /// This returns `None` in many circumstances, such as :
709 ///
710 /// - Early data is disabled if [`ServerConfig::max_early_data_size`] is zero (the default).
711 /// - The session negotiated with the client is not TLS1.3.
712 /// - The client just doesn't support early data.
713 /// - The connection doesn't resume an existing session.
714 /// - The client hasn't sent a full ClientHello yet.
715 pub fn early_data(&mut self) -> Option<ReadEarlyData<'_>> {
716 let data = &mut self.inner.core.data;
717 if data.early_data.was_accepted() {
718 Some(ReadEarlyData::new(&mut data.early_data))
719 } else {
720 None
721 }
722 }
723
724 /// Return true if the connection was made with a `ServerConfig` that is FIPS compatible.
725 ///
726 /// This is different from [`crate::crypto::CryptoProvider::fips()`]:
727 /// it is concerned only with cryptography, whereas this _also_ covers TLS-level
728 /// configuration that NIST recommends, as well as ECH HPKE suites if applicable.
729 pub fn fips(&self) -> bool {
730 self.inner.core.common_state.fips
731 }
732
733 /// Extract secrets, so they can be used when configuring kTLS, for example.
734 /// Should be used with care as it exposes secret key material.
735 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
736 self.inner.dangerous_extract_secrets()
737 }
738 }
739
740 impl Debug for ServerConnection {
741 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
742 f.debug_struct("ServerConnection")
743 .finish()
744 }
745 }
746
747 impl Deref for ServerConnection {
748 type Target = ConnectionCommon<ServerConnectionData>;
749
750 fn deref(&self) -> &Self::Target {
751 &self.inner
752 }
753 }
754
755 impl DerefMut for ServerConnection {
756 fn deref_mut(&mut self) -> &mut Self::Target {
757 &mut self.inner
758 }
759 }
760
761 impl From<ServerConnection> for crate::Connection {
762 fn from(conn: ServerConnection) -> Self {
763 Self::Server(conn)
764 }
765 }
766
767 /// Handle a server-side connection before configuration is available.
768 ///
769 /// `Acceptor` allows the caller to choose a [`ServerConfig`] after reading
770 /// the [`super::ClientHello`] of an incoming connection. This is useful for servers
771 /// that choose different certificates or cipher suites based on the
772 /// characteristics of the `ClientHello`. In particular it is useful for
773 /// servers that need to do some I/O to load a certificate and its private key
774 /// and don't want to use the blocking interface provided by
775 /// [`super::ResolvesServerCert`].
776 ///
777 /// Create an Acceptor with [`Acceptor::default()`].
778 ///
779 /// # Example
780 ///
781 /// ```no_run
782 /// # #[cfg(feature = "aws_lc_rs")] {
783 /// # fn choose_server_config(
784 /// # _: rustls::server::ClientHello,
785 /// # ) -> std::sync::Arc<rustls::ServerConfig> {
786 /// # unimplemented!();
787 /// # }
788 /// # #[allow(unused_variables)]
789 /// # fn main() {
790 /// use rustls::server::{Acceptor, ServerConfig};
791 /// let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
792 /// for stream in listener.incoming() {
793 /// let mut stream = stream.unwrap();
794 /// let mut acceptor = Acceptor::default();
795 /// let accepted = loop {
796 /// acceptor.read_tls(&mut stream).unwrap();
797 /// if let Some(accepted) = acceptor.accept().unwrap() {
798 /// break accepted;
799 /// }
800 /// };
801 ///
802 /// // For some user-defined choose_server_config:
803 /// let config = choose_server_config(accepted.client_hello());
804 /// let conn = accepted
805 /// .into_connection(config)
806 /// .unwrap();
807 ///
808 /// // Proceed with handling the ServerConnection.
809 /// }
810 /// # }
811 /// # }
812 /// ```
813 pub struct Acceptor {
814 inner: Option<ConnectionCommon<ServerConnectionData>>,
815 }
816
817 impl Default for Acceptor {
818 /// Return an empty Acceptor, ready to receive bytes from a new client connection.
819 fn default() -> Self {
820 Self {
821 inner: Some(
822 ConnectionCore::new(
823 Box::new(Accepting),
824 ServerConnectionData::default(),
825 CommonState::new(Side::Server),
826 )
827 .into(),
828 ),
829 }
830 }
831 }
832
833 impl Acceptor {
834 /// Read TLS content from `rd`.
835 ///
836 /// Returns an error if this `Acceptor` has already yielded an [`Accepted`]. For more details,
837 /// refer to [`Connection::read_tls()`].
838 ///
839 /// [`Connection::read_tls()`]: crate::Connection::read_tls
840 pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> {
841 match &mut self.inner {
842 Some(conn) => conn.read_tls(rd),
843 None => Err(io::Error::new(
844 io::ErrorKind::Other,
845 "acceptor cannot read after successful acceptance",
846 )),
847 }
848 }
849
850 /// Check if a `ClientHello` message has been received.
851 ///
852 /// Returns `Ok(None)` if the complete `ClientHello` has not yet been received.
853 /// Do more I/O and then call this function again.
854 ///
855 /// Returns `Ok(Some(accepted))` if the connection has been accepted. Call
856 /// `accepted.into_connection()` to continue. Do not call this function again.
857 ///
858 /// Returns `Err((err, alert))` if an error occurred. If an alert is returned, the
859 /// application should call `alert.write()` to send the alert to the client. It should
860 /// not call `accept()` again.
861 pub fn accept(&mut self) -> Result<Option<Accepted>, (Error, AcceptedAlert)> {
862 let Some(mut connection) = self.inner.take() else {
863 return Err((
864 Error::General("Acceptor polled after completion".into()),
865 AcceptedAlert::empty(),
866 ));
867 };
868
869 let message = match connection.first_handshake_message() {
870 Ok(Some(msg)) => msg,
871 Ok(None) => {
872 self.inner = Some(connection);
873 return Ok(None);
874 }
875 Err(err) => return Err((err, AcceptedAlert::from(connection))),
876 };
877
878 let mut cx = Context::from(&mut connection);
879 let sig_schemes = match hs::process_client_hello(&message, false, &mut cx) {
880 Ok((_, sig_schemes)) => sig_schemes,
881 Err(err) => {
882 return Err((err, AcceptedAlert::from(connection)));
883 }
884 };
885
886 Ok(Some(Accepted {
887 connection,
888 message,
889 sig_schemes,
890 }))
891 }
892 }
893
894 /// Represents a TLS alert resulting from handling the client's `ClientHello` message.
895 ///
896 /// When [`Acceptor::accept()`] returns an error, it yields an `AcceptedAlert` such that the
897 /// application can communicate failure to the client via [`AcceptedAlert::write()`].
898 pub struct AcceptedAlert(ChunkVecBuffer);
899
900 impl AcceptedAlert {
901 pub(super) fn empty() -> Self {
902 Self(ChunkVecBuffer::new(None))
903 }
904
905 /// Send the alert to the client.
906 ///
907 /// To account for short writes this function should be called repeatedly until it
908 /// returns `Ok(0)` or an error.
909 pub fn write(&mut self, wr: &mut dyn io::Write) -> Result<usize, io::Error> {
910 self.0.write_to(wr)
911 }
912
913 /// Send the alert to the client.
914 ///
915 /// This function will invoke the writer until the buffer is empty.
916 pub fn write_all(&mut self, wr: &mut dyn io::Write) -> Result<(), io::Error> {
917 while self.write(wr)? != 0 {}
918 Ok(())
919 }
920 }
921
922 impl From<ConnectionCommon<ServerConnectionData>> for AcceptedAlert {
923 fn from(conn: ConnectionCommon<ServerConnectionData>) -> Self {
924 Self(conn.core.common_state.sendable_tls)
925 }
926 }
927
928 impl Debug for AcceptedAlert {
929 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
930 f.debug_struct("AcceptedAlert").finish()
931 }
932 }
933}
934
935#[cfg(feature = "std")]
936pub use connection::{AcceptedAlert, Acceptor, ReadEarlyData, ServerConnection};
937
938/// Unbuffered version of `ServerConnection`
939///
940/// See the [`crate::unbuffered`] module docs for more details
941pub struct UnbufferedServerConnection {
942 inner: UnbufferedConnectionCommon<ServerConnectionData>,
943}
944
945impl UnbufferedServerConnection {
946 /// Make a new ServerConnection. `config` controls how we behave in the TLS protocol.
947 pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> {
948 Ok(Self {
949 inner: UnbufferedConnectionCommon::from(ConnectionCore::for_server(
950 config,
951 ServerExtensionsInput::default(),
952 )?),
953 })
954 }
955
956 /// Extract secrets, so they can be used when configuring kTLS, for example.
957 /// Should be used with care as it exposes secret key material.
958 #[deprecated = "dangerous_extract_secrets() does not support session tickets or \
959 key updates, use dangerous_into_kernel_connection() instead"]
960 pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> {
961 self.inner.dangerous_extract_secrets()
962 }
963
964 /// Extract secrets and an [`KernelConnection`] object.
965 ///
966 /// This allows you use rustls to manage keys and then manage encryption and
967 /// decryption yourself (e.g. for kTLS).
968 ///
969 /// Should be used with care as it exposes secret key material.
970 ///
971 /// See the [`crate::kernel`] documentations for details on prerequisites
972 /// for calling this method.
973 pub fn dangerous_into_kernel_connection(
974 self,
975 ) -> Result<(ExtractedSecrets, KernelConnection<ServerConnectionData>), Error> {
976 self.inner
977 .core
978 .dangerous_into_kernel_connection()
979 }
980}
981
982impl Deref for UnbufferedServerConnection {
983 type Target = UnbufferedConnectionCommon<ServerConnectionData>;
984
985 fn deref(&self) -> &Self::Target {
986 &self.inner
987 }
988}
989
990impl DerefMut for UnbufferedServerConnection {
991 fn deref_mut(&mut self) -> &mut Self::Target {
992 &mut self.inner
993 }
994}
995
996impl UnbufferedConnectionCommon<ServerConnectionData> {
997 pub(crate) fn pop_early_data(&mut self) -> Option<Vec<u8>> {
998 self.core.data.early_data.pop()
999 }
1000
1001 pub(crate) fn peek_early_data(&self) -> Option<&[u8]> {
1002 self.core.data.early_data.peek()
1003 }
1004}
1005
1006/// Represents a `ClientHello` message received through the [`Acceptor`].
1007///
1008/// Contains the state required to resume the connection through [`Accepted::into_connection()`].
1009pub struct Accepted {
1010 connection: ConnectionCommon<ServerConnectionData>,
1011 message: Message<'static>,
1012 sig_schemes: Vec<SignatureScheme>,
1013}
1014
1015impl Accepted {
1016 /// Get the [`ClientHello`] for this connection.
1017 pub fn client_hello(&self) -> ClientHello<'_> {
1018 let payload = Self::client_hello_payload(&self.message);
1019 let ch = ClientHello {
1020 server_name: &self.connection.core.data.sni,
1021 signature_schemes: &self.sig_schemes,
1022 alpn: payload.protocols.as_ref(),
1023 server_cert_types: payload
1024 .server_certificate_types
1025 .as_deref(),
1026 client_cert_types: payload
1027 .client_certificate_types
1028 .as_deref(),
1029 cipher_suites: &payload.cipher_suites,
1030 certificate_authorities: payload
1031 .certificate_authority_names
1032 .as_deref(),
1033 named_groups: payload.named_groups.as_deref(),
1034 };
1035
1036 trace!("Accepted::client_hello(): {ch:#?}");
1037 ch
1038 }
1039
1040 /// Convert the [`Accepted`] into a [`ServerConnection`].
1041 ///
1042 /// Takes the state returned from [`Acceptor::accept()`] as well as the [`ServerConfig`] and
1043 /// [`sign::CertifiedKey`] that should be used for the session. Returns an error if
1044 /// configuration-dependent validation of the received `ClientHello` message fails.
1045 #[cfg(feature = "std")]
1046 pub fn into_connection(
1047 mut self,
1048 config: Arc<ServerConfig>,
1049 ) -> Result<ServerConnection, (Error, AcceptedAlert)> {
1050 if let Err(err) = self
1051 .connection
1052 .set_max_fragment_size(config.max_fragment_size)
1053 {
1054 // We have a connection here, but it won't contain an alert since the error
1055 // is with the fragment size configured in the `ServerConfig`.
1056 return Err((err, AcceptedAlert::empty()));
1057 }
1058
1059 self.connection.enable_secret_extraction = config.enable_secret_extraction;
1060
1061 let state = hs::ExpectClientHello::new(config, ServerExtensionsInput::default());
1062 let mut cx = hs::ServerContext::from(&mut self.connection);
1063
1064 let ch = Self::client_hello_payload(&self.message);
1065 let new = match state.with_certified_key(self.sig_schemes, ch, &self.message, &mut cx) {
1066 Ok(new) => new,
1067 Err(err) => return Err((err, AcceptedAlert::from(self.connection))),
1068 };
1069
1070 self.connection.replace_state(new);
1071 Ok(ServerConnection {
1072 inner: self.connection,
1073 })
1074 }
1075
1076 fn client_hello_payload<'a>(message: &'a Message<'_>) -> &'a ClientHelloPayload {
1077 match &message.payload {
1078 crate::msgs::message::MessagePayload::Handshake { parsed, .. } => match &parsed.0 {
1079 crate::msgs::handshake::HandshakePayload::ClientHello(ch) => ch,
1080 _ => unreachable!(),
1081 },
1082 _ => unreachable!(),
1083 }
1084 }
1085}
1086
1087impl Debug for Accepted {
1088 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1089 f.debug_struct("Accepted").finish()
1090 }
1091}
1092
1093#[cfg(feature = "std")]
1094struct Accepting;
1095
1096#[cfg(feature = "std")]
1097impl State<ServerConnectionData> for Accepting {
1098 fn handle<'m>(
1099 self: Box<Self>,
1100 _cx: &mut hs::ServerContext<'_>,
1101 _m: Message<'m>,
1102 ) -> Result<Box<dyn State<ServerConnectionData> + 'm>, Error>
1103 where
1104 Self: 'm,
1105 {
1106 Err(Error::General("unreachable state".into()))
1107 }
1108
1109 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1110 self
1111 }
1112}
1113
1114pub(super) enum EarlyDataState {
1115 New,
1116 Accepted {
1117 received: ChunkVecBuffer,
1118 left: usize,
1119 },
1120 Rejected,
1121}
1122
1123impl Default for EarlyDataState {
1124 fn default() -> Self {
1125 Self::New
1126 }
1127}
1128
1129impl EarlyDataState {
1130 pub(super) fn reject(&mut self) {
1131 *self = Self::Rejected;
1132 }
1133
1134 pub(super) fn accept(&mut self, max_size: usize) {
1135 *self = Self::Accepted {
1136 received: ChunkVecBuffer::new(Some(max_size)),
1137 left: max_size,
1138 };
1139 }
1140
1141 #[cfg(feature = "std")]
1142 fn was_accepted(&self) -> bool {
1143 matches!(self, Self::Accepted { .. })
1144 }
1145
1146 pub(super) fn was_rejected(&self) -> bool {
1147 matches!(self, Self::Rejected)
1148 }
1149
1150 fn peek(&self) -> Option<&[u8]> {
1151 match self {
1152 Self::Accepted { received, .. } => received.peek(),
1153 _ => None,
1154 }
1155 }
1156
1157 fn pop(&mut self) -> Option<Vec<u8>> {
1158 match self {
1159 Self::Accepted { received, .. } => received.pop(),
1160 _ => None,
1161 }
1162 }
1163
1164 #[cfg(feature = "std")]
1165 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
1166 match self {
1167 Self::Accepted { received, .. } => received.read(buf),
1168 _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
1169 }
1170 }
1171
1172 #[cfg(read_buf)]
1173 fn read_buf(&mut self, cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> {
1174 match self {
1175 Self::Accepted { received, .. } => received.read_buf(cursor),
1176 _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)),
1177 }
1178 }
1179
1180 pub(super) fn take_received_plaintext(&mut self, bytes: Payload<'_>) -> bool {
1181 let available = bytes.bytes().len();
1182 let Self::Accepted { received, left } = self else {
1183 return false;
1184 };
1185
1186 if received.apply_limit(available) != available || available > *left {
1187 return false;
1188 }
1189
1190 received.append(bytes.into_vec());
1191 *left -= available;
1192 true
1193 }
1194}
1195
1196impl Debug for EarlyDataState {
1197 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1198 match self {
1199 Self::New => write!(f, "EarlyDataState::New"),
1200 Self::Accepted { received, left } => write!(
1201 f,
1202 "EarlyDataState::Accepted {{ received: {}, left: {} }}",
1203 received.len(),
1204 left
1205 ),
1206 Self::Rejected => write!(f, "EarlyDataState::Rejected"),
1207 }
1208 }
1209}
1210
1211impl ConnectionCore<ServerConnectionData> {
1212 pub(crate) fn for_server(
1213 config: Arc<ServerConfig>,
1214 extra_exts: ServerExtensionsInput<'static>,
1215 ) -> Result<Self, Error> {
1216 let mut common = CommonState::new(Side::Server);
1217 common.set_max_fragment_size(config.max_fragment_size)?;
1218 common.enable_secret_extraction = config.enable_secret_extraction;
1219 common.fips = config.fips();
1220 Ok(Self::new(
1221 Box::new(hs::ExpectClientHello::new(config, extra_exts)),
1222 ServerConnectionData::default(),
1223 common,
1224 ))
1225 }
1226
1227 #[cfg(feature = "std")]
1228 pub(crate) fn reject_early_data(&mut self) {
1229 assert!(
1230 self.common_state.is_handshaking(),
1231 "cannot retroactively reject early data"
1232 );
1233 self.data.early_data.reject();
1234 }
1235
1236 #[cfg(feature = "std")]
1237 pub(crate) fn get_sni_str(&self) -> Option<&str> {
1238 self.data.get_sni_str()
1239 }
1240}
1241
1242/// State associated with a server connection.
1243#[derive(Default, Debug)]
1244pub struct ServerConnectionData {
1245 pub(super) sni: Option<DnsName<'static>>,
1246 pub(super) received_resumption_data: Option<Vec<u8>>,
1247 pub(super) resumption_data: Vec<u8>,
1248 pub(super) early_data: EarlyDataState,
1249}
1250
1251impl ServerConnectionData {
1252 #[cfg(feature = "std")]
1253 pub(super) fn get_sni_str(&self) -> Option<&str> {
1254 self.sni.as_ref().map(AsRef::as_ref)
1255 }
1256}
1257
1258impl crate::conn::SideData for ServerConnectionData {}
1259
1260#[cfg(feature = "std")]
1261#[cfg(test)]
1262mod tests {
1263 use std::format;
1264
1265 use super::*;
1266
1267 // these branches not reachable externally, unless something else goes wrong.
1268 #[test]
1269 fn test_read_in_new_state() {
1270 assert_eq!(
1271 format!("{:?}", EarlyDataState::default().read(&mut [0u8; 5])),
1272 "Err(Kind(BrokenPipe))"
1273 );
1274 }
1275
1276 #[cfg(read_buf)]
1277 #[test]
1278 fn test_read_buf_in_new_state() {
1279 use core::io::BorrowedBuf;
1280
1281 let mut buf = [0u8; 5];
1282 let mut buf: BorrowedBuf<'_> = buf.as_mut_slice().into();
1283 assert_eq!(
1284 format!("{:?}", EarlyDataState::default().read_buf(buf.unfilled())),
1285 "Err(Kind(BrokenPipe))"
1286 );
1287 }
1288}