rustls/server/
hs.rs

1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4
5use pki_types::DnsName;
6
7use super::server_conn::ServerConnectionData;
8#[cfg(feature = "tls12")]
9use super::tls12;
10use crate::common_state::{KxState, Protocol, State};
11use crate::conn::ConnectionRandoms;
12use crate::crypto::SupportedKxGroup;
13use crate::enums::{
14    AlertDescription, CipherSuite, HandshakeType, ProtocolVersion, SignatureAlgorithm,
15    SignatureScheme,
16};
17use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
18use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
19use crate::log::{debug, trace};
20use crate::msgs::enums::{CertificateType, Compression, ExtensionType, NamedGroup};
21#[cfg(feature = "tls12")]
22use crate::msgs::handshake::SessionId;
23use crate::msgs::handshake::{
24    ClientHelloPayload, HandshakePayload, KeyExchangeAlgorithm, Random, ServerExtension,
25    ServerNamePayload, SingleProtocolName,
26};
27use crate::msgs::message::{Message, MessagePayload};
28use crate::msgs::persist;
29use crate::server::common::ActiveCertifiedKey;
30use crate::server::{ClientHello, ServerConfig, tls13};
31use crate::sync::Arc;
32use crate::{SupportedCipherSuite, suites};
33
34pub(super) type NextState<'a> = Box<dyn State<ServerConnectionData> + 'a>;
35pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
36pub(super) type ServerContext<'a> = crate::common_state::Context<'a, ServerConnectionData>;
37
38pub(super) fn can_resume(
39    suite: SupportedCipherSuite,
40    sni: &Option<DnsName<'_>>,
41    using_ems: bool,
42    resumedata: &persist::ServerSessionValue,
43) -> 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    //
52    // RFC 8446: "The server MUST ensure that it selects
53    // a compatible PSK (if any) and cipher suite."
54    resumedata.cipher_suite == suite.suite()
55        && (resumedata.extended_ms == using_ems || (resumedata.extended_ms && !using_ems))
56        && &resumedata.sni == sni
57}
58
59#[derive(Default)]
60pub(super) struct ExtensionProcessing {
61    // extensions to reply with
62    pub(super) exts: Vec<ServerExtension>,
63    #[cfg(feature = "tls12")]
64    pub(super) send_ticket: bool,
65}
66
67impl ExtensionProcessing {
68    pub(super) fn new() -> Self {
69        Default::default()
70    }
71
72    pub(super) fn process_common(
73        &mut self,
74        config: &ServerConfig,
75        cx: &mut ServerContext<'_>,
76        ocsp_response: &mut Option<&[u8]>,
77        hello: &ClientHelloPayload,
78        resumedata: Option<&persist::ServerSessionValue>,
79        extra_exts: Vec<ServerExtension>,
80    ) -> Result<(), Error> {
81        // ALPN
82        let our_protocols = &config.alpn_protocols;
83        let maybe_their_protocols = hello.alpn_extension();
84        if let Some(their_protocols) = maybe_their_protocols {
85            cx.common.alpn_protocol = our_protocols
86                .iter()
87                .find(|ours| {
88                    their_protocols
89                        .iter()
90                        .any(|theirs| theirs.as_ref() == ours.as_slice())
91                })
92                .cloned();
93            if let Some(selected_protocol) = &cx.common.alpn_protocol {
94                debug!("Chosen ALPN protocol {:?}", selected_protocol);
95                self.exts
96                    .push(ServerExtension::Protocols(SingleProtocolName::new(
97                        selected_protocol.clone(),
98                    )));
99            } else if !our_protocols.is_empty() {
100                return Err(cx.common.send_fatal_alert(
101                    AlertDescription::NoApplicationProtocol,
102                    Error::NoApplicationProtocol,
103                ));
104            }
105        }
106
107        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            if cx.common.alpn_protocol.is_none()
116                && (!our_protocols.is_empty() || maybe_their_protocols.is_some())
117            {
118                return Err(cx.common.send_fatal_alert(
119                    AlertDescription::NoApplicationProtocol,
120                    Error::NoApplicationProtocol,
121                ));
122            }
123
124            match hello.quic_params_extension() {
125                Some(params) => cx.common.quic.params = Some(params),
126                None => {
127                    return Err(cx
128                        .common
129                        .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
130                }
131            }
132        }
133
134        let for_resume = resumedata.is_some();
135        // SNI
136        if !for_resume && hello.sni_extension().is_some() {
137            self.exts
138                .push(ServerExtension::ServerNameAck);
139        }
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        if !for_resume
145            && hello
146                .find_extension(ExtensionType::StatusRequest)
147                .is_some()
148        {
149            if ocsp_response.is_some() && !cx.common.is_tls13() {
150                // Only TLS1.2 sends confirmation in ServerHello
151                self.exts
152                    .push(ServerExtension::CertificateStatusAck);
153            }
154        } else {
155            // Throw away any OCSP response so we don't try to send it later.
156            ocsp_response.take();
157        }
158
159        self.validate_server_cert_type_extension(hello, config, cx)?;
160        self.validate_client_cert_type_extension(hello, config, cx)?;
161
162        self.exts.extend(extra_exts);
163
164        Ok(())
165    }
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    fn validate_server_cert_type_extension(
209        &mut self,
210        hello: &ClientHelloPayload,
211        config: &ServerConfig,
212        cx: &mut ServerContext<'_>,
213    ) -> Result<(), Error> {
214        let client_supports = hello
215            .server_certificate_extension()
216            .map(|certificate_types| certificate_types.to_vec())
217            .unwrap_or_default();
218
219        self.process_cert_type_extension(
220            client_supports,
221            config
222                .cert_resolver
223                .only_raw_public_keys(),
224            ExtensionType::ServerCertificateType,
225            cx,
226        )
227    }
228
229    fn validate_client_cert_type_extension(
230        &mut self,
231        hello: &ClientHelloPayload,
232        config: &ServerConfig,
233        cx: &mut ServerContext<'_>,
234    ) -> Result<(), Error> {
235        let client_supports = hello
236            .client_certificate_extension()
237            .map(|certificate_types| certificate_types.to_vec())
238            .unwrap_or_default();
239
240        self.process_cert_type_extension(
241            client_supports,
242            config
243                .verifier
244                .requires_raw_public_keys(),
245            ExtensionType::ClientCertificateType,
246            cx,
247        )
248    }
249
250    fn process_cert_type_extension(
251        &mut self,
252        client_supports: Vec<CertificateType>,
253        requires_raw_keys: bool,
254        extension_type: ExtensionType,
255        cx: &mut ServerContext<'_>,
256    ) -> Result<(), Error> {
257        debug_assert!(
258            extension_type == ExtensionType::ClientCertificateType
259                || extension_type == ExtensionType::ServerCertificateType
260        );
261        let raw_key_negotation_result = match (
262            requires_raw_keys,
263            client_supports.contains(&CertificateType::RawPublicKey),
264            client_supports.contains(&CertificateType::X509),
265        ) {
266            (true, true, _) => Ok((extension_type, CertificateType::RawPublicKey)),
267            (false, _, true) => Ok((extension_type, CertificateType::X509)),
268            (false, true, false) => Err(Error::PeerIncompatible(
269                PeerIncompatible::IncorrectCertificateTypeExtension,
270            )),
271            (true, false, _) => Err(Error::PeerIncompatible(
272                PeerIncompatible::IncorrectCertificateTypeExtension,
273            )),
274            (false, false, false) => return Ok(()),
275        };
276
277        match raw_key_negotation_result {
278            Ok((ExtensionType::ClientCertificateType, cert_type)) => {
279                self.exts
280                    .push(ServerExtension::ClientCertType(cert_type));
281            }
282            Ok((ExtensionType::ServerCertificateType, cert_type)) => {
283                self.exts
284                    .push(ServerExtension::ServerCertType(cert_type));
285            }
286            Err(err) => {
287                return Err(cx
288                    .common
289                    .send_fatal_alert(AlertDescription::HandshakeFailure, err));
290            }
291            Ok((_, _)) => unreachable!(),
292        }
293        Ok(())
294    }
295}
296
297pub(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
309impl ExpectClientHello {
310    pub(super) fn new(config: Arc<ServerConfig>, extra_exts: Vec<ServerExtension>) -> Self {
311        let mut transcript_buffer = HandshakeHashBuffer::new();
312
313        if config.verifier.offer_client_auth() {
314            transcript_buffer.set_client_auth_enabled();
315        }
316
317        Self {
318            config,
319            extra_exts,
320            transcript: HandshakeHashOrBuffer::Buffer(transcript_buffer),
321            #[cfg(feature = "tls12")]
322            session_id: SessionId::empty(),
323            #[cfg(feature = "tls12")]
324            using_ems: false,
325            done_retry: false,
326            send_tickets: 0,
327        }
328    }
329
330    /// Continues handling of a `ClientHello` message once config and certificate are available.
331    pub(super) fn with_certified_key(
332        self,
333        mut sig_schemes: Vec<SignatureScheme>,
334        client_hello: &ClientHelloPayload,
335        m: &Message<'_>,
336        cx: &mut ServerContext<'_>,
337    ) -> NextStateOrError<'static> {
338        let tls13_enabled = self
339            .config
340            .supports_version(ProtocolVersion::TLSv1_3);
341        let tls12_enabled = self
342            .config
343            .supports_version(ProtocolVersion::TLSv1_2);
344
345        // Are we doing TLS1.3?
346        let maybe_versions_ext = client_hello.versions_extension();
347        let version = if let Some(versions) = maybe_versions_ext {
348            if versions.tls13 && tls13_enabled {
349                ProtocolVersion::TLSv1_3
350            } else if !versions.tls12 || !tls12_enabled {
351                return Err(cx.common.send_fatal_alert(
352                    AlertDescription::ProtocolVersion,
353                    PeerIncompatible::Tls12NotOfferedOrEnabled,
354                ));
355            } else if cx.common.is_quic() {
356                return Err(cx.common.send_fatal_alert(
357                    AlertDescription::ProtocolVersion,
358                    PeerIncompatible::Tls13RequiredForQuic,
359                ));
360            } else {
361                ProtocolVersion::TLSv1_2
362            }
363        } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
364            return Err(cx.common.send_fatal_alert(
365                AlertDescription::ProtocolVersion,
366                PeerIncompatible::Tls12NotOffered,
367            ));
368        } else if !tls12_enabled && tls13_enabled {
369            return Err(cx.common.send_fatal_alert(
370                AlertDescription::ProtocolVersion,
371                PeerIncompatible::SupportedVersionsExtensionRequired,
372            ));
373        } else if cx.common.is_quic() {
374            return Err(cx.common.send_fatal_alert(
375                AlertDescription::ProtocolVersion,
376                PeerIncompatible::Tls13RequiredForQuic,
377            ));
378        } else {
379            ProtocolVersion::TLSv1_2
380        };
381
382        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        let client_suites = self
390            .config
391            .provider
392            .cipher_suites
393            .iter()
394            .copied()
395            .filter(|scs| {
396                client_hello
397                    .cipher_suites
398                    .contains(&scs.suite())
399            })
400            .collect::<Vec<_>>();
401
402        sig_schemes
403            .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        let certificate_authorities = match version {
407            ProtocolVersion::TLSv1_2 => None,
408            _ => client_hello.certificate_authorities_extension(),
409        };
410        // Choose a certificate.
411        let certkey = {
412            let client_hello = ClientHello {
413                server_name: &cx.data.sni,
414                signature_schemes: &sig_schemes,
415                alpn: client_hello.alpn_extension(),
416                client_cert_types: client_hello.server_certificate_extension(),
417                server_cert_types: client_hello.client_certificate_extension(),
418                cipher_suites: &client_hello.cipher_suites,
419                certificate_authorities,
420            };
421            trace!("Resolving server certificate: {client_hello:#?}");
422
423            let certkey = self
424                .config
425                .cert_resolver
426                .resolve(client_hello);
427
428            certkey.ok_or_else(|| {
429                cx.common.send_fatal_alert(
430                    AlertDescription::AccessDenied,
431                    Error::General("no server certificate chain resolved".to_owned()),
432                )
433            })?
434        };
435        let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
436
437        let (suite, skxg) = self
438            .choose_suite_and_kx_group(
439                version,
440                certkey.get_key().algorithm(),
441                cx.common.protocol,
442                client_hello
443                    .namedgroups_extension()
444                    .unwrap_or(&[]),
445                &client_hello.cipher_suites,
446            )
447            .map_err(|incompat| {
448                cx.common
449                    .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
450            })?;
451
452        debug!("decided upon suite {:?}", suite);
453        cx.common.suite = Some(suite);
454        cx.common.kx_state = KxState::Start(skxg);
455
456        // Start handshake hash.
457        let starting_hash = suite.hash_provider();
458        let transcript = match self.transcript {
459            HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
460            HandshakeHashOrBuffer::Hash(inner)
461                if inner.algorithm() == starting_hash.algorithm() =>
462            {
463                inner
464            }
465            _ => {
466                return Err(cx.common.send_fatal_alert(
467                    AlertDescription::IllegalParameter,
468                    PeerMisbehaved::HandshakeHashVariedAfterRetry,
469                ));
470            }
471        };
472
473        // Save their Random.
474        let randoms = ConnectionRandoms::new(
475            client_hello.random,
476            Random::new(self.config.provider.secure_random)?,
477        );
478        match suite {
479            SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
480                config: self.config,
481                transcript,
482                suite,
483                randoms,
484                done_retry: self.done_retry,
485                send_tickets: self.send_tickets,
486                extra_exts: self.extra_exts,
487            }
488            .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    }
511
512    fn choose_suite_and_kx_group(
513        &self,
514        selected_version: ProtocolVersion,
515        sig_key_algorithm: SignatureAlgorithm,
516        protocol: Protocol,
517        client_groups: &[NamedGroup],
518        client_suites: &[CipherSuite],
519    ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
520        // Determine which `KeyExchangeAlgorithm`s are theoretically possible, based
521        // on the offered and supported groups.
522        let mut ecdhe_possible = false;
523        let mut ffdhe_possible = false;
524        let mut ffdhe_offered = false;
525        let mut supported_groups = Vec::with_capacity(client_groups.len());
526
527        for offered_group in client_groups {
528            let supported = self
529                .config
530                .provider
531                .kx_groups
532                .iter()
533                .find(|skxg| {
534                    skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
535                });
536
537            match offered_group.key_exchange_algorithm() {
538                KeyExchangeAlgorithm::DHE => {
539                    ffdhe_possible |= supported.is_some();
540                    ffdhe_offered = true;
541                }
542                KeyExchangeAlgorithm::ECDHE => {
543                    ecdhe_possible |= supported.is_some();
544                }
545            }
546
547            supported_groups.push(supported);
548        }
549
550        let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
551            // https://datatracker.ietf.org/doc/html/rfc7919#section-4 (paragraph 2)
552            let first_supported_dhe_kxg = self
553                .config
554                .provider
555                .kx_groups
556                .iter()
557                .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
558            ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
559            first_supported_dhe_kxg
560        } else {
561            // In TLS1.3, the server may only directly negotiate a group.
562            None
563        };
564
565        if !ecdhe_possible && !ffdhe_possible {
566            return Err(PeerIncompatible::NoKxGroupsInCommon);
567        }
568
569        let mut suitable_suites_iter = self
570            .config
571            .provider
572            .cipher_suites
573            .iter()
574            .filter(|suite| {
575                // Reduce our supported ciphersuites by the certified key's algorithm.
576                suite.usable_for_signature_algorithm(sig_key_algorithm)
577                // And version
578                && suite.version().version == selected_version
579                // And protocol
580                && suite.usable_for_protocol(protocol)
581                // And support one of key exchange groups
582                && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
583                || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
584            });
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        let suite = if self.config.ignore_client_order {
593            suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
594        } else {
595            let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
596            client_suites
597                .iter()
598                .find_map(|client_suite| {
599                    suitable_suites
600                        .iter()
601                        .find(|x| *client_suite == x.suite())
602                })
603                .copied()
604        }
605        .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
606
607        // Finally, choose a key exchange group that is compatible with the selected cipher
608        // suite.
609        let maybe_skxg = supported_groups
610            .iter()
611            .find_map(|maybe_skxg| match maybe_skxg {
612                Some(skxg) => suite
613                    .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
614                    .then_some(*skxg),
615                None => None,
616            });
617
618        if selected_version == ProtocolVersion::TLSv1_3 {
619            // This unwrap is structurally guaranteed by the early return for `!ffdhe_possible && !ecdhe_possible`
620            return Ok((*suite, *maybe_skxg.unwrap()));
621        }
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        match maybe_skxg {
626            Some(skxg) => Ok((*suite, *skxg)),
627            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                if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
631                    Ok((*suite, *server_selected_ffdhe_skxg))
632                } else {
633                    Err(PeerIncompatible::NoKxGroupsInCommon)
634                }
635            }
636            None => Err(PeerIncompatible::NoKxGroupsInCommon),
637        }
638    }
639}
640
641impl State<ServerConnectionData> for ExpectClientHello {
642    fn handle<'m>(
643        self: Box<Self>,
644        cx: &mut ServerContext<'_>,
645        m: Message<'m>,
646    ) -> NextStateOrError<'m>
647    where
648        Self: 'm,
649    {
650        let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
651        self.with_certified_key(sig_schemes, client_hello, &m, cx)
652    }
653
654    fn into_owned(self: Box<Self>) -> NextState<'static> {
655        self
656    }
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
668pub(super) fn process_client_hello<'m>(
669    m: &'m Message<'m>,
670    done_retry: bool,
671    cx: &mut ServerContext<'_>,
672) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
673    let client_hello =
674        require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
675    trace!("we got a clienthello {:?}", client_hello);
676
677    if !client_hello
678        .compression_methods
679        .contains(&Compression::Null)
680    {
681        return Err(cx.common.send_fatal_alert(
682            AlertDescription::IllegalParameter,
683            PeerIncompatible::NullCompressionRequired,
684        ));
685    }
686
687    if client_hello.has_duplicate_extension() {
688        return Err(cx.common.send_fatal_alert(
689            AlertDescription::DecodeError,
690            PeerMisbehaved::DuplicateClientHelloExtensions,
691        ));
692    }
693
694    // No handshake messages should follow this one in this flight.
695    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    //
703    // [RFC6066][] specifies that literal IP addresses are illegal in
704    // `ServerName`s with a `name_type` of `host_name`.
705    //
706    // Some clients incorrectly send such extensions: we choose to
707    // successfully parse these (into `ServerNamePayload::IpAddress`)
708    // but then act like the client sent no `server_name` extension.
709    //
710    // [RFC6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-3
711    let sni: Option<DnsName<'_>> = match client_hello.sni_extension() {
712        Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
713        Some(ServerNamePayload::IpAddress) => None,
714        Some(ServerNamePayload::Invalid) => {
715            return Err(cx.common.send_fatal_alert(
716                AlertDescription::IllegalParameter,
717                PeerMisbehaved::ServerNameMustContainOneHostName,
718            ));
719        }
720        None => None,
721    };
722
723    // save only the first SNI
724    if let (Some(sni), false) = (&sni, done_retry) {
725        // Save the SNI into the session.
726        // The SNI hostname is immutable once set.
727        assert!(cx.data.sni.is_none());
728        cx.data.sni = Some(sni.clone());
729    } else if cx.data.sni != sni {
730        return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
731    }
732
733    let sig_schemes = client_hello
734        .sigalgs_extension()
735        .ok_or_else(|| {
736            cx.common.send_fatal_alert(
737                AlertDescription::HandshakeFailure,
738                PeerIncompatible::SignatureAlgorithmsExtensionRequired,
739            )
740        })?;
741
742    Ok((client_hello, sig_schemes.to_owned()))
743}
744
745pub(crate) enum HandshakeHashOrBuffer {
746    Buffer(HandshakeHashBuffer),
747    Hash(HandshakeHash),
748}