Coverage Report

Created: 2026-03-17 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/src/server/hs.rs
Line
Count
Source
1
use alloc::borrow::ToOwned;
2
use alloc::boxed::Box;
3
use alloc::vec::Vec;
4
5
use pki_types::DnsName;
6
7
use super::server_conn::ServerConnectionData;
8
#[cfg(feature = "tls12")]
9
use super::tls12;
10
use crate::common_state::{KxState, Protocol, State};
11
use crate::conn::ConnectionRandoms;
12
use crate::crypto::SupportedKxGroup;
13
use crate::enums::{
14
    AlertDescription, CertificateType, CipherSuite, HandshakeType, ProtocolVersion,
15
    SignatureAlgorithm, SignatureScheme,
16
};
17
use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
18
use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
19
use crate::log::{debug, trace};
20
use crate::msgs::enums::{Compression, ExtensionType, NamedGroup};
21
#[cfg(feature = "tls12")]
22
use crate::msgs::handshake::SessionId;
23
use crate::msgs::handshake::{
24
    ClientHelloPayload, HandshakePayload, KeyExchangeAlgorithm, ProtocolName, Random,
25
    ServerExtensions, ServerExtensionsInput, ServerNamePayload, SingleProtocolName,
26
    TransportParameters,
27
};
28
use crate::msgs::message::{Message, MessagePayload};
29
use crate::msgs::persist;
30
use crate::server::common::ActiveCertifiedKey;
31
use crate::server::{ClientHello, ServerConfig, tls13};
32
use crate::sync::Arc;
33
use crate::{SupportedCipherSuite, suites};
34
35
pub(super) type NextState<'a> = Box<dyn State<ServerConnectionData> + 'a>;
36
pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
37
pub(super) type ServerContext<'a> = crate::common_state::Context<'a, ServerConnectionData>;
38
39
0
pub(super) fn can_resume(
40
0
    suite: SupportedCipherSuite,
41
0
    sni: &Option<DnsName<'_>>,
42
0
    using_ems: bool,
43
0
    resumedata: &persist::ServerSessionValue,
44
0
) -> bool {
45
    // The RFCs underspecify what happens if we try to resume to
46
    // an unoffered/varying suite.  We merely don't resume in weird cases.
47
    //
48
    // RFC 6066 says "A server that implements this extension MUST NOT accept
49
    // the request to resume the session if the server_name extension contains
50
    // a different name. Instead, it proceeds with a full handshake to
51
    // establish a new session."
52
    //
53
    // RFC 8446: "The server MUST ensure that it selects
54
    // a compatible PSK (if any) and cipher suite."
55
0
    resumedata.cipher_suite == suite.suite()
56
0
        && (resumedata.extended_ms == using_ems || (resumedata.extended_ms && !using_ems))
57
0
        && &resumedata.sni == sni
58
0
}
59
60
#[derive(Default)]
61
pub(super) struct ExtensionProcessing {
62
    // extensions to reply with
63
    pub(super) extensions: Box<ServerExtensions<'static>>,
64
    #[cfg(feature = "tls12")]
65
    pub(super) send_ticket: bool,
66
}
67
68
impl ExtensionProcessing {
69
0
    pub(super) fn new(extra_exts: ServerExtensionsInput<'static>) -> Self {
70
        let ServerExtensionsInput {
71
0
            transport_parameters,
72
0
        } = extra_exts;
73
74
0
        let mut extensions = Box::new(ServerExtensions::default());
75
0
        match transport_parameters {
76
0
            Some(TransportParameters::Quic(v)) => extensions.transport_parameters = Some(v),
77
0
            Some(TransportParameters::QuicDraft(v)) => {
78
0
                extensions.transport_parameters_draft = Some(v)
79
            }
80
0
            None => {}
81
        }
82
83
0
        Self {
84
0
            extensions,
85
0
            #[cfg(feature = "tls12")]
86
0
            send_ticket: false,
87
0
        }
88
0
    }
89
90
0
    pub(super) fn process_common(
91
0
        &mut self,
92
0
        config: &ServerConfig,
93
0
        cx: &mut ServerContext<'_>,
94
0
        ocsp_response: &mut Option<&[u8]>,
95
0
        hello: &ClientHelloPayload,
96
0
        resumedata: Option<&persist::ServerSessionValue>,
97
0
    ) -> Result<(), Error> {
98
        // ALPN
99
0
        let our_protocols = &config.alpn_protocols;
100
0
        if let Some(their_protocols) = &hello.protocols {
101
0
            cx.common.alpn_protocol = our_protocols
102
0
                .iter()
103
0
                .find(|ours| {
104
0
                    their_protocols
105
0
                        .iter()
106
0
                        .any(|theirs| theirs.as_ref() == ours.as_slice())
107
0
                })
108
0
                .map(|bytes| ProtocolName::from(bytes.clone()));
109
0
            if let Some(selected_protocol) = &cx.common.alpn_protocol {
110
0
                debug!("Chosen ALPN protocol {selected_protocol:?}");
111
0
112
0
                self.extensions.selected_protocol =
113
0
                    Some(SingleProtocolName::new(selected_protocol.clone()));
114
0
            } else if !our_protocols.is_empty() {
115
0
                return Err(cx.common.send_fatal_alert(
116
0
                    AlertDescription::NoApplicationProtocol,
117
0
                    Error::NoApplicationProtocol,
118
0
                ));
119
0
            }
120
0
        }
121
122
0
        if cx.common.is_quic() {
123
            // QUIC has strict ALPN, unlike TLS's more backwards-compatible behavior. RFC 9001
124
            // says: "The server MUST treat the inability to select a compatible application
125
            // protocol as a connection error of type 0x0178". We judge that ALPN was desired
126
            // (rather than some out-of-band protocol negotiation mechanism) if and only if any ALPN
127
            // protocols were configured locally or offered by the client. This helps prevent
128
            // successful establishment of connections between peers that can't understand
129
            // each other.
130
0
            if cx.common.alpn_protocol.is_none()
131
0
                && (!our_protocols.is_empty() || hello.protocols.is_some())
132
            {
133
0
                return Err(cx.common.send_fatal_alert(
134
0
                    AlertDescription::NoApplicationProtocol,
135
0
                    Error::NoApplicationProtocol,
136
0
                ));
137
0
            }
138
139
0
            let transport_params = hello
140
0
                .transport_parameters
141
0
                .as_ref()
142
0
                .or(hello
143
0
                    .transport_parameters_draft
144
0
                    .as_ref());
145
0
            match transport_params {
146
0
                Some(params) => cx.common.quic.params = Some(params.to_owned().into_vec()),
147
                None => {
148
0
                    return Err(cx
149
0
                        .common
150
0
                        .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
151
                }
152
            }
153
0
        }
154
155
0
        let for_resume = resumedata.is_some();
156
        // SNI
157
0
        if let (false, Some(ServerNamePayload::SingleDnsName(_))) = (for_resume, &hello.server_name)
158
0
        {
159
0
            self.extensions.server_name_ack = Some(());
160
0
        }
161
162
        // Send status_request response if we have one.  This is not allowed
163
        // if we're resuming, and is only triggered if we have an OCSP response
164
        // to send.
165
0
        if !for_resume
166
0
            && hello
167
0
                .certificate_status_request
168
0
                .is_some()
169
        {
170
0
            if ocsp_response.is_some() && !cx.common.is_tls13() {
171
0
                // Only TLS1.2 sends confirmation in ServerHello
172
0
                self.extensions
173
0
                    .certificate_status_request_ack = Some(());
174
0
            }
175
0
        } else {
176
0
            // Throw away any OCSP response so we don't try to send it later.
177
0
            ocsp_response.take();
178
0
        }
179
180
0
        self.validate_server_cert_type_extension(hello, config, cx)?;
181
0
        self.validate_client_cert_type_extension(hello, config, cx)?;
182
183
0
        Ok(())
184
0
    }
185
186
    #[cfg(feature = "tls12")]
187
0
    pub(super) fn process_tls12(
188
0
        &mut self,
189
0
        config: &ServerConfig,
190
0
        hello: &ClientHelloPayload,
191
0
        using_ems: bool,
192
0
    ) {
193
        // Renegotiation.
194
        // (We don't do reneg at all, but would support the secure version if we did.)
195
196
        use crate::msgs::base::PayloadU8;
197
0
        let secure_reneg_offered = hello.renegotiation_info.is_some()
198
0
            || hello
199
0
                .cipher_suites
200
0
                .contains(&CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
201
202
0
        if secure_reneg_offered {
203
0
            self.extensions.renegotiation_info = Some(PayloadU8::new(Vec::new()));
204
0
        }
205
206
        // Tickets:
207
        // If we get any SessionTicket extension and have tickets enabled,
208
        // we send an ack.
209
0
        if hello.session_ticket.is_some() && config.ticketer.enabled() {
210
0
            self.send_ticket = true;
211
0
            self.extensions.session_ticket_ack = Some(());
212
0
        }
213
214
        // Confirm use of EMS if offered.
215
0
        if using_ems {
216
0
            self.extensions
217
0
                .extended_master_secret_ack = Some(());
218
0
        }
219
0
    }
220
221
0
    fn validate_server_cert_type_extension(
222
0
        &mut self,
223
0
        hello: &ClientHelloPayload,
224
0
        config: &ServerConfig,
225
0
        cx: &mut ServerContext<'_>,
226
0
    ) -> Result<(), Error> {
227
0
        let client_supports = hello
228
0
            .server_certificate_types
229
0
            .as_deref()
230
0
            .unwrap_or_default();
231
232
0
        self.process_cert_type_extension(
233
0
            client_supports,
234
0
            config
235
0
                .cert_resolver
236
0
                .only_raw_public_keys(),
237
0
            ExtensionType::ServerCertificateType,
238
0
            cx,
239
        )
240
0
    }
241
242
0
    fn validate_client_cert_type_extension(
243
0
        &mut self,
244
0
        hello: &ClientHelloPayload,
245
0
        config: &ServerConfig,
246
0
        cx: &mut ServerContext<'_>,
247
0
    ) -> Result<(), Error> {
248
0
        let client_supports = hello
249
0
            .client_certificate_types
250
0
            .as_deref()
251
0
            .unwrap_or_default();
252
253
0
        self.process_cert_type_extension(
254
0
            client_supports,
255
0
            config
256
0
                .verifier
257
0
                .requires_raw_public_keys(),
258
0
            ExtensionType::ClientCertificateType,
259
0
            cx,
260
        )
261
0
    }
262
263
0
    fn process_cert_type_extension(
264
0
        &mut self,
265
0
        client_supports: &[CertificateType],
266
0
        requires_raw_keys: bool,
267
0
        extension_type: ExtensionType,
268
0
        cx: &mut ServerContext<'_>,
269
0
    ) -> Result<(), Error> {
270
0
        debug_assert!(
271
0
            extension_type == ExtensionType::ClientCertificateType
272
0
                || extension_type == ExtensionType::ServerCertificateType
273
        );
274
0
        let raw_key_negotation_result = match (
275
0
            requires_raw_keys,
276
0
            client_supports.contains(&CertificateType::RawPublicKey),
277
0
            client_supports.contains(&CertificateType::X509),
278
0
        ) {
279
0
            (true, true, _) => Ok((extension_type, CertificateType::RawPublicKey)),
280
0
            (false, _, true) => Ok((extension_type, CertificateType::X509)),
281
0
            (false, true, false) => Err(Error::PeerIncompatible(
282
0
                PeerIncompatible::IncorrectCertificateTypeExtension,
283
0
            )),
284
0
            (true, false, _) => Err(Error::PeerIncompatible(
285
0
                PeerIncompatible::IncorrectCertificateTypeExtension,
286
0
            )),
287
0
            (false, false, false) => return Ok(()),
288
        };
289
290
0
        match raw_key_negotation_result {
291
0
            Ok((ExtensionType::ClientCertificateType, cert_type)) => {
292
0
                self.extensions.client_certificate_type = Some(cert_type);
293
0
            }
294
0
            Ok((ExtensionType::ServerCertificateType, cert_type)) => {
295
0
                self.extensions.server_certificate_type = Some(cert_type);
296
0
            }
297
0
            Err(err) => {
298
0
                return Err(cx
299
0
                    .common
300
0
                    .send_fatal_alert(AlertDescription::HandshakeFailure, err));
301
            }
302
0
            Ok((_, _)) => unreachable!(),
303
        }
304
0
        Ok(())
305
0
    }
306
}
307
308
pub(super) struct ExpectClientHello {
309
    pub(super) config: Arc<ServerConfig>,
310
    pub(super) extra_exts: ServerExtensionsInput<'static>,
311
    pub(super) transcript: HandshakeHashOrBuffer,
312
    #[cfg(feature = "tls12")]
313
    pub(super) session_id: SessionId,
314
    #[cfg(feature = "tls12")]
315
    pub(super) using_ems: bool,
316
    pub(super) done_retry: bool,
317
    pub(super) send_tickets: usize,
318
}
319
320
impl ExpectClientHello {
321
0
    pub(super) fn new(
322
0
        config: Arc<ServerConfig>,
323
0
        extra_exts: ServerExtensionsInput<'static>,
324
0
    ) -> Self {
325
0
        let mut transcript_buffer = HandshakeHashBuffer::new();
326
327
0
        if config.verifier.offer_client_auth() {
328
0
            transcript_buffer.set_client_auth_enabled();
329
0
        }
330
331
0
        Self {
332
0
            config,
333
0
            extra_exts,
334
0
            transcript: HandshakeHashOrBuffer::Buffer(transcript_buffer),
335
0
            #[cfg(feature = "tls12")]
336
0
            session_id: SessionId::empty(),
337
0
            #[cfg(feature = "tls12")]
338
0
            using_ems: false,
339
0
            done_retry: false,
340
0
            send_tickets: 0,
341
0
        }
342
0
    }
343
344
    /// Continues handling of a `ClientHello` message once config and certificate are available.
345
0
    pub(super) fn with_certified_key(
346
0
        self,
347
0
        mut sig_schemes: Vec<SignatureScheme>,
348
0
        client_hello: &ClientHelloPayload,
349
0
        m: &Message<'_>,
350
0
        cx: &mut ServerContext<'_>,
351
0
    ) -> NextStateOrError<'static> {
352
0
        let tls13_enabled = self
353
0
            .config
354
0
            .supports_version(ProtocolVersion::TLSv1_3);
355
0
        let tls12_enabled = self
356
0
            .config
357
0
            .supports_version(ProtocolVersion::TLSv1_2);
358
359
        // Are we doing TLS1.3?
360
0
        let version = if let Some(versions) = &client_hello.supported_versions {
361
0
            if versions.tls13 && tls13_enabled {
362
0
                ProtocolVersion::TLSv1_3
363
0
            } else if !versions.tls12 || !tls12_enabled {
364
0
                return Err(cx.common.send_fatal_alert(
365
0
                    AlertDescription::ProtocolVersion,
366
0
                    PeerIncompatible::Tls12NotOfferedOrEnabled,
367
0
                ));
368
0
            } else if cx.common.is_quic() {
369
0
                return Err(cx.common.send_fatal_alert(
370
0
                    AlertDescription::ProtocolVersion,
371
0
                    PeerIncompatible::Tls13RequiredForQuic,
372
0
                ));
373
            } else {
374
0
                ProtocolVersion::TLSv1_2
375
            }
376
0
        } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
377
0
            return Err(cx.common.send_fatal_alert(
378
0
                AlertDescription::ProtocolVersion,
379
0
                PeerIncompatible::Tls12NotOffered,
380
0
            ));
381
0
        } else if !tls12_enabled && tls13_enabled {
382
0
            return Err(cx.common.send_fatal_alert(
383
0
                AlertDescription::ProtocolVersion,
384
0
                PeerIncompatible::SupportedVersionsExtensionRequired,
385
0
            ));
386
0
        } else if cx.common.is_quic() {
387
0
            return Err(cx.common.send_fatal_alert(
388
0
                AlertDescription::ProtocolVersion,
389
0
                PeerIncompatible::Tls13RequiredForQuic,
390
0
            ));
391
        } else {
392
0
            ProtocolVersion::TLSv1_2
393
        };
394
395
0
        cx.common.negotiated_version = Some(version);
396
397
        // We communicate to the upper layer what kind of key they should choose
398
        // via the sigschemes value.  Clients tend to treat this extension
399
        // orthogonally to offered ciphersuites (even though, in TLS1.2 it is not).
400
        // So: reduce the offered sigschemes to those compatible with the
401
        // intersection of ciphersuites.
402
0
        let client_suites = self
403
0
            .config
404
0
            .provider
405
0
            .cipher_suites
406
0
            .iter()
407
0
            .copied()
408
0
            .filter(|scs| {
409
0
                client_hello
410
0
                    .cipher_suites
411
0
                    .contains(&scs.suite())
412
0
            })
413
0
            .collect::<Vec<_>>();
414
415
0
        sig_schemes
416
0
            .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
417
418
        // We adhere to the TLS 1.2 RFC by not exposing this to the cert resolver if TLS version is 1.2
419
0
        let certificate_authorities = match version {
420
0
            ProtocolVersion::TLSv1_2 => None,
421
0
            _ => client_hello
422
0
                .certificate_authority_names
423
0
                .as_deref(),
424
        };
425
        // Choose a certificate.
426
0
        let certkey = {
427
0
            let client_hello = ClientHello {
428
0
                server_name: &cx.data.sni,
429
0
                signature_schemes: &sig_schemes,
430
0
                alpn: client_hello.protocols.as_ref(),
431
0
                client_cert_types: client_hello
432
0
                    .client_certificate_types
433
0
                    .as_deref(),
434
0
                server_cert_types: client_hello
435
0
                    .server_certificate_types
436
0
                    .as_deref(),
437
0
                cipher_suites: &client_hello.cipher_suites,
438
0
                certificate_authorities,
439
0
                named_groups: client_hello.named_groups.as_deref(),
440
0
            };
441
0
            trace!("Resolving server certificate: {client_hello:#?}");
442
443
0
            let certkey = self
444
0
                .config
445
0
                .cert_resolver
446
0
                .resolve(client_hello);
447
448
0
            certkey.ok_or_else(|| {
449
0
                cx.common.send_fatal_alert(
450
0
                    AlertDescription::AccessDenied,
451
0
                    Error::General("no server certificate chain resolved".to_owned()),
452
                )
453
0
            })?
454
        };
455
0
        let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
456
457
0
        let (suite, skxg) = self
458
0
            .choose_suite_and_kx_group(
459
0
                version,
460
0
                certkey.get_key().algorithm(),
461
0
                cx.common.protocol,
462
0
                client_hello
463
0
                    .named_groups
464
0
                    .as_deref()
465
0
                    .unwrap_or_default(),
466
0
                &client_hello.cipher_suites,
467
            )
468
0
            .map_err(|incompat| {
469
0
                cx.common
470
0
                    .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
471
0
            })?;
472
473
0
        debug!("decided upon suite {suite:?}");
474
0
        cx.common.suite = Some(suite);
475
0
        cx.common.kx_state = KxState::Start(skxg);
476
477
        // Start handshake hash.
478
0
        let starting_hash = suite.hash_provider();
479
0
        let transcript = match self.transcript {
480
0
            HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
481
0
            HandshakeHashOrBuffer::Hash(inner)
482
0
                if inner.algorithm() == starting_hash.algorithm() =>
483
            {
484
0
                inner
485
            }
486
            _ => {
487
0
                return Err(cx.common.send_fatal_alert(
488
0
                    AlertDescription::IllegalParameter,
489
0
                    PeerMisbehaved::HandshakeHashVariedAfterRetry,
490
0
                ));
491
            }
492
        };
493
494
        // Save their Random.
495
0
        let randoms = ConnectionRandoms::new(
496
0
            client_hello.random,
497
0
            Random::new(self.config.provider.secure_random)?,
498
        );
499
0
        match suite {
500
0
            SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
501
0
                config: self.config,
502
0
                transcript,
503
0
                suite,
504
0
                randoms,
505
0
                done_retry: self.done_retry,
506
0
                send_tickets: self.send_tickets,
507
0
                extra_exts: self.extra_exts,
508
0
            }
509
0
            .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
510
            #[cfg(feature = "tls12")]
511
0
            SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
512
0
                config: self.config,
513
0
                transcript,
514
0
                session_id: self.session_id,
515
0
                suite,
516
0
                using_ems: self.using_ems,
517
0
                randoms,
518
0
                send_ticket: self.send_tickets > 0,
519
0
                extra_exts: self.extra_exts,
520
0
            }
521
0
            .handle_client_hello(
522
0
                cx,
523
0
                certkey,
524
0
                m,
525
0
                client_hello,
526
0
                skxg,
527
0
                sig_schemes,
528
0
                tls13_enabled,
529
            ),
530
        }
