/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.22/src/msgs/enums.rs
Line | Count | Source (jump to first uncovered line) |
1 | | #![allow(clippy::upper_case_acronyms)] |
2 | | #![allow(non_camel_case_types)] |
3 | | use crate::crypto::KeyExchangeAlgorithm; |
4 | | use crate::msgs::codec::{Codec, Reader}; |
5 | | |
6 | | enum_builder! { |
7 | | /// The `HashAlgorithm` TLS protocol enum. Values in this enum are taken |
8 | | /// from the various RFCs covering TLS, and are listed by IANA. |
9 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
10 | | #[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 | | |
22 | | enum_builder! { |
23 | | /// The `ClientCertificateType` TLS protocol enum. Values in this enum are taken |
24 | | /// from the various RFCs covering TLS, and are listed by IANA. |
25 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
26 | | #[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 | | |
41 | | enum_builder! { |
42 | | /// The `Compression` TLS protocol enum. Values in this enum are taken |
43 | | /// from the various RFCs covering TLS, and are listed by IANA. |
44 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
45 | | #[repr(u8)] |
46 | | pub enum Compression { |
47 | | Null => 0x00, |
48 | | Deflate => 0x01, |
49 | | LSZ => 0x40, |
50 | | } |
51 | | } |
52 | | |
53 | | enum_builder! { |
54 | | /// The `AlertLevel` TLS protocol enum. Values in this enum are taken |
55 | | /// from the various RFCs covering TLS, and are listed by IANA. |
56 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
57 | | #[repr(u8)] |
58 | | pub enum AlertLevel { |
59 | | Warning => 0x01, |
60 | | Fatal => 0x02, |
61 | | } |
62 | | } |
63 | | |
64 | | enum_builder! { |
65 | | /// The `HeartbeatMessageType` TLS protocol enum. Values in this enum are taken |
66 | | /// from the various RFCs covering TLS, and are listed by IANA. |
67 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
68 | | #[repr(u8)] |
69 | | pub(crate) enum HeartbeatMessageType { |
70 | | Request => 0x01, |
71 | | Response => 0x02, |
72 | | } |
73 | | } |
74 | | |
75 | | enum_builder! { |
76 | | /// The `ExtensionType` TLS protocol enum. Values in this enum are taken |
77 | | /// from the various RFCs covering TLS, and are listed by IANA. |
78 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
79 | | #[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, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-11.1 |
122 | | EncryptedClientHelloOuterExtensions => 0xfd00, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5.1 |
123 | | } |
124 | | } |
125 | | |
126 | | impl ExtensionType { |
127 | | /// Returns true if the extension type can be compressed in an "inner" client hello for ECH. |
128 | | /// |
129 | | /// This function should only return true for extension types where the inner hello and outer |
130 | | /// hello extensions values will always be identical. Extensions that may be identical |
131 | | /// sometimes (e.g. server name, cert compression methods), but not always, SHOULD NOT be |
132 | | /// compressed. |
133 | | /// |
134 | | /// See [draft-ietf-esni-18 §5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5) |
135 | | /// and [draft-ietf-esni-18 §10.5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-10.5) |
136 | | /// for more information. |
137 | 0 | pub(crate) fn ech_compress(&self) -> bool { |
138 | | // We match which extensions we will compress with BoringSSL and Go's stdlib. |
139 | 0 | matches!( |
140 | 0 | 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 | 0 | } |
152 | | } |
153 | | |
154 | | enum_builder! { |
155 | | /// The `ServerNameType` TLS protocol enum. Values in this enum are taken |
156 | | /// from the various RFCs covering TLS, and are listed by IANA. |
157 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
158 | | #[repr(u8)] |
159 | | pub(crate) enum ServerNameType { |
160 | | HostName => 0x00, |
161 | | } |
162 | | } |
163 | | |
164 | | enum_builder! { |
165 | | /// The `NamedCurve` TLS protocol enum. Values in this enum are taken |
166 | | /// from the various RFCs covering TLS, and are listed by IANA. |
167 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
168 | | /// |
169 | | /// This enum is used for recognizing elliptic curve parameters advertised |
170 | | /// by a peer during a TLS handshake. It is **not** a list of curves that |
171 | | /// Rustls supports. See [`crate::crypto::ring::kx_group`] for the list of supported |
172 | | /// elliptic curve groups. |
173 | | #[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 | | |
210 | | enum_builder! { |
211 | | /// The `NamedGroup` TLS protocol enum. Values in this enum are taken |
212 | | /// from the various RFCs covering TLS, and are listed by IANA. |
213 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
214 | | #[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 | | |
234 | | impl NamedGroup { |
235 | | /// Return the key exchange algorithm associated with this `NamedGroup` |
236 | 0 | pub fn key_exchange_algorithm(self) -> KeyExchangeAlgorithm { |
237 | 0 | match u16::from(self) { |
238 | 0 | x if (0x100..0x200).contains(&x) => KeyExchangeAlgorithm::DHE, |
239 | 0 | _ => KeyExchangeAlgorithm::ECDHE, |
240 | | } |
241 | 0 | } |
242 | | } |
243 | | |
244 | | enum_builder! { |
245 | | /// The `ECPointFormat` TLS protocol enum. Values in this enum are taken |
246 | | /// from the various RFCs covering TLS, and are listed by IANA. |
247 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
248 | | #[repr(u8)] |
249 | | pub enum ECPointFormat { |
250 | | Uncompressed => 0x00, |
251 | | ANSIX962CompressedPrime => 0x01, |
252 | | ANSIX962CompressedChar2 => 0x02, |
253 | | } |
254 | | } |
255 | | |
256 | | impl ECPointFormat { |
257 | | pub(crate) const SUPPORTED: [Self; 1] = [Self::Uncompressed]; |
258 | | } |
259 | | |
260 | | enum_builder! { |
261 | | /// The `HeartbeatMode` TLS protocol enum. Values in this enum are taken |
262 | | /// from the various RFCs covering TLS, and are listed by IANA. |
263 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
264 | | #[repr(u8)] |
265 | | pub(crate) enum HeartbeatMode { |
266 | | PeerAllowedToSend => 0x01, |
267 | | PeerNotAllowedToSend => 0x02, |
268 | | } |
269 | | } |
270 | | |
271 | | enum_builder! { |
272 | | /// The `ECCurveType` TLS protocol enum. Values in this enum are taken |
273 | | /// from the various RFCs covering TLS, and are listed by IANA. |
274 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
275 | | #[repr(u8)] |
276 | | pub(crate) enum ECCurveType { |
277 | | ExplicitPrime => 0x01, |
278 | | ExplicitChar2 => 0x02, |
279 | | NamedCurve => 0x03, |
280 | | } |
281 | | } |
282 | | |
283 | | enum_builder! { |
284 | | /// The `PSKKeyExchangeMode` TLS protocol enum. Values in this enum are taken |
285 | | /// from the various RFCs covering TLS, and are listed by IANA. |
286 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
287 | | #[repr(u8)] |
288 | | pub enum PSKKeyExchangeMode { |
289 | | PSK_KE => 0x00, |
290 | | PSK_DHE_KE => 0x01, |
291 | | } |
292 | | } |
293 | | |
294 | | enum_builder! { |
295 | | /// The `KeyUpdateRequest` TLS protocol enum. Values in this enum are taken |
296 | | /// from the various RFCs covering TLS, and are listed by IANA. |
297 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
298 | | #[repr(u8)] |
299 | | pub enum KeyUpdateRequest { |
300 | | UpdateNotRequested => 0x00, |
301 | | UpdateRequested => 0x01, |
302 | | } |
303 | | } |
304 | | |
305 | | enum_builder! { |
306 | | /// The `CertificateStatusType` TLS protocol enum. Values in this enum are taken |
307 | | /// from the various RFCs covering TLS, and are listed by IANA. |
308 | | /// The `Unknown` item is used when processing unrecognised ordinals. |
309 | | #[repr(u8)] |
310 | | pub enum CertificateStatusType { |
311 | | OCSP => 0x01, |
312 | | } |
313 | | } |
314 | | |
315 | | enum_builder! { |
316 | | /// The `CertificateType` enum sent in the cert_type extensions. |
317 | | /// Values in this enum are taken from the various RFCs covering TLS, and are listed by IANA. |
318 | | /// |
319 | | /// [RFC 6091 Section 5]: <https://datatracker.ietf.org/doc/html/rfc6091#section-5> |
320 | | /// [RFC 7250 Section 7]: <https://datatracker.ietf.org/doc/html/rfc7250#section-7> |
321 | | #[repr(u8)] |
322 | | pub enum CertificateType { |
323 | | X509 => 0x00, |
324 | | RawPublicKey => 0x02, |
325 | | } |
326 | | } |
327 | | |
328 | | enum_builder! { |
329 | | /// The Key Encapsulation Mechanism (`Kem`) type for HPKE operations. |
330 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.1] |
331 | | /// |
332 | | /// [RFC 9180 Section 7.1]: <https://datatracker.ietf.org/doc/html/rfc9180#kemid-values> |
333 | | #[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 | | |
343 | | enum_builder! { |
344 | | /// The Key Derivation Function (`Kdf`) type for HPKE operations. |
345 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.2] |
346 | | /// |
347 | | /// [RFC 9180 Section 7.2]: <https://datatracker.ietf.org/doc/html/rfc9180#name-key-derivation-functions-kd> |
348 | | #[repr(u16)] |
349 | | pub enum HpkeKdf { |
350 | | HKDF_SHA256 => 0x0001, |
351 | | HKDF_SHA384 => 0x0002, |
352 | | HKDF_SHA512 => 0x0003, |
353 | | } |
354 | | } |
355 | | |
356 | | impl Default for HpkeKdf { |
357 | | // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now. |
358 | 0 | fn default() -> Self { |
359 | 0 | Self::HKDF_SHA256 |
360 | 0 | } |
361 | | } |
362 | | |
363 | | enum_builder! { |
364 | | /// The Authenticated Encryption with Associated Data (`Aead`) type for HPKE operations. |
365 | | /// Listed by IANA, as specified in [RFC 9180 Section 7.3] |
366 | | /// |
367 | | /// [RFC 9180 Section 7.3]: <https://datatracker.ietf.org/doc/html/rfc9180#name-authenticated-encryption-wi> |
368 | | #[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 | | |
377 | | impl HpkeAead { |
378 | | /// Returns the length of the tag for the AEAD algorithm, or none if the AEAD is EXPORT_ONLY. |
379 | 0 | pub(crate) fn tag_len(&self) -> Option<usize> { |
380 | 0 | match self { |
381 | | // See RFC 9180 Section 7.3, column `Nt`, the length in bytes of the authentication tag |
382 | | // for the algorithm. |
383 | | // https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3 |
384 | 0 | Self::AES_128_GCM | Self::AES_256_GCM | Self::CHACHA20_POLY_1305 => Some(16), |
385 | 0 | _ => None, |
386 | | } |
387 | 0 | } |
388 | | } |
389 | | |
390 | | impl Default for HpkeAead { |
391 | | // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now. |
392 | 0 | fn default() -> Self { |
393 | 0 | Self::AES_128_GCM |
394 | 0 | } |
395 | | } |
396 | | |
397 | | enum_builder! { |
398 | | /// The Encrypted Client Hello protocol version (`EchVersion`). |
399 | | /// |
400 | | /// Specified in [draft-ietf-tls-esni Section 4]. |
401 | | /// TODO(XXX): Update reference once RFC is published. |
402 | | /// |
403 | | /// [draft-ietf-tls-esni Section 4]: <https://www.ietf.org/archive/id/draft-ietf-tls-esni-17.html#section-4> |
404 | | #[repr(u16)] |
405 | | pub enum EchVersion { |
406 | | V18 => 0xfe0d, |
407 | | } |
408 | | } |
409 | | |
410 | | #[cfg(test)] |
411 | | pub(crate) mod tests { |
412 | | // These tests are intended to provide coverage and |
413 | | // check panic-safety of relatively unused values. |
414 | | |
415 | | 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 | | } |