1use super::super::extend::Aead;
2use crate::boring::{Hasher, HashType};
3use crate::error::RlsResult;
4use crate::RlsError;
5use std::fmt::{Debug, Formatter};
6
7pub struct CipherSuite {
8 value: u16,
9 hasher: Option<Hasher>,
10 aead: Option<Aead>,
11}
12
13impl CipherSuite {
14 pub const TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: CipherSuite = CipherSuite {
16 value: 0xc02b,
17 hasher: None,
18 aead: None,
19 };
20 pub const TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: CipherSuite = CipherSuite {
21 value: 0xc02c,
22 hasher: None,
23 aead: None,
24 };
25 pub const TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: CipherSuite = CipherSuite {
26 value: 0xc023,
27 hasher: None,
28 aead: None,
29 };
30 pub const TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: CipherSuite = CipherSuite {
31 value: 0xc024,
32 hasher: None,
33 aead: None,
34 };
35 pub const TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: CipherSuite = CipherSuite {
36 value: 0xc009,
37 hasher: None,
38 aead: None,
39 };
40 pub const TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: CipherSuite = CipherSuite {
41 value: 0xc00a,
42 hasher: None,
43 aead: None,
44 };
45 pub const TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: CipherSuite = CipherSuite {
46 value: 0xcca9,
47 hasher: None,
48 aead: None,
49 };
50
51 pub const TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: CipherSuite = CipherSuite {
53 value: 0xc02f,
54 hasher: None,
55 aead: None,
56 };
57 pub const TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: CipherSuite = CipherSuite {
58 value: 0xc030,
59 hasher: None,
60 aead: None,
61 };
62 pub const TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: CipherSuite = CipherSuite {
63 value: 0xc027,
64 hasher: None,
65 aead: None,
66 };
67 pub const TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: CipherSuite = CipherSuite {
68 value: 0xc028,
69 hasher: None,
70 aead: None,
71 };
72 pub const TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: CipherSuite = CipherSuite {
73 value: 0xc013,
74 hasher: None,
75 aead: None,
76 };
77 pub const TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: CipherSuite = CipherSuite {
78 value: 0xc014,
79 hasher: None,
80 aead: None,
81 };
82 pub const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: CipherSuite = CipherSuite {
83 value: 0xcca8,
84 hasher: None,
85 aead: None,
86 };
87
88 pub const TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: CipherSuite = CipherSuite {
90 value: 0x009e,
91 hasher: None,
92 aead: None,
93 };
94 pub const TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: CipherSuite = CipherSuite {
95 value: 0x009f,
96 hasher: None,
97 aead: None,
98 };
99 pub const TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: CipherSuite = CipherSuite {
100 value: 0x0067,
101 hasher: None,
102 aead: None,
103 };
104 pub const TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: CipherSuite = CipherSuite {
105 value: 0x006b,
106 hasher: None,
107 aead: None,
108 };
109 pub const TLS_DHE_RSA_WITH_AES_128_CBC_SHA: CipherSuite = CipherSuite {
110 value: 0x0033,
111 hasher: None,
112 aead: None,
113 };
114 pub const TLS_DHE_RSA_WITH_AES_256_CBC_SHA: CipherSuite = CipherSuite {
115 value: 0x0039,
116 hasher: None,
117 aead: None,
118 };
119 pub const TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256: CipherSuite = CipherSuite {
120 value: 0xccaa,
121 hasher: None,
122 aead: None,
123 };
124
125
126 pub const TLS_RSA_WITH_AES_128_GCM_SHA256: CipherSuite = CipherSuite {
128 value: 0x009c,
129 hasher: None,
130 aead: None,
131 };
132 pub const TLS_RSA_WITH_AES_256_GCM_SHA384: CipherSuite = CipherSuite {
133 value: 0x009d,
134 hasher: None,
135 aead: None,
136 };
137 pub const TLS_RSA_WITH_AES_128_CBC_SHA256: CipherSuite = CipherSuite {
138 value: 0x003c,
139 hasher: None,
140 aead: None,
141 };
142 pub const TLS_RSA_WITH_AES_256_CBC_SHA256: CipherSuite = CipherSuite {
143 value: 0x003d,
144 hasher: None,
145 aead: None,
146 };
147 pub const TLS_RSA_WITH_AES_128_CBC_SHA: CipherSuite = CipherSuite {
148 value: 0x002f,
149 hasher: None,
150 aead: None,
151 };
152 pub const TLS_RSA_WITH_AES_256_CBC_SHA: CipherSuite = CipherSuite {
153 value: 0x0035,
154 hasher: None,
155 aead: None,
156 };
157
158 pub const TLS_AES_128_GCM_SHA256: CipherSuite = CipherSuite {
160 value: 0x1301,
161 hasher: None,
162 aead: None,
163 };
164 pub const TLS_AES_256_GCM_SHA384: CipherSuite = CipherSuite {
165 value: 0x1302,
166 hasher: None,
167 aead: None,
168 };
169 pub const TLS_CHACHA20_POLY1305_SHA256: CipherSuite = CipherSuite {
170 value: 0x1303,
171 hasher: None,
172 aead: None,
173 };
174
175 pub const TLS_EMPTY_RENEGOTIATION_INFO_SCSV: CipherSuite = CipherSuite {
176 value: 0x00ff,
177 hasher: None,
178 aead: None,
179 };
180
181 pub const SUITES: [u16; 31] = [0xc02b, 0xc02c, 0xc023, 0xc024, 0xc009, 0xc00a, 0xcca9, 0xc02f, 0xc030, 0xc027, 0xc028, 0xc013, 0xc014, 0xcca8, 0x009e, 0x009f, 0x0067, 0x006b, 0x0033, 0x0039, 0xccaa, 0x009c, 0x009d, 0x003c, 0x003d, 0x002f, 0x0035, 0x1301, 0x1302, 0x1303, 0x00ff];
182
183 pub fn spec(&self) -> &str {
184 match self.value {
185 0xc02b => "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
186 0xc02c => "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
187 0xc023 => "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
188 0xc024 => "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
189 0xc009 => "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
190 0xc00a => "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
191 0xcca9 => "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
192
193 0xc02f => "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
194 0xc030 => "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
195 0xc027 => "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
196 0xc028 => "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
197 0xc013 => "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
198 0xc014 => "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
199 0xcca8 => "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
200
201 0x009e => "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
202 0x009f => "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
203 0x0067 => "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
204 0x006b => "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
205 0x0033 => "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
206 0x0039 => "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
207 0xccaa => "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
208
209 0x009c => "TLS_RSA_WITH_AES_128_GCM_SHA256",
210 0x009d => "TLS_RSA_WITH_AES_256_GCM_SHA384",
211 0x003c => "TLS_RSA_WITH_AES_128_CBC_SHA256",
212 0x003d => "TLS_RSA_WITH_AES_256_CBC_SHA256",
213 0x002f => "TLS_RSA_WITH_AES_128_CBC_SHA",
214 0x0035 => "TLS_RSA_WITH_AES_256_CBC_SHA",
215
216 0x1301 => "TLS_AES_128_GCM_SHA256",
217 0x1302 => "TLS_AES_256_GCM_SHA384",
218 0x1303 => "TLS_CHACHA20_POLY1305_SHA256",
219
220 0x00ff => "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
221 _ => "Reserved"
222 }
223 }
224
225 pub fn key_size(&self) -> u8 {
226 match self.value {
227 0x009c | 0x009d | 0x003c | 0x003d | 0x002f | 0x0035 => 2,
228 _ => 1,
229 }
230 }
231
232 pub fn is_aead(&self) -> bool {
233 matches!(self.value, 0xc02b | 0xc02c | 0xcca9 | 0xc02f | 0xc030 | 0xcca8 | 0x009e | 0x009f | 0xccaa | 0x009c | 0x009d | 0x1301 | 0x1302 | 0x1303)
234 }
235
236
237 pub fn mac_hash(&self) -> Option<HashType> {
238 match self.value {
239 0xc02b => Some(HashType::Sha256),
240 0xc02c => Some(HashType::Sha384),
241 0xc023 => Some(HashType::Sha256),
242 0xc024 => Some(HashType::Sha384),
243 0xc009 => Some(HashType::Sha1),
244 0xc00a => Some(HashType::Sha1),
245 0xcca9 => Some(HashType::Sha256),
246
247 0xc02f => Some(HashType::Sha256),
248 0xc030 => Some(HashType::Sha384),
249 0xc027 => Some(HashType::Sha256),
250 0xc028 => Some(HashType::Sha384),
251 0xc013 => Some(HashType::Sha1),
252 0xc014 => Some(HashType::Sha1),
253 0xcca8 => Some(HashType::Sha256),
254
255 0x009e => Some(HashType::Sha256),
256 0x009f => Some(HashType::Sha384),
257 0x0067 => Some(HashType::Sha256),
258 0x006b => Some(HashType::Sha256),
259 0x0033 => Some(HashType::Sha1),
260 0x0039 => Some(HashType::Sha1),
261 0xccaa => Some(HashType::Sha256),
262
263 0x009c => Some(HashType::Sha256),
264 0x009d => Some(HashType::Sha384),
265 0x003c => Some(HashType::Sha256),
266 0x003d => Some(HashType::Sha256),
267 0x002f => Some(HashType::Sha1),
268 0x0035 => Some(HashType::Sha1),
269
270 0x1301 => Some(HashType::Sha256),
271 0x1302 => Some(HashType::Sha384),
272 0x1303 => Some(HashType::Sha256),
273 _ => None
274 }
275 }
276}
277
278impl PartialEq for CipherSuite {
279 fn eq(&self, other: &CipherSuite) -> bool {
280 self.value == other.value
281 }
282}
283
284impl CipherSuite {
285 pub fn new(v: u16) -> CipherSuite {
286 CipherSuite {
287 value: v,
288 hasher: None,
289 aead: None,
290 }
291 }
292
293 pub fn from_bytes(bytes: &[u8]) -> RlsResult<Vec<CipherSuite>> {
294 let mut res = vec![];
295 for chuck in bytes.chunks(2) {
296 let v = u16::from_be_bytes(chuck.try_into()?);
297 res.push(CipherSuite::new(v));
298 }
299 Ok(res)
300 }
301
302 pub fn is_reserved(&self) -> bool {
303 !CipherSuite::SUITES.contains(&self.value)
304 }
305
306 pub fn into_inner(self) -> u16 { self.value }
307
308 pub fn as_u16(&self) -> u16 {
309 self.value
310 }
311
312 pub fn update(&mut self, data: impl AsRef<[u8]>) -> RlsResult<()> {
313 match self.hasher.as_mut() {
314 None => Err(RlsError::HasherNone),
315 Some(hasher) => hasher.update(data),
316 }
317 }
318
319 fn find_hasher(&self) -> RlsResult<Hasher> {
320 let text = self.spec().to_lowercase();
321 if text.contains("sha256") {
322 Ok(Hasher::new(HashType::Sha256)?)
323 } else if text.contains("sha384") {
324 Ok(Hasher::new(HashType::Sha384)?)
325 } else if text.ends_with("_sha") {
326 Ok(Hasher::new(HashType::Sha256)?)
327 } else {
328 Err(RlsError::HasherNone)
329 }
330 }
331
332 pub fn current_session_hash(&mut self) -> RlsResult<&[u8]> {
333 self.hasher.as_mut().ok_or(RlsError::HasherNone)?.current_hash()
334 }
335
336 pub fn aead(&self) -> Option<&Aead> {
337 self.aead.as_ref()
338 }
339
340 pub fn init_aead_hasher(&mut self) -> RlsResult<()> {
341 self.hasher = Some(self.find_hasher()?);
343 self.aead = Some(Aead::from_cipher_kind(self.spec()).ok_or(RlsError::AeadNone)?);
345 Ok(())
346 }
347
348 pub fn hasher(&self) -> &Option<Hasher> {
349 &self.hasher
350 }
351}
352
353impl Debug for CipherSuite {
354 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
355 write!(f, "{}(0x{:x})", self.spec(), self.value)
356 }
357}
358
359impl Clone for CipherSuite {
360 fn clone(&self) -> Self {
361 CipherSuite {
362 value: self.value,
363 hasher: None,
364 aead: None,
365 }
366 }
367}