531
0
    }
532
533
0
    fn choose_suite_and_kx_group(
534
0
        &self,
535
0
        selected_version: ProtocolVersion,
536
0
        sig_key_algorithm: SignatureAlgorithm,
537
0
        protocol: Protocol,
538
0
        client_groups: &[NamedGroup],
539
0
        client_suites: &[CipherSuite],
540
0
    ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
541
        // Determine which `KeyExchangeAlgorithm`s are theoretically possible, based
542
        // on the offered and supported groups.
543
0
        let mut ecdhe_possible = false;
544
0
        let mut ffdhe_possible = false;
545
0
        let mut ffdhe_offered = false;
546
0
        let mut supported_groups = Vec::with_capacity(client_groups.len());
547
548
0
        for offered_group in client_groups {
549
0
            let supported = self
550
0
                .config
551
0
                .provider
552
0
                .kx_groups
553
0
                .iter()
554
0
                .find(|skxg| {
555
0
                    skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
556
0
                });
557
558
0
            match offered_group.key_exchange_algorithm() {
559
0
                KeyExchangeAlgorithm::DHE => {
560
0
                    ffdhe_possible |= supported.is_some();
561
0
                    ffdhe_offered = true;
562
0
                }
563
0
                KeyExchangeAlgorithm::ECDHE => {
564
0
                    ecdhe_possible |= supported.is_some();
565
0
                }
566
            }
567
568
0
            supported_groups.push(supported);
569
        }
570
571
0
        let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
572
            // https://datatracker.ietf.org/doc/html/rfc7919#section-4 (paragraph 2)
573
0
            let first_supported_dhe_kxg = self
574
0
                .config
575
0
                .provider
576
0
                .kx_groups
577
0
                .iter()
578
0
                .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
579
0
            ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
580
0
            first_supported_dhe_kxg
581
        } else {
582
            // In TLS1.3, the server may only directly negotiate a group.
583
0
            None
584
        };
