rustls/
versions.rs

1use std::fmt;
2
3use crate::enums::ProtocolVersion;
4
5/// A TLS protocol version supported by rustls.
6///
7/// All possible instances of this class are provided by the library in
8/// the [`ALL_VERSIONS`] array, as well as individually as [`TLS12`]
9/// and [`TLS13`].
10#[derive(Eq, PartialEq)]
11#[allow(clippy::manual_non_exhaustive)] // Fixed in main
12pub struct SupportedProtocolVersion {
13    /// The TLS enumeration naming this version.
14    pub version: ProtocolVersion,
15    is_private: (),
16}
17
18impl fmt::Debug for SupportedProtocolVersion {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        self.version.fmt(f)
21    }
22}
23
24/// TLS1.2
25#[cfg(feature = "tls12")]
26pub static TLS12: SupportedProtocolVersion = SupportedProtocolVersion {
27    version: ProtocolVersion::TLSv1_2,
28    is_private: (),
29};
30
31/// TLS1.3
32pub static TLS13: SupportedProtocolVersion = SupportedProtocolVersion {
33    version: ProtocolVersion::TLSv1_3,
34    is_private: (),
35};
36
37/// A list of all the protocol versions supported by rustls.
38pub static ALL_VERSIONS: &[&SupportedProtocolVersion] = &[
39    &TLS13,
40    #[cfg(feature = "tls12")]
41    &TLS12,
42];
43
44/// The version configuration that an application should use by default.
45///
46/// This will be [`ALL_VERSIONS`] for now, but gives space in the future
47/// to remove a version from here and require users to opt-in to older
48/// versions.
49pub static DEFAULT_VERSIONS: &[&SupportedProtocolVersion] = ALL_VERSIONS;
50
51#[derive(Clone)]
52pub(crate) struct EnabledVersions {
53    #[cfg(feature = "tls12")]
54    tls12: Option<&'static SupportedProtocolVersion>,
55    tls13: Option<&'static SupportedProtocolVersion>,
56}
57
58impl fmt::Debug for EnabledVersions {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        let mut list = &mut f.debug_list();
61        #[cfg(feature = "tls12")]
62        if let Some(v) = self.tls12 {
63            list = list.entry(v);
64        }
65        if let Some(v) = self.tls13 {
66            list = list.entry(v);
67        }
68        list.finish()
69    }
70}
71
72impl EnabledVersions {
73    pub(crate) fn new(versions: &[&'static SupportedProtocolVersion]) -> Self {
74        let mut ev = Self {
75            #[cfg(feature = "tls12")]
76            tls12: None,
77            tls13: None,
78        };
79
80        for v in versions {
81            match v.version {
82                #[cfg(feature = "tls12")]
83                ProtocolVersion::TLSv1_2 => ev.tls12 = Some(v),
84                ProtocolVersion::TLSv1_3 => ev.tls13 = Some(v),
85                _ => {}
86            }
87        }
88
89        ev
90    }
91
92    pub(crate) fn contains(&self, version: ProtocolVersion) -> bool {
93        match version {
94            #[cfg(feature = "tls12")]
95            ProtocolVersion::TLSv1_2 => self.tls12.is_some(),
96            ProtocolVersion::TLSv1_3 => self.tls13.is_some(),
97            _ => false,
98        }
99    }
100}