1 use crate::builder::{ConfigBuilder, WantsCipherSuites};
2 use crate::conn::{CommonState, ConnectionCommon, Protocol};
3 use crate::error::Error;
4 use crate::keylog::KeyLog;
5 use crate::kx::SupportedKxGroup;
6 #[cfg(feature = "logging")]
7 use crate::log::trace;
8 #[cfg(feature = "quic")]
9 use crate::msgs::enums::AlertDescription;
10 use crate::msgs::enums::CipherSuite;
11 use crate::msgs::enums::ProtocolVersion;
12 use crate::msgs::enums::SignatureScheme;
13 use crate::msgs::handshake::ClientExtension;
14 use crate::sign;
15 use crate::suites::SupportedCipherSuite;
16 use crate::verify;
17 use crate::versions;
18 
19 use super::hs;
20 #[cfg(feature = "quic")]
21 use crate::quic;
22 
23 use std::convert::TryFrom;
24 use std::error::Error as StdError;
25 use std::marker::PhantomData;
26 use std::ops::{Deref, DerefMut};
27 use std::sync::Arc;
28 use std::{fmt, io, mem};
29 
30 /// A trait for the ability to store client session data.
31 /// The keys and values are opaque.
32 ///
33 /// Both the keys and values should be treated as
34 /// **highly sensitive data**, containing enough key material
35 /// to break all security of the corresponding session.
36 ///
37 /// `put` is a mutating operation; this isn't expressed
38 /// in the type system to allow implementations freedom in
39 /// how to achieve interior mutability.  `Mutex` is a common
40 /// choice.
41 pub trait StoresClientSessions: Send + Sync {
42     /// Stores a new `value` for `key`.  Returns `true`
43     /// if the value was stored.
44     fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool;
45 
46     /// Returns the latest value for `key`.  Returns `None`
47     /// if there's no such value.
48     fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
49 }
50 
51 /// A trait for the ability to choose a certificate chain and
52 /// private key for the purposes of client authentication.
53 pub trait ResolvesClientCert: Send + Sync {
54     /// With the server-supplied acceptable issuers in `acceptable_issuers`,
55     /// the server's supported signature schemes in `sigschemes`,
56     /// return a certificate chain and signing key to authenticate.
57     ///
58     /// `acceptable_issuers` is undecoded and unverified by the rustls
59     /// library, but it should be expected to contain a DER encodings
60     /// of X501 NAMEs.
61     ///
62     /// Return None to continue the handshake without any client
63     /// authentication.  The server may reject the handshake later
64     /// if it requires authentication.
65     fn resolve(
66         &self,
67         acceptable_issuers: &[&[u8]],
68         sigschemes: &[SignatureScheme],
69     ) -> Option<Arc<sign::CertifiedKey>>;
70 
71     /// Return true if any certificates at all are available.
72     fn has_certs(&self) -> bool;
73 }
74 
75 /// Common configuration for (typically) all connections made by
76 /// a program.
77 ///
78 /// Making one of these can be expensive, and should be
79 /// once per process rather than once per connection.
80 ///
81 /// These must be created via the [`ClientConfig::builder()`] function.
82 ///
83 /// # Defaults
84 ///
85 /// * [`ClientConfig::max_fragment_size`]: the default is `None`: TLS packets are not fragmented to a specific size.
86 /// * [`ClientConfig::session_storage`]: the default stores 256 sessions in memory.
87 /// * [`ClientConfig::alpn_protocols`]: the default is empty -- no ALPN protocol is negotiated.
88 /// * [`ClientConfig::key_log`]: key material is not logged.
89 #[derive(Clone)]
90 pub struct ClientConfig {
91     /// List of ciphersuites, in preference order.
92     pub(super) cipher_suites: Vec<SupportedCipherSuite>,
93 
94     /// List of supported key exchange algorithms, in preference order -- the
95     /// first element is the highest priority.
96     ///
97     /// The first element in this list is the _default key share algorithm_,
98     /// and in TLS1.3 a key share for it is sent in the client hello.
99     pub(super) kx_groups: Vec<&'static SupportedKxGroup>,
100 
101     /// Which ALPN protocols we include in our client hello.
102     /// If empty, no ALPN extension is sent.
103     pub alpn_protocols: Vec<Vec<u8>>,
104 
105     /// How we store session data or tickets.
106     pub session_storage: Arc<dyn StoresClientSessions>,
107 
108     /// The maximum size of TLS message we'll emit.  If None, we don't limit TLS
109     /// message lengths except to the 2**16 limit specified in the standard.
110     ///
111     /// rustls enforces an arbitrary minimum of 32 bytes for this field.
112     /// Out of range values are reported as errors from ClientConnection::new.
113     ///
114     /// Setting this value to the TCP MSS may improve latency for stream-y workloads.
115     pub max_fragment_size: Option<usize>,
116 
117     /// How to decide what client auth certificate/keys to use.
118     pub client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
119 
120     /// Whether to support RFC5077 tickets.  You must provide a working
121     /// `session_storage` member for this to have any meaningful
122     /// effect.
123     ///
124     /// The default is true.
125     pub enable_tickets: bool,
126 
127     /// Supported versions, in no particular order.  The default
128     /// is all supported versions.
129     pub(super) versions: versions::EnabledVersions,
130 
131     /// Whether to send the Server Name Indication (SNI) extension
132     /// during the client handshake.
133     ///
134     /// The default is true.
135     pub enable_sni: bool,
136 
137     /// How to verify the server certificate chain.
138     pub(super) verifier: Arc<dyn verify::ServerCertVerifier>,
139 
140     /// How to output key material for debugging.  The default
141     /// does nothing.
142     pub key_log: Arc<dyn KeyLog>,
143 
144     /// Whether to send data on the first flight ("early data") in
145     /// TLS 1.3 handshakes.
146     ///
147     /// The default is false.
148     pub enable_early_data: bool,
149 }
150 
151 impl ClientConfig {
152     /// Create a builder to build up the client configuration.
153     ///
154     /// For more information, see the [`ConfigBuilder`] documentation.
155     pub fn builder() -> ConfigBuilder<Self, WantsCipherSuites> {
156         ConfigBuilder {
157             state: WantsCipherSuites(()),
158             side: PhantomData::default(),
159         }
160     }
161 
162     #[doc(hidden)]
163     /// We support a given TLS version if it's quoted in the configured
164     /// versions *and* at least one ciphersuite for this version is
165     /// also configured.
166     pub fn supports_version(&self, v: ProtocolVersion) -> bool {
167         self.versions.contains(v)
168             && self
169                 .cipher_suites
170                 .iter()
171                 .any(|cs| cs.version().version == v)
172     }
173 
174     /// Access configuration options whose use is dangerous and requires
175     /// extra care.
176     #[cfg(feature = "dangerous_configuration")]
177     pub fn dangerous(&mut self) -> danger::DangerousClientConfig {
178         danger::DangerousClientConfig { cfg: self }
179     }
180 
181     pub(super) fn find_cipher_suite(&self, suite: CipherSuite) -> Option<SupportedCipherSuite> {
182         self.cipher_suites
183             .iter()
184             .copied()
185             .find(|&scs| scs.suite() == suite)
186     }
187 }
188 
189 /// Encodes ways a client can know the expected name of the server.
190 ///
191 /// This currently covers knowing the DNS name of the server, but
192 /// will be extended in the future to knowing the IP address of the
193 /// server, as well as supporting privacy-preserving names for the
194 /// server ("ECH").  For this reason this enum is `non_exhaustive`.
195 ///
196 /// # Making one
197 ///
198 /// If you have a DNS name as a `&str`, this type implements `TryFrom<&str>`,
199 /// so you can do:
200 ///
201 /// ```
202 /// # use std::convert::{TryInto, TryFrom};
203 /// # use rustls::ServerName;
204 /// ServerName::try_from("example.com").expect("invalid DNS name");
205 ///
206 /// // or, alternatively...
207 ///
208 /// let x = "example.com".try_into().expect("invalid DNS name");
209 /// # let _: ServerName = x;
210 /// ```
211 #[non_exhaustive]
212 #[derive(Debug, PartialEq, Clone)]
213 pub enum ServerName {
214     /// The server is identified by a DNS name.  The name
215     /// is sent in the TLS Server Name Indication (SNI)
216     /// extension.
217     DnsName(verify::DnsName),
218 }
219 
220 impl ServerName {
221     /// Return the name that should go in the SNI extension.
222     /// If [`None`] is returned, the SNI extension is not included
223     /// in the handshake.
224     pub(crate) fn for_sni(&self) -> Option<webpki::DnsNameRef> {
225         match self {
226             Self::DnsName(dns_name) => Some(dns_name.0.as_ref()),
227         }
228     }
229 
230     /// Return a prefix-free, unique encoding for the name.
231     pub(crate) fn encode(&self) -> Vec<u8> {
232         enum UniqueTypeCode {
233             DnsName = 0x01,
234         }
235 
236         let Self::DnsName(dns_name) = self;
237         let bytes = dns_name.0.as_ref();
238 
239         let mut r = Vec::with_capacity(2 + bytes.as_ref().len());
240         r.push(UniqueTypeCode::DnsName as u8);
241         r.push(bytes.as_ref().len() as u8);
242         r.extend_from_slice(bytes.as_ref());
243 
244         r
245     }
246 }
247 
248 /// Attempt to make a ServerName from a string by parsing
249 /// it as a DNS name.
250 impl TryFrom<&str> for ServerName {
251     type Error = InvalidDnsNameError;
252     fn try_from(s: &str) -> Result<Self, Self::Error> {
253         match webpki::DnsNameRef::try_from_ascii_str(s) {
254             Ok(dns) => Ok(Self::DnsName(verify::DnsName(dns.into()))),
255             Err(webpki::InvalidDnsNameError) => Err(InvalidDnsNameError),
256         }
257     }
258 }
259 
260 /// The provided input could not be parsed because
261 /// it is not a syntactically-valid DNS Name.
262 #[derive(Debug)]
263 pub struct InvalidDnsNameError;
264 
265 impl fmt::Display for InvalidDnsNameError {
266     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267         f.write_str("invalid dns name")
268     }
269 }
270 
271 impl StdError for InvalidDnsNameError {}
272 
273 /// Container for unsafe APIs
274 #[cfg(feature = "dangerous_configuration")]
275 pub(super) mod danger {
276     use std::sync::Arc;
277 
278     use super::verify::ServerCertVerifier;
279     use super::ClientConfig;
280 
281     /// Accessor for dangerous configuration options.
282     pub struct DangerousClientConfig<'a> {
283         /// The underlying ClientConfig
284         pub cfg: &'a mut ClientConfig,
285     }
286 
287     impl<'a> DangerousClientConfig<'a> {
288         /// Overrides the default `ServerCertVerifier` with something else.
289         pub fn set_certificate_verifier(&mut self, verifier: Arc<dyn ServerCertVerifier>) {
290             self.cfg.verifier = verifier;
291         }
292     }
293 }
294 
295 #[derive(Debug, PartialEq)]
296 enum EarlyDataState {
297     Disabled,
298     Ready,
299     Accepted,
300     AcceptedFinished,
301     Rejected,
302 }
303 
304 pub(super) struct EarlyData {
305     state: EarlyDataState,
306     left: usize,
307 }
308 
309 impl EarlyData {
310     fn new() -> Self {
311         Self {
312             left: 0,
313             state: EarlyDataState::Disabled,
314         }
315     }
316 
317     pub(super) fn is_enabled(&self) -> bool {
318         matches!(self.state, EarlyDataState::Ready | EarlyDataState::Accepted)
319     }
320 
321     fn is_accepted(&self) -> bool {
322         matches!(
323             self.state,
324             EarlyDataState::Accepted | EarlyDataState::AcceptedFinished
325         )
326     }
327 
328     pub(super) fn enable(&mut self, max_data: usize) {
329         assert_eq!(self.state, EarlyDataState::Disabled);
330         self.state = EarlyDataState::Ready;
331         self.left = max_data;
332     }
333 
334     pub(super) fn rejected(&mut self) {
335         trace!("EarlyData rejected");
336         self.state = EarlyDataState::Rejected;
337     }
338 
339     pub(super) fn accepted(&mut self) {
340         trace!("EarlyData accepted");
341         assert_eq!(self.state, EarlyDataState::Ready);
342         self.state = EarlyDataState::Accepted;
343     }
344 
345     pub(super) fn finished(&mut self) {
346         trace!("EarlyData finished");
347         self.state = match self.state {
348             EarlyDataState::Accepted => EarlyDataState::AcceptedFinished,
349             _ => panic!("bad EarlyData state"),
350         }
351     }
352 
353     fn check_write(&mut self, sz: usize) -> io::Result<usize> {
354         match self.state {
355             EarlyDataState::Disabled => unreachable!(),
356             EarlyDataState::Ready | EarlyDataState::Accepted => {
357                 let take = if self.left < sz {
358                     mem::replace(&mut self.left, 0)
359                 } else {
360                     self.left -= sz;
361                     sz
362                 };
363 
364                 Ok(take)
365             }
366             EarlyDataState::Rejected | EarlyDataState::AcceptedFinished => {
367                 Err(io::Error::from(io::ErrorKind::InvalidInput))
368             }
369         }
370     }
371 
372     fn bytes_left(&self) -> usize {
373         self.left
374     }
375 }
376 
377 /// Stub that implements io::Write and dispatches to `write_early_data`.
378 pub struct WriteEarlyData<'a> {
379     sess: &'a mut ClientConnection,
380 }
381 
382 impl<'a> WriteEarlyData<'a> {
383     fn new(sess: &'a mut ClientConnection) -> WriteEarlyData<'a> {
384         WriteEarlyData { sess }
385     }
386 
387     /// How many bytes you may send.  Writes will become short
388     /// once this reaches zero.
389     pub fn bytes_left(&self) -> usize {
390         self.sess
391             .inner
392             .data
393             .early_data
394             .bytes_left()
395     }
396 }
397 
398 impl<'a> io::Write for WriteEarlyData<'a> {
399     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
400         self.sess.write_early_data(buf)
401     }
402 
403     fn flush(&mut self) -> io::Result<()> {
404         Ok(())
405     }
406 }
407 
408 /// This represents a single TLS client connection.
409 pub struct ClientConnection {
410     inner: ConnectionCommon<ClientConnectionData>,
411 }
412 
413 impl fmt::Debug for ClientConnection {
414     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415         f.debug_struct("ClientConnection")
416             .finish()
417     }
418 }
419 
420 impl ClientConnection {
421     /// Make a new ClientConnection.  `config` controls how
422     /// we behave in the TLS protocol, `name` is the
423     /// name of the server we want to talk to.
424     pub fn new(config: Arc<ClientConfig>, name: ServerName) -> Result<Self, Error> {
425         Self::new_inner(config, name, Vec::new(), Protocol::Tcp)
426     }
427 
428     fn new_inner(
429         config: Arc<ClientConfig>,
430         name: ServerName,
431         extra_exts: Vec<ClientExtension>,
432         proto: Protocol,
433     ) -> Result<Self, Error> {
434         let mut common_state = CommonState::new(config.max_fragment_size, true)?;
435         common_state.protocol = proto;
436         let mut data = ClientConnectionData::new();
437 
438         let mut cx = hs::ClientContext {
439             common: &mut common_state,
440             data: &mut data,
441         };
442 
443         let state = hs::start_handshake(name, extra_exts, config, &mut cx)?;
444         let inner = ConnectionCommon::new(state, data, common_state);
445 
446         Ok(Self { inner })
447     }
448 
449     /// Returns an `io::Write` implementer you can write bytes to
450     /// to send TLS1.3 early data (a.k.a. "0-RTT data") to the server.
451     ///
452     /// This returns None in many circumstances when the capability to
453     /// send early data is not available, including but not limited to:
454     ///
455     /// - The server hasn't been talked to previously.
456     /// - The server does not support resumption.
457     /// - The server does not support early data.
458     /// - The resumption data for the server has expired.
459     ///
460     /// The server specifies a maximum amount of early data.  You can
461     /// learn this limit through the returned object, and writes through
462     /// it will process only this many bytes.
463     ///
464     /// The server can choose not to accept any sent early data --
465     /// in this case the data is lost but the connection continues.  You
466     /// can tell this happened using `is_early_data_accepted`.
467     pub fn early_data(&mut self) -> Option<WriteEarlyData> {
468         if self.inner.data.early_data.is_enabled() {
469             Some(WriteEarlyData::new(self))
470         } else {
471             None
472         }
473     }
474 
475     /// Returns True if the server signalled it will process early data.
476     ///
477     /// If you sent early data and this returns false at the end of the
478     /// handshake then the server will not process the data.  This
479     /// is not an error, but you may wish to resend the data.
480     pub fn is_early_data_accepted(&self) -> bool {
481         self.inner.data.early_data.is_accepted()
482     }
483 
484     fn write_early_data(&mut self, data: &[u8]) -> io::Result<usize> {
485         self.inner
486             .data
487             .early_data
488             .check_write(data.len())
489             .map(|sz| {
490                 self.inner
491                     .common_state
492                     .send_early_plaintext(&data[..sz])
493             })
494     }
495 }
496 
497 impl Deref for ClientConnection {
498     type Target = ConnectionCommon<ClientConnectionData>;
499 
500     fn deref(&self) -> &Self::Target {
501         &self.inner
502     }
503 }
504 
505 impl DerefMut for ClientConnection {
506     fn deref_mut(&mut self) -> &mut Self::Target {
507         &mut self.inner
508     }
509 }
510 
511 #[doc(hidden)]
512 impl<'a> TryFrom<&'a mut crate::Connection> for &'a mut ClientConnection {
513     type Error = ();
514 
515     fn try_from(value: &'a mut crate::Connection) -> Result<Self, Self::Error> {
516         use crate::Connection::*;
517         match value {
518             Client(conn) => Ok(conn),
519             Server(_) => Err(()),
520         }
521     }
522 }
523 
524 impl From<ClientConnection> for crate::Connection {
525     fn from(conn: ClientConnection) -> Self {
526         Self::Client(conn)
527     }
528 }
529 
530 /// State associated with a client connection.
531 pub struct ClientConnectionData {
532     pub(super) early_data: EarlyData,
533     pub(super) resumption_ciphersuite: Option<SupportedCipherSuite>,
534 }
535 
536 impl ClientConnectionData {
537     fn new() -> Self {
538         Self {
539             early_data: EarlyData::new(),
540             resumption_ciphersuite: None,
541         }
542     }
543 }
544 
545 impl crate::conn::SideData for ClientConnectionData {}
546 
547 #[cfg(feature = "quic")]
548 impl quic::QuicExt for ClientConnection {
549     fn quic_transport_parameters(&self) -> Option<&[u8]> {
550         self.inner
551             .common_state
552             .quic
553             .params
554             .as_ref()
555             .map(|v| v.as_ref())
556     }
557 
558     fn zero_rtt_keys(&self) -> Option<quic::DirectionalKeys> {
559         Some(quic::DirectionalKeys::new(
560             self.inner
561                 .data
562                 .resumption_ciphersuite
563                 .and_then(|suite| suite.tls13())?,
564             self.inner
565                 .common_state
566                 .quic
567                 .early_secret
568                 .as_ref()?,
569         ))
570     }
571 
572     fn read_hs(&mut self, plaintext: &[u8]) -> Result<(), Error> {
573         self.inner.read_quic_hs(plaintext)
574     }
575 
576     fn write_hs(&mut self, buf: &mut Vec<u8>) -> Option<quic::KeyChange> {
577         quic::write_hs(&mut self.inner.common_state, buf)
578     }
579 
580     fn alert(&self) -> Option<AlertDescription> {
581         self.inner.common_state.quic.alert
582     }
583 }
584 
585 /// Methods specific to QUIC client sessions
586 #[cfg(feature = "quic")]
587 pub trait ClientQuicExt {
588     /// Make a new QUIC ClientConnection. This differs from `ClientConnection::new()`
589     /// in that it takes an extra argument, `params`, which contains the
590     /// TLS-encoded transport parameters to send.
591     fn new_quic(
592         config: Arc<ClientConfig>,
593         quic_version: quic::Version,
594         name: ServerName,
595         params: Vec<u8>,
596     ) -> Result<ClientConnection, Error> {
597         if !config.supports_version(ProtocolVersion::TLSv1_3) {
598             return Err(Error::General(
599                 "TLS 1.3 support is required for QUIC".into(),
600             ));
601         }
602 
603         let ext = match quic_version {
604             quic::Version::V1Draft => ClientExtension::TransportParametersDraft(params),
605             quic::Version::V1 => ClientExtension::TransportParameters(params),
606         };
607 
608         ClientConnection::new_inner(config, name, vec![ext], Protocol::Quic)
609     }
610 }
611 
612 #[cfg(feature = "quic")]
613 impl ClientQuicExt for ClientConnection {}
614