Coverage Report

Created: 2025-02-25 06:39

/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
}