Coverage Report

Created: 2025-07-14 07:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/rustls-0.23.29/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, hash};
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
impl HashAlgorithm {
23
    /// Returns the hash of the empty input.
24
    ///
25
    /// This returns `None` for some hash algorithms, so the caller
26
    /// should be prepared to do the computation themselves in this case.
27
0
    pub(crate) fn hash_for_empty_input(&self) -> Option<hash::Output> {
28
0
        match self {
29
0
            Self::SHA256 => Some(hash::Output::new(
30
0
                b"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\
31
0
                  \x9a\xfb\xf4\xc8\x99\x6f\xb9\x24\
32
0
                  \x27\xae\x41\xe4\x64\x9b\x93\x4c\
33
0
                  \xa4\x95\x99\x1b\x78\x52\xb8\x55",
34
0
            )),
35
0
            Self::SHA384 => Some(hash::Output::new(
36
0
                b"\x38\xb0\x60\xa7\x51\xac\x96\x38\
37
0
                  \x4c\xd9\x32\x7e\xb1\xb1\xe3\x6a\
38
0
                  \x21\xfd\xb7\x11\x14\xbe\x07\x43\
39
0
                  \x4c\x0c\xc7\xbf\x63\xf6\xe1\xda\
40
0
                  \x27\x4e\xde\xbf\xe7\x6f\x65\xfb\
41
0
                  \xd5\x1a\xd2\xf1\x48\x98\xb9\x5b",
42
0
            )),
43
0
            _ => None,
44
        }
45
0
    }
Unexecuted instantiation: <rustls::msgs::enums::HashAlgorithm>::hash_for_empty_input
Unexecuted instantiation: <rustls::msgs::enums::HashAlgorithm>::hash_for_empty_input
46
}
47
48
enum_builder! {
49
    /// The `ClientCertificateType` TLS protocol enum.  Values in this enum are taken
50
    /// from the various RFCs covering TLS, and are listed by IANA.
51
    /// The `Unknown` item is used when processing unrecognised ordinals.
52
    #[repr(u8)]
53
    pub(crate) enum ClientCertificateType {
54
        RSASign => 0x01,
55
        DSSSign => 0x02,
56
        RSAFixedDH => 0x03,
57
        DSSFixedDH => 0x04,
58
        RSAEphemeralDH => 0x05,
59
        DSSEphemeralDH => 0x06,
60
        FortezzaDMS => 0x14,
61
        ECDSASign => 0x40,
62
        RSAFixedECDH => 0x41,
63
        ECDSAFixedECDH => 0x42,
64
    }
65
}
66
67
enum_builder! {
68
    /// The `Compression` TLS protocol enum.  Values in this enum are taken
69
    /// from the various RFCs covering TLS, and are listed by IANA.
70
    /// The `Unknown` item is used when processing unrecognised ordinals.
71
    #[repr(u8)]
72
    pub enum Compression {
73
        Null => 0x00,
74
        Deflate => 0x01,
75
        LSZ => 0x40,
76
    }
77
}
78
79
enum_builder! {
80
    /// The `AlertLevel` TLS protocol enum.  Values in this enum are taken
81
    /// from the various RFCs covering TLS, and are listed by IANA.
82
    /// The `Unknown` item is used when processing unrecognised ordinals.
83
    #[repr(u8)]
84
    pub enum AlertLevel {
85
        Warning => 0x01,
86
        Fatal => 0x02,
87
    }
88
}
89
90
enum_builder! {
91
    /// The `HeartbeatMessageType` TLS protocol enum.  Values in this enum are taken
92
    /// from the various RFCs covering TLS, and are listed by IANA.
93
    /// The `Unknown` item is used when processing unrecognised ordinals.
94
    #[repr(u8)]
95
    pub(crate) enum HeartbeatMessageType {
96
        Request => 0x01,
97
        Response => 0x02,
98
    }
99
}
100
101
enum_builder! {
102
    /// The `ExtensionType` TLS protocol enum.  Values in this enum are taken
103
    /// from the various RFCs covering TLS, and are listed by IANA.
104
    /// The `Unknown` item is used when processing unrecognised ordinals.
105
    #[repr(u16)]
106
    pub enum ExtensionType {
107
        ServerName => 0x0000,
108
        MaxFragmentLength => 0x0001,
109
        ClientCertificateUrl => 0x0002,
110
        TrustedCAKeys => 0x0003,
111
        TruncatedHMAC => 0x0004,
112
        StatusRequest => 0x0005,
113
        UserMapping => 0x0006,
114
        ClientAuthz => 0x0007,
115
        ServerAuthz => 0x0008,
116
        CertificateType => 0x0009,
117
        EllipticCurves => 0x000a,
118
        ECPointFormats => 0x000b,
119
        SRP => 0x000c,
120
        SignatureAlgorithms => 0x000d,
121
        UseSRTP => 0x000e,
122
        Heartbeat => 0x000f,
123
        ALProtocolNegotiation => 0x0010,
124
        SCT => 0x0012,
125
        ClientCertificateType => 0x0013,
126
        ServerCertificateType => 0x0014,
127
        Padding => 0x0015,
128
        ExtendedMasterSecret => 0x0017,
129
        CompressCertificate => 0x001b,
130
        SessionTicket => 0x0023,
131
        PreSharedKey => 0x0029,
132
        EarlyData => 0x002a,
133
        SupportedVersions => 0x002b,
134
        Cookie => 0x002c,
135
        PSKKeyExchangeModes => 0x002d,
136
        TicketEarlyDataInfo => 0x002e,
137
        CertificateAuthorities => 0x002f,
138
        OIDFilters => 0x0030,
139
        PostHandshakeAuth => 0x0031,
140
        SignatureAlgorithmsCert => 0x0032,
141
        KeyShare => 0x0033,
142
        TransportParameters => 0x0039,
143
        NextProtocolNegotiation => 0x3374,
144
        ChannelId => 0x754f,
145
        RenegotiationInfo => 0xff01,
146
        TransportParametersDraft => 0xffa5,
147
        EncryptedClientHello => 0xfe0d, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-11.1
148
        EncryptedClientHelloOuterExtensions => 0xfd00, // https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5.1
149
    }
150
}
151
152
impl ExtensionType {
153
    /// Returns true if the extension type can be compressed in an "inner" client hello for ECH.
154
    ///
155
    /// This function should only return true for extension types where the inner hello and outer
156
    /// hello extensions values will always be identical. Extensions that may be identical
157
    /// sometimes (e.g. server name, cert compression methods), but not always, SHOULD NOT be
158
    /// compressed.
159
    ///
160
    /// See [draft-ietf-esni-18 §5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-5)
161
    /// and [draft-ietf-esni-18 §10.5](https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-18#section-10.5)
162
    /// for more information.
163
0
    pub(crate) fn ech_compress(&self) -> bool {
164
        // We match which extensions we will compress with BoringSSL and Go's stdlib.
165
0
        matches!(
166
0
            self,
167
            Self::StatusRequest
168
                | Self::EllipticCurves
169
                | Self::SignatureAlgorithms
170
                | Self::SignatureAlgorithmsCert
171
                | Self::ALProtocolNegotiation
172
                | Self::SupportedVersions
173
                | Self::Cookie
174
                | Self::KeyShare
175
                | Self::PSKKeyExchangeModes
176
        )
177
0
    }
Unexecuted instantiation: <rustls::msgs::enums::ExtensionType>::ech_compress
Unexecuted instantiation: <rustls::msgs::enums::ExtensionType>::ech_compress
178
}
179
180
enum_builder! {
181
    /// The `ServerNameType` TLS protocol enum.  Values in this enum are taken
182
    /// from the various RFCs covering TLS, and are listed by IANA.
183
    /// The `Unknown` item is used when processing unrecognised ordinals.
184
    #[repr(u8)]
185
    pub(crate) enum ServerNameType {
186
        HostName => 0x00,
187
    }
188
}
189
190
enum_builder! {
191
    /// The `NamedCurve` TLS protocol enum.  Values in this enum are taken
192
    /// from the various RFCs covering TLS, and are listed by IANA.
193
    /// The `Unknown` item is used when processing unrecognised ordinals.
194
    ///
195
    /// This enum is used for recognizing elliptic curve parameters advertised
196
    /// by a peer during a TLS handshake. It is **not** a list of curves that
197
    /// Rustls supports. See [`crate::crypto::ring::kx_group`] for the list of supported
198
    /// elliptic curve groups.
199
    #[repr(u16)]
200
    pub(crate) enum NamedCurve {
201
        sect163k1 => 0x0001,
202
        sect163r1 => 0x0002,
203
        sect163r2 => 0x0003,
204
        sect193r1 => 0x0004,
205
        sect193r2 => 0x0005,
206
        sect233k1 => 0x0006,
207
        sect233r1 => 0x0007,
208
        sect239k1 => 0x0008,
209
        sect283k1 => 0x0009,
210
        sect283r1 => 0x000a,
211
        sect409k1 => 0x000b,
212
        sect409r1 => 0x000c,
213
        sect571k1 => 0x000d,
214
        sect571r1 => 0x000e,
215
        secp160k1 => 0x000f,
216
        secp160r1 => 0x0010,
217
        secp160r2 => 0x0011,
218
        secp192k1 => 0x0012,
219
        secp192r1 => 0x0013,
220
        secp224k1 => 0x0014,
221
        secp224r1 => 0x0015,
222
        secp256k1 => 0x0016,
223
        secp256r1 => 0x0017,
224
        secp384r1 => 0x0018,
225
        secp521r1 => 0x0019,
226
        brainpoolp256r1 => 0x001a,
227
        brainpoolp384r1 => 0x001b,
228
        brainpoolp512r1 => 0x001c,
229
        X25519 => 0x001d,
230
        X448 => 0x001e,
231
        arbitrary_explicit_prime_curves => 0xff01,
232
        arbitrary_explicit_char2_curves => 0xff02,
233
    }
234
}
235
236
enum_builder! {
237
    /// The `NamedGroup` TLS protocol enum.  Values in this enum are taken
238
    /// from the various RFCs covering TLS, and are listed by IANA.
239
    /// The `Unknown` item is used when processing unrecognised ordinals.
240
    #[repr(u16)]
241
    pub enum NamedGroup {
242
        secp256r1 => 0x0017,
243
        secp384r1 => 0x0018,
244
        secp521r1 => 0x0019,
245
        X25519 => 0x001d,
246
        X448 => 0x001e,
247
        FFDHE2048 => 0x0100,
248
        FFDHE3072 => 0x0101,
249
        FFDHE4096 => 0x0102,
250
        FFDHE6144 => 0x0103,
251
        FFDHE8192 => 0x0104,
252
        MLKEM512 => 0x0200,
253
        MLKEM768 => 0x0201,
254
        MLKEM1024 => 0x0202,
255
        secp256r1MLKEM768 => 0x11eb,
256
        X25519MLKEM768 => 0x11ec,
257
    }
258
}
259
260
impl NamedGroup {
261
    /// Return the key exchange algorithm associated with this `NamedGroup`
262
0
    pub fn key_exchange_algorithm(self) -> KeyExchangeAlgorithm {
263
0
        match u16::from(self) {
264
0
            x if (0x100..0x200).contains(&x) => KeyExchangeAlgorithm::DHE,
265
0
            _ => KeyExchangeAlgorithm::ECDHE,
266
        }
267
0
    }
Unexecuted instantiation: <rustls::msgs::enums::NamedGroup>::key_exchange_algorithm
Unexecuted instantiation: <rustls::msgs::enums::NamedGroup>::key_exchange_algorithm
268
}
269
270
enum_builder! {
271
    /// The `ECPointFormat` TLS protocol enum.  Values in this enum are taken
272
    /// from the various RFCs covering TLS, and are listed by IANA.
273
    /// The `Unknown` item is used when processing unrecognised ordinals.
274
    #[repr(u8)]
275
    pub enum ECPointFormat {
276
        Uncompressed => 0x00,
277
        ANSIX962CompressedPrime => 0x01,
278
        ANSIX962CompressedChar2 => 0x02,
279
    }
280
}
281
282
enum_builder! {
283
    /// The `HeartbeatMode` TLS protocol enum.  Values in this enum are taken
284
    /// from the various RFCs covering TLS, and are listed by IANA.
285
    /// The `Unknown` item is used when processing unrecognised ordinals.
286
    #[repr(u8)]
287
    pub(crate) enum HeartbeatMode {
288
        PeerAllowedToSend => 0x01,
289
        PeerNotAllowedToSend => 0x02,
290
    }
291
}
292
293
enum_builder! {
294
    /// The `ECCurveType` TLS protocol enum.  Values in this enum are taken
295
    /// from the various RFCs covering TLS, and are listed by IANA.
296
    /// The `Unknown` item is used when processing unrecognised ordinals.
297
    #[repr(u8)]
298
    pub(crate) enum ECCurveType {
299
        ExplicitPrime => 0x01,
300
        ExplicitChar2 => 0x02,
301
        NamedCurve => 0x03,
302
    }
303
}
304
305
enum_builder! {
306
    /// The `PskKeyExchangeMode` 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 PskKeyExchangeMode {
311
        PSK_KE => 0x00,
312
        PSK_DHE_KE => 0x01,
313
    }
