1#![allow(clippy::upper_case_acronyms)]
2#![allow(non_camel_case_types)]
3use crate::crypto::KeyExchangeAlgorithm;
4use crate::msgs::codec::{Codec, Reader};
5
6enum_builder! {
7 #[repr(u8)]
11 pub enum HashAlgorithm {
12 NONE => 0x00,
13 MD5 => 0x01,
14 SHA1 => 0x02,
15 SHA224 => 0x03,
16 SHA256 => 0x04,
17 SHA384 => 0x05,
18 SHA512 => 0x06,
19 }
20}
21
22enum_builder! {
23 #[repr(u8)]
27 pub(crate) enum ClientCertificateType {
28 RSASign => 0x01,
29 DSSSign => 0x02,
30 RSAFixedDH => 0x03,
31 DSSFixedDH => 0x04,
32 RSAEphemeralDH => 0x05,
33 DSSEphemeralDH => 0x06,
34 FortezzaDMS => 0x14,
35 ECDSASign => 0x40,
36 RSAFixedECDH => 0x41,
37 ECDSAFixedECDH => 0x42,
38 }
39}
40
41enum_builder! {
42 #[repr(u8)]
46 pub enum Compression {
47 Null => 0x00,
48 Deflate => 0x01,
49 LSZ => 0x40,
50 }
51}
52
53enum_builder! {
54 #[repr(u8)]
58 pub enum AlertLevel {
59 Warning => 0x01,
60 Fatal => 0x02,
61 }
62}
63
64enum_builder! {
65 #[repr(u8)]
69 pub(crate) enum HeartbeatMessageType {
70 Request => 0x01,
71 Response => 0x02,
72 }
73}
74
75enum_builder! {
76 #[repr(u16)]
80 pub enum ExtensionType {
81 ServerName => 0x0000,
82 MaxFragmentLength => 0x0001,
83 ClientCertificateUrl => 0x0002,
84 TrustedCAKeys => 0x0003,
85 TruncatedHMAC => 0x0004,
86 StatusRequest => 0x0005,
87 UserMapping => 0x0006,
88 ClientAuthz => 0x0007,
89 ServerAuthz => 0x0008,
90 CertificateType => 0x0009,
91 EllipticCurves => 0x000a,
92 ECPointFormats => 0x000b,
93 SRP => 0x000c,
94 SignatureAlgorithms => 0x000d,
95 UseSRTP => 0x000e,
96 Heartbeat => 0x000f,
97 ALProtocolNegotiation => 0x0010,
98 SCT => 0x0012,
99 ClientCertificateType => 0x0013,
100 ServerCertificateType => 0x0014,
101 Padding => 0x0015,
102 ExtendedMasterSecret => 0x0017,
103 CompressCertificate => 0x001b,
104 SessionTicket => 0x0023,
105 PreSharedKey => 0x0029,
106 EarlyData => 0x002a,
107 SupportedVersions => 0x002b,
108 Cookie => 0x002c,
109 PSKKeyExchangeModes => 0x002d,
110 TicketEarlyDataInfo => 0x002e,
111 CertificateAuthorities => 0x002f,
112 OIDFilters => 0x0030,
113 PostHandshakeAuth => 0x0031,
114 SignatureAlgorithmsCert => 0x0032,
115 KeyShare => 0x0033,
116 TransportParameters => 0x0039,
117 NextProtocolNegotiation => 0x3374,
118 ChannelId => 0x754f,
119 RenegotiationInfo => 0xff01,
120 TransportParametersDraft => 0xffa5,
121 EncryptedClientHello => 0xfe0d, EncryptedClientHelloOuterExtensions => 0xfd00, }
124}
125
126impl ExtensionType {
127 pub(crate) fn ech_compress(&self) -> bool {
138 matches!(
140 self,
141 Self::StatusRequest
142 | Self::EllipticCurves
143 | Self::SignatureAlgorithms
144 | Self::SignatureAlgorithmsCert
145 | Self::ALProtocolNegotiation
146 | Self::SupportedVersions
147 | Self::Cookie
148 | Self::KeyShare
149 | Self::PSKKeyExchangeModes
150 )
151 }
152}
153
154enum_builder! {
155 #[repr(u8)]
159 pub(crate) enum ServerNameType {
160 HostName => 0x00,
161 }
162}
163
164enum_builder! {
165 #[repr(u16)]
174 pub(crate) enum NamedCurve {
175 sect163k1 => 0x0001,
176 sect163r1 => 0x0002,
177 sect163r2 => 0x0003,
178 sect193r1 => 0x0004,
179 sect193r2 => 0x0005,
180 sect233k1 => 0x0006,
181 sect233r1 => 0x0007,
182 sect239k1 => 0x0008,
183 sect283k1 => 0x0009,
184 sect283r1 => 0x000a,
185 sect409k1 => 0x000b,
186 sect409r1 => 0x000c,
187 sect571k1 => 0x000d,
188 sect571r1 => 0x000e,
189 secp160k1 => 0x000f,
190 secp160r1 => 0x0010,
191 secp160r2 => 0x0011,
192 secp192k1 => 0x0012,
193 secp192r1 => 0x0013,
194 secp224k1 => 0x0014,
195 secp224r1 => 0x0015,
196 secp256k1 => 0x0016,
197 secp256r1 => 0x0017,
198 secp384r1 => 0x0018,
199 secp521r1 => 0x0019,
200 brainpoolp256r1 => 0x001a,
201 brainpoolp384r1 => 0x001b,
202 brainpoolp512r1 => 0x001c,
203 X25519 => 0x001d,
204 X448 => 0x001e,
205 arbitrary_explicit_prime_curves => 0xff01,
206 arbitrary_explicit_char2_curves => 0xff02,
207 }
208}
209
210enum_builder! {
211 #[repr(u16)]
215 pub enum NamedGroup {
216 secp256r1 => 0x0017,
217 secp384r1 => 0x0018,
218 secp521r1 => 0x0019,
219 X25519 => 0x001d,
220 X448 => 0x001e,
221 FFDHE2048 => 0x0100,
222 FFDHE3072 => 0x0101,
223 FFDHE4096 => 0x0102,
224 FFDHE6144 => 0x0103,
225 FFDHE8192 => 0x0104,
226 MLKEM512 => 0x0200,
227 MLKEM768 => 0x0201,
228 MLKEM1024 => 0x0202,
229 secp256r1MLKEM768 => 0x11eb,
230 X25519MLKEM768 => 0x11ec,
231 }
232}
233
234impl NamedGroup {
235 pub fn key_exchange_algorithm(self) -> KeyExchangeAlgorithm {
237 match u16::from(self) {
238 x if (0x100..0x200).contains(&x) => KeyExchangeAlgorithm::DHE,
239 _ => KeyExchangeAlgorithm::ECDHE,
240 }
241 }
242}
243
244enum_builder! {
245 #[repr(u8)]
249 pub enum ECPointFormat {
250 Uncompressed => 0x00,
251 ANSIX962CompressedPrime => 0x01,
252 ANSIX962CompressedChar2 => 0x02,
253 }
254}
255
256impl ECPointFormat {
257 pub(crate) const SUPPORTED: [Self; 1] = [Self::Uncompressed];
258}
259
260enum_builder! {
261 #[repr(u8)]
265 pub(crate) enum HeartbeatMode {
266 PeerAllowedToSend => 0x01,
267 PeerNotAllowedToSend => 0x02,
268 }
269}
270
271enum_builder! {
272 #[repr(u8)]
276 pub(crate) enum ECCurveType {
277 ExplicitPrime => 0x01,
278 ExplicitChar2 => 0x02,
279 NamedCurve => 0x03,
280 }
281}
282
283enum_builder! {
284 #[repr(u8)]
288 pub enum PSKKeyExchangeMode {
289 PSK_KE => 0x00,
290 PSK_DHE_KE => 0x01,
291 }
292}
293
294enum_builder! {
295 #[repr(u8)]
299 pub enum KeyUpdateRequest {
300 UpdateNotRequested => 0x00,
301 UpdateRequested => 0x01,
302 }
303}
304
305enum_builder! {
306 #[repr(u8)]
310 pub enum CertificateStatusType {
311 OCSP => 0x01,
312 }
313}
314
315enum_builder! {
316 #[repr(u8)]
322 pub enum CertificateType {
323 X509 => 0x00,
324 RawPublicKey => 0x02,
325 }
326}
327
328enum_builder! {
329 #[repr(u16)]
334 pub enum HpkeKem {
335 DHKEM_P256_HKDF_SHA256 => 0x0010,
336 DHKEM_P384_HKDF_SHA384 => 0x0011,
337 DHKEM_P521_HKDF_SHA512 => 0x0012,
338 DHKEM_X25519_HKDF_SHA256 => 0x0020,
339 DHKEM_X448_HKDF_SHA512 => 0x0021,
340 }
341}
342
343enum_builder! {
344 #[repr(u16)]
349 pub enum HpkeKdf {
350 HKDF_SHA256 => 0x0001,
351 HKDF_SHA384 => 0x0002,
352 HKDF_SHA512 => 0x0003,
353 }
354}
355
356impl Default for HpkeKdf {
357 fn default() -> Self {
359 Self::HKDF_SHA256
360 }
361}
362
363enum_builder! {
364 #[repr(u16)]
369 pub enum HpkeAead {
370 AES_128_GCM => 0x0001,
371 AES_256_GCM => 0x0002,
372 CHACHA20_POLY_1305 => 0x0003,
373 EXPORT_ONLY => 0xFFFF,
374 }
375}
376
377impl HpkeAead {
378 pub(crate) fn tag_len(&self) -> Option<usize> {
380 match self {
381 Self::AES_128_GCM | Self::AES_256_GCM | Self::CHACHA20_POLY_1305 => Some(16),
385 _ => None,
386 }
387 }
388}
389
390impl Default for HpkeAead {
391 fn default() -> Self {
393 Self::AES_128_GCM
394 }
395}
396
397enum_builder! {
398 #[repr(u16)]
405 pub enum EchVersion {
406 V18 => 0xfe0d,
407 }
408}
409
410#[cfg(test)]
411pub(crate) mod tests {
412 use std::prelude::v1::*;
416
417 use super::*;
418
419 #[test]
420 fn test_enums() {
421 test_enum8::<HashAlgorithm>(HashAlgorithm::NONE, HashAlgorithm::SHA512);
422 test_enum8::<ClientCertificateType>(
423 ClientCertificateType::RSASign,
424 ClientCertificateType::ECDSAFixedECDH,
425 );
426 test_enum8::<Compression>(Compression::Null, Compression::LSZ);
427 test_enum8::<AlertLevel>(AlertLevel::Warning, AlertLevel::Fatal);
428 test_enum8::<HeartbeatMessageType>(
429 HeartbeatMessageType::Request,
430 HeartbeatMessageType::Response,
431 );
432 test_enum16::<ExtensionType>(ExtensionType::ServerName, ExtensionType::RenegotiationInfo);
433 test_enum8::<ServerNameType>(ServerNameType::HostName, ServerNameType::HostName);
434 test_enum16::<NamedCurve>(
435 NamedCurve::sect163k1,
436 NamedCurve::arbitrary_explicit_char2_curves,
437 );
438 test_enum16::<NamedGroup>(NamedGroup::secp256r1, NamedGroup::FFDHE8192);
439 test_enum8::<ECPointFormat>(
440 ECPointFormat::Uncompressed,
441 ECPointFormat::ANSIX962CompressedChar2,
442 );
443 test_enum8::<HeartbeatMode>(
444 HeartbeatMode::PeerAllowedToSend,
445 HeartbeatMode::PeerNotAllowedToSend,
446 );
447 test_enum8::<ECCurveType>(ECCurveType::ExplicitPrime, ECCurveType::NamedCurve);
448 test_enum8::<PSKKeyExchangeMode>(
449 PSKKeyExchangeMode::PSK_KE,
450 PSKKeyExchangeMode::PSK_DHE_KE,
451 );
452 test_enum8::<KeyUpdateRequest>(
453 KeyUpdateRequest::UpdateNotRequested,
454 KeyUpdateRequest::UpdateRequested,
455 );
456 test_enum8::<CertificateStatusType>(
457 CertificateStatusType::OCSP,
458 CertificateStatusType::OCSP,
459 );
460 test_enum8::<CertificateType>(CertificateType::X509, CertificateType::RawPublicKey);
461 }
462
463 pub(crate) fn test_enum8<T: for<'a> Codec<'a>>(first: T, last: T) {
464 let first_v = get8(&first);
465 let last_v = get8(&last);
466
467 for val in first_v..last_v + 1 {
468 let mut buf = Vec::new();
469 val.encode(&mut buf);
470 assert_eq!(buf.len(), 1);
471
472 let t = T::read_bytes(&buf).unwrap();
473 assert_eq!(val, get8(&t));
474 }
475 }
476
477 pub(crate) fn test_enum16<T: for<'a> Codec<'a>>(first: T, last: T) {
478 let first_v = get16(&first);
479 let last_v = get16(&last);
480
481 for val in first_v..last_v + 1 {
482 let mut buf = Vec::new();
483 val.encode(&mut buf);
484 assert_eq!(buf.len(), 2);
485
486 let t = T::read_bytes(&buf).unwrap();
487 assert_eq!(val, get16(&t));
488 }
489 }
490
491 fn get8<T: for<'a> Codec<'a>>(enum_value: &T) -> u8 {
492 let enc = enum_value.get_encoding();
493 assert_eq!(enc.len(), 1);
494 enc[0]
495 }
496
497 fn get16<T: for<'a> Codec<'a>>(enum_value: &T) -> u16 {
498 let enc = enum_value.get_encoding();
499 assert_eq!(enc.len(), 2);
500 (enc[0] as u16 >> 8) | (enc[1] as u16)
501 }
502}