585
586
0
        if !ecdhe_possible && !ffdhe_possible {
587
0
            return Err(PeerIncompatible::NoKxGroupsInCommon);
588
0
        }
589
590
0
        let mut suitable_suites_iter = self
591
0
            .config
592
0
            .provider
593
0
            .cipher_suites
594
0
            .iter()
595
0
            .filter(|suite| {
596
                // Reduce our supported ciphersuites by the certified key's algorithm.
597
0
                suite.usable_for_signature_algorithm(sig_key_algorithm)
598
                // And version
599
0
                && suite.version().version == selected_version
600
                // And protocol
601
0
                && suite.usable_for_protocol(protocol)
602
                // And support one of key exchange groups
603
0
                && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
604
0
                || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
605
0
            });
606
607
        // RFC 7919 (https://datatracker.ietf.org/doc/html/rfc7919#section-4) requires us to send
608
        // the InsufficientSecurity alert in case we don't recognize client's FFDHE groups (i.e.,
609
        // `suitable_suites` becomes empty). But that does not make a lot of sense (e.g., client
610
        // proposes FFDHE4096 and we only support FFDHE2048), so we ignore that requirement here,
611
        // and continue to send HandshakeFailure.
612
613
0
        let suite = if self.config.ignore_client_order {
614
0
            suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
615
        } else {
616
0
            let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
617
0
            client_suites
618
0
                .iter()
619
0
                .find_map(|client_suite| {
620
0
                    suitable_suites
621
0
                        .iter()
622
0
                        .find(|x| *client_suite == x.suite())
623
0
                })
624
0
                .copied()
625
        }