314
}
315
316
enum_builder! {
317
    /// The `KeyUpdateRequest` TLS protocol enum.  Values in this enum are taken
318
    /// from the various RFCs covering TLS, and are listed by IANA.
319
    /// The `Unknown` item is used when processing unrecognised ordinals.
320
    #[repr(u8)]
321
    pub enum KeyUpdateRequest {
322
        UpdateNotRequested => 0x00,
323
        UpdateRequested => 0x01,
324
    }
325
}
326
327
enum_builder! {
328
    /// The `CertificateStatusType` TLS protocol enum.  Values in this enum are taken
329
    /// from the various RFCs covering TLS, and are listed by IANA.
330
    /// The `Unknown` item is used when processing unrecognised ordinals.
331
    #[repr(u8)]
332
    pub enum CertificateStatusType {
333
        OCSP => 0x01,
334
    }
335
}
336
337
enum_builder! {
338
    /// The Key Encapsulation Mechanism (`Kem`) type for HPKE operations.
339
    /// Listed by IANA, as specified in [RFC 9180 Section 7.1]
340
    ///
341
    /// [RFC 9180 Section 7.1]: <https://datatracker.ietf.org/doc/html/rfc9180#kemid-values>
342
    #[repr(u16)]
343
    pub enum HpkeKem {
344
        DHKEM_P256_HKDF_SHA256 => 0x0010,
345
        DHKEM_P384_HKDF_SHA384 => 0x0011,
346
        DHKEM_P521_HKDF_SHA512 => 0x0012,
347
        DHKEM_X25519_HKDF_SHA256 => 0x0020,
348
        DHKEM_X448_HKDF_SHA512 => 0x0021,
349
    }
350
}
351
352
enum_builder! {
353
    /// The Key Derivation Function (`Kdf`) type for HPKE operations.
354
    /// Listed by IANA, as specified in [RFC 9180 Section 7.2]
355
    ///
356
    /// [RFC 9180 Section 7.2]: <https://datatracker.ietf.org/doc/html/rfc9180#name-key-derivation-functions-kd>
357
    #[repr(u16)]
358
    pub enum HpkeKdf {
359
        HKDF_SHA256 => 0x0001,
360
        HKDF_SHA384 => 0x0002,
361
        HKDF_SHA512 => 0x0003,
362
    }
363
}
364
365
impl Default for HpkeKdf {
366
    // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now.
367
0
    fn default() -> Self {
368
0
        Self::HKDF_SHA256
369
0
    }
Unexecuted instantiation: <rustls::msgs::enums::HpkeKdf as core::default::Default>::default
Unexecuted instantiation: <rustls::msgs::enums::HpkeKdf as core::default::Default>::default
370
}
371
372
enum_builder! {
373
    /// The Authenticated Encryption with Associated Data (`Aead`) type for HPKE operations.
374
    /// Listed by IANA, as specified in [RFC 9180 Section 7.3]
375
    ///
376
    /// [RFC 9180 Section 7.3]: <https://datatracker.ietf.org/doc/html/rfc9180#name-authenticated-encryption-wi>
377
    #[repr(u16)]
378
    pub enum HpkeAead {
379
        AES_128_GCM => 0x0001,
380
        AES_256_GCM => 0x0002,
381
        CHACHA20_POLY_1305 => 0x0003,
382
        EXPORT_ONLY => 0xFFFF,
383
    }
384
}
385
386
impl HpkeAead {
387
    /// Returns the length of the tag for the AEAD algorithm, or none if the AEAD is EXPORT_ONLY.
388
0
    pub(crate) fn tag_len(&self) -> Option<usize> {
389
0
        match self {
390
            // See RFC 9180 Section 7.3, column `Nt`, the length in bytes of the authentication tag
391
            // for the algorithm.
392
            // https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3
393
0
            Self::AES_128_GCM | Self::AES_256_GCM | Self::CHACHA20_POLY_1305 => Some(16),
394
0
            _ => None,
395
        }
396
0
    }
Unexecuted instantiation: <rustls::msgs::enums::HpkeAead>::tag_len
Unexecuted instantiation: <rustls::msgs::enums::HpkeAead>::tag_len
397
}
398
399
impl Default for HpkeAead {
400
    // TODO(XXX): revisit the default configuration. This is just what Cloudflare ships right now.
401
0
    fn default() -> Self {
402
0
        Self::AES_128_GCM
403
0
    }
Unexecuted instantiation: <rustls::msgs::enums::HpkeAead as core::default::Default>::default
Unexecuted instantiation: <rustls::msgs::enums::HpkeAead as core::default::Default>::default
404
}
405
406
enum_builder! {
407
    /// The Encrypted Client Hello protocol version (`EchVersion`).
408
    ///
409
    /// Specified in [draft-ietf-tls-esni Section 4].
410
    /// TODO(XXX): Update reference once RFC is published.
411
    ///
412
    /// [draft-ietf-tls-esni Section 4]: <https://www.ietf.org/archive/id/draft-ietf-tls-esni-17.html#section-4>
413
    #[repr(u16)]
414
    pub enum EchVersion {
415
        V18 => 0xfe0d,
416
    }
417
}
418
419
#[cfg(test)]
420
pub(crate) mod tests {
421
    // These tests are intended to provide coverage and
422
    // check panic-safety of relatively unused values.
423
424
    use std::prelude::v1::*;
425
426
    use super::*;
427
428
    #[test]
429
    fn test_enums() {
430
        test_enum8::<HashAlgorithm>(HashAlgorithm::NONE, HashAlgorithm::SHA512);
431
        test_enum8::<ClientCertificateType>(
432
            ClientCertificateType::RSASign,
433
            ClientCertificateType::ECDSAFixedECDH,
434
        );
435
        test_enum8::<Compression>(Compression::Null, Compression::LSZ);
436
        test_enum8::<AlertLevel>(AlertLevel::Warning, AlertLevel::Fatal);
437
        test_enum8::<HeartbeatMessageType>(
438
            HeartbeatMessageType::Request,
439
            HeartbeatMessageType::Response,
440
        );
441
        test_enum16::<ExtensionType>(ExtensionType::ServerName, ExtensionType::RenegotiationInfo);
442
        test_enum8::<ServerNameType>(ServerNameType::HostName, ServerNameType::HostName);
443
        test_enum16::<NamedCurve>(
444
            NamedCurve::sect163k1,
445
            NamedCurve::arbitrary_explicit_char2_curves,
446
        );
447
        test_enum16::<NamedGroup>(NamedGroup::secp256r1, NamedGroup::FFDHE8192);
448
        test_enum8::<ECPointFormat>(
449
            ECPointFormat::Uncompressed,
450
            ECPointFormat::ANSIX962CompressedChar2,
451
        );
452
        test_enum8::<HeartbeatMode>(
453
            HeartbeatMode::PeerAllowedToSend,
454
            HeartbeatMode::PeerNotAllowedToSend,
455
        );
456
        test_enum8::<ECCurveType>(ECCurveType::ExplicitPrime, ECCurveType::NamedCurve);
457
        test_enum8::<PskKeyExchangeMode>(
458
            PskKeyExchangeMode::PSK_KE,
459
            PskKeyExchangeMode::PSK_DHE_KE,
460
        );
461
        test_enum8::<KeyUpdateRequest>(
462
            KeyUpdateRequest::UpdateNotRequested,
463
            KeyUpdateRequest::UpdateRequested,
464
        );
465
        test_enum8::<CertificateStatusType>(
466
            CertificateStatusType::OCSP,
467
            CertificateStatusType::OCSP,
468
        );
469
    }
470
471
    pub(crate) fn test_enum8<T: for<'a> Codec<'a>>(first: T, last: T) {
472
        let first_v = get8(&first);
473
        let last_v = get8(&last);
474
475
        for val in first_v..last_v + 1 {
476
            let mut buf = Vec::new();
477
            val.encode(&mut buf);
478
            assert_eq!(buf.len(), 1);
479
480
            let t = T::read_bytes(&buf).unwrap();
481
            assert_eq!(val, get8(&t));
482
        }
483
    }
484
485
    pub(crate) fn test_enum16<T: for<'a> Codec<'a>>(first: T, last: T) {
486
        let first_v = get16(&first);
487
        let last_v = get16(&last);
488
489
        for val in first_v..last_v + 1 {
490
            let mut buf = Vec::new();
491
            val.encode(&mut buf);
492
            assert_eq!(buf.len(), 2);
493
494
            let t = T::read_bytes(&buf).unwrap();
495
            assert_eq!(val, get16(&t));
496
        }
497
    }
498
499
    fn get8<T: for<'a> Codec<'a>>(enum_value: &T) -> u8 {
500
        let enc = enum_value.get_encoding();
501
        assert_eq!(enc.len(), 1);
502
        enc[0]
503
    }
504
505
    fn get16<T: for<'a> Codec<'a>>(enum_value: &T) -> u16 {
506
        let enc = enum_value.get_encoding();
507
        assert_eq!(enc.len(), 2);
508
        (enc[0] as u16 >> 8) | (enc[1] as u16)
509
    }
510
}