/src/suricata8/rust/src/tls_version.rs
Line | Count | Source |
1 | | use std::borrow::Cow; |
2 | | use std::ffi::c_char; |
3 | | use std::ptr; |
4 | | |
5 | | /* Max string length of the TLS version string */ |
6 | | pub const SSL_VERSION_MAX_STRLEN: usize = 20; |
7 | | |
8 | | // Enum as constants for C ABI |
9 | | pub const TLS_VERSION_UNKNOWN: u16 = 0x0000; |
10 | | pub const SSL_VERSION_2: u16 = 0x0200; |
11 | | pub const SSL_VERSION_3: u16 = 0x0300; |
12 | | pub const TLS_VERSION_10: u16 = 0x0301; |
13 | | pub const TLS_VERSION_11: u16 = 0x0302; |
14 | | pub const TLS_VERSION_12: u16 = 0x0303; |
15 | | pub const TLS_VERSION_13: u16 = 0x0304; |
16 | | pub const TLS_VERSION_13_DRAFT28: u16 = 0x7f1c; |
17 | | pub const TLS_VERSION_13_DRAFT27: u16 = 0x7f1b; |
18 | | pub const TLS_VERSION_13_DRAFT26: u16 = 0x7f1a; |
19 | | pub const TLS_VERSION_13_DRAFT25: u16 = 0x7f19; |
20 | | pub const TLS_VERSION_13_DRAFT24: u16 = 0x7f18; |
21 | | pub const TLS_VERSION_13_DRAFT23: u16 = 0x7f17; |
22 | | pub const TLS_VERSION_13_DRAFT22: u16 = 0x7f16; |
23 | | pub const TLS_VERSION_13_DRAFT21: u16 = 0x7f15; |
24 | | pub const TLS_VERSION_13_DRAFT20: u16 = 0x7f14; |
25 | | pub const TLS_VERSION_13_DRAFT19: u16 = 0x7f13; |
26 | | pub const TLS_VERSION_13_DRAFT18: u16 = 0x7f12; |
27 | | pub const TLS_VERSION_13_DRAFT17: u16 = 0x7f11; |
28 | | pub const TLS_VERSION_13_DRAFT16: u16 = 0x7f10; |
29 | | pub const TLS_VERSION_13_PRE_DRAFT16: u16 = 0x7f01; |
30 | | pub const TLS_VERSION_13_DRAFT20_FB: u16 = 0xfb14; |
31 | | pub const TLS_VERSION_13_DRAFT21_FB: u16 = 0xfb15; |
32 | | pub const TLS_VERSION_13_DRAFT22_FB: u16 = 0xfb16; |
33 | | pub const TLS_VERSION_13_DRAFT23_FB: u16 = 0xfb17; |
34 | | pub const TLS_VERSION_13_DRAFT26_FB: u16 = 0xfb1a; |
35 | | |
36 | | /* SSL versions. We'll use a unified format for all, with the top byte |
37 | | * holding the major version and the lower byte the minor version */ |
38 | | #[repr(u16)] |
39 | | #[derive(Default)] |
40 | | pub enum SCTlsVersion { |
41 | | #[default] |
42 | | Unknown = TLS_VERSION_UNKNOWN, |
43 | | SslV2 = SSL_VERSION_2, |
44 | | SslV3 = SSL_VERSION_3, |
45 | | TlsV1_0 = TLS_VERSION_10, |
46 | | TlsV1_1 = TLS_VERSION_11, |
47 | | TlsV1_2 = TLS_VERSION_12, |
48 | | TlsV1_3 = TLS_VERSION_13, |
49 | | Tls13Draft28 = TLS_VERSION_13_DRAFT28, |
50 | | Tls13Draft27 = TLS_VERSION_13_DRAFT27, |
51 | | Tls13Draft26 = TLS_VERSION_13_DRAFT26, |
52 | | Tls13Draft25 = TLS_VERSION_13_DRAFT25, |
53 | | Tls13Draft24 = TLS_VERSION_13_DRAFT24, |
54 | | Tls13Draft23 = TLS_VERSION_13_DRAFT23, |
55 | | Tls13Draft22 = TLS_VERSION_13_DRAFT22, |
56 | | Tls13Draft21 = TLS_VERSION_13_DRAFT21, |
57 | | Tls13Draft20 = TLS_VERSION_13_DRAFT20, |
58 | | Tls13Draft19 = TLS_VERSION_13_DRAFT19, |
59 | | Tls13Draft18 = TLS_VERSION_13_DRAFT18, |
60 | | Tls13Draft17 = TLS_VERSION_13_DRAFT17, |
61 | | Tls13Draft16 = TLS_VERSION_13_DRAFT16, |
62 | | Tls13PreDraft16 = TLS_VERSION_13_PRE_DRAFT16, |
63 | | Tls13Draft20Fb = TLS_VERSION_13_DRAFT20_FB, |
64 | | Tls13Draft21Fb = TLS_VERSION_13_DRAFT21_FB, |
65 | | Tls13Draft22Fb = TLS_VERSION_13_DRAFT22_FB, |
66 | | Tls13Draft23Fb = TLS_VERSION_13_DRAFT23_FB, |
67 | | Tls13Draft26Fb = TLS_VERSION_13_DRAFT26_FB, |
68 | | } |
69 | | |
70 | | impl TryFrom<u16> for SCTlsVersion { |
71 | | type Error = (); |
72 | | |
73 | 99.8k | fn try_from(v: u16) -> Result<Self, Self::Error> { |
74 | 99.8k | match v { |
75 | 1.42k | 0x0000 => Ok(Self::Unknown), |
76 | 185 | 0x0200 => Ok(Self::SslV2), |
77 | 5.30k | 0x0300 => Ok(Self::SslV3), |
78 | 27.9k | 0x0301 => Ok(Self::TlsV1_0), |
79 | 13.6k | 0x0302 => Ok(Self::TlsV1_1), |
80 | 498 | 0x0303 => Ok(Self::TlsV1_2), |
81 | 100 | 0x0304 => Ok(Self::TlsV1_3), |
82 | 221 | 0x7f1c => Ok(Self::Tls13Draft28), |
83 | 426 | 0x7f1b => Ok(Self::Tls13Draft27), |
84 | 258 | 0x7f1a => Ok(Self::Tls13Draft26), |
85 | 217 | 0x7f19 => Ok(Self::Tls13Draft25), |
86 | 1.26k | 0x7f18 => Ok(Self::Tls13Draft24), |
87 | 391 | 0x7f17 => Ok(Self::Tls13Draft23), |
88 | 208 | 0x7f16 => Ok(Self::Tls13Draft22), |
89 | 194 | 0x7f15 => Ok(Self::Tls13Draft21), |
90 | 195 | 0x7f14 => Ok(Self::Tls13Draft20), |
91 | 512 | 0x7f13 => Ok(Self::Tls13Draft19), |
92 | 198 | 0x7f12 => Ok(Self::Tls13Draft18), |
93 | 244 | 0x7f11 => Ok(Self::Tls13Draft17), |
94 | 205 | 0x7f10 => Ok(Self::Tls13Draft16), |
95 | 579 | 0x7f01 => Ok(Self::Tls13PreDraft16), |
96 | 35.8k | 0xfb14 => Ok(Self::Tls13Draft20Fb), |
97 | 251 | 0xfb15 => Ok(Self::Tls13Draft21Fb), |
98 | 368 | 0xfb16 => Ok(Self::Tls13Draft22Fb), |
99 | 280 | 0xfb17 => Ok(Self::Tls13Draft23Fb), |
100 | 246 | 0xfb1a => Ok(Self::Tls13Draft26Fb), |
101 | 8.58k | _ => Err(()), |
102 | | } |
103 | 99.8k | } |
104 | | } |
105 | | |
106 | | impl SCTlsVersion { |
107 | 236 | pub fn as_str(&self) -> &'static str { |
108 | 236 | match self { |
109 | 93 | Self::Unknown => "UNDETERMINED", |
110 | 116 | Self::SslV2 => "SSLv2", |
111 | 0 | Self::SslV3 => "SSLv3", |
112 | 2 | Self::TlsV1_0 => "TLSv1", |
113 | 0 | Self::TlsV1_1 => "TLS 1.1", |
114 | 23 | Self::TlsV1_2 => "TLS 1.2", |
115 | 1 | Self::TlsV1_3 => "TLS 1.3", |
116 | 0 | Self::Tls13Draft28 => "TLS 1.3 draft-28", |
117 | 0 | Self::Tls13Draft27 => "TLS 1.3 draft-27", |
118 | 0 | Self::Tls13Draft26 => "TLS 1.3 draft-26", |
119 | 0 | Self::Tls13Draft25 => "TLS 1.3 draft-25", |
120 | 0 | Self::Tls13Draft24 => "TLS 1.3 draft-24", |
121 | 0 | Self::Tls13Draft23 => "TLS 1.3 draft-23", |
122 | 0 | Self::Tls13Draft22 => "TLS 1.3 draft-22", |
123 | 0 | Self::Tls13Draft21 => "TLS 1.3 draft-21", |
124 | 0 | Self::Tls13Draft20 => "TLS 1.3 draft-20", |
125 | 0 | Self::Tls13Draft19 => "TLS 1.3 draft-19", |
126 | 0 | Self::Tls13Draft18 => "TLS 1.3 draft-18", |
127 | 0 | Self::Tls13Draft17 => "TLS 1.3 draft-17", |
128 | 0 | Self::Tls13Draft16 => "TLS 1.3 draft-16", |
129 | 1 | Self::Tls13PreDraft16 => "TLS 1.3 draft-<16", |
130 | 0 | Self::Tls13Draft20Fb => "TLS 1.3 draft-20-fb", |
131 | 0 | Self::Tls13Draft21Fb => "TLS 1.3 draft-21-fb", |
132 | 0 | Self::Tls13Draft22Fb => "TLS 1.3 draft-22-fb", |
133 | 0 | Self::Tls13Draft23Fb => "TLS 1.3 draft-23-fb", |
134 | 0 | Self::Tls13Draft26Fb => "TLS 1.3 draft-26-fb", |
135 | | } |
136 | 236 | } |
137 | | |
138 | 99.4k | fn is_valid(v: u16) -> bool { |
139 | 99.4k | match Self::try_from(v) { |
140 | 1.33k | Ok(SCTlsVersion::Unknown) => false, |
141 | 69 | Ok(SCTlsVersion::SslV2) => false, |
142 | 8.47k | Err(_) => false, |
143 | 89.5k | _ => true, |
144 | | } |
145 | 99.4k | } |
146 | | } |
147 | | |
148 | | #[no_mangle] |
149 | 99.4k | pub unsafe extern "C" fn TLSVersionValid(v: u16) -> bool { |
150 | 99.4k | SCTlsVersion::is_valid(v) |
151 | 99.4k | } |
152 | | |
153 | | #[no_mangle] |
154 | 340 | pub unsafe extern "C" fn SSLVersionToString(v: u16, buf: *mut c_char) -> bool { |
155 | 340 | let vers = match SCTlsVersion::try_from(v) { |
156 | 236 | Ok(val) => Cow::Borrowed(val.as_str()), |
157 | 104 | Err(_) => Cow::Owned(v.to_string()), |
158 | | }; |
159 | 340 | let b = vers.as_bytes(); |
160 | | |
161 | 340 | if b.len() > SSL_VERSION_MAX_STRLEN { |
162 | 0 | return false; |
163 | 340 | } |
164 | | |
165 | 340 | ptr::write_bytes(buf, 0, b.len()); |
166 | 340 | std::ptr::copy_nonoverlapping(b.as_ptr() as *const c_char, buf, b.len()); |
167 | 340 | *buf.add(b.len()) = 0; |
168 | 340 | true |
169 | 340 | } |
170 | | |
171 | | #[cfg(test)] |
172 | | mod tests { |
173 | | use super::*; |
174 | | |
175 | | #[test] |
176 | | fn test_valid_versions() { |
177 | | assert!(SCTlsVersion::is_valid(SSL_VERSION_3)); |
178 | | assert!(SCTlsVersion::is_valid(TLS_VERSION_10)); |
179 | | assert!(SCTlsVersion::is_valid(TLS_VERSION_11)); |
180 | | assert!(SCTlsVersion::is_valid(TLS_VERSION_12)); |
181 | | assert!(SCTlsVersion::is_valid(TLS_VERSION_13_DRAFT16)); |
182 | | } |
183 | | |
184 | | #[test] |
185 | | fn test_invalid_versions() { |
186 | | assert!(!SCTlsVersion::is_valid(TLS_VERSION_UNKNOWN)); |
187 | | assert!(!SCTlsVersion::is_valid(SSL_VERSION_2)); |
188 | | } |
189 | | |
190 | | // Out-of-range ie unknown currently |
191 | | #[test] |
192 | | fn test_oor_versions() { |
193 | | assert!(!SCTlsVersion::is_valid(0xffff)); |
194 | | assert!(!SCTlsVersion::is_valid(0xfffe)); |
195 | | } |
196 | | } |