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