rustls/msgs/
enums.rs

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    /// 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
22enum_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
41enum_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
53enum_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
64enum_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
75enum_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
126impl 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    pub(crate) fn ech_compress(&self) -> bool {
138        // We match which extensions we will compress with BoringSSL and Go's stdlib.
139        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    /// 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
164enum_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
210enum_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
234impl NamedGroup {
235    /// Return the key exchange algorithm associated with this `NamedGroup`
236    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    /// 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
256impl ECPointFormat {
257    pub(crate) const SUPPORTED: [Self; 1] = [Self::Uncompressed];
258}
259
260enum_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
271enum_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
283enum_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
294enum_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
305enum_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
315enum_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
328enum_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
343enum_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
356impl Default for HpkeKdf {
357    // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now.
358    fn default() -> Self {
359        Self::HKDF_SHA256
360    }
361}
362
363enum_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
377impl HpkeAead {
378    /// Returns the length of the tag for the AEAD algorithm, or none if the AEAD is EXPORT_ONLY.
379    pub(crate) fn tag_len(&self) -> Option<usize> {
380        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            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    // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now.
392    fn default() -> Self {
393        Self::AES_128_GCM
394    }
395}
396
397enum_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)]
411pub(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}