rustls/client/
hs.rs

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