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