rustls/client/
hs.rs

1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::sync::Arc;
4use alloc::vec;
5use alloc::vec::Vec;
6use core::ops::Deref;
7
8use pki_types::ServerName;
9
10#[cfg(feature = "tls12")]
11use super::tls12;
12use super::Tls12Resumption;
13#[cfg(feature = "logging")]
14use crate::bs_debug;
15use crate::check::inappropriate_handshake_message;
16use crate::client::client_conn::ClientConnectionData;
17use crate::client::common::ClientHelloDetails;
18use crate::client::ech::EchState;
19use crate::client::{tls13, ClientConfig, EchMode, EchStatus};
20use crate::common_state::{CommonState, HandshakeKind, KxState, State};
21use crate::conn::ConnectionRandoms;
22use crate::crypto::{ActiveKeyExchange, KeyExchangeAlgorithm};
23use crate::enums::{AlertDescription, CipherSuite, ContentType, HandshakeType, ProtocolVersion};
24use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
25use crate::hash_hs::HandshakeHashBuffer;
26use crate::log::{debug, trace};
27use crate::msgs::base::Payload;
28use crate::msgs::enums::{Compression, ECPointFormat, ExtensionType, PSKKeyExchangeMode};
29use crate::msgs::handshake::{
30    CertificateStatusRequest, ClientExtension, ClientHelloPayload, ClientSessionTicket,
31    ConvertProtocolNameList, HandshakeMessagePayload, HandshakePayload, HasServerExtensions,
32    HelloRetryRequest, KeyShareEntry, Random, SessionId,
33};
34use crate::msgs::message::{Message, MessagePayload};
35use crate::msgs::persist;
36use crate::tls13::key_schedule::KeyScheduleEarly;
37use crate::SupportedCipherSuite;
38
39pub(super) type NextState<'a> = Box<dyn State<ClientConnectionData> + 'a>;
40pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
41pub(super) type ClientContext<'a> = crate::common_state::Context<'a, ClientConnectionData>;
42
43fn find_session(
44    server_name: &ServerName<'static>,
45    config: &ClientConfig,
46    cx: &mut ClientContext<'_>,
47) -> Option<persist::Retrieved<ClientSessionValue>> {
48    let found = config
49        .resumption
50        .store
51        .take_tls13_ticket(server_name)
52        .map(ClientSessionValue::Tls13)
53        .or_else(|| {
54            #[cfg(feature = "tls12")]
55            {
56                config
57                    .resumption
58                    .store
59                    .tls12_session(server_name)
60                    .map(ClientSessionValue::Tls12)
61            }
62
63            #[cfg(not(feature = "tls12"))]
64            None
65        })
66        .and_then(|resuming| {
67            let now = config
68                .current_time()
69                .map_err(|_err| debug!("Could not get current time: {_err}"))
70                .ok()?;
71
72            let retrieved = persist::Retrieved::new(resuming, now);
73            match retrieved.has_expired() {
74                false => Some(retrieved),
75                true => None,
76            }
77        })
78        .or_else(|| {
79            debug!("No cached session for {:?}", server_name);
80            None
81        });
82
83    if let Some(resuming) = &found {
84        if cx.common.is_quic() {
85            cx.common.quic.params = resuming
86                .tls13()
87                .map(|v| v.quic_params());
88        }
89    }
90
91    found
92}
93
94pub(super) fn start_handshake(
95    server_name: ServerName<'static>,
96    extra_exts: Vec<ClientExtension>,
97    config: Arc<ClientConfig>,
98    cx: &mut ClientContext<'_>,
99) -> NextStateOrError<'static> {
100    let mut transcript_buffer = HandshakeHashBuffer::new();
101    if config
102        .client_auth_cert_resolver
103        .has_certs()
104    {
105        transcript_buffer.set_client_auth_enabled();
106    }
107
108    let mut resuming = find_session(&server_name, &config, cx);
109
110    let key_share = if config.supports_version(ProtocolVersion::TLSv1_3) {
111        Some(tls13::initial_key_share(
112            &config,
113            &server_name,
114            &mut cx.common.kx_state,
115        )?)
116    } else {
117        None
118    };
119
120    let session_id = if let Some(_resuming) = &mut resuming {
121        debug!("Resuming session");
122
123        match &mut _resuming.value {
124            #[cfg(feature = "tls12")]
125            ClientSessionValue::Tls12(inner) => {
126                // If we have a ticket, we use the sessionid as a signal that
127                // we're  doing an abbreviated handshake.  See section 3.4 in
128                // RFC5077.
129                if !inner.ticket().is_empty() {
130                    inner.session_id = SessionId::random(config.provider.secure_random)?;
131                }
132                Some(inner.session_id)
133            }
134            _ => None,
135        }
136    } else {
137        debug!("Not resuming any session");
138        None
139    };
140
141    // https://tools.ietf.org/html/rfc8446#appendix-D.4
142    // https://tools.ietf.org/html/draft-ietf-quic-tls-34#section-8.4
143    let session_id = match session_id {
144        Some(session_id) => session_id,
145        None if cx.common.is_quic() => SessionId::empty(),
146        None if !config.supports_version(ProtocolVersion::TLSv1_3) => SessionId::empty(),
147        None => SessionId::random(config.provider.secure_random)?,
148    };
149
150    let random = Random::new(config.provider.secure_random)?;
151    let extension_order_seed = crate::rand::random_u16(config.provider.secure_random)?;
152
153    let ech_state = match config.ech_mode.as_ref() {
154        Some(EchMode::Enable(ech_config)) => Some(EchState::new(
155            ech_config,
156            server_name.clone(),
157            config
158                .client_auth_cert_resolver
159                .has_certs(),
160            config.provider.secure_random,
161            config.enable_sni,
162        )?),
163        _ => None,
164    };
165
166    emit_client_hello_for_retry(
167        transcript_buffer,
168        None,
169        key_share,
170        extra_exts,
171        None,
172        ClientHelloInput {
173            config,
174            resuming,
175            random,
176            #[cfg(feature = "tls12")]
177            using_ems: false,
178            sent_tls13_fake_ccs: false,
179            hello: ClientHelloDetails::new(extension_order_seed),
180            session_id,
181            server_name,
182            prev_ech_ext: None,
183        },
184        cx,
185        ech_state,
186    )
187}
188
189struct ExpectServerHello {
190    input: ClientHelloInput,
191    transcript_buffer: HandshakeHashBuffer,
192    early_key_schedule: Option<KeyScheduleEarly>,
193    offered_key_share: Option<Box<dyn ActiveKeyExchange>>,
194    suite: Option<SupportedCipherSuite>,
195    ech_state: Option<EchState>,
196}
197
198struct ExpectServerHelloOrHelloRetryRequest {
199    next: ExpectServerHello,
200    extra_exts: Vec<ClientExtension>,
201}
202
203struct ClientHelloInput {
204    config: Arc<ClientConfig>,
205    resuming: Option<persist::Retrieved<ClientSessionValue>>,
206    random: Random,
207    #[cfg(feature = "tls12")]
208    using_ems: bool,
209    sent_tls13_fake_ccs: bool,
210    hello: ClientHelloDetails,
211    session_id: SessionId,
212    server_name: ServerName<'static>,
213    prev_ech_ext: Option<ClientExtension>,
214}
215
216fn emit_client_hello_for_retry(
217    mut transcript_buffer: HandshakeHashBuffer,
218    retryreq: Option<&HelloRetryRequest>,
219    key_share: Option<Box<dyn ActiveKeyExchange>>,
220    extra_exts: Vec<ClientExtension>,
221    suite: Option<SupportedCipherSuite>,
222    mut input: ClientHelloInput,
223    cx: &mut ClientContext<'_>,
224    mut ech_state: Option<EchState>,
225) -> NextStateOrError<'static> {
226    let config = &input.config;
227    // Defense in depth: the ECH state should be None if ECH is disabled based on config
228    // builder semantics.
229    let forbids_tls12 = cx.common.is_quic() || ech_state.is_some();
230    let support_tls12 = config.supports_version(ProtocolVersion::TLSv1_2) && !forbids_tls12;
231    let support_tls13 = config.supports_version(ProtocolVersion::TLSv1_3);
232
233    let mut supported_versions = Vec::new();
234    if support_tls13 {
235        supported_versions.push(ProtocolVersion::TLSv1_3);
236    }
237
238    if support_tls12 {
239        supported_versions.push(ProtocolVersion::TLSv1_2);
240    }
241
242    // should be unreachable thanks to config builder
243    assert!(!supported_versions.is_empty());
244
245    let mut exts = vec![
246        ClientExtension::SupportedVersions(supported_versions),
247        ClientExtension::NamedGroups(
248            config
249                .provider
250                .kx_groups
251                .iter()
252                .map(|skxg| skxg.name())
253                .collect(),
254        ),
255        ClientExtension::SignatureAlgorithms(
256            config
257                .verifier
258                .supported_verify_schemes(),
259        ),
260        ClientExtension::ExtendedMasterSecretRequest,
261        ClientExtension::CertificateStatusRequest(CertificateStatusRequest::build_ocsp()),
262    ];
263
264    // Send the ECPointFormat extension only if we are proposing ECDHE
265    if config
266        .provider
267        .kx_groups
268        .iter()
269        .any(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::ECDHE)
270    {
271        exts.push(ClientExtension::EcPointFormats(
272            ECPointFormat::SUPPORTED.to_vec(),
273        ));
274    }
275
276    match (ech_state.as_ref(), config.enable_sni) {
277        // If we have ECH state we have a "cover name" to send in the outer hello
278        // as the SNI domain name. This happens unconditionally so we ignore the
279        // `enable_sni` value. That will be used later to decide what to do for
280        // the protected inner hello's SNI.
281        (Some(ech_state), _) => exts.push(ClientExtension::make_sni(&ech_state.outer_name)),
282
283        // If we have no ECH state, and SNI is enabled, try to use the input server_name
284        // for the SNI domain name.
285        (None, true) => {
286            if let ServerName::DnsName(dns_name) = &input.server_name {
287                exts.push(ClientExtension::make_sni(dns_name))
288            }
289        }
290
291        // If we have no ECH state, and SNI is not enabled, there's nothing to do.
292        (None, false) => {}
293    };
294
295    if let Some(key_share) = &key_share {
296        debug_assert!(support_tls13);
297        let key_share = KeyShareEntry::new(key_share.group(), key_share.pub_key());
298        exts.push(ClientExtension::KeyShare(vec![key_share]));
299    }
300
301    if let Some(cookie) = retryreq.and_then(HelloRetryRequest::cookie) {
302        exts.push(ClientExtension::Cookie(cookie.clone()));
303    }
304
305    if support_tls13 {
306        // We could support PSK_KE here too. Such connections don't
307        // have forward secrecy, and are similar to TLS1.2 resumption.
308        let psk_modes = vec![PSKKeyExchangeMode::PSK_DHE_KE];
309        exts.push(ClientExtension::PresharedKeyModes(psk_modes));
310    }
311
312    if !config.alpn_protocols.is_empty() {
313        exts.push(ClientExtension::Protocols(Vec::from_slices(
314            &config
315                .alpn_protocols
316                .iter()
317                .map(|proto| &proto[..])
318                .collect::<Vec<_>>(),
319        )));
320    }
321
322    input.hello.offered_cert_compression = if support_tls13 && !config.cert_decompressors.is_empty()
323    {
324        exts.push(ClientExtension::CertificateCompressionAlgorithms(
325            config
326                .cert_decompressors
327                .iter()
328                .map(|dec| dec.algorithm())
329                .collect(),
330        ));
331        true
332    } else {
333        false
334    };
335
336    // Extra extensions must be placed before the PSK extension
337    exts.extend(extra_exts.iter().cloned());
338
339    // If this is a second client hello we're constructing in response to an HRR, and
340    // we've rejected ECH or sent GREASE ECH, then we need to carry forward the
341    // exact same ECH extension we used in the first hello.
342    if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
343        if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
344            exts.push(prev_ech_ext);
345        }
346    }
347
348    // Do we have a SessionID or ticket cached for this host?
349    let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
350
351    // Extensions MAY be randomized
352    // but they also need to keep the same order as the previous ClientHello
353    exts.sort_by_cached_key(|new_ext| {
354        match (&cx.data.ech_status, new_ext) {
355            // When not offering ECH/GREASE, the PSK extension is always last.
356            (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
357            // When ECH or GREASE are in-play, the ECH extension is always last.
358            (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
359            // ... and the PSK extension should be second-to-last.
360            (_, ClientExtension::PresharedKey(..)) => return u32::MAX - 1,
361            _ => {}
362        };
363
364        let seed = (input.hello.extension_order_seed as u32) << 16
365            | (u16::from(new_ext.ext_type()) as u32);
366        match low_quality_integer_hash(seed) {
367            u32::MAX => 0,
368            key => key,
369        }
370    });
371
372    let mut cipher_suites: Vec<_> = config
373        .provider
374        .cipher_suites
375        .iter()
376        .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
377            true => Some(cs.suite()),
378            false => None,
379        })
380        .collect();
381    // We don't do renegotiation at all, in fact.
382    cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
383
384    let mut chp_payload = ClientHelloPayload {
385        client_version: ProtocolVersion::TLSv1_2,
386        random: input.random,
387        session_id: input.session_id,
388        cipher_suites,
389        compression_methods: vec![Compression::Null],
390        extensions: exts,
391    };
392
393    let ech_grease_ext = config
394        .ech_mode
395        .as_ref()
396        .and_then(|mode| match mode {
397            EchMode::Grease(cfg) => Some(cfg.grease_ext(
398                config.provider.secure_random,
399                input.server_name.clone(),
400                &chp_payload,
401            )),
402            _ => None,
403        });
404
405    match (cx.data.ech_status, &mut ech_state) {
406        // If we haven't offered ECH, or have offered ECH but got a non-rejecting HRR, then
407        // we need to replace the client hello payload with an ECH client hello payload.
408        (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
409            // Replace the client hello payload with an ECH client hello payload.
410            chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
411            cx.data.ech_status = EchStatus::Offered;
412            // Store the ECH extension in case we need to carry it forward in a subsequent hello.
413            input.prev_ech_ext = chp_payload.extensions.last().cloned();
414        }
415        // If we haven't offered ECH, and have no ECH state, then consider whether to use GREASE
416        // ECH.
417        (EchStatus::NotOffered, None) => {
418            if let Some(grease_ext) = ech_grease_ext {
419                // Add the GREASE ECH extension.
420                let grease_ext = grease_ext?;
421                chp_payload
422                    .extensions
423                    .push(grease_ext.clone());
424                cx.data.ech_status = EchStatus::Grease;
425                // Store the GREASE ECH extension in case we need to carry it forward in a
426                // subsequent hello.
427                input.prev_ech_ext = Some(grease_ext);
428            }
429        }
430        _ => {}
431    }
432
433    // Note what extensions we sent.
434    input.hello.sent_extensions = chp_payload
435        .extensions
436        .iter()
437        .map(ClientExtension::ext_type)
438        .collect();
439
440    let mut chp = HandshakeMessagePayload {
441        typ: HandshakeType::ClientHello,
442        payload: HandshakePayload::ClientHello(chp_payload),
443    };
444
445    let early_key_schedule = match (ech_state.as_mut(), tls13_session) {
446        // If we're performing ECH and resuming, then the PSK binder will have been dealt with
447        // separately, and we need to take the early_data_key_schedule computed for the inner hello.
448        (Some(ech_state), Some(tls13_session)) => ech_state
449            .early_data_key_schedule
450            .take()
451            .map(|schedule| (tls13_session.suite(), schedule)),
452
453        // When we're not doing ECH and resuming, then the PSK binder need to be filled in as
454        // normal.
455        (_, Some(tls13_session)) => Some((
456            tls13_session.suite(),
457            tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
458        )),
459
460        // No early key schedule in other cases.
461        _ => None,
462    };
463
464    let ch = Message {
465        version: match retryreq {
466            // <https://datatracker.ietf.org/doc/html/rfc8446#section-5.1>:
467            // "This value MUST be set to 0x0303 for all records generated
468            //  by a TLS 1.3 implementation ..."
469            Some(_) => ProtocolVersion::TLSv1_2,
470            // "... other than an initial ClientHello (i.e., one not
471            // generated after a HelloRetryRequest), where it MAY also be
472            // 0x0301 for compatibility purposes"
473            //
474            // (retryreq == None means we're in the "initial ClientHello" case)
475            None => ProtocolVersion::TLSv1_0,
476        },
477        payload: MessagePayload::handshake(chp),
478    };
479
480    if retryreq.is_some() {
481        // send dummy CCS to fool middleboxes prior
482        // to second client hello
483        tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
484    }
485
486    trace!("Sending ClientHello {:#?}", ch);
487
488    transcript_buffer.add_message(&ch);
489    cx.common.send_msg(ch, false);
490
491    // Calculate the hash of ClientHello and use it to derive EarlyTrafficSecret
492    let early_key_schedule = early_key_schedule.map(|(resuming_suite, schedule)| {
493        if !cx.data.early_data.is_enabled() {
494            return schedule;
495        }
496
497        let (transcript_buffer, random) = match &ech_state {
498            // When using ECH the early data key schedule is derived based on the inner
499            // hello transcript and random.
500            Some(ech_state) => (
501                &ech_state.inner_hello_transcript,
502                &ech_state.inner_hello_random.0,
503            ),
504            None => (&transcript_buffer, &input.random.0),
505        };
506
507        tls13::derive_early_traffic_secret(
508            &*config.key_log,
509            cx,
510            resuming_suite,
511            &schedule,
512            &mut input.sent_tls13_fake_ccs,
513            transcript_buffer,
514            random,
515        );
516        schedule
517    });
518
519    let next = ExpectServerHello {
520        input,
521        transcript_buffer,
522        early_key_schedule,
523        offered_key_share: key_share,
524        suite,
525        ech_state,
526    };
527
528    Ok(if support_tls13 && retryreq.is_none() {
529        Box::new(ExpectServerHelloOrHelloRetryRequest { next, extra_exts })
530    } else {
531        Box::new(next)
532    })
533}
534
535/// Prepare resumption with the session state retrieved from storage.
536///
537/// This function will push onto `exts` to
538///
539/// (a) request a new ticket if we don't have one,
540/// (b) send our TLS 1.2 ticket after retrieving an 1.2 session,
541/// (c) send a request for 1.3 early data if allowed and
542/// (d) send a 1.3 preshared key if we have one.
543///
544/// For resumption to work, the currently negotiated cipher suite (if available) must be
545/// able to resume from the resuming session's cipher suite.
546///
547/// If 1.3 resumption can continue, returns the 1.3 session value for further processing.
548fn prepare_resumption<'a>(
549    resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
550    exts: &mut Vec<ClientExtension>,
551    suite: Option<SupportedCipherSuite>,
552    cx: &mut ClientContext<'_>,
553    config: &ClientConfig,
554) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
555    // Check whether we're resuming with a non-empty ticket.
556    let resuming = match resuming {
557        Some(resuming) if !resuming.ticket().is_empty() => resuming,
558        _ => {
559            if config.supports_version(ProtocolVersion::TLSv1_3)
560                || config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
561            {
562                // If we don't have a ticket, request one.
563                exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
564            }
565            return None;
566        }
567    };
568
569    let tls13 = match resuming.map(|csv| csv.tls13()) {
570        Some(tls13) => tls13,
571        None => {
572            // TLS 1.2; send the ticket if we have support this protocol version
573            if config.supports_version(ProtocolVersion::TLSv1_2)
574                && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
575            {
576                exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Offer(
577                    Payload::new(resuming.ticket()),
578                )));
579            }
580            return None; // TLS 1.2, so nothing to return here
581        }
582    };
583
584    if !config.supports_version(ProtocolVersion::TLSv1_3) {
585        return None;
586    }
587
588    // If the server selected TLS 1.2, we can't resume.
589    let suite = match suite {
590        Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
591        #[cfg(feature = "tls12")]
592        Some(SupportedCipherSuite::Tls12(_)) => return None,
593        None => None,
594    };
595
596    // If the selected cipher suite can't select from the session's, we can't resume.
597    if let Some(suite) = suite {
598        suite.can_resume_from(tls13.suite())?;
599    }
600
601    tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
602    Some(tls13)
603}
604
605pub(super) fn process_alpn_protocol(
606    common: &mut CommonState,
607    config: &ClientConfig,
608    proto: Option<&[u8]>,
609) -> Result<(), Error> {
610    common.alpn_protocol = proto.map(ToOwned::to_owned);
611
612    if let Some(alpn_protocol) = &common.alpn_protocol {
613        if !config
614            .alpn_protocols
615            .contains(alpn_protocol)
616        {
617            return Err(common.send_fatal_alert(
618                AlertDescription::IllegalParameter,
619                PeerMisbehaved::SelectedUnofferedApplicationProtocol,
620            ));
621        }
622    }
623
624    // RFC 9001 says: "While ALPN only specifies that servers use this alert, QUIC clients MUST
625    // use error 0x0178 to terminate a connection when ALPN negotiation fails." We judge that
626    // the user intended to use ALPN (rather than some out-of-band protocol negotiation
627    // mechanism) if and only if any ALPN protocols were configured. This defends against badly-behaved
628    // servers which accept a connection that requires an application-layer protocol they do not
629    // understand.
630    if common.is_quic() && common.alpn_protocol.is_none() && !config.alpn_protocols.is_empty() {
631        return Err(common.send_fatal_alert(
632            AlertDescription::NoApplicationProtocol,
633            Error::NoApplicationProtocol,
634        ));
635    }
636
637    debug!(
638        "ALPN protocol is {:?}",
639        common
640            .alpn_protocol
641            .as_ref()
642            .map(|v| bs_debug::BsDebug(v))
643    );
644    Ok(())
645}
646
647impl State<ClientConnectionData> for ExpectServerHello {
648    fn handle<'m>(
649        mut self: Box<Self>,
650        cx: &mut ClientContext<'_>,
651        m: Message<'m>,
652    ) -> NextStateOrError<'m>
653    where
654        Self: 'm,
655    {
656        let server_hello =
657            require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
658        trace!("We got ServerHello {:#?}", server_hello);
659
660        use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
661        let config = &self.input.config;
662        let tls13_supported = config.supports_version(TLSv1_3);
663
664        let server_version = if server_hello.legacy_version == TLSv1_2 {
665            server_hello
666                .supported_versions()
667                .unwrap_or(server_hello.legacy_version)
668        } else {
669            server_hello.legacy_version
670        };
671
672        let version = match server_version {
673            TLSv1_3 if tls13_supported => TLSv1_3,
674            TLSv1_2 if config.supports_version(TLSv1_2) => {
675                if cx.data.early_data.is_enabled() && cx.common.early_traffic {
676                    // The client must fail with a dedicated error code if the server
677                    // responds with TLS 1.2 when offering 0-RTT.
678                    return Err(PeerMisbehaved::OfferedEarlyDataWithOldProtocolVersion.into());
679                }
680
681                if server_hello
682                    .supported_versions()
683                    .is_some()
684                {
685                    return Err({
686                        cx.common.send_fatal_alert(
687                            AlertDescription::IllegalParameter,
688                            PeerMisbehaved::SelectedTls12UsingTls13VersionExtension,
689                        )
690                    });
691                }
692
693                TLSv1_2
694            }
695            _ => {
696                let reason = match server_version {
697                    TLSv1_2 | TLSv1_3 => PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig,
698                    _ => PeerIncompatible::ServerDoesNotSupportTls12Or13,
699                };
700                return Err(cx
701                    .common
702                    .send_fatal_alert(AlertDescription::ProtocolVersion, reason));
703            }
704        };
705
706        if server_hello.compression_method != Compression::Null {
707            return Err({
708                cx.common.send_fatal_alert(
709                    AlertDescription::IllegalParameter,
710                    PeerMisbehaved::SelectedUnofferedCompression,
711                )
712            });
713        }
714
715        if server_hello.has_duplicate_extension() {
716            return Err(cx.common.send_fatal_alert(
717                AlertDescription::DecodeError,
718                PeerMisbehaved::DuplicateServerHelloExtensions,
719            ));
720        }
721
722        let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
723        if self
724            .input
725            .hello
726            .server_sent_unsolicited_extensions(&server_hello.extensions, &allowed_unsolicited)
727        {
728            return Err(cx.common.send_fatal_alert(
729                AlertDescription::UnsupportedExtension,
730                PeerMisbehaved::UnsolicitedServerHelloExtension,
731            ));
732        }
733
734        cx.common.negotiated_version = Some(version);
735
736        // Extract ALPN protocol
737        if !cx.common.is_tls13() {
738            process_alpn_protocol(cx.common, config, server_hello.alpn_protocol())?;
739        }
740
741        // If ECPointFormats extension is supplied by the server, it must contain
742        // Uncompressed.  But it's allowed to be omitted.
743        if let Some(point_fmts) = server_hello.ecpoints_extension() {
744            if !point_fmts.contains(&ECPointFormat::Uncompressed) {
745                return Err(cx.common.send_fatal_alert(
746                    AlertDescription::HandshakeFailure,
747                    PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
748                ));
749            }
750        }
751
752        let suite = config
753            .find_cipher_suite(server_hello.cipher_suite)
754            .ok_or_else(|| {
755                cx.common.send_fatal_alert(
756                    AlertDescription::HandshakeFailure,
757                    PeerMisbehaved::SelectedUnofferedCipherSuite,
758                )
759            })?;
760
761        if version != suite.version().version {
762            return Err({
763                cx.common.send_fatal_alert(
764                    AlertDescription::IllegalParameter,
765                    PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
766                )
767            });
768        }
769
770        match self.suite {
771            Some(prev_suite) if prev_suite != suite => {
772                return Err({
773                    cx.common.send_fatal_alert(
774                        AlertDescription::IllegalParameter,
775                        PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
776                    )
777                });
778            }
779            _ => {
780                debug!("Using ciphersuite {:?}", suite);
781                self.suite = Some(suite);
782                cx.common.suite = Some(suite);
783            }
784        }
785
786        // Start our handshake hash, and input the server-hello.
787        let mut transcript = self
788            .transcript_buffer
789            .start_hash(suite.hash_provider());
790        transcript.add_message(&m);
791
792        let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
793        // For TLS1.3, start message encryption using
794        // handshake_traffic_secret.
795        match suite {
796            SupportedCipherSuite::Tls13(suite) => {
797                #[allow(clippy::bind_instead_of_map)]
798                let resuming_session = self
799                    .input
800                    .resuming
801                    .and_then(|resuming| match resuming.value {
802                        ClientSessionValue::Tls13(inner) => Some(inner),
803                        #[cfg(feature = "tls12")]
804                        ClientSessionValue::Tls12(_) => None,
805                    });
806
807                tls13::handle_server_hello(
808                    self.input.config,
809                    cx,
810                    server_hello,
811                    resuming_session,
812                    self.input.server_name,
813                    randoms,
814                    suite,
815                    transcript,
816                    self.early_key_schedule,
817                    self.input.hello,
818                    // We always send a key share when TLS 1.3 is enabled.
819                    self.offered_key_share.unwrap(),
820                    self.input.sent_tls13_fake_ccs,
821                    &m,
822                    self.ech_state,
823                )
824            }
825            #[cfg(feature = "tls12")]
826            SupportedCipherSuite::Tls12(suite) => {
827                let resuming_session = self
828                    .input
829                    .resuming
830                    .and_then(|resuming| match resuming.value {
831                        ClientSessionValue::Tls12(inner) => Some(inner),
832                        ClientSessionValue::Tls13(_) => None,
833                    });
834
835                tls12::CompleteServerHelloHandling {
836                    config: self.input.config,
837                    resuming_session,
838                    server_name: self.input.server_name,
839                    randoms,
840                    using_ems: self.input.using_ems,
841                    transcript,
842                }
843                .handle_server_hello(cx, suite, server_hello, tls13_supported)
844            }
845        }
846    }
847
848    fn into_owned(self: Box<Self>) -> NextState<'static> {
849        self
850    }
851}
852
853impl ExpectServerHelloOrHelloRetryRequest {
854    fn into_expect_server_hello(self) -> NextState<'static> {
855        Box::new(self.next)
856    }
857
858    fn handle_hello_retry_request(
859        mut self,
860        cx: &mut ClientContext<'_>,
861        m: Message<'_>,
862    ) -> NextStateOrError<'static> {
863        let hrr = require_handshake_msg!(
864            m,
865            HandshakeType::HelloRetryRequest,
866            HandshakePayload::HelloRetryRequest
867        )?;
868        trace!("Got HRR {:?}", hrr);
869
870        cx.common.check_aligned_handshake()?;
871
872        let cookie = hrr.cookie();
873        let req_group = hrr.requested_key_share_group();
874
875        // We always send a key share when TLS 1.3 is enabled.
876        let offered_key_share = self.next.offered_key_share.unwrap();
877
878        // A retry request is illegal if it contains no cookie and asks for
879        // retry of a group we already sent.
880        if cookie.is_none() && req_group == Some(offered_key_share.group()) {
881            return Err({
882                cx.common.send_fatal_alert(
883                    AlertDescription::IllegalParameter,
884                    PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
885                )
886            });
887        }
888
889        // Or has an empty cookie.
890        if let Some(cookie) = cookie {
891            if cookie.0.is_empty() {
892                return Err({
893                    cx.common.send_fatal_alert(
894                        AlertDescription::IllegalParameter,
895                        PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
896                    )
897                });
898            }
899        }
900
901        // Or has something unrecognised
902        if hrr.has_unknown_extension() {
903            return Err(cx.common.send_fatal_alert(
904                AlertDescription::UnsupportedExtension,
905                PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
906            ));
907        }
908
909        // Or has the same extensions more than once
910        if hrr.has_duplicate_extension() {
911            return Err({
912                cx.common.send_fatal_alert(
913                    AlertDescription::IllegalParameter,
914                    PeerMisbehaved::DuplicateHelloRetryRequestExtensions,
915                )
916            });
917        }
918
919        // Or asks us to change nothing.
920        if cookie.is_none() && req_group.is_none() {
921            return Err({
922                cx.common.send_fatal_alert(
923                    AlertDescription::IllegalParameter,
924                    PeerMisbehaved::IllegalHelloRetryRequestWithNoChanges,
925                )
926            });
927        }
928
929        // Or does not echo the session_id from our ClientHello:
930        //
931        // > the HelloRetryRequest has the same format as a ServerHello message,
932        // > and the legacy_version, legacy_session_id_echo, cipher_suite, and
933        // > legacy_compression_method fields have the same meaning
934        // <https://www.rfc-editor.org/rfc/rfc8446#section-4.1.4>
935        //
936        // and
937        //
938        // > A client which receives a legacy_session_id_echo field that does not
939        // > match what it sent in the ClientHello MUST abort the handshake with an
940        // > "illegal_parameter" alert.
941        // <https://www.rfc-editor.org/rfc/rfc8446#section-4.1.3>
942        if hrr.session_id != self.next.input.session_id {
943            return Err({
944                cx.common.send_fatal_alert(
945                    AlertDescription::IllegalParameter,
946                    PeerMisbehaved::IllegalHelloRetryRequestWithWrongSessionId,
947                )
948            });
949        }
950
951        // Or asks us to talk a protocol we didn't offer, or doesn't support HRR at all.
952        match hrr.supported_versions() {
953            Some(ProtocolVersion::TLSv1_3) => {
954                cx.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
955            }
956            _ => {
957                return Err({
958                    cx.common.send_fatal_alert(
959                        AlertDescription::IllegalParameter,
960                        PeerMisbehaved::IllegalHelloRetryRequestWithUnsupportedVersion,
961                    )
962                });
963            }
964        }
965
966        // Or asks us to use a ciphersuite we didn't offer.
967        let config = &self.next.input.config;
968        let cs = match config.find_cipher_suite(hrr.cipher_suite) {
969            Some(cs) => cs,
970            None => {
971                return Err({
972                    cx.common.send_fatal_alert(
973                        AlertDescription::IllegalParameter,
974                        PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
975                    )
976                });
977            }
978        };
979
980        // Or offers ECH related extensions when we didn't offer ECH.
981        if cx.data.ech_status == EchStatus::NotOffered && hrr.ech().is_some() {
982            return Err({
983                cx.common.send_fatal_alert(
984                    AlertDescription::UnsupportedExtension,
985                    PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
986                )
987            });
988        }
989
990        // HRR selects the ciphersuite.
991        cx.common.suite = Some(cs);
992        cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
993
994        // If we offered ECH, we need to confirm that the server accepted it.
995        match (self.next.ech_state.as_ref(), cs.tls13()) {
996            (Some(ech_state), Some(tls13_cs)) => {
997                if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? {
998                    // If the server did not confirm, then note the new ECH status but
999                    // continue the handshake. We will abort with an ECH required error
1000                    // at the end.
1001                    cx.data.ech_status = EchStatus::Rejected;
1002                }
1003            }
1004            (Some(_), None) => {
1005                unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1006            }
1007            _ => {}
1008        };
1009
1010        // This is the draft19 change where the transcript became a tree
1011        let transcript = self
1012            .next
1013            .transcript_buffer
1014            .start_hash(cs.hash_provider());
1015        let mut transcript_buffer = transcript.into_hrr_buffer();
1016        transcript_buffer.add_message(&m);
1017
1018        // If we offered ECH and the server accepted, we also need to update the separate
1019        // ECH transcript with the hello retry request message.
1020        if let Some(ech_state) = self.next.ech_state.as_mut() {
1021            ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1022        }
1023
1024        // Early data is not allowed after HelloRetryrequest
1025        if cx.data.early_data.is_enabled() {
1026            cx.data.early_data.rejected();
1027        }
1028
1029        let key_share = match req_group {
1030            Some(group) if group != offered_key_share.group() => {
1031                let skxg = match config.find_kx_group(group) {
1032                    Some(skxg) => skxg,
1033                    None => {
1034                        return Err(cx.common.send_fatal_alert(
1035                            AlertDescription::IllegalParameter,
1036                            PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1037                        ));
1038                    }
1039                };
1040
1041                cx.common.kx_state = KxState::Start(skxg);
1042                skxg.start()?
1043            }
1044            _ => offered_key_share,
1045        };
1046
1047        emit_client_hello_for_retry(
1048            transcript_buffer,
1049            Some(hrr),
1050            Some(key_share),
1051            self.extra_exts,
1052            Some(cs),
1053            self.next.input,
1054            cx,
1055            self.next.ech_state,
1056        )
1057    }
1058}
1059
1060impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1061    fn handle<'m>(
1062        self: Box<Self>,
1063        cx: &mut ClientContext<'_>,
1064        m: Message<'m>,
1065    ) -> NextStateOrError<'m>
1066    where
1067        Self: 'm,
1068    {
1069        match m.payload {
1070            MessagePayload::Handshake {
1071                parsed:
1072                    HandshakeMessagePayload {
1073                        payload: HandshakePayload::ServerHello(..),
1074                        ..
1075                    },
1076                ..
1077            } => self
1078                .into_expect_server_hello()
1079                .handle(cx, m),
1080            MessagePayload::Handshake {
1081                parsed:
1082                    HandshakeMessagePayload {
1083                        payload: HandshakePayload::HelloRetryRequest(..),
1084                        ..
1085                    },
1086                ..
1087            } => self.handle_hello_retry_request(cx, m),
1088            payload => Err(inappropriate_handshake_message(
1089                &payload,
1090                &[ContentType::Handshake],
1091                &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1092            )),
1093        }
1094    }
1095
1096    fn into_owned(self: Box<Self>) -> NextState<'static> {
1097        self
1098    }
1099}
1100
1101enum ClientSessionValue {
1102    Tls13(persist::Tls13ClientSessionValue),
1103    #[cfg(feature = "tls12")]
1104    Tls12(persist::Tls12ClientSessionValue),
1105}
1106
1107impl ClientSessionValue {
1108    fn common(&self) -> &persist::ClientSessionCommon {
1109        match self {
1110            Self::Tls13(inner) => &inner.common,
1111            #[cfg(feature = "tls12")]
1112            Self::Tls12(inner) => &inner.common,
1113        }
1114    }
1115
1116    fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1117        match self {
1118            Self::Tls13(v) => Some(v),
1119            #[cfg(feature = "tls12")]
1120            Self::Tls12(_) => None,
1121        }
1122    }
1123}
1124
1125impl Deref for ClientSessionValue {
1126    type Target = persist::ClientSessionCommon;
1127
1128    fn deref(&self) -> &Self::Target {
1129        self.common()
1130    }
1131}
1132
1133fn low_quality_integer_hash(mut x: u32) -> u32 {
1134    x = x
1135        .wrapping_add(0x7ed55d16)
1136        .wrapping_add(x << 12);
1137    x = (x ^ 0xc761c23c) ^ (x >> 19);
1138    x = x
1139        .wrapping_add(0x165667b1)
1140        .wrapping_add(x << 5);
1141    x = x.wrapping_add(0xd3a2646c) ^ (x << 9);
1142    x = x
1143        .wrapping_add(0xfd7046c5)
1144        .wrapping_add(x << 3);
1145    x = (x ^ 0xb55a4f09) ^ (x >> 16);
1146    x
1147}