626
0
        .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
627
628
        // Finally, choose a key exchange group that is compatible with the selected cipher
629
        // suite.
630
0
        let maybe_skxg = supported_groups
631
0
            .iter()
632
0
            .find_map(|maybe_skxg| match maybe_skxg {
633
0
                Some(skxg) => suite
634
0
                    .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
635
0
                    .then_some(*skxg),
636
0
                None => None,
637
0
            });
638
639
0
        if selected_version == ProtocolVersion::TLSv1_3 {
640
            // This unwrap is structurally guaranteed by the early return for `!ffdhe_possible && !ecdhe_possible`
641
0
            return Ok((*suite, *maybe_skxg.unwrap()));
642
0
        }
643
644
        // For TLS1.2, the server can unilaterally choose a DHE group if it has one and
645
        // there was no better option.
646
0
        match maybe_skxg {
647
0
            Some(skxg) => Ok((*suite, *skxg)),
648
0
            None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
649
                // If kx for the selected cipher suite is DHE and no DHE groups are specified in the extension,
650
                // the server is free to choose DHE params, we choose the first DHE kx group of the provider.
651
0
                if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
652
0
                    Ok((*suite, *server_selected_ffdhe_skxg))
653
                } else {
654
0
                    Err(PeerIncompatible::NoKxGroupsInCommon)
655
                }
