Skip to main content

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) previous_hello: Option<PreviousClientHello>,
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            previous_hello: None,
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, cx.common.protocol);
355        let tls12_enabled = self
356            .config
357            .supports_version(ProtocolVersion::TLSv1_2, cx.common.protocol)
358            && !self.previous_hello.is_some();
359
360        // Are we doing TLS1.3?
361        let version = if let Some(versions) = &client_hello.supported_versions {
362            if versions.tls13 && tls13_enabled {
363                ProtocolVersion::TLSv1_3
364            } else if !versions.tls12 || !tls12_enabled {
365                return Err(cx.common.send_fatal_alert(
366                    AlertDescription::ProtocolVersion,
367                    PeerIncompatible::Tls12NotOfferedOrEnabled,
368                ));
369            } else if cx.common.is_quic() {
370                return Err(cx.common.send_fatal_alert(
371                    AlertDescription::ProtocolVersion,
372                    PeerIncompatible::Tls13RequiredForQuic,
373                ));
374            } else {
375                ProtocolVersion::TLSv1_2
376            }
377        } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
378            return Err(cx.common.send_fatal_alert(
379                AlertDescription::ProtocolVersion,
380                PeerIncompatible::Tls12NotOffered,
381            ));
382        } else if cx.common.is_quic() {
383            return Err(cx.common.send_fatal_alert(
384                AlertDescription::ProtocolVersion,
385                PeerIncompatible::Tls13RequiredForQuic,
386            ));
387        } else if !tls12_enabled && tls13_enabled {
388            return Err(cx.common.send_fatal_alert(
389                AlertDescription::ProtocolVersion,
390                PeerIncompatible::SupportedVersionsExtensionRequired,
391            ));
392        } else {
393            ProtocolVersion::TLSv1_2
394        };
395
396        cx.common.negotiated_version = Some(version);
397
398        // We communicate to the upper layer what kind of key they should choose
399        // via the sigschemes value.  Clients tend to treat this extension
400        // orthogonally to offered ciphersuites (even though, in TLS1.2 it is not).
401        // So: reduce the offered sigschemes to those compatible with the
402        // intersection of ciphersuites.
403        let client_suites = self
404            .config
405            .provider
406            .cipher_suites
407            .iter()
408            .copied()
409            .filter(|scs| {
410                client_hello
411                    .cipher_suites
412                    .contains(&scs.suite())
413            })
414            .collect::<Vec<_>>();
415
416        sig_schemes
417            .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
418
419        // We adhere to the TLS 1.2 RFC by not exposing this to the cert resolver if TLS version is 1.2
420        let certificate_authorities = match version {
421            ProtocolVersion::TLSv1_2 => None,
422            _ => client_hello
423                .certificate_authority_names
424                .as_deref(),
425        };
426        // Choose a certificate.
427        let certkey = {
428            let client_hello = ClientHello {
429                server_name: &cx.data.sni,
430                signature_schemes: &sig_schemes,
431                alpn: client_hello.protocols.as_ref(),
432                client_cert_types: client_hello
433                    .client_certificate_types
434                    .as_deref(),
435                server_cert_types: client_hello
436                    .server_certificate_types
437                    .as_deref(),
438                cipher_suites: &client_hello.cipher_suites,
439                certificate_authorities,
440                named_groups: client_hello.named_groups.as_deref(),
441            };
442            trace!("Resolving server certificate: {client_hello:#?}");
443
444            let certkey = self
445                .config
446                .cert_resolver
447                .resolve(client_hello);
448
449            certkey.ok_or_else(|| {
450                cx.common.send_fatal_alert(
451                    AlertDescription::AccessDenied,
452                    Error::General("no server certificate chain resolved".to_owned()),
453                )
454            })?
455        };
456        let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
457
458        let (suite, skxg) = self
459            .choose_suite_and_kx_group(
460                version,
461                certkey.get_key().algorithm(),
462                cx.common.protocol,
463                client_hello
464                    .named_groups
465                    .as_deref()
466                    .unwrap_or_default(),
467                &client_hello.cipher_suites,
468            )
469            .map_err(|incompat| {
470                cx.common
471                    .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
472            })?;
473
474        // RFC 9846 section 4.2.4: the server must negotiate the same cipher suite it
475        // named in its HelloRetryRequest
476        if let Some(PreviousClientHello {
477            suite: before_retry,
478            ..
479        }) = self.previous_hello
480        {
481            if before_retry != suite.suite() {
482                return Err(cx.common.send_fatal_alert(
483                    AlertDescription::IllegalParameter,
484                    PeerMisbehaved::CipherSuiteDifferedOnRetry,
485                ));
486            }
487        }
488
489        debug!("decided upon suite {suite:?}");
490        cx.common.suite = Some(suite);
491        cx.common.kx_state = KxState::Start(skxg);
492
493        // Start handshake hash.
494        let starting_hash = suite.hash_provider();
495        let transcript = match self.transcript {
496            HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
497            HandshakeHashOrBuffer::Hash(inner)
498                if inner.algorithm() == starting_hash.algorithm() =>
499            {
500                inner
501            }
502            _ => {
503                return Err(cx.common.send_fatal_alert(
504                    AlertDescription::IllegalParameter,
505                    PeerMisbehaved::HandshakeHashVariedAfterRetry,
506                ));
507            }
508        };
509
510        // Save their Random.
511        let randoms = ConnectionRandoms::new(
512            client_hello.random,
513            Random::new(self.config.provider.secure_random)?,
514        );
515        match suite {
516            SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
517                config: self.config,
518                transcript,
519                suite,
520                randoms,
521                previous_hello: self.previous_hello,
522                send_tickets: self.send_tickets,
523                extra_exts: self.extra_exts,
524            }
525            .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
526            #[cfg(feature = "tls12")]
527            SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
528                config: self.config,
529                transcript,
530                session_id: self.session_id,
531                suite,
532                using_ems: self.using_ems,
533                randoms,
534                send_ticket: self.send_tickets > 0,
535                extra_exts: self.extra_exts,
536            }
537            .handle_client_hello(
538                cx,
539                certkey,
540                m,
541                client_hello,
542                skxg,
543                sig_schemes,
544                tls13_enabled,
545            ),
546        }
547    }
548
549    fn choose_suite_and_kx_group(
550        &self,
551        selected_version: ProtocolVersion,
552        sig_key_algorithm: SignatureAlgorithm,
553        protocol: Protocol,
554        client_groups: &[NamedGroup],
555        client_suites: &[CipherSuite],
556    ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
557        // Determine which `KeyExchangeAlgorithm`s are theoretically possible, based
558        // on the offered and supported groups.
559        let mut ecdhe_possible = false;
560        let mut ffdhe_possible = false;
561        let mut ffdhe_offered = false;
562        let mut supported_groups = Vec::with_capacity(client_groups.len());
563
564        for offered_group in client_groups {
565            let supported = self
566                .config
567                .provider
568                .kx_groups
569                .iter()
570                .find(|skxg| {
571                    skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
572                });
573
574            match offered_group.key_exchange_algorithm() {
575                KeyExchangeAlgorithm::DHE => {
576                    ffdhe_possible |= supported.is_some();
577                    ffdhe_offered = true;
578                }
579                KeyExchangeAlgorithm::ECDHE => {
580                    ecdhe_possible |= supported.is_some();
581                }
582            }
583
584            supported_groups.push(supported);
585        }
586
587        let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
588            // https://datatracker.ietf.org/doc/html/rfc7919#section-4 (paragraph 2)
589            let first_supported_dhe_kxg = self
590                .config
591                .provider
592                .kx_groups
593                .iter()
594                .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
595            ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
596            first_supported_dhe_kxg
597        } else {
598            // In TLS1.3, the server may only directly negotiate a group.
599            None
600        };
601
602        if !ecdhe_possible && !ffdhe_possible {
603            return Err(PeerIncompatible::NoKxGroupsInCommon);
604        }
605
606        let mut suitable_suites_iter = self
607            .config
608            .provider
609            .cipher_suites
610            .iter()
611            .filter(|suite| {
612                // Reduce our supported ciphersuites by the certified key's algorithm.
613                suite.usable_for_signature_algorithm(sig_key_algorithm)
614                // And version
615                && suite.version().version == selected_version
616                // And protocol
617                && suite.usable_for_protocol(protocol)
618                // And support one of key exchange groups
619                && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
620                || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
621            });
622
623        // RFC 7919 (https://datatracker.ietf.org/doc/html/rfc7919#section-4) requires us to send
624        // the InsufficientSecurity alert in case we don't recognize client's FFDHE groups (i.e.,
625        // `suitable_suites` becomes empty). But that does not make a lot of sense (e.g., client
626        // proposes FFDHE4096 and we only support FFDHE2048), so we ignore that requirement here,
627        // and continue to send HandshakeFailure.
628
629        let suite = if self.config.ignore_client_order {
630            suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
631        } else {
632            let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
633            client_suites
634                .iter()
635                .find_map(|client_suite| {
636                    suitable_suites
637                        .iter()
638                        .find(|x| *client_suite == x.suite())
639                })
640                .copied()
641        }
642        .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
643
644        // Finally, choose a key exchange group that is compatible with the selected cipher
645        // suite.
646        let maybe_skxg = supported_groups
647            .iter()
648            .find_map(|maybe_skxg| match maybe_skxg {
649                Some(skxg) => suite
650                    .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
651                    .then_some(*skxg),
652                None => None,
653            });
654
655        if selected_version == ProtocolVersion::TLSv1_3 {
656            // This unwrap is structurally guaranteed by the early return for `!ffdhe_possible && !ecdhe_possible`
657            return Ok((*suite, *maybe_skxg.unwrap()));
658        }
659
660        // For TLS1.2, the server can unilaterally choose a DHE group if it has one and
661        // there was no better option.
662        match maybe_skxg {
663            Some(skxg) => Ok((*suite, *skxg)),
664            None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
665                // If kx for the selected cipher suite is DHE and no DHE groups are specified in the extension,
666                // the server is free to choose DHE params, we choose the first DHE kx group of the provider.
667                if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
668                    Ok((*suite, *server_selected_ffdhe_skxg))
669                } else {
670                    Err(PeerIncompatible::NoKxGroupsInCommon)
671                }
672            }
673            None => Err(PeerIncompatible::NoKxGroupsInCommon),
674        }
675    }
676}
677
678pub(super) struct PreviousClientHello {
679    pub(super) offered_psk: bool,
680    pub(super) suite: CipherSuite,
681}
682
683impl State<ServerConnectionData> for ExpectClientHello {
684    fn handle<'m>(
685        self: Box<Self>,
686        cx: &mut ServerContext<'_>,
687        m: Message<'m>,
688    ) -> NextStateOrError<'m>
689    where
690        Self: 'm,
691    {
692        let (client_hello, sig_schemes) =
693            process_client_hello(&m, self.previous_hello.is_some(), cx)?;
694        self.with_certified_key(sig_schemes, client_hello, &m, cx)
695    }
696
697    fn into_owned(self: Box<Self>) -> NextState<'static> {
698        self
699    }
700}
701
702/// Configuration-independent validation of a `ClientHello` message.
703///
704/// This represents the first part of the `ClientHello` handling, where we do all validation that
705/// doesn't depend on a `ServerConfig` being available and extract everything needed to build a
706/// [`ClientHello`] value for a [`ResolvesServerCert`].
707///
708/// Note that this will modify `data.sni` even if config or certificate resolution fail.
709///
710/// [`ResolvesServerCert`]: crate::server::ResolvesServerCert
711pub(super) fn process_client_hello<'m>(
712    m: &'m Message<'m>,
713    done_retry: bool,
714    cx: &mut ServerContext<'_>,
715) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
716    let client_hello =
717        require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
718    trace!("we got a clienthello {client_hello:?}");
719
720    if !client_hello
721        .compression_methods
722        .contains(&Compression::Null)
723    {
724        return Err(cx.common.send_fatal_alert(
725            AlertDescription::IllegalParameter,
726            PeerIncompatible::NullCompressionRequired,
727        ));
728    }
729
730    // No handshake messages should follow this one in this flight.
731    cx.common.check_aligned_handshake()?;
732
733    // Extract and validate the SNI DNS name, if any, before giving it to
734    // the cert resolver. In particular, if it is invalid then we should
735    // send an Illegal Parameter alert instead of the Internal Error alert
736    // (or whatever) that we'd send if this were checked later or in a
737    // different way.
738    //
739    // [RFC6066][] specifies that literal IP addresses are illegal in
740    // `ServerName`s with a `name_type` of `host_name`.
741    //
742    // Some clients incorrectly send such extensions: we choose to
743    // successfully parse these (into `ServerNamePayload::IpAddress`)
744    // but then act like the client sent no `server_name` extension.
745    //
746    // [RFC6066]: https://datatracker.ietf.org/doc/html/rfc6066#section-3
747    let sni = match &client_hello.server_name {
748        Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
749        Some(ServerNamePayload::IpAddress) => None,
750        Some(ServerNamePayload::Invalid) => {
751            return Err(cx.common.send_fatal_alert(
752                AlertDescription::IllegalParameter,
753                PeerMisbehaved::ServerNameMustContainOneHostName,
754            ));
755        }
756        None => None,
757    };
758
759    // save only the first SNI
760    if let (Some(sni), false) = (&sni, done_retry) {
761        // Save the SNI into the session.
762        // The SNI hostname is immutable once set.
763        assert!(cx.data.sni.is_none());
764        cx.data.sni = Some(sni.clone());
765    } else if cx.data.sni != sni {
766        return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
767    }
768
769    let sig_schemes = client_hello
770        .signature_schemes
771        .as_ref()
772        .ok_or_else(|| {
773            cx.common.send_fatal_alert(
774                AlertDescription::HandshakeFailure,
775                PeerIncompatible::SignatureAlgorithmsExtensionRequired,
776            )
777        })?;
778
779    Ok((client_hello, sig_schemes.to_owned()))
780}
781
782pub(crate) enum HandshakeHashOrBuffer {
783    Buffer(HandshakeHashBuffer),
784    Hash(HandshakeHash),
785}