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