656
            }
657
0
            None => Err(PeerIncompatible::NoKxGroupsInCommon),
658
        }
659
0
    }
660
}
661
662
impl State<ServerConnectionData> for ExpectClientHello {
663
0
    fn handle<'m>(
664
0
        self: Box<Self>,
665
0
        cx: &mut ServerContext<'_>,
666
0
        m: Message<'m>,
667
0
    ) -> NextStateOrError<'m>
668
0
    where
669
0
        Self: 'm,
670
    {
671
0
        let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
672
0
        self.with_certified_key(sig_schemes, client_hello, &m, cx)
673
0
    }
674
675
0
    fn into_owned(self: Box<Self>) -> NextState<'static> {
676
0
        self
677
0
    }
678
}
679
680
/// Configuration-independent validation of a `ClientHello` message.
681
///
682
/// This represents the first part of the `ClientHello` handling, where we do all validation that
683
/// doesn't depend on a `ServerConfig` being available and extract everything needed to build a
684
/// [`ClientHello`] value for a [`ResolvesServerCert`].
685
///
686
/// Note that this will modify `data.sni` even if config or certificate resolution fail.
687
///
688
/// [`ResolvesServerCert`]: crate::server::ResolvesServerCert
689
0
pub(super) fn process_client_hello<'m>(
690
0
    m: &'m Message<'m>,
