1 | use crate::builder::ConfigBuilder; |
2 | use crate::common_state::{CommonState, Context, Protocol, Side, State}; |
3 | use crate::conn::{ConnectionCommon, ConnectionCore}; |
4 | use crate::crypto::CryptoProvider; |
5 | use crate::enums::{CipherSuite, ProtocolVersion, SignatureScheme}; |
6 | use crate::error::Error; |
7 | #[cfg (feature = "logging" )] |
8 | use crate::log::trace; |
9 | use crate::msgs::base::Payload; |
10 | use crate::msgs::handshake::{ClientHelloPayload, ProtocolName, ServerExtension}; |
11 | use crate::msgs::message::Message; |
12 | use crate::suites::ExtractedSecrets; |
13 | use crate::vecbuf::ChunkVecBuffer; |
14 | use crate::verify; |
15 | #[cfg (feature = "ring" )] |
16 | use crate::versions; |
17 | use crate::KeyLog; |
18 | #[cfg (feature = "ring" )] |
19 | use crate::WantsVerifier; |
20 | use crate::{sign, WantsVersions}; |
21 | |
22 | use super::hs; |
23 | |
24 | use pki_types::DnsName; |
25 | |
26 | use alloc::boxed::Box; |
27 | use alloc::sync::Arc; |
28 | use alloc::vec::Vec; |
29 | use core::fmt; |
30 | use core::fmt::{Debug, Formatter}; |
31 | use core::marker::PhantomData; |
32 | use core::ops::{Deref, DerefMut}; |
33 | use std::io; |
34 | |
35 | #[cfg (doc)] |
36 | use crate::crypto; |
37 | |
38 | /// A trait for the ability to store server session data. |
39 | /// |
40 | /// The keys and values are opaque. |
41 | /// |
42 | /// Both the keys and values should be treated as |
43 | /// **highly sensitive data**, containing enough key material |
44 | /// to break all security of the corresponding sessions. |
45 | /// |
46 | /// Implementations can be lossy (in other words, forgetting |
47 | /// key/value pairs) without any negative security consequences. |
48 | /// |
49 | /// However, note that `take` **must** reliably delete a returned |
50 | /// value. If it does not, there may be security consequences. |
51 | /// |
52 | /// `put` and `take` are mutating operations; this isn't expressed |
53 | /// in the type system to allow implementations freedom in |
54 | /// how to achieve interior mutability. `Mutex` is a common |
55 | /// choice. |
56 | pub trait StoresServerSessions: Debug + Send + Sync { |
57 | /// Store session secrets encoded in `value` against `key`, |
58 | /// overwrites any existing value against `key`. Returns `true` |
59 | /// if the value was stored. |
60 | fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool; |
61 | |
62 | /// Find a value with the given `key`. Return it, or None |
63 | /// if it doesn't exist. |
64 | fn get(&self, key: &[u8]) -> Option<Vec<u8>>; |
65 | |
66 | /// Find a value with the given `key`. Return it and delete it; |
67 | /// or None if it doesn't exist. |
68 | fn take(&self, key: &[u8]) -> Option<Vec<u8>>; |
69 | |
70 | /// Whether the store can cache another session. This is used to indicate to clients |
71 | /// whether their session can be resumed; the implementation is not required to remember |
72 | /// a session even if it returns `true` here. |
73 | fn can_cache(&self) -> bool; |
74 | } |
75 | |
76 | /// A trait for the ability to encrypt and decrypt tickets. |
77 | pub trait ProducesTickets: Debug + Send + Sync { |
78 | /// Returns true if this implementation will encrypt/decrypt |
79 | /// tickets. Should return false if this is a dummy |
80 | /// implementation: the server will not send the SessionTicket |
81 | /// extension and will not call the other functions. |
82 | fn enabled(&self) -> bool; |
83 | |
84 | /// Returns the lifetime in seconds of tickets produced now. |
85 | /// The lifetime is provided as a hint to clients that the |
86 | /// ticket will not be useful after the given time. |
87 | /// |
88 | /// This lifetime must be implemented by key rolling and |
89 | /// erasure, *not* by storing a lifetime in the ticket. |
90 | /// |
91 | /// The objective is to limit damage to forward secrecy caused |
92 | /// by tickets, not just limiting their lifetime. |
93 | fn lifetime(&self) -> u32; |
94 | |
95 | /// Encrypt and authenticate `plain`, returning the resulting |
96 | /// ticket. Return None if `plain` cannot be encrypted for |
97 | /// some reason: an empty ticket will be sent and the connection |
98 | /// will continue. |
99 | fn encrypt(&self, plain: &[u8]) -> Option<Vec<u8>>; |
100 | |
101 | /// Decrypt `cipher`, validating its authenticity protection |
102 | /// and recovering the plaintext. `cipher` is fully attacker |
103 | /// controlled, so this decryption must be side-channel free, |
104 | /// panic-proof, and otherwise bullet-proof. If the decryption |
105 | /// fails, return None. |
106 | fn decrypt(&self, cipher: &[u8]) -> Option<Vec<u8>>; |
107 | } |
108 | |
109 | /// How to choose a certificate chain and signing key for use |
110 | /// in server authentication. |
111 | /// |
112 | /// This is suitable when selecting a certificate does not require |
113 | /// I/O or when the application is using blocking I/O anyhow. |
114 | /// |
115 | /// For applications that use async I/O and need to do I/O to choose |
116 | /// a certificate (for instance, fetching a certificate from a data store), |
117 | /// the [`Acceptor`] interface is more suitable. |
118 | pub trait ResolvesServerCert: Debug + Send + Sync { |
119 | /// Choose a certificate chain and matching key given simplified |
120 | /// ClientHello information. |
121 | /// |
122 | /// Return `None` to abort the handshake. |
123 | fn resolve(&self, client_hello: ClientHello) -> Option<Arc<sign::CertifiedKey>>; |
124 | } |
125 | |
126 | /// A struct representing the received Client Hello |
127 | pub struct ClientHello<'a> { |
128 | server_name: &'a Option<DnsName<'a>>, |
129 | signature_schemes: &'a [SignatureScheme], |
130 | alpn: Option<&'a Vec<ProtocolName>>, |
131 | cipher_suites: &'a [CipherSuite], |
132 | } |
133 | |
134 | impl<'a> ClientHello<'a> { |
135 | /// Creates a new ClientHello |
136 | pub(super) fn new( |
137 | server_name: &'a Option<DnsName>, |
138 | signature_schemes: &'a [SignatureScheme], |
139 | alpn: Option<&'a Vec<ProtocolName>>, |
140 | cipher_suites: &'a [CipherSuite], |
141 | ) -> Self { |
142 | trace!("sni {:?}" , server_name); |
143 | trace!("sig schemes {:?}" , signature_schemes); |
144 | trace!("alpn protocols {:?}" , alpn); |
145 | trace!("cipher suites {:?}" , cipher_suites); |
146 | |
147 | ClientHello { |
148 | server_name, |
149 | signature_schemes, |
150 | alpn, |
151 | cipher_suites, |
152 | } |
153 | } |
154 | |
155 | /// Get the server name indicator. |
156 | /// |
157 | /// Returns `None` if the client did not supply a SNI. |
158 | pub fn server_name(&self) -> Option<&str> { |
159 | self.server_name |
160 | .as_ref() |
161 | .map(<DnsName as AsRef<str>>::as_ref) |
162 | } |
163 | |
164 | /// Get the compatible signature schemes. |
165 | /// |
166 | /// Returns standard-specified default if the client omitted this extension. |
167 | pub fn signature_schemes(&self) -> &[SignatureScheme] { |
168 | self.signature_schemes |
169 | } |
170 | |
171 | /// Get the ALPN protocol identifiers submitted by the client. |
172 | /// |
173 | /// Returns `None` if the client did not include an ALPN extension. |
174 | /// |
175 | /// Application Layer Protocol Negotiation (ALPN) is a TLS extension that lets a client |
176 | /// submit a set of identifiers that each a represent an application-layer protocol. |
177 | /// The server will then pick its preferred protocol from the set submitted by the client. |
178 | /// Each identifier is represented as a byte array, although common values are often ASCII-encoded. |
179 | /// See the official RFC-7301 specifications at <https://datatracker.ietf.org/doc/html/rfc7301> |
180 | /// for more information on ALPN. |
181 | /// |
182 | /// For example, a HTTP client might specify "http/1.1" and/or "h2". Other well-known values |
183 | /// are listed in the at IANA registry at |
184 | /// <https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>. |
185 | /// |
186 | /// The server can specify supported ALPN protocols by setting [`ServerConfig::alpn_protocols`]. |
187 | /// During the handshake, the server will select the first protocol configured that the client supports. |
188 | pub fn alpn(&self) -> Option<impl Iterator<Item = &'a [u8]>> { |
189 | self.alpn.map(|protocols| { |
190 | protocols |
191 | .iter() |
192 | .map(|proto| proto.as_ref()) |
193 | }) |
194 | } |
195 | |
196 | /// Get cipher suites. |
197 | pub fn cipher_suites(&self) -> &[CipherSuite] { |
198 | self.cipher_suites |
199 | } |
200 | } |
201 | |
202 | /// Common configuration for a set of server sessions. |
203 | /// |
204 | /// Making one of these is cheap, though one of the inputs may be expensive: gathering trust roots |
205 | /// from the operating system to add to the [`RootCertStore`] passed to a `ClientCertVerifier` |
206 | /// builder may take on the order of a few hundred milliseconds. |
207 | /// |
208 | /// These must be created via the [`ServerConfig::builder()`] or [`ServerConfig::builder_with_provider()`] |
209 | /// function. |
210 | /// |
211 | /// # Defaults |
212 | /// |
213 | /// * [`ServerConfig::max_fragment_size`]: the default is `None` (meaning 16kB). |
214 | /// * [`ServerConfig::session_storage`]: the default stores 256 sessions in memory. |
215 | /// * [`ServerConfig::alpn_protocols`]: the default is empty -- no ALPN protocol is negotiated. |
216 | /// * [`ServerConfig::key_log`]: key material is not logged. |
217 | /// * [`ServerConfig::send_tls13_tickets`]: 4 tickets are sent. |
218 | /// |
219 | /// [`RootCertStore`]: crate::RootCertStore |
220 | #[derive (Debug)] |
221 | pub struct ServerConfig { |
222 | /// Source of randomness and other crypto. |
223 | pub(super) provider: Arc<CryptoProvider>, |
224 | |
225 | /// Ignore the client's ciphersuite order. Instead, |
226 | /// choose the top ciphersuite in the server list |
227 | /// which is supported by the client. |
228 | pub ignore_client_order: bool, |
229 | |
230 | /// The maximum size of plaintext input to be emitted in a single TLS record. |
231 | /// A value of None is equivalent to the [TLS maximum] of 16 kB. |
232 | /// |
233 | /// rustls enforces an arbitrary minimum of 32 bytes for this field. |
234 | /// Out of range values are reported as errors from [ServerConnection::new]. |
235 | /// |
236 | /// Setting this value to a little less than the TCP MSS may improve latency |
237 | /// for stream-y workloads. |
238 | /// |
239 | /// [TLS maximum]: https://datatracker.ietf.org/doc/html/rfc8446#section-5.1 |
240 | /// [ServerConnection::new]: crate::server::ServerConnection::new |
241 | pub max_fragment_size: Option<usize>, |
242 | |
243 | /// How to store client sessions. |
244 | pub session_storage: Arc<dyn StoresServerSessions + Send + Sync>, |
245 | |
246 | /// How to produce tickets. |
247 | pub ticketer: Arc<dyn ProducesTickets>, |
248 | |
249 | /// How to choose a server cert and key. This is usually set by |
250 | /// [ConfigBuilder::with_single_cert] or [ConfigBuilder::with_cert_resolver]. |
251 | /// For async applications, see also [Acceptor]. |
252 | pub cert_resolver: Arc<dyn ResolvesServerCert>, |
253 | |
254 | /// Protocol names we support, most preferred first. |
255 | /// If empty we don't do ALPN at all. |
256 | pub alpn_protocols: Vec<Vec<u8>>, |
257 | |
258 | /// Supported protocol versions, in no particular order. |
259 | /// The default is all supported versions. |
260 | pub(super) versions: crate::versions::EnabledVersions, |
261 | |
262 | /// How to verify client certificates. |
263 | pub(super) verifier: Arc<dyn verify::ClientCertVerifier>, |
264 | |
265 | /// How to output key material for debugging. The default |
266 | /// does nothing. |
267 | pub key_log: Arc<dyn KeyLog>, |
268 | |
269 | /// Allows traffic secrets to be extracted after the handshake, |
270 | /// e.g. for kTLS setup. |
271 | pub enable_secret_extraction: bool, |
272 | |
273 | /// Amount of early data to accept for sessions created by |
274 | /// this config. Specify 0 to disable early data. The |
275 | /// default is 0. |
276 | /// |
277 | /// Read the early data via [`ServerConnection::early_data`]. |
278 | /// |
279 | /// The units for this are _both_ plaintext bytes, _and_ ciphertext |
280 | /// bytes, depending on whether the server accepts a client's early_data |
281 | /// or not. It is therefore recommended to include some slop in |
282 | /// this value to account for the unknown amount of ciphertext |
283 | /// expansion in the latter case. |
284 | pub max_early_data_size: u32, |
285 | |
286 | /// Whether the server should send "0.5RTT" data. This means the server |
287 | /// sends data after its first flight of handshake messages, without |
288 | /// waiting for the client to complete the handshake. |
289 | /// |
290 | /// This can improve TTFB latency for either server-speaks-first protocols, |
291 | /// or client-speaks-first protocols when paired with "0RTT" data. This |
292 | /// comes at the cost of a subtle weakening of the normal handshake |
293 | /// integrity guarantees that TLS provides. Note that the initial |
294 | /// `ClientHello` is indirectly authenticated because it is included |
295 | /// in the transcript used to derive the keys used to encrypt the data. |
296 | /// |
297 | /// This only applies to TLS1.3 connections. TLS1.2 connections cannot |
298 | /// do this optimisation and this setting is ignored for them. It is |
299 | /// also ignored for TLS1.3 connections that even attempt client |
300 | /// authentication. |
301 | /// |
302 | /// This defaults to false. This means the first application data |
303 | /// sent by the server comes after receiving and validating the client's |
304 | /// handshake up to the `Finished` message. This is the safest option. |
305 | pub send_half_rtt_data: bool, |
306 | |
307 | /// How many TLS1.3 tickets to send immediately after a successful |
308 | /// handshake. |
309 | /// |
310 | /// Because TLS1.3 tickets are single-use, this allows |
311 | /// a client to perform multiple resumptions. |
312 | /// |
313 | /// The default is 4. |
314 | /// |
315 | /// If this is 0, no tickets are sent and clients will not be able to |
316 | /// do any resumption. |
317 | pub send_tls13_tickets: usize, |
318 | } |
319 | |
320 | // Avoid a `Clone` bound on `C`. |
321 | impl Clone for ServerConfig { |
322 | fn clone(&self) -> Self { |
323 | Self { |
324 | provider: Arc::<CryptoProvider>::clone(&self.provider), |
325 | ignore_client_order: self.ignore_client_order, |
326 | max_fragment_size: self.max_fragment_size, |
327 | session_storage: Arc::clone(&self.session_storage), |
328 | ticketer: Arc::clone(&self.ticketer), |
329 | cert_resolver: Arc::clone(&self.cert_resolver), |
330 | alpn_protocols: self.alpn_protocols.clone(), |
331 | versions: self.versions, |
332 | verifier: Arc::clone(&self.verifier), |
333 | key_log: Arc::clone(&self.key_log), |
334 | enable_secret_extraction: self.enable_secret_extraction, |
335 | max_early_data_size: self.max_early_data_size, |
336 | send_half_rtt_data: self.send_half_rtt_data, |
337 | send_tls13_tickets: self.send_tls13_tickets, |
338 | } |
339 | } |
340 | } |
341 | |
342 | impl ServerConfig { |
343 | /// Create a builder for a server configuration with the default |
344 | /// [`CryptoProvider`]: [`crypto::ring::default_provider`] and safe ciphersuite and protocol |
345 | /// defaults. |
346 | /// |
347 | /// For more information, see the [`ConfigBuilder`] documentation. |
348 | #[cfg (feature = "ring" )] |
349 | pub fn builder() -> ConfigBuilder<Self, WantsVerifier> { |
350 | // Safety: we know the *ring* provider's ciphersuites are compatible with the safe default protocol versions. |
351 | Self::builder_with_provider(crate::crypto::ring::default_provider().into()) |
352 | .with_safe_default_protocol_versions() |
353 | .unwrap() |
354 | } |
355 | |
356 | /// Create a builder for a server configuration with the default |
357 | /// [`CryptoProvider`]: [`crypto::ring::default_provider`], safe ciphersuite defaults and |
358 | /// the provided protocol versions. |
359 | /// |
360 | /// Panics if provided an empty slice of supported versions. |
361 | /// |
362 | /// For more information, see the [`ConfigBuilder`] documentation. |
363 | #[cfg (feature = "ring" )] |
364 | pub fn builder_with_protocol_versions( |
365 | versions: &[&'static versions::SupportedProtocolVersion], |
366 | ) -> ConfigBuilder<Self, WantsVerifier> { |
367 | // Safety: we know the *ring* provider's ciphersuites are compatible with all protocol version choices. |
368 | Self::builder_with_provider(crate::crypto::ring::default_provider().into()) |
369 | .with_protocol_versions(versions) |
370 | .unwrap() |
371 | } |
372 | |
373 | /// Create a builder for a server configuration with a specific [`CryptoProvider`]. |
374 | /// |
375 | /// This will use the provider's configured ciphersuites. You must additionally choose |
376 | /// which protocol versions to enable, using `with_protocol_versions` or |
377 | /// `with_safe_default_protocol_versions` and handling the `Result` in case a protocol |
378 | /// version is not supported by the provider's ciphersuites. |
379 | /// |
380 | /// For more information, see the [`ConfigBuilder`] documentation. |
381 | pub fn builder_with_provider( |
382 | provider: Arc<CryptoProvider>, |
383 | ) -> ConfigBuilder<Self, WantsVersions> { |
384 | ConfigBuilder { |
385 | state: WantsVersions { provider }, |
386 | side: PhantomData, |
387 | } |
388 | } |
389 | |
390 | /// We support a given TLS version if it's quoted in the configured |
391 | /// versions *and* at least one ciphersuite for this version is |
392 | /// also configured. |
393 | pub(crate) fn supports_version(&self, v: ProtocolVersion) -> bool { |
394 | self.versions.contains(v) |
395 | && self |
396 | .provider |
397 | .cipher_suites |
398 | .iter() |
399 | .any(|cs| cs.version().version == v) |
400 | } |
401 | |
402 | pub(crate) fn supports_protocol(&self, proto: Protocol) -> bool { |
403 | self.provider |
404 | .cipher_suites |
405 | .iter() |
406 | .any(|cs| cs.usable_for_protocol(proto)) |
407 | } |
408 | } |
409 | |
410 | /// Allows reading of early data in resumed TLS1.3 connections. |
411 | /// |
412 | /// "Early data" is also known as "0-RTT data". |
413 | /// |
414 | /// This structure implements [`std::io::Read`]. |
415 | pub struct ReadEarlyData<'a> { |
416 | early_data: &'a mut EarlyDataState, |
417 | } |
418 | |
419 | impl<'a> ReadEarlyData<'a> { |
420 | fn new(early_data: &'a mut EarlyDataState) -> Self { |
421 | ReadEarlyData { early_data } |
422 | } |
423 | } |
424 | |
425 | impl<'a> std::io::Read for ReadEarlyData<'a> { |
426 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
427 | self.early_data.read(buf) |
428 | } |
429 | |
430 | #[cfg (read_buf)] |
431 | fn read_buf(&mut self, cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> { |
432 | self.early_data.read_buf(cursor) |
433 | } |
434 | } |
435 | |
436 | /// This represents a single TLS server connection. |
437 | /// |
438 | /// Send TLS-protected data to the peer using the `io::Write` trait implementation. |
439 | /// Read data from the peer using the `io::Read` trait implementation. |
440 | pub struct ServerConnection { |
441 | inner: ConnectionCommon<ServerConnectionData>, |
442 | } |
443 | |
444 | impl ServerConnection { |
445 | /// Make a new ServerConnection. `config` controls how |
446 | /// we behave in the TLS protocol. |
447 | pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error> { |
448 | let mut common = CommonState::new(Side::Server); |
449 | common.set_max_fragment_size(config.max_fragment_size)?; |
450 | common.enable_secret_extraction = config.enable_secret_extraction; |
451 | Ok(Self { |
452 | inner: ConnectionCommon::from(ConnectionCore::for_server(config, Vec::new())?), |
453 | }) |
454 | } |
455 | |
456 | /// Retrieves the server name, if any, used to select the certificate and |
457 | /// private key. |
458 | /// |
459 | /// This returns `None` until some time after the client's server name indication |
460 | /// (SNI) extension value is processed during the handshake. It will never be |
461 | /// `None` when the connection is ready to send or process application data, |
462 | /// unless the client does not support SNI. |
463 | /// |
464 | /// This is useful for application protocols that need to enforce that the |
465 | /// server name matches an application layer protocol hostname. For |
466 | /// example, HTTP/1.1 servers commonly expect the `Host:` header field of |
467 | /// every request on a connection to match the hostname in the SNI extension |
468 | /// when the client provides the SNI extension. |
469 | /// |
470 | /// The server name is also used to match sessions during session resumption. |
471 | pub fn server_name(&self) -> Option<&str> { |
472 | self.inner.core.get_sni_str() |
473 | } |
474 | |
475 | /// Application-controlled portion of the resumption ticket supplied by the client, if any. |
476 | /// |
477 | /// Recovered from the prior session's `set_resumption_data`. Integrity is guaranteed by rustls. |
478 | /// |
479 | /// Returns `Some` iff a valid resumption ticket has been received from the client. |
480 | pub fn received_resumption_data(&self) -> Option<&[u8]> { |
481 | self.inner |
482 | .core |
483 | .data |
484 | .received_resumption_data |
485 | .as_ref() |
486 | .map(|x| &x[..]) |
487 | } |
488 | |
489 | /// Set the resumption data to embed in future resumption tickets supplied to the client. |
490 | /// |
491 | /// Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other |
492 | /// data. Should be called while `is_handshaking` returns true to ensure all transmitted |
493 | /// resumption tickets are affected. |
494 | /// |
495 | /// Integrity will be assured by rustls, but the data will be visible to the client. If secrecy |
496 | /// from the client is desired, encrypt the data separately. |
497 | pub fn set_resumption_data(&mut self, data: &[u8]) { |
498 | assert!(data.len() < 2usize.pow(15)); |
499 | self.inner.core.data.resumption_data = data.into(); |
500 | } |
501 | |
502 | /// Explicitly discard early data, notifying the client |
503 | /// |
504 | /// Useful if invariants encoded in `received_resumption_data()` cannot be respected. |
505 | /// |
506 | /// Must be called while `is_handshaking` is true. |
507 | pub fn reject_early_data(&mut self) { |
508 | self.inner.core.reject_early_data() |
509 | } |
510 | |
511 | /// Returns an `io::Read` implementer you can read bytes from that are |
512 | /// received from a client as TLS1.3 0RTT/"early" data, during the handshake. |
513 | /// |
514 | /// This returns `None` in many circumstances, such as : |
515 | /// |
516 | /// - Early data is disabled if [`ServerConfig::max_early_data_size`] is zero (the default). |
517 | /// - The session negotiated with the client is not TLS1.3. |
518 | /// - The client just doesn't support early data. |
519 | /// - The connection doesn't resume an existing session. |
520 | /// - The client hasn't sent a full ClientHello yet. |
521 | pub fn early_data(&mut self) -> Option<ReadEarlyData> { |
522 | let data = &mut self.inner.core.data; |
523 | if data.early_data.was_accepted() { |
524 | Some(ReadEarlyData::new(&mut data.early_data)) |
525 | } else { |
526 | None |
527 | } |
528 | } |
529 | |
530 | /// Extract secrets, so they can be used when configuring kTLS, for example. |
531 | /// Should be used with care as it exposes secret key material. |
532 | pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error> { |
533 | self.inner.dangerous_extract_secrets() |
534 | } |
535 | } |
536 | |
537 | impl Debug for ServerConnection { |
538 | fn fmt(&self, f: &mut Formatter) -> fmt::Result { |
539 | fDebugStruct<'_, '_>.debug_struct(name:"ServerConnection" ) |
540 | .finish() |
541 | } |
542 | } |
543 | |
544 | impl Deref for ServerConnection { |
545 | type Target = ConnectionCommon<ServerConnectionData>; |
546 | |
547 | fn deref(&self) -> &Self::Target { |
548 | &self.inner |
549 | } |
550 | } |
551 | |
552 | impl DerefMut for ServerConnection { |
553 | fn deref_mut(&mut self) -> &mut Self::Target { |
554 | &mut self.inner |
555 | } |
556 | } |
557 | |
558 | impl From<ServerConnection> for crate::Connection { |
559 | fn from(conn: ServerConnection) -> Self { |
560 | Self::Server(conn) |
561 | } |
562 | } |
563 | |
564 | /// Handle a server-side connection before configuration is available. |
565 | /// |
566 | /// `Acceptor` allows the caller to choose a [`ServerConfig`] after reading |
567 | /// the [`ClientHello`] of an incoming connection. This is useful for servers |
568 | /// that choose different certificates or cipher suites based on the |
569 | /// characteristics of the `ClientHello`. In particular it is useful for |
570 | /// servers that need to do some I/O to load a certificate and its private key |
571 | /// and don't want to use the blocking interface provided by |
572 | /// [`ResolvesServerCert`]. |
573 | /// |
574 | /// Create an Acceptor with [`Acceptor::default()`]. |
575 | /// |
576 | /// # Example |
577 | /// |
578 | /// ```no_run |
579 | /// # #[cfg (feature = "ring" )] { |
580 | /// # fn choose_server_config( |
581 | /// # _: rustls::server::ClientHello, |
582 | /// # ) -> std::sync::Arc<rustls::ServerConfig> { |
583 | /// # unimplemented!(); |
584 | /// # } |
585 | /// # #[allow (unused_variables)] |
586 | /// # fn main() { |
587 | /// use rustls::server::{Acceptor, ServerConfig}; |
588 | /// let listener = std::net::TcpListener::bind("127.0.0.1:0" ).unwrap(); |
589 | /// for stream in listener.incoming() { |
590 | /// let mut stream = stream.unwrap(); |
591 | /// let mut acceptor = Acceptor::default(); |
592 | /// let accepted = loop { |
593 | /// acceptor.read_tls(&mut stream).unwrap(); |
594 | /// if let Some(accepted) = acceptor.accept().unwrap() { |
595 | /// break accepted; |
596 | /// } |
597 | /// }; |
598 | /// |
599 | /// // For some user-defined choose_server_config: |
600 | /// let config = choose_server_config(accepted.client_hello()); |
601 | /// let conn = accepted |
602 | /// .into_connection(config) |
603 | /// .unwrap(); |
604 | |
605 | /// // Proceed with handling the ServerConnection. |
606 | /// } |
607 | /// # } |
608 | /// # } |
609 | /// ``` |
610 | pub struct Acceptor { |
611 | inner: Option<ConnectionCommon<ServerConnectionData>>, |
612 | } |
613 | |
614 | impl Default for Acceptor { |
615 | /// Return an empty Acceptor, ready to receive bytes from a new client connection. |
616 | fn default() -> Self { |
617 | Self { |
618 | inner: Some( |
619 | ConnectionCoreConnectionCore::new( |
620 | state:Box::new(Accepting), |
621 | data:ServerConnectionData::default(), |
622 | CommonState::new(Side::Server), |
623 | ) |
624 | .into(), |
625 | ), |
626 | } |
627 | } |
628 | } |
629 | |
630 | impl Acceptor { |
631 | /// Read TLS content from `rd`. |
632 | /// |
633 | /// Returns an error if this `Acceptor` has already yielded an [`Accepted`]. For more details, |
634 | /// refer to [`Connection::read_tls()`]. |
635 | /// |
636 | /// [`Connection::read_tls()`]: crate::Connection::read_tls |
637 | pub fn read_tls(&mut self, rd: &mut dyn io::Read) -> Result<usize, io::Error> { |
638 | match &mut self.inner { |
639 | Some(conn) => conn.read_tls(rd), |
640 | None => Err(io::Error::new( |
641 | io::ErrorKind::Other, |
642 | "acceptor cannot read after successful acceptance" , |
643 | )), |
644 | } |
645 | } |
646 | |
647 | /// Check if a `ClientHello` message has been received. |
648 | /// |
649 | /// Returns `Ok(None)` if the complete `ClientHello` has not yet been received. |
650 | /// Do more I/O and then call this function again. |
651 | /// |
652 | /// Returns `Ok(Some(accepted))` if the connection has been accepted. Call |
653 | /// `accepted.into_connection()` to continue. Do not call this function again. |
654 | /// |
655 | /// Returns `Err(err)` if an error occurred. Do not call this function again. |
656 | pub fn accept(&mut self) -> Result<Option<Accepted>, Error> { |
657 | let mut connection = match self.inner.take() { |
658 | Some(conn) => conn, |
659 | None => { |
660 | return Err(Error::General("Acceptor polled after completion" .into())); |
661 | } |
662 | }; |
663 | |
664 | let message = match connection.first_handshake_message()? { |
665 | Some(msg) => msg, |
666 | None => { |
667 | self.inner = Some(connection); |
668 | return Ok(None); |
669 | } |
670 | }; |
671 | |
672 | let (_, sig_schemes) = |
673 | hs::process_client_hello(&message, false, &mut Context::from(&mut connection))?; |
674 | |
675 | Ok(Some(Accepted { |
676 | connection, |
677 | message, |
678 | sig_schemes, |
679 | })) |
680 | } |
681 | } |
682 | |
683 | /// Represents a `ClientHello` message received through the [`Acceptor`]. |
684 | /// |
685 | /// Contains the state required to resume the connection through [`Accepted::into_connection()`]. |
686 | pub struct Accepted { |
687 | connection: ConnectionCommon<ServerConnectionData>, |
688 | message: Message, |
689 | sig_schemes: Vec<SignatureScheme>, |
690 | } |
691 | |
692 | impl Accepted { |
693 | /// Get the [`ClientHello`] for this connection. |
694 | pub fn client_hello(&self) -> ClientHello<'_> { |
695 | let payload = Self::client_hello_payload(&self.message); |
696 | ClientHello::new( |
697 | &self.connection.core.data.sni, |
698 | &self.sig_schemes, |
699 | payload.get_alpn_extension(), |
700 | &payload.cipher_suites, |
701 | ) |
702 | } |
703 | |
704 | /// Convert the [`Accepted`] into a [`ServerConnection`]. |
705 | /// |
706 | /// Takes the state returned from [`Acceptor::accept()`] as well as the [`ServerConfig`] and |
707 | /// [`sign::CertifiedKey`] that should be used for the session. Returns an error if |
708 | /// configuration-dependent validation of the received `ClientHello` message fails. |
709 | pub fn into_connection(mut self, config: Arc<ServerConfig>) -> Result<ServerConnection, Error> { |
710 | self.connection |
711 | .set_max_fragment_size(config.max_fragment_size)?; |
712 | |
713 | self.connection.enable_secret_extraction = config.enable_secret_extraction; |
714 | |
715 | let state = hs::ExpectClientHello::new(config, Vec::new()); |
716 | let mut cx = hs::ServerContext::from(&mut self.connection); |
717 | |
718 | let new = state.with_certified_key( |
719 | self.sig_schemes, |
720 | Self::client_hello_payload(&self.message), |
721 | &self.message, |
722 | &mut cx, |
723 | )?; |
724 | |
725 | self.connection.replace_state(new); |
726 | Ok(ServerConnection { |
727 | inner: self.connection, |
728 | }) |
729 | } |
730 | |
731 | fn client_hello_payload(message: &Message) -> &ClientHelloPayload { |
732 | match &message.payload { |
733 | crate::msgs::message::MessagePayload::Handshake { parsed, .. } => match &parsed.payload |
734 | { |
735 | crate::msgs::handshake::HandshakePayload::ClientHello(ch) => ch, |
736 | _ => unreachable!(), |
737 | }, |
738 | _ => unreachable!(), |
739 | } |
740 | } |
741 | } |
742 | |
743 | struct Accepting; |
744 | |
745 | impl State<ServerConnectionData> for Accepting { |
746 | fn handle( |
747 | self: Box<Self>, |
748 | _cx: &mut hs::ServerContext<'_>, |
749 | _m: Message, |
750 | ) -> Result<Box<dyn State<ServerConnectionData>>, Error> { |
751 | Err(Error::General("unreachable state" .into())) |
752 | } |
753 | } |
754 | |
755 | pub(super) enum EarlyDataState { |
756 | New, |
757 | Accepted(ChunkVecBuffer), |
758 | Rejected, |
759 | } |
760 | |
761 | impl Default for EarlyDataState { |
762 | fn default() -> Self { |
763 | Self::New |
764 | } |
765 | } |
766 | |
767 | impl EarlyDataState { |
768 | pub(super) fn reject(&mut self) { |
769 | *self = Self::Rejected; |
770 | } |
771 | |
772 | pub(super) fn accept(&mut self, max_size: usize) { |
773 | *self = Self::Accepted(ChunkVecBuffer::new(Some(max_size))); |
774 | } |
775 | |
776 | fn was_accepted(&self) -> bool { |
777 | matches!(self, Self::Accepted(_)) |
778 | } |
779 | |
780 | pub(super) fn was_rejected(&self) -> bool { |
781 | matches!(self, Self::Rejected) |
782 | } |
783 | |
784 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
785 | match self { |
786 | Self::Accepted(ref mut received) => received.read(buf), |
787 | _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)), |
788 | } |
789 | } |
790 | |
791 | #[cfg (read_buf)] |
792 | fn read_buf(&mut self, cursor: core::io::BorrowedCursor<'_>) -> io::Result<()> { |
793 | match self { |
794 | Self::Accepted(ref mut received) => received.read_buf(cursor), |
795 | _ => Err(io::Error::from(io::ErrorKind::BrokenPipe)), |
796 | } |
797 | } |
798 | |
799 | pub(super) fn take_received_plaintext(&mut self, bytes: Payload) -> bool { |
800 | let available = bytes.0.len(); |
801 | match self { |
802 | Self::Accepted(ref mut received) if received.apply_limit(available) == available => { |
803 | received.append(bytes.0); |
804 | true |
805 | } |
806 | _ => false, |
807 | } |
808 | } |
809 | } |
810 | |
811 | impl Debug for EarlyDataState { |
812 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
813 | match self { |
814 | Self::New => write!(f, "EarlyDataState::New" ), |
815 | Self::Accepted(buf: &ChunkVecBuffer) => write!(f, "EarlyDataState::Accepted( {})" , buf.len()), |
816 | Self::Rejected => write!(f, "EarlyDataState::Rejected" ), |
817 | } |
818 | } |
819 | } |
820 | |
821 | impl ConnectionCore<ServerConnectionData> { |
822 | pub(crate) fn for_server( |
823 | config: Arc<ServerConfig>, |
824 | extra_exts: Vec<ServerExtension>, |
825 | ) -> Result<Self, Error> { |
826 | let mut common = CommonState::new(Side::Server); |
827 | common.set_max_fragment_size(config.max_fragment_size)?; |
828 | common.enable_secret_extraction = config.enable_secret_extraction; |
829 | Ok(Self::new( |
830 | Box::new(hs::ExpectClientHello::new(config, extra_exts)), |
831 | ServerConnectionData::default(), |
832 | common, |
833 | )) |
834 | } |
835 | |
836 | pub(crate) fn reject_early_data(&mut self) { |
837 | assert!( |
838 | self.common_state.is_handshaking(), |
839 | "cannot retroactively reject early data" |
840 | ); |
841 | self.data.early_data.reject(); |
842 | } |
843 | |
844 | pub(crate) fn get_sni_str(&self) -> Option<&str> { |
845 | self.data.get_sni_str() |
846 | } |
847 | } |
848 | |
849 | /// State associated with a server connection. |
850 | #[derive (Default, Debug)] |
851 | pub struct ServerConnectionData { |
852 | pub(super) sni: Option<DnsName<'static>>, |
853 | pub(super) received_resumption_data: Option<Vec<u8>>, |
854 | pub(super) resumption_data: Vec<u8>, |
855 | pub(super) early_data: EarlyDataState, |
856 | } |
857 | |
858 | impl ServerConnectionData { |
859 | pub(super) fn get_sni_str(&self) -> Option<&str> { |
860 | self.sni.as_ref().map(AsRef::as_ref) |
861 | } |
862 | } |
863 | |
864 | impl crate::conn::SideData for ServerConnectionData {} |
865 | |
866 | #[cfg (test)] |
867 | mod tests { |
868 | use super::*; |
869 | |
870 | // these branches not reachable externally, unless something else goes wrong. |
871 | #[test ] |
872 | fn test_read_in_new_state() { |
873 | assert_eq!( |
874 | format!("{:?}" , EarlyDataState::default().read(&mut [0u8; 5])), |
875 | "Err(Kind(BrokenPipe))" |
876 | ); |
877 | } |
878 | |
879 | #[cfg (read_buf)] |
880 | #[test ] |
881 | fn test_read_buf_in_new_state() { |
882 | use core::io::BorrowedBuf; |
883 | |
884 | let mut buf = [0u8; 5]; |
885 | let mut buf: BorrowedBuf<'_> = buf.as_mut_slice().into(); |
886 | assert_eq!( |
887 | format!("{:?}" , EarlyDataState::default().read_buf(buf.unfilled())), |
888 | "Err(Kind(BrokenPipe))" |
889 | ); |
890 | } |
891 | } |
892 | |