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, CertificateType, CipherSuite, HandshakeType, ProtocolVersion,
15    SignatureAlgorithm, SignatureScheme,
16};
17use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
18use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
19use crate::log::{debug, trace};
20use crate::msgs::enums::{Compression, ExtensionType, NamedGroup};
21#[cfg(feature = "tls12")]
22use crate::msgs::handshake::SessionId;
23use crate::msgs::handshake::{
24    ClientHelloPayload, HandshakePayload, KeyExchangeAlgorithm, ProtocolName, Random,
25    ServerExtension, 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                .map(|bytes| ProtocolName::from(bytes.clone()));
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                named_groups: client_hello.namedgroups_extension(),
421            };
422            trace!("Resolving server certificate: {client_hello:#?}");
423
424            let certkey = self
425                .config
426                .cert_resolver
427                .resolve(client_hello);
428
429            certkey.ok_or_else(|| {
430                cx.common.send_fatal_alert(
431                    AlertDescription::AccessDenied,
432                    Error::General("no server certificate chain resolved".to_owned()),
433                )
434            })?
435        };
436        let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
437
438        let (suite, skxg) = self
439            .choose_suite_and_kx_group(
440                version,
441                certkey.get_key().algorithm(),
442                cx.common.protocol,
443                client_hello
444                    .namedgroups_extension()
445                    .unwrap_or(&[]),
446                &client_hello.cipher_suites,
447            )
448            .map_err(|incompat| {
449                cx.common
450                    .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
451            })?;
452
453        debug!("decided upon suite {suite:?}");
454        cx.common.suite = Some(suite);
455        cx.common.kx_state = KxState::Start(skxg);
456
457        // Start handshake hash.
458        let starting_hash = suite.hash_provider();
459        let transcript = match self.transcript {
460            HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
461            HandshakeHashOrBuffer::Hash(inner)
462                if inner.algorithm() == starting_hash.algorithm() =>
463            {
464                inner
465            }
466            _ => {
467                return Err(cx.common.send_fatal_alert(
468                    AlertDescription::IllegalParameter,
469                    PeerMisbehaved::HandshakeHashVariedAfterRetry,
470                ));
471            }
472        };
473
474        // Save their Random.
475        let randoms = ConnectionRandoms::new(
476            client_hello.random,
477            Random::new(self.config.provider.secure_random)?,
478        );
479        match suite {
480            SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
481                config: self.config,
482                transcript,
483                suite,
484                randoms,
485                done_retry: self.done_retry,
486                send_tickets: self.send_tickets,
487                extra_exts: self.extra_exts,
488            }
489            .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
490            #[cfg(feature = "tls12")]
491            SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
492                config: self.config,
493                transcript,
494                session_id: self.session_id,
495                suite,
496                using_ems: self.using_ems,
497                randoms,
498                send_ticket: self.send_tickets > 0,
499                extra_exts: self.extra_exts,
500            }
501            .handle_client_hello(
502                cx,
503                certkey,
504                m,
505                client_hello,
506                skxg,
507                sig_schemes,
508                tls13_enabled,
509            ),
510        }
511    }
512
513    fn choose_suite_and_kx_group(
514        &self,
515        selected_version: ProtocolVersion,
516        sig_key_algorithm: SignatureAlgorithm,
517        protocol: Protocol,
518        client_groups: &[NamedGroup],
519        client_suites: &[CipherSuite],
520    ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
521        // Determine which `KeyExchangeAlgorithm`s are theoretically possible, based
522        // on the offered and supported groups.
523        let mut ecdhe_possible = false;
524        let mut ffdhe_possible = false;
525        let mut ffdhe_offered = false;
526        let mut supported_groups = Vec::with_capacity(client_groups.len());
527
528        for offered_group in client_groups {
529            let supported = self
530                .config
531                .provider
532                .kx_groups
533                .iter()
534                .find(|skxg| {
535                    skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
536                });
537
538            match offered_group.key_exchange_algorithm() {
539                KeyExchangeAlgorithm::DHE => {
540                    ffdhe_possible |= supported.is_some();
541                    ffdhe_offered = true;
542                }
543                KeyExchangeAlgorithm::ECDHE => {
544                    ecdhe_possible |= supported.is_some();
545                }
546            }
547
548            supported_groups.push(supported);
549        }
550
551        let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
552            // https://datatracker.ietf.org/doc/html/rfc7919#section-4 (paragraph 2)
553            let first_supported_dhe_kxg = self
554                .config
555                .provider
556                .kx_groups
557                .iter()
558                .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
559            ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
560            first_supported_dhe_kxg
561        } else {
562            // In TLS1.3, the server may only directly negotiate a group.
563            None
564        };
565
566        if !ecdhe_possible && !ffdhe_possible {
567            return Err(PeerIncompatible::NoKxGroupsInCommon);
568        }
569
570        let mut suitable_suites_iter = self
571            .config
572            .provider
573            .cipher_suites
574            .iter()
575            .filter(|suite| {
576                // Reduce our supported ciphersuites by the certified key's algorithm.
577                suite.usable_for_signature_algorithm(sig_key_algorithm)
578                // And version
579                && suite.version().version == selected_version
580                // And protocol
581                && suite.usable_for_protocol(protocol)
582                // And support one of key exchange groups
583                && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
584                || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
585            });
586
587        // RFC 7919 (https://datatracker.ietf.org/doc/html/rfc7919#section-4) requires us to send
588        // the InsufficientSecurity alert in case we don't recognize client's FFDHE groups (i.e.,
589        // `suitable_suites` becomes empty). But that does not make a lot of sense (e.g., client
590        // proposes FFDHE4096 and we only support FFDHE2048), so we ignore that requirement here,
591        // and continue to send HandshakeFailure.
592
593        let suite = if self.config.ignore_client_order {
594            suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
595        } else {
596            let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
597            client_suites
598                .iter()
599                .find_map(|client_suite| {
600                    suitable_suites
601                        .iter()
602                        .find(|x| *client_suite == x.suite())
603                })
604                .copied()
605        }
606        .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
607
608        // Finally, choose a key exchange group that is compatible with the selected cipher
609        // suite.
610        let maybe_skxg = supported_groups
611            .iter()
612            .find_map(|maybe_skxg| match maybe_skxg {
613                Some(skxg) => suite
614                    .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
615                    .then_some(*skxg),
616                None => None,
617            });
618
619        if selected_version == ProtocolVersion::TLSv1_3 {
620            // This unwrap is structurally guaranteed by the early return for `!ffdhe_possible && !ecdhe_possible`
621            return Ok((*suite, *maybe_skxg.unwrap()));
622        }
623
624        // For TLS1.2, the server can unilaterally choose a DHE group if it has one and
625        // there was no better option.
626        match maybe_skxg {
627            Some(skxg) => Ok((*suite, *skxg)),
628            None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
629                // If kx for the selected cipher suite is DHE and no DHE groups are specified in the extension,
630                // the server is free to choose DHE params, we choose the first DHE kx group of the provider.
631                if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
632                    Ok((*suite, *server_selected_ffdhe_skxg))
633                } else {
634                    Err(PeerIncompatible::NoKxGroupsInCommon)
635                }
636            }
637            None => Err(PeerIncompatible::NoKxGroupsInCommon),
638        }
639    }
640}
641
642impl State<ServerConnectionData> for ExpectClientHello {
643    fn handle<'m>(
644        self: Box<Self>,
645        cx: &mut ServerContext<'_>,
646        m: Message<'m>,
647    ) -> NextStateOrError<'m>
648    where
649        Self: 'm,
650    {
651        let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
652        self.with_certified_key(sig_schemes, client_hello, &m, cx)
653    }
654
655    fn into_owned(self: Box<Self>) -> NextState<'static> {
656        self
657    }
658}
659
660/// Configuration-independent validation of a `ClientHello` message.
661///
662/// This represents the first part of the `ClientHello` handling, where we do all validation that
663/// doesn't depend on a `ServerConfig` being available and extract everything needed to build a
664/// [`ClientHello`] value for a [`ResolvesServerCert`].
665///
666/// Note that this will modify `data.sni` even if config or certificate resolution fail.
667///
668/// [`ResolvesServerCert`]: crate::server::ResolvesServerCert
669pub(super) fn process_client_hello<'m>(
670    m: &'m Message<'m>,
671    done_retry: bool,
672    cx: &mut ServerContext<'_>,
673) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
674    let client_hello =
675        require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
676    trace!("we got a clienthello {client_hello:?}");
677
678    if !client_hello
679        .compression_methods
680        .contains(&Compression::Null)
681    {
682        return Err(cx.common.send_fatal_alert(
683            AlertDescription::IllegalParameter,
684            PeerIncompatible::NullCompressionRequired,
685        ));
686    }
687
688    if client_hello.has_duplicate_extension() {
689        return Err(cx.common.send_fatal_alert(
690            AlertDescription::DecodeError,
691            PeerMisbehaved::DuplicateClientHelloExtensions,
692        ));
693    }
694
695    // No handshake messages should follow this one in this flight.
696    cx.common.check_aligned_handshake()?;
697
698    // Extract and validate the SNI DNS name, if any, before giving it to
699    // the cert resolver. In particular, if it is invalid then we should
700    // send an Illegal Parameter alert instead of the Internal Error alert
701    // (or whatever) that we'd send if this were checked later or in a
702    // different way.
703    //
704    // [RFC6066][] specifies that literal IP addresses are illegal in
705    // `ServerName`s with a `name_type` of `host_name`.
706    //
707    // Some clients incorrectly send such extensions: we choose to
708    // successfully parse these (into `ServerNamePayload::IpAddress`)
709    // but then act like the client sent no `server_name` extension.
710    //
711    // [RFC6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-3
712    let sni: Option<DnsName<'_>> = match client_hello.sni_extension() {
713        Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
714        Some(ServerNamePayload::IpAddress) => None,
715        Some(ServerNamePayload::Invalid) => {
716            return Err(cx.common.send_fatal_alert(
717                AlertDescription::IllegalParameter,
718                PeerMisbehaved::ServerNameMustContainOneHostName,
719            ));
720        }
721        None => None,
722    };
723
724    // save only the first SNI
725    if let (Some(sni), false) = (&sni, done_retry) {
726        // Save the SNI into the session.
727        // The SNI hostname is immutable once set.
728        assert!(cx.data.sni.is_none());
729        cx.data.sni = Some(sni.clone());
730    } else if cx.data.sni != sni {
731        return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
732    }
733
734    let sig_schemes = client_hello
735        .sigalgs_extension()
736        .ok_or_else(|| {
737            cx.common.send_fatal_alert(
738                AlertDescription::HandshakeFailure,
739                PeerIncompatible::SignatureAlgorithmsExtensionRequired,
740            )
741        })?;
742
743    Ok((client_hello, sig_schemes.to_owned()))
744}
745
746pub(crate) enum HandshakeHashOrBuffer {
747    Buffer(HandshakeHashBuffer),
748    Hash(HandshakeHash),
749}