691
0
    done_retry: bool,
692
0
    cx: &mut ServerContext<'_>,
693
0
) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
694
0
    let client_hello =
695
0
        require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
696
0
    trace!("we got a clienthello {client_hello:?}");
697
698
0
    if !client_hello
699
0
        .compression_methods
700
0
        .contains(&Compression::Null)
701
    {
702
0
        return Err(cx.common.send_fatal_alert(
703
0
            AlertDescription::IllegalParameter,
704
0
            PeerIncompatible::NullCompressionRequired,
705
0
        ));
706
0
    }
707
708
    // No handshake messages should follow this one in this flight.
709
0
    cx.common.check_aligned_handshake()?;
710
711
    // Extract and validate the SNI DNS name, if any, before giving it to
712
    // the cert resolver. In particular, if it is invalid then we should
713
    // send an Illegal Parameter alert instead of the Internal Error alert
714
    // (or whatever) that we'd send if this were checked later or in a
715
    // different way.
716
    //
717
    // [RFC6066][] specifies that literal IP addresses are illegal in
718
    // `ServerName`s with a `name_type` of `host_name`.
719
    //
720
    // Some clients incorrectly send such extensions: we choose to
721
    // successfully parse these (into `ServerNamePayload::IpAddress`)
722
    // but then act like the client sent no `server_name` extension.
