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 !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 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 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
232fn 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 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 assert!(supported_versions.any(|_| true));
259
260 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 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 (Some(ech_state), _) => {
305 exts.push(ClientExtension::ServerName((&ech_state.outer_name).into()))
306 }
307
308 (None, true) => {
311 if let ServerName::DnsName(dns_name) = &input.server_name {
312 exts.push(ClientExtension::ServerName(dns_name.into()));
313 }
314 }
315
316 (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 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 let psk_modes = vec![PskKeyExchangeMode::PSK_DHE_KE];
356 exts.push(ClientExtension::PresharedKeyModes(psk_modes));
357 }
358
359 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 exts.extend(extra_exts.iter().cloned());
400
401 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 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
412
413 exts.sort_by_cached_key(|new_ext| {
416 match (&cx.data.ech_status, new_ext) {
417 (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
419 (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
421 (_, 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 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 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
474 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
476 cx.data.ech_status = EchStatus::Offered;
477 input.prev_ech_ext = chp_payload.extensions.last().cloned();
479 }
480 (EchStatus::NotOffered, None) => {
483 if let Some(grease_ext) = ech_grease_ext {
484 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 input.prev_ech_ext = Some(grease_ext);
493 }
494 }
495 _ => {}
496 }
497
498 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 (Some(ech_state), Some(tls13_session)) => ech_state
511 .early_data_key_schedule
512 .take()
513 .map(|schedule| (tls13_session.suite(), schedule)),
514
515 (_, Some(tls13_session)) => Some((
518 tls13_session.suite(),
519 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
520 )),
521
522 _ => None,
524 };
525
526 let ch = Message {
527 version: match retryreq {
528 Some(_) => ProtocolVersion::TLSv1_2,
532 None => ProtocolVersion::TLSv1_0,
538 },
539 payload: MessagePayload::handshake(chp),
540 };
541
542 if retryreq.is_some() {
543 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 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 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
598fn 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 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 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
629 }
630 return None;
631 }
632 };
633
634 let Some(tls13) = resuming.map(|csv| csv.tls13()) else {
635 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; };
645
646 if !config.supports_version(ProtocolVersion::TLSv1_3) {
647 return None;
648 }
649
650 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 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 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 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(
828 cx.common,
829 &self.input.hello.alpn_protocols,
830 server_hello.alpn_protocol(),
831 )?;
832 }
833
834 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 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 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 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 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 let offered_key_share = self.next.offered_key_share.unwrap();
987
988 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 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 if hrr.has_unknown_extension() {
1024 return Err(cx.common.send_fatal_alert(
1025 AlertDescription::UnsupportedExtension,
1026 PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
1027 ));
1028 }
1029
1030 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 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 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 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 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 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 cx.common.suite = Some(cs);
1109 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
1110
1111 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 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 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 let Some(ech_state) = self.next.ech_state.as_mut() {
1138 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1139 }
1140
1141 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}