Coverage Report

Created: 2025-10-29 07:05

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