723
    //
724
    // [RFC6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-3
725
0
    let sni = match &client_hello.server_name {
726
0
        Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
727
0
        Some(ServerNamePayload::IpAddress) => None,
728
        Some(ServerNamePayload::Invalid) => {
729
0
            return Err(cx.common.send_fatal_alert(
730
0
                AlertDescription::IllegalParameter,
731
0
                PeerMisbehaved::ServerNameMustContainOneHostName,
732
0
            ));
733
        }
734
0
        None => None,
735
    };
736
737
    // save only the first SNI
738
0
    if let (Some(sni), false) = (&sni, done_retry) {
739
        // Save the SNI into the session.
740
        // The SNI hostname is immutable once set.
741
0
        assert!(cx.data.sni.is_none());
742
0
        cx.data.sni = Some(sni.clone());
743
0
    } else if cx.data.sni != sni {
744
0
        return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
745
0
    }
746
747
0
    let sig_schemes = client_hello
748
0
        .signature_schemes
749
0
        .as_ref()
750
0
        .ok_or_else(|| {
751
0
            cx.common.send_fatal_alert(
752
0
                AlertDescription::HandshakeFailure,
753
0
                PeerIncompatible::SignatureAlgorithmsExtensionRequired,
754
            )
755
0
        })?;
756
757
0
    Ok((client_hello, sig_schemes.to_owned()))
758
0
}
759
760
pub(crate) enum HandshakeHashOrBuffer {
761
    Buffer(HandshakeHashBuffer),
762
    Hash(HandshakeHash),
763
}