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::{
21 CommonState, HandshakeKind, KxState, RawKeyNegotationResult, RawKeyNegotiationParams, State,
22};
23use crate::conn::ConnectionRandoms;
24use crate::crypto::{ActiveKeyExchange, KeyExchangeAlgorithm};
25use crate::enums::{AlertDescription, CipherSuite, ContentType, HandshakeType, ProtocolVersion};
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::{
31 CertificateType, Compression, ECPointFormat, ExtensionType, PSKKeyExchangeMode,
32};
33use crate::msgs::handshake::{
34 CertificateStatusRequest, ClientExtension, ClientHelloPayload, ClientSessionTicket,
35 ConvertProtocolNameList, HandshakeMessagePayload, HandshakePayload, HasServerExtensions,
36 HelloRetryRequest, KeyShareEntry, Random, SessionId,
37};
38use crate::msgs::message::{Message, MessagePayload};
39use crate::msgs::persist;
40use crate::tls13::key_schedule::KeyScheduleEarly;
41use crate::SupportedCipherSuite;
42
43pub(super) type NextState<'a> = Box<dyn State<ClientConnectionData> + 'a>;
44pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
45pub(super) type ClientContext<'a> = crate::common_state::Context<'a, ClientConnectionData>;
46
47fn find_session(
48 server_name: &ServerName<'static>,
49 config: &ClientConfig,
50 cx: &mut ClientContext<'_>,
51) -> Option<persist::Retrieved<ClientSessionValue>> {
52 let found = config
53 .resumption
54 .store
55 .take_tls13_ticket(server_name)
56 .map(ClientSessionValue::Tls13)
57 .or_else(|| {
58 #[cfg(feature = "tls12")]
59 {
60 config
61 .resumption
62 .store
63 .tls12_session(server_name)
64 .map(ClientSessionValue::Tls12)
65 }
66
67 #[cfg(not(feature = "tls12"))]
68 None
69 })
70 .and_then(|resuming| {
71 let now = config
72 .current_time()
73 .map_err(|_err| debug!("Could not get current time: {_err}"))
74 .ok()?;
75
76 let retrieved = persist::Retrieved::new(resuming, now);
77 match retrieved.has_expired() {
78 false => Some(retrieved),
79 true => None,
80 }
81 })
82 .or_else(|| {
83 debug!("No cached session for {:?}", server_name);
84 None
85 });
86
87 if let Some(resuming) = &found {
88 if cx.common.is_quic() {
89 cx.common.quic.params = resuming
90 .tls13()
91 .map(|v| v.quic_params());
92 }
93 }
94
95 found
96}
97
98pub(super) fn start_handshake(
99 server_name: ServerName<'static>,
100 extra_exts: Vec<ClientExtension>,
101 config: Arc<ClientConfig>,
102 cx: &mut ClientContext<'_>,
103) -> NextStateOrError<'static> {
104 let mut transcript_buffer = HandshakeHashBuffer::new();
105 if config
106 .client_auth_cert_resolver
107 .has_certs()
108 {
109 transcript_buffer.set_client_auth_enabled();
110 }
111
112 let mut resuming = find_session(&server_name, &config, cx);
113
114 let key_share = if config.supports_version(ProtocolVersion::TLSv1_3) {
115 Some(tls13::initial_key_share(
116 &config,
117 &server_name,
118 &mut cx.common.kx_state,
119 )?)
120 } else {
121 None
122 };
123
124 let session_id = if let Some(_resuming) = &mut resuming {
125 debug!("Resuming session");
126
127 match &mut _resuming.value {
128 #[cfg(feature = "tls12")]
129 ClientSessionValue::Tls12(inner) => {
130 if !inner.ticket().0.is_empty() {
134 inner.session_id = SessionId::random(config.provider.secure_random)?;
135 }
136 Some(inner.session_id)
137 }
138 _ => None,
139 }
140 } else {
141 debug!("Not resuming any session");
142 None
143 };
144
145 let session_id = match session_id {
148 Some(session_id) => session_id,
149 None if cx.common.is_quic() => SessionId::empty(),
150 None if !config.supports_version(ProtocolVersion::TLSv1_3) => SessionId::empty(),
151 None => SessionId::random(config.provider.secure_random)?,
152 };
153
154 let random = Random::new(config.provider.secure_random)?;
155 let extension_order_seed = crate::rand::random_u16(config.provider.secure_random)?;
156
157 let ech_state = match config.ech_mode.as_ref() {
158 Some(EchMode::Enable(ech_config)) => Some(EchState::new(
159 ech_config,
160 server_name.clone(),
161 config
162 .client_auth_cert_resolver
163 .has_certs(),
164 config.provider.secure_random,
165 config.enable_sni,
166 )?),
167 _ => None,
168 };
169
170 emit_client_hello_for_retry(
171 transcript_buffer,
172 None,
173 key_share,
174 extra_exts,
175 None,
176 ClientHelloInput {
177 config,
178 resuming,
179 random,
180 #[cfg(feature = "tls12")]
181 using_ems: false,
182 sent_tls13_fake_ccs: false,
183 hello: ClientHelloDetails::new(extension_order_seed),
184 session_id,
185 server_name,
186 prev_ech_ext: None,
187 },
188 cx,
189 ech_state,
190 )
191}
192
193struct ExpectServerHello {
194 input: ClientHelloInput,
195 transcript_buffer: HandshakeHashBuffer,
196 early_key_schedule: Option<KeyScheduleEarly>,
197 offered_key_share: Option<Box<dyn ActiveKeyExchange>>,
198 suite: Option<SupportedCipherSuite>,
199 ech_state: Option<EchState>,
200}
201
202struct ExpectServerHelloOrHelloRetryRequest {
203 next: ExpectServerHello,
204 extra_exts: Vec<ClientExtension>,
205}
206
207struct ClientHelloInput {
208 config: Arc<ClientConfig>,
209 resuming: Option<persist::Retrieved<ClientSessionValue>>,
210 random: Random,
211 #[cfg(feature = "tls12")]
212 using_ems: bool,
213 sent_tls13_fake_ccs: bool,
214 hello: ClientHelloDetails,
215 session_id: SessionId,
216 server_name: ServerName<'static>,
217 prev_ech_ext: Option<ClientExtension>,
218}
219
220fn emit_client_hello_for_retry(
221 mut transcript_buffer: HandshakeHashBuffer,
222 retryreq: Option<&HelloRetryRequest>,
223 key_share: Option<Box<dyn ActiveKeyExchange>>,
224 extra_exts: Vec<ClientExtension>,
225 suite: Option<SupportedCipherSuite>,
226 mut input: ClientHelloInput,
227 cx: &mut ClientContext<'_>,
228 mut ech_state: Option<EchState>,
229) -> NextStateOrError<'static> {
230 let config = &input.config;
231 let forbids_tls12 = cx.common.is_quic() || ech_state.is_some();
234 let support_tls12 = config.supports_version(ProtocolVersion::TLSv1_2) && !forbids_tls12;
235 let support_tls13 = config.supports_version(ProtocolVersion::TLSv1_3);
236
237 let mut supported_versions = Vec::new();
238 if support_tls13 {
239 supported_versions.push(ProtocolVersion::TLSv1_3);
240 }
241
242 if support_tls12 {
243 supported_versions.push(ProtocolVersion::TLSv1_2);
244 }
245
246 assert!(!supported_versions.is_empty());
248
249 let offered_groups = config
251 .provider
252 .kx_groups
253 .iter()
254 .filter(|skxg| {
255 supported_versions
256 .iter()
257 .any(|v| skxg.usable_for_version(*v))
258 })
259 .map(|skxg| skxg.name())
260 .collect();
261
262 let mut exts = vec![
263 ClientExtension::SupportedVersions(supported_versions),
264 ClientExtension::NamedGroups(offered_groups),
265 ClientExtension::SignatureAlgorithms(
266 config
267 .verifier
268 .supported_verify_schemes(),
269 ),
270 ClientExtension::ExtendedMasterSecretRequest,
271 ClientExtension::CertificateStatusRequest(CertificateStatusRequest::build_ocsp()),
272 ];
273
274 if config
276 .provider
277 .kx_groups
278 .iter()
279 .any(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::ECDHE)
280 {
281 exts.push(ClientExtension::EcPointFormats(
282 ECPointFormat::SUPPORTED.to_vec(),
283 ));
284 }
285
286 match (ech_state.as_ref(), config.enable_sni) {
287 (Some(ech_state), _) => exts.push(ClientExtension::make_sni(&ech_state.outer_name)),
292
293 (None, true) => {
296 if let ServerName::DnsName(dns_name) = &input.server_name {
297 exts.push(ClientExtension::make_sni(dns_name))
298 }
299 }
300
301 (None, false) => {}
303 };
304
305 if let Some(key_share) = &key_share {
306 debug_assert!(support_tls13);
307 let mut shares = vec![KeyShareEntry::new(key_share.group(), key_share.pub_key())];
308
309 if retryreq.is_none() {
310 if let Some((component_group, component_share)) =
314 key_share
315 .hybrid_component()
316 .filter(|(group, _)| {
317 config
318 .find_kx_group(*group, ProtocolVersion::TLSv1_3)
319 .is_some()
320 })
321 {
322 shares.push(KeyShareEntry::new(component_group, component_share));
323 }
324 }
325
326 exts.push(ClientExtension::KeyShare(shares));
327 }
328
329 if let Some(cookie) = retryreq.and_then(HelloRetryRequest::cookie) {
330 exts.push(ClientExtension::Cookie(cookie.clone()));
331 }
332
333 if support_tls13 {
334 let psk_modes = vec![PSKKeyExchangeMode::PSK_DHE_KE];
337 exts.push(ClientExtension::PresharedKeyModes(psk_modes));
338 }
339
340 if !config.alpn_protocols.is_empty() {
341 exts.push(ClientExtension::Protocols(Vec::from_slices(
342 &config
343 .alpn_protocols
344 .iter()
345 .map(|proto| &proto[..])
346 .collect::<Vec<_>>(),
347 )));
348 }
349
350 input.hello.offered_cert_compression = if support_tls13 && !config.cert_decompressors.is_empty()
351 {
352 exts.push(ClientExtension::CertificateCompressionAlgorithms(
353 config
354 .cert_decompressors
355 .iter()
356 .map(|dec| dec.algorithm())
357 .collect(),
358 ));
359 true
360 } else {
361 false
362 };
363
364 if config
365 .client_auth_cert_resolver
366 .only_raw_public_keys()
367 {
368 exts.push(ClientExtension::ClientCertTypes(vec![
369 CertificateType::RawPublicKey,
370 ]));
371 }
372
373 if config
374 .verifier
375 .requires_raw_public_keys()
376 {
377 exts.push(ClientExtension::ServerCertTypes(vec![
378 CertificateType::RawPublicKey,
379 ]));
380 }
381
382 exts.extend(extra_exts.iter().cloned());
384
385 if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
389 if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
390 exts.push(prev_ech_ext);
391 }
392 }
393
394 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
396
397 exts.sort_by_cached_key(|new_ext| {
400 match (&cx.data.ech_status, new_ext) {
401 (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
403 (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
405 (_, ClientExtension::PresharedKey(..)) => return u32::MAX - 1,
407 _ => {}
408 };
409
410 let seed = (input.hello.extension_order_seed as u32) << 16
411 | (u16::from(new_ext.ext_type()) as u32);
412 match low_quality_integer_hash(seed) {
413 u32::MAX => 0,
414 key => key,
415 }
416 });
417
418 let mut cipher_suites: Vec<_> = config
419 .provider
420 .cipher_suites
421 .iter()
422 .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
423 true => Some(cs.suite()),
424 false => None,
425 })
426 .collect();
427 cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
429
430 let mut chp_payload = ClientHelloPayload {
431 client_version: ProtocolVersion::TLSv1_2,
432 random: input.random,
433 session_id: input.session_id,
434 cipher_suites,
435 compression_methods: vec![Compression::Null],
436 extensions: exts,
437 };
438
439 let ech_grease_ext = config
440 .ech_mode
441 .as_ref()
442 .and_then(|mode| match mode {
443 EchMode::Grease(cfg) => Some(cfg.grease_ext(
444 config.provider.secure_random,
445 input.server_name.clone(),
446 &chp_payload,
447 )),
448 _ => None,
449 });
450
451 match (cx.data.ech_status, &mut ech_state) {
452 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
455 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
457 cx.data.ech_status = EchStatus::Offered;
458 input.prev_ech_ext = chp_payload.extensions.last().cloned();
460 }
461 (EchStatus::NotOffered, None) => {
464 if let Some(grease_ext) = ech_grease_ext {
465 let grease_ext = grease_ext?;
467 chp_payload
468 .extensions
469 .push(grease_ext.clone());
470 cx.data.ech_status = EchStatus::Grease;
471 input.prev_ech_ext = Some(grease_ext);
474 }
475 }
476 _ => {}
477 }
478
479 input.hello.sent_extensions = chp_payload
481 .extensions
482 .iter()
483 .map(ClientExtension::ext_type)
484 .collect();
485
486 let mut chp = HandshakeMessagePayload {
487 typ: HandshakeType::ClientHello,
488 payload: HandshakePayload::ClientHello(chp_payload),
489 };
490
491 let early_key_schedule = match (ech_state.as_mut(), tls13_session) {
492 (Some(ech_state), Some(tls13_session)) => ech_state
495 .early_data_key_schedule
496 .take()
497 .map(|schedule| (tls13_session.suite(), schedule)),
498
499 (_, Some(tls13_session)) => Some((
502 tls13_session.suite(),
503 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
504 )),
505
506 _ => None,
508 };
509
510 let ch = Message {
511 version: match retryreq {
512 Some(_) => ProtocolVersion::TLSv1_2,
516 None => ProtocolVersion::TLSv1_0,
522 },
523 payload: MessagePayload::handshake(chp),
524 };
525
526 if retryreq.is_some() {
527 tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
530 }
531
532 trace!("Sending ClientHello {:#?}", ch);
533
534 transcript_buffer.add_message(&ch);
535 cx.common.send_msg(ch, false);
536
537 let early_key_schedule = early_key_schedule.map(|(resuming_suite, schedule)| {
539 if !cx.data.early_data.is_enabled() {
540 return schedule;
541 }
542
543 let (transcript_buffer, random) = match &ech_state {
544 Some(ech_state) => (
547 &ech_state.inner_hello_transcript,
548 &ech_state.inner_hello_random.0,
549 ),
550 None => (&transcript_buffer, &input.random.0),
551 };
552
553 tls13::derive_early_traffic_secret(
554 &*config.key_log,
555 cx,
556 resuming_suite,
557 &schedule,
558 &mut input.sent_tls13_fake_ccs,
559 transcript_buffer,
560 random,
561 );
562 schedule
563 });
564
565 let next = ExpectServerHello {
566 input,
567 transcript_buffer,
568 early_key_schedule,
569 offered_key_share: key_share,
570 suite,
571 ech_state,
572 };
573
574 Ok(if support_tls13 && retryreq.is_none() {
575 Box::new(ExpectServerHelloOrHelloRetryRequest { next, extra_exts })
576 } else {
577 Box::new(next)
578 })
579}
580
581fn prepare_resumption<'a>(
595 resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
596 exts: &mut Vec<ClientExtension>,
597 suite: Option<SupportedCipherSuite>,
598 cx: &mut ClientContext<'_>,
599 config: &ClientConfig,
600) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
601 let resuming = match resuming {
603 Some(resuming) if !resuming.ticket().is_empty() => resuming,
604 _ => {
605 if config.supports_version(ProtocolVersion::TLSv1_2)
606 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
607 {
608 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
610 }
611 return None;
612 }
613 };
614
615 let Some(tls13) = resuming.map(|csv| csv.tls13()) else {
616 if config.supports_version(ProtocolVersion::TLSv1_2)
618 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
619 {
620 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Offer(
621 Payload::new(resuming.ticket()),
622 )));
623 }
624 return None; };
626
627 if !config.supports_version(ProtocolVersion::TLSv1_3) {
628 return None;
629 }
630
631 let suite = match suite {
633 Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
634 #[cfg(feature = "tls12")]
635 Some(SupportedCipherSuite::Tls12(_)) => return None,
636 None => None,
637 };
638
639 if let Some(suite) = suite {
641 suite.can_resume_from(tls13.suite())?;
642 }
643
644 tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
645 Some(tls13)
646}
647
648pub(super) fn process_alpn_protocol(
649 common: &mut CommonState,
650 config: &ClientConfig,
651 proto: Option<&[u8]>,
652) -> Result<(), Error> {
653 common.alpn_protocol = proto.map(ToOwned::to_owned);
654
655 if let Some(alpn_protocol) = &common.alpn_protocol {
656 if !config
657 .alpn_protocols
658 .contains(alpn_protocol)
659 {
660 return Err(common.send_fatal_alert(
661 AlertDescription::IllegalParameter,
662 PeerMisbehaved::SelectedUnofferedApplicationProtocol,
663 ));
664 }
665 }
666
667 if common.is_quic() && common.alpn_protocol.is_none() && !config.alpn_protocols.is_empty() {
674 return Err(common.send_fatal_alert(
675 AlertDescription::NoApplicationProtocol,
676 Error::NoApplicationProtocol,
677 ));
678 }
679
680 debug!(
681 "ALPN protocol is {:?}",
682 common
683 .alpn_protocol
684 .as_ref()
685 .map(|v| bs_debug::BsDebug(v))
686 );
687 Ok(())
688}
689
690pub(super) fn process_server_cert_type_extension(
691 common: &mut CommonState,
692 config: &ClientConfig,
693 server_cert_extension: Option<&CertificateType>,
694) -> Result<(), Error> {
695 let requires_server_rpk = config
696 .verifier
697 .requires_raw_public_keys();
698 let server_offers_rpk = matches!(server_cert_extension, Some(CertificateType::RawPublicKey));
699
700 let raw_key_negotation_params = RawKeyNegotiationParams {
701 peer_supports_raw_key: server_offers_rpk,
702 local_expects_raw_key: requires_server_rpk,
703 extension_type: ExtensionType::ServerCertificateType,
704 };
705 match raw_key_negotation_params.validate_raw_key_negotiation() {
706 RawKeyNegotationResult::Err(err) => {
707 Err(common.send_fatal_alert(AlertDescription::HandshakeFailure, err))
708 }
709 _ => Ok(()),
710 }
711}
712
713pub(super) fn process_client_cert_type_extension(
714 common: &mut CommonState,
715 config: &ClientConfig,
716 client_cert_extension: Option<&CertificateType>,
717) -> Result<(), Error> {
718 let requires_client_rpk = config
719 .client_auth_cert_resolver
720 .only_raw_public_keys();
721 let server_allows_rpk = matches!(client_cert_extension, Some(CertificateType::RawPublicKey));
722
723 let raw_key_negotation_params = RawKeyNegotiationParams {
724 peer_supports_raw_key: server_allows_rpk,
725 local_expects_raw_key: requires_client_rpk,
726 extension_type: ExtensionType::ClientCertificateType,
727 };
728 match raw_key_negotation_params.validate_raw_key_negotiation() {
729 RawKeyNegotationResult::Err(err) => {
730 Err(common.send_fatal_alert(AlertDescription::HandshakeFailure, err))
731 }
732 _ => Ok(()),
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 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 if !cx.common.is_tls13() {
827 process_alpn_protocol(cx.common, config, server_hello.alpn_protocol())?;
828 }
829
830 if let Some(point_fmts) = server_hello.ecpoints_extension() {
833 if !point_fmts.contains(&ECPointFormat::Uncompressed) {
834 return Err(cx.common.send_fatal_alert(
835 AlertDescription::HandshakeFailure,
836 PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
837 ));
838 }
839 }
840
841 let suite = config
842 .find_cipher_suite(server_hello.cipher_suite)
843 .ok_or_else(|| {
844 cx.common.send_fatal_alert(
845 AlertDescription::HandshakeFailure,
846 PeerMisbehaved::SelectedUnofferedCipherSuite,
847 )
848 })?;
849
850 if version != suite.version().version {
851 return Err({
852 cx.common.send_fatal_alert(
853 AlertDescription::IllegalParameter,
854 PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
855 )
856 });
857 }
858
859 match self.suite {
860 Some(prev_suite) if prev_suite != suite => {
861 return Err({
862 cx.common.send_fatal_alert(
863 AlertDescription::IllegalParameter,
864 PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
865 )
866 });
867 }
868 _ => {
869 debug!("Using ciphersuite {:?}", suite);
870 self.suite = Some(suite);
871 cx.common.suite = Some(suite);
872 }
873 }
874
875 let mut transcript = self
877 .transcript_buffer
878 .start_hash(suite.hash_provider());
879 transcript.add_message(&m);
880
881 let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
882 match suite {
885 SupportedCipherSuite::Tls13(suite) => {
886 #[allow(clippy::bind_instead_of_map)]
887 let resuming_session = self
888 .input
889 .resuming
890 .and_then(|resuming| match resuming.value {
891 ClientSessionValue::Tls13(inner) => Some(inner),
892 #[cfg(feature = "tls12")]
893 ClientSessionValue::Tls12(_) => None,
894 });
895
896 tls13::handle_server_hello(
897 self.input.config,
898 cx,
899 server_hello,
900 resuming_session,
901 self.input.server_name,
902 randoms,
903 suite,
904 transcript,
905 self.early_key_schedule,
906 self.input.hello,
907 self.offered_key_share.unwrap(),
909 self.input.sent_tls13_fake_ccs,
910 &m,
911 self.ech_state,
912 )
913 }
914 #[cfg(feature = "tls12")]
915 SupportedCipherSuite::Tls12(suite) => {
916 let resuming_session = self
917 .input
918 .resuming
919 .and_then(|resuming| match resuming.value {
920 ClientSessionValue::Tls12(inner) => Some(inner),
921 ClientSessionValue::Tls13(_) => None,
922 });
923
924 tls12::CompleteServerHelloHandling {
925 config: self.input.config,
926 resuming_session,
927 server_name: self.input.server_name,
928 randoms,
929 using_ems: self.input.using_ems,
930 transcript,
931 }
932 .handle_server_hello(cx, suite, server_hello, tls13_supported)
933 }
934 }
935 }
936
937 fn into_owned(self: Box<Self>) -> NextState<'static> {
938 self
939 }
940}
941
942impl ExpectServerHelloOrHelloRetryRequest {
943 fn into_expect_server_hello(self) -> NextState<'static> {
944 Box::new(self.next)
945 }
946
947 fn handle_hello_retry_request(
948 mut self,
949 cx: &mut ClientContext<'_>,
950 m: Message<'_>,
951 ) -> NextStateOrError<'static> {
952 let hrr = require_handshake_msg!(
953 m,
954 HandshakeType::HelloRetryRequest,
955 HandshakePayload::HelloRetryRequest
956 )?;
957 trace!("Got HRR {:?}", hrr);
958
959 cx.common.check_aligned_handshake()?;
960
961 let cookie = hrr.cookie();
962 let req_group = hrr.requested_key_share_group();
963
964 let offered_key_share = self.next.offered_key_share.unwrap();
966
967 if cookie.is_none() && req_group == Some(offered_key_share.group()) {
970 return Err({
971 cx.common.send_fatal_alert(
972 AlertDescription::IllegalParameter,
973 PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
974 )
975 });
976 }
977
978 if let Some(cookie) = cookie {
980 if cookie.0.is_empty() {
981 return Err({
982 cx.common.send_fatal_alert(
983 AlertDescription::IllegalParameter,
984 PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
985 )
986 });
987 }
988 }
989
990 if hrr.has_unknown_extension() {
992 return Err(cx.common.send_fatal_alert(
993 AlertDescription::UnsupportedExtension,
994 PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
995 ));
996 }
997
998 if hrr.has_duplicate_extension() {
1000 return Err({
1001 cx.common.send_fatal_alert(
1002 AlertDescription::IllegalParameter,
1003 PeerMisbehaved::DuplicateHelloRetryRequestExtensions,
1004 )
1005 });
1006 }
1007
1008 if cookie.is_none() && req_group.is_none() {
1010 return Err({
1011 cx.common.send_fatal_alert(
1012 AlertDescription::IllegalParameter,
1013 PeerMisbehaved::IllegalHelloRetryRequestWithNoChanges,
1014 )
1015 });
1016 }
1017
1018 if hrr.session_id != self.next.input.session_id {
1032 return Err({
1033 cx.common.send_fatal_alert(
1034 AlertDescription::IllegalParameter,
1035 PeerMisbehaved::IllegalHelloRetryRequestWithWrongSessionId,
1036 )
1037 });
1038 }
1039
1040 match hrr.supported_versions() {
1042 Some(ProtocolVersion::TLSv1_3) => {
1043 cx.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
1044 }
1045 _ => {
1046 return Err({
1047 cx.common.send_fatal_alert(
1048 AlertDescription::IllegalParameter,
1049 PeerMisbehaved::IllegalHelloRetryRequestWithUnsupportedVersion,
1050 )
1051 });
1052 }
1053 }
1054
1055 let config = &self.next.input.config;
1057 let Some(cs) = config.find_cipher_suite(hrr.cipher_suite) else {
1058 return Err({
1059 cx.common.send_fatal_alert(
1060 AlertDescription::IllegalParameter,
1061 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
1062 )
1063 });
1064 };
1065
1066 if cx.data.ech_status == EchStatus::NotOffered && hrr.ech().is_some() {
1068 return Err({
1069 cx.common.send_fatal_alert(
1070 AlertDescription::UnsupportedExtension,
1071 PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
1072 )
1073 });
1074 }
1075
1076 cx.common.suite = Some(cs);
1078 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
1079
1080 match (self.next.ech_state.as_ref(), cs.tls13()) {
1082 (Some(ech_state), Some(tls13_cs)) => {
1083 if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? {
1084 cx.data.ech_status = EchStatus::Rejected;
1088 }
1089 }
1090 (Some(_), None) => {
1091 unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1092 }
1093 _ => {}
1094 };
1095
1096 let transcript = self
1098 .next
1099 .transcript_buffer
1100 .start_hash(cs.hash_provider());
1101 let mut transcript_buffer = transcript.into_hrr_buffer();
1102 transcript_buffer.add_message(&m);
1103
1104 if let Some(ech_state) = self.next.ech_state.as_mut() {
1107 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1108 }
1109
1110 if cx.data.early_data.is_enabled() {
1112 cx.data.early_data.rejected();
1113 }
1114
1115 let key_share = match req_group {
1116 Some(group) if group != offered_key_share.group() => {
1117 let Some(skxg) = config.find_kx_group(group, ProtocolVersion::TLSv1_3) else {
1118 return Err(cx.common.send_fatal_alert(
1119 AlertDescription::IllegalParameter,
1120 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1121 ));
1122 };
1123
1124 cx.common.kx_state = KxState::Start(skxg);
1125 skxg.start()?
1126 }
1127 _ => offered_key_share,
1128 };
1129
1130 emit_client_hello_for_retry(
1131 transcript_buffer,
1132 Some(hrr),
1133 Some(key_share),
1134 self.extra_exts,
1135 Some(cs),
1136 self.next.input,
1137 cx,
1138 self.next.ech_state,
1139 )
1140 }
1141}
1142
1143impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1144 fn handle<'m>(
1145 self: Box<Self>,
1146 cx: &mut ClientContext<'_>,
1147 m: Message<'m>,
1148 ) -> NextStateOrError<'m>
1149 where
1150 Self: 'm,
1151 {
1152 match m.payload {
1153 MessagePayload::Handshake {
1154 parsed:
1155 HandshakeMessagePayload {
1156 payload: HandshakePayload::ServerHello(..),
1157 ..
1158 },
1159 ..
1160 } => self
1161 .into_expect_server_hello()
1162 .handle(cx, m),
1163 MessagePayload::Handshake {
1164 parsed:
1165 HandshakeMessagePayload {
1166 payload: HandshakePayload::HelloRetryRequest(..),
1167 ..
1168 },
1169 ..
1170 } => self.handle_hello_retry_request(cx, m),
1171 payload => Err(inappropriate_handshake_message(
1172 &payload,
1173 &[ContentType::Handshake],
1174 &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1175 )),
1176 }
1177 }
1178
1179 fn into_owned(self: Box<Self>) -> NextState<'static> {
1180 self
1181 }
1182}
1183
1184enum ClientSessionValue {
1185 Tls13(persist::Tls13ClientSessionValue),
1186 #[cfg(feature = "tls12")]
1187 Tls12(persist::Tls12ClientSessionValue),
1188}
1189
1190impl ClientSessionValue {
1191 fn common(&self) -> &persist::ClientSessionCommon {
1192 match self {
1193 Self::Tls13(inner) => &inner.common,
1194 #[cfg(feature = "tls12")]
1195 Self::Tls12(inner) => &inner.common,
1196 }
1197 }
1198
1199 fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1200 match self {
1201 Self::Tls13(v) => Some(v),
1202 #[cfg(feature = "tls12")]
1203 Self::Tls12(_) => None,
1204 }
1205 }
1206}
1207
1208impl Deref for ClientSessionValue {
1209 type Target = persist::ClientSessionCommon;
1210
1211 fn deref(&self) -> &Self::Target {
1212 self.common()
1213 }
1214}
1215
1216fn low_quality_integer_hash(mut x: u32) -> u32 {
1217 x = x
1218 .wrapping_add(0x7ed55d16)
1219 .wrapping_add(x << 12);
1220 x = (x ^ 0xc761c23c) ^ (x >> 19);
1221 x = x
1222 .wrapping_add(0x165667b1)
1223 .wrapping_add(x << 5);
1224 x = x.wrapping_add(0xd3a2646c) ^ (x << 9);
1225 x = x
1226 .wrapping_add(0xfd7046c5)
1227 .wrapping_add(x << 3);
1228 x = (x ^ 0xb55a4f09) ^ (x >> 16);
1229 x
1230}