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
9use super::ResolvesClientCert;
10use super::Tls12Resumption;
11#[cfg(feature = "tls12")]
12use super::tls12;
13use crate::SupportedCipherSuite;
14#[cfg(feature = "logging")]
15use crate::bs_debug;
16use crate::check::inappropriate_handshake_message;
17use crate::client::client_conn::ClientConnectionData;
18use crate::client::common::ClientHelloDetails;
19use crate::client::ech::EchState;
20use crate::client::{ClientConfig, EchMode, EchStatus, tls13};
21use crate::common_state::{CommonState, HandshakeKind, KxState, State};
22use crate::conn::ConnectionRandoms;
23use crate::crypto::{ActiveKeyExchange, KeyExchangeAlgorithm};
24use crate::enums::{AlertDescription, CipherSuite, ContentType, HandshakeType, ProtocolVersion};
25use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
26use crate::hash_hs::HandshakeHashBuffer;
27use crate::log::{debug, trace};
28use crate::msgs::base::Payload;
29use crate::msgs::enums::{
30 CertificateType, Compression, ECPointFormat, ExtensionType, PskKeyExchangeMode,
31};
32use crate::msgs::handshake::ProtocolName;
33use crate::msgs::handshake::SupportedProtocolVersions;
34use crate::msgs::handshake::{
35 CertificateStatusRequest, ClientExtension, ClientHelloPayload, ClientSessionTicket,
36 HandshakeMessagePayload, HandshakePayload, HasServerExtensions, HelloRetryRequest,
37 KeyShareEntry, Random, SessionId,
38};
39use crate::msgs::message::{Message, MessagePayload};
40use crate::msgs::persist;
41use crate::sync::Arc;
42use crate::tls13::key_schedule::KeyScheduleEarly;
43use crate::verify::ServerCertVerifier;
44
45pub(super) type NextState<'a> = Box<dyn State<ClientConnectionData> + 'a>;
46pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
47pub(super) type ClientContext<'a> = crate::common_state::Context<'a, ClientConnectionData>;
48
49fn find_session(
50 server_name: &ServerName<'static>,
51 config: &ClientConfig,
52 cx: &mut ClientContext<'_>,
53) -> Option<persist::Retrieved<ClientSessionValue>> {
54 let found = config
55 .resumption
56 .store
57 .take_tls13_ticket(server_name)
58 .map(ClientSessionValue::Tls13)
59 .or_else(|| {
60 #[cfg(feature = "tls12")]
61 {
62 config
63 .resumption
64 .store
65 .tls12_session(server_name)
66 .map(ClientSessionValue::Tls12)
67 }
68
69 #[cfg(not(feature = "tls12"))]
70 None
71 })
72 .and_then(|resuming| {
73 resuming.compatible_config(&config.verifier, &config.client_auth_cert_resolver)
74 })
75 .and_then(|resuming| {
76 let now = config
77 .current_time()
78 .map_err(|_err| debug!("Could not get current time: {_err}"))
79 .ok()?;
80
81 let retrieved = persist::Retrieved::new(resuming, now);
82 match retrieved.has_expired() {
83 false => Some(retrieved),
84 true => None,
85 }
86 })
87 .or_else(|| {
88 debug!("No cached session for {:?}", server_name);
89 None
90 });
91
92 if let Some(resuming) = &found {
93 if cx.common.is_quic() {
94 cx.common.quic.params = resuming
95 .tls13()
96 .map(|v| v.quic_params());
97 }
98 }
99
100 found
101}
102
103pub(super) fn start_handshake(
104 server_name: ServerName<'static>,
105 alpn_protocols: Vec<Vec<u8>>,
106 extra_exts: Vec<ClientExtension>,
107 config: Arc<ClientConfig>,
108 cx: &mut ClientContext<'_>,
109) -> NextStateOrError<'static> {
110 let mut transcript_buffer = HandshakeHashBuffer::new();
111 if config
112 .client_auth_cert_resolver
113 .has_certs()
114 {
115 transcript_buffer.set_client_auth_enabled();
116 }
117
118 let mut resuming = find_session(&server_name, &config, cx);
119
120 let key_share = if config.supports_version(ProtocolVersion::TLSv1_3) {
121 Some(tls13::initial_key_share(
122 &config,
123 &server_name,
124 &mut cx.common.kx_state,
125 )?)
126 } else {
127 None
128 };
129
130 let session_id = match &mut resuming {
131 Some(_resuming) => {
132 debug!("Resuming session");
133 match &mut _resuming.value {
134 #[cfg(feature = "tls12")]
135 ClientSessionValue::Tls12(inner) => {
136 if !inner.ticket().0.is_empty() {
140 inner.session_id = SessionId::random(config.provider.secure_random)?;
141 }
142 Some(inner.session_id)
143 }
144 _ => None,
145 }
146 }
147 _ => {
148 debug!("Not resuming any session");
149 None
150 }
151 };
152
153 let session_id = match session_id {
156 Some(session_id) => session_id,
157 None if cx.common.is_quic() => SessionId::empty(),
158 None if !config.supports_version(ProtocolVersion::TLSv1_3) => SessionId::empty(),
159 None => SessionId::random(config.provider.secure_random)?,
160 };
161
162 let random = Random::new(config.provider.secure_random)?;
163 let extension_order_seed = crate::rand::random_u16(config.provider.secure_random)?;
164
165 let ech_state = match config.ech_mode.as_ref() {
166 Some(EchMode::Enable(ech_config)) => Some(EchState::new(
167 ech_config,
168 server_name.clone(),
169 config
170 .client_auth_cert_resolver
171 .has_certs(),
172 config.provider.secure_random,
173 config.enable_sni,
174 )?),
175 _ => None,
176 };
177
178 emit_client_hello_for_retry(
179 transcript_buffer,
180 None,
181 key_share,
182 extra_exts,
183 None,
184 ClientHelloInput {
185 config,
186 resuming,
187 random,
188 #[cfg(feature = "tls12")]
189 using_ems: false,
190 sent_tls13_fake_ccs: false,
191 hello: ClientHelloDetails::new(alpn_protocols, extension_order_seed),
192 session_id,
193 server_name,
194 prev_ech_ext: None,
195 },
196 cx,
197 ech_state,
198 )
199}
200
201struct ExpectServerHello {
202 input: ClientHelloInput,
203 transcript_buffer: HandshakeHashBuffer,
204 early_data_key_schedule: Option<KeyScheduleEarly>,
212 offered_key_share: Option<Box<dyn ActiveKeyExchange>>,
213 suite: Option<SupportedCipherSuite>,
214 ech_state: Option<EchState>,
215}
216
217struct ExpectServerHelloOrHelloRetryRequest {
218 next: ExpectServerHello,
219 extra_exts: Vec<ClientExtension>,
220}
221
222struct ClientHelloInput {
223 config: Arc<ClientConfig>,
224 resuming: Option<persist::Retrieved<ClientSessionValue>>,
225 random: Random,
226 #[cfg(feature = "tls12")]
227 using_ems: bool,
228 sent_tls13_fake_ccs: bool,
229 hello: ClientHelloDetails,
230 session_id: SessionId,
231 server_name: ServerName<'static>,
232 prev_ech_ext: Option<ClientExtension>,
233}
234
235fn emit_client_hello_for_retry(
241 mut transcript_buffer: HandshakeHashBuffer,
242 retryreq: Option<&HelloRetryRequest>,
243 key_share: Option<Box<dyn ActiveKeyExchange>>,
244 extra_exts: Vec<ClientExtension>,
245 suite: Option<SupportedCipherSuite>,
246 mut input: ClientHelloInput,
247 cx: &mut ClientContext<'_>,
248 mut ech_state: Option<EchState>,
249) -> NextStateOrError<'static> {
250 let config = &input.config;
251 let forbids_tls12 = cx.common.is_quic() || ech_state.is_some();
254
255 let supported_versions = SupportedProtocolVersions {
256 tls12: config.supports_version(ProtocolVersion::TLSv1_2) && !forbids_tls12,
257 tls13: config.supports_version(ProtocolVersion::TLSv1_3),
258 };
259
260 assert!(supported_versions.any(|_| true));
262
263 let offered_groups = config
265 .provider
266 .kx_groups
267 .iter()
268 .filter(|skxg| supported_versions.any(|v| skxg.usable_for_version(v)))
269 .map(|skxg| skxg.name())
270 .collect();
271
272 let mut exts = vec![
273 ClientExtension::SupportedVersions(supported_versions),
274 ClientExtension::NamedGroups(offered_groups),
275 ClientExtension::SignatureAlgorithms(
276 config
277 .verifier
278 .supported_verify_schemes(),
279 ),
280 ClientExtension::ExtendedMasterSecretRequest,
281 ClientExtension::CertificateStatusRequest(CertificateStatusRequest::build_ocsp()),
282 ];
283
284 if supported_versions.tls13 {
285 if let Some(cas_extension) = config.verifier.root_hint_subjects() {
286 exts.push(ClientExtension::AuthorityNames(cas_extension.to_owned()));
287 }
288 }
289
290 if config
292 .provider
293 .kx_groups
294 .iter()
295 .any(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::ECDHE)
296 {
297 exts.push(ClientExtension::EcPointFormats(
298 ECPointFormat::SUPPORTED.to_vec(),
299 ));
300 }
301
302 match (ech_state.as_ref(), config.enable_sni) {
303 (Some(ech_state), _) => {
308 exts.push(ClientExtension::ServerName((&ech_state.outer_name).into()))
309 }
310
311 (None, true) => {
314 if let ServerName::DnsName(dns_name) = &input.server_name {
315 exts.push(ClientExtension::ServerName(dns_name.into()));
316 }
317 }
318
319 (None, false) => {}
321 };
322
323 if let Some(key_share) = &key_share {
324 debug_assert!(supported_versions.tls13);
325 let mut shares = vec![KeyShareEntry::new(key_share.group(), key_share.pub_key())];
326
327 if !retryreq
328 .map(|rr| rr.requested_key_share_group().is_some())
329 .unwrap_or_default()
330 {
331 if let Some((component_group, component_share)) =
336 key_share
337 .hybrid_component()
338 .filter(|(group, _)| {
339 config
340 .find_kx_group(*group, ProtocolVersion::TLSv1_3)
341 .is_some()
342 })
343 {
344 shares.push(KeyShareEntry::new(component_group, component_share));
345 }
346 }
347
348 exts.push(ClientExtension::KeyShare(shares));
349 }
350
351 if let Some(cookie) = retryreq.and_then(HelloRetryRequest::cookie) {
352 exts.push(ClientExtension::Cookie(cookie.clone()));
353 }
354
355 if supported_versions.tls13 {
356 let psk_modes = vec![PskKeyExchangeMode::PSK_DHE_KE];
359 exts.push(ClientExtension::PresharedKeyModes(psk_modes));
360 }
361
362 if !input.hello.alpn_protocols.is_empty() {
364 exts.push(ClientExtension::Protocols(
365 input
366 .hello
367 .alpn_protocols
368 .iter()
369 .map(|proto| ProtocolName::from(proto.clone()))
370 .collect::<Vec<_>>(),
371 ));
372 }
373
374 input.hello.offered_cert_compression =
375 if supported_versions.tls13 && !config.cert_decompressors.is_empty() {
376 exts.push(ClientExtension::CertificateCompressionAlgorithms(
377 config
378 .cert_decompressors
379 .iter()
380 .map(|dec| dec.algorithm())
381 .collect(),
382 ));
383 true
384 } else {
385 false
386 };
387
388 if config
389 .client_auth_cert_resolver
390 .only_raw_public_keys()
391 {
392 exts.push(ClientExtension::ClientCertTypes(vec![
393 CertificateType::RawPublicKey,
394 ]));
395 }
396
397 if config
398 .verifier
399 .requires_raw_public_keys()
400 {
401 exts.push(ClientExtension::ServerCertTypes(vec![
402 CertificateType::RawPublicKey,
403 ]));
404 }
405
406 exts.extend(extra_exts.iter().cloned());
408
409 if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
413 if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
414 exts.push(prev_ech_ext);
415 }
416 }
417
418 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
420
421 exts.sort_by_cached_key(|new_ext| {
424 match (&cx.data.ech_status, new_ext) {
425 (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
427 (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
429 (_, ClientExtension::PresharedKey(..)) => return u32::MAX - 1,
431 _ => {}
432 };
433
434 let seed = ((input.hello.extension_order_seed as u32) << 16)
435 | (u16::from(new_ext.ext_type()) as u32);
436 match low_quality_integer_hash(seed) {
437 u32::MAX => 0,
438 key => key,
439 }
440 });
441
442 let mut cipher_suites: Vec<_> = config
443 .provider
444 .cipher_suites
445 .iter()
446 .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
447 true => Some(cs.suite()),
448 false => None,
449 })
450 .collect();
451 cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
453
454 let mut chp_payload = ClientHelloPayload {
455 client_version: ProtocolVersion::TLSv1_2,
456 random: input.random,
457 session_id: input.session_id,
458 cipher_suites,
459 compression_methods: vec![Compression::Null],
460 extensions: exts,
461 };
462
463 let ech_grease_ext = config
464 .ech_mode
465 .as_ref()
466 .and_then(|mode| match mode {
467 EchMode::Grease(cfg) => Some(cfg.grease_ext(
468 config.provider.secure_random,
469 input.server_name.clone(),
470 &chp_payload,
471 )),
472 _ => None,
473 });
474
475 match (cx.data.ech_status, &mut ech_state) {
476 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
479 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
481 cx.data.ech_status = EchStatus::Offered;
482 input.prev_ech_ext = chp_payload.extensions.last().cloned();
484 }
485 (EchStatus::NotOffered, None) => {
488 if let Some(grease_ext) = ech_grease_ext {
489 let grease_ext = grease_ext?;
491 chp_payload
492 .extensions
493 .push(grease_ext.clone());
494 cx.data.ech_status = EchStatus::Grease;
495 input.prev_ech_ext = Some(grease_ext);
498 }
499 }
500 _ => {}
501 }
502
503 input.hello.sent_extensions = chp_payload
505 .extensions
506 .iter()
507 .map(ClientExtension::ext_type)
508 .collect();
509
510 let mut chp = HandshakeMessagePayload {
511 typ: HandshakeType::ClientHello,
512 payload: HandshakePayload::ClientHello(chp_payload),
513 };
514
515 let tls13_early_data_key_schedule = match (ech_state.as_mut(), tls13_session) {
516 (Some(ech_state), Some(tls13_session)) => ech_state
519 .early_data_key_schedule
520 .take()
521 .map(|schedule| (tls13_session.suite(), schedule)),
522
523 (_, Some(tls13_session)) => Some((
526 tls13_session.suite(),
527 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
528 )),
529
530 _ => None,
532 };
533
534 let ch = Message {
535 version: match retryreq {
536 Some(_) => ProtocolVersion::TLSv1_2,
540 None => ProtocolVersion::TLSv1_0,
546 },
547 payload: MessagePayload::handshake(chp),
548 };
549
550 if retryreq.is_some() {
551 tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
554 }
555
556 trace!("Sending ClientHello {:#?}", ch);
557
558 transcript_buffer.add_message(&ch);
559 cx.common.send_msg(ch, false);
560
561 let early_data_key_schedule =
563 tls13_early_data_key_schedule.map(|(resuming_suite, schedule)| {
564 if !cx.data.early_data.is_enabled() {
565 return schedule;
566 }
567
568 let (transcript_buffer, random) = match &ech_state {
569 Some(ech_state) => (
572 &ech_state.inner_hello_transcript,
573 &ech_state.inner_hello_random.0,
574 ),
575 None => (&transcript_buffer, &input.random.0),
576 };
577
578 tls13::derive_early_traffic_secret(
579 &*config.key_log,
580 cx,
581 resuming_suite,
582 &schedule,
583 &mut input.sent_tls13_fake_ccs,
584 transcript_buffer,
585 random,
586 );
587 schedule
588 });
589
590 let next = ExpectServerHello {
591 input,
592 transcript_buffer,
593 early_data_key_schedule,
594 offered_key_share: key_share,
595 suite,
596 ech_state,
597 };
598
599 Ok(if supported_versions.tls13 && retryreq.is_none() {
600 Box::new(ExpectServerHelloOrHelloRetryRequest { next, extra_exts })
601 } else {
602 Box::new(next)
603 })
604}
605
606fn prepare_resumption<'a>(
622 resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
623 exts: &mut Vec<ClientExtension>,
624 suite: Option<SupportedCipherSuite>,
625 cx: &mut ClientContext<'_>,
626 config: &ClientConfig,
627) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
628 let resuming = match resuming {
630 Some(resuming) if !resuming.ticket().is_empty() => resuming,
631 _ => {
632 if config.supports_version(ProtocolVersion::TLSv1_2)
633 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
634 {
635 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
637 }
638 return None;
639 }
640 };
641
642 let Some(tls13) = resuming.map(|csv| csv.tls13()) else {
643 if config.supports_version(ProtocolVersion::TLSv1_2)
645 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
646 {
647 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Offer(
648 Payload::new(resuming.ticket()),
649 )));
650 }
651 return None; };
653
654 if !config.supports_version(ProtocolVersion::TLSv1_3) {
655 return None;
656 }
657
658 let suite = match suite {
660 Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
661 #[cfg(feature = "tls12")]
662 Some(SupportedCipherSuite::Tls12(_)) => return None,
663 None => None,
664 };
665
666 if let Some(suite) = suite {
668 suite.can_resume_from(tls13.suite())?;
669 }
670
671 tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
672 Some(tls13)
673}
674
675pub(super) fn process_alpn_protocol(
676 common: &mut CommonState,
677 offered_protocols: &[Vec<u8>],
678 proto: Option<&[u8]>,
679) -> Result<(), Error> {
680 common.alpn_protocol = proto.map(ToOwned::to_owned);
681
682 if let Some(alpn_protocol) = &common.alpn_protocol {
683 if !offered_protocols.contains(alpn_protocol) {
684 return Err(common.send_fatal_alert(
685 AlertDescription::IllegalParameter,
686 PeerMisbehaved::SelectedUnofferedApplicationProtocol,
687 ));
688 }
689 }
690
691 if common.is_quic() && common.alpn_protocol.is_none() && !offered_protocols.is_empty() {
698 return Err(common.send_fatal_alert(
699 AlertDescription::NoApplicationProtocol,
700 Error::NoApplicationProtocol,
701 ));
702 }
703
704 debug!(
705 "ALPN protocol is {:?}",
706 common
707 .alpn_protocol
708 .as_ref()
709 .map(|v| bs_debug::BsDebug(v))
710 );
711 Ok(())
712}
713
714pub(super) fn process_server_cert_type_extension(
715 common: &mut CommonState,
716 config: &ClientConfig,
717 server_cert_extension: Option<&CertificateType>,
718) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
719 process_cert_type_extension(
720 common,
721 config
722 .verifier
723 .requires_raw_public_keys(),
724 server_cert_extension.copied(),
725 ExtensionType::ServerCertificateType,
726 )
727}
728
729pub(super) fn process_client_cert_type_extension(
730 common: &mut CommonState,
731 config: &ClientConfig,
732 client_cert_extension: Option<&CertificateType>,
733) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
734 process_cert_type_extension(
735 common,
736 config
737 .client_auth_cert_resolver
738 .only_raw_public_keys(),
739 client_cert_extension.copied(),
740 ExtensionType::ClientCertificateType,
741 )
742}
743
744impl State<ClientConnectionData> for ExpectServerHello {
745 fn handle<'m>(
746 mut self: Box<Self>,
747 cx: &mut ClientContext<'_>,
748 m: Message<'m>,
749 ) -> NextStateOrError<'m>
750 where
751 Self: 'm,
752 {
753 let server_hello =
754 require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
755 trace!("We got ServerHello {:#?}", server_hello);
756
757 use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
758 let config = &self.input.config;
759 let tls13_supported = config.supports_version(TLSv1_3);
760
761 let server_version = if server_hello.legacy_version == TLSv1_2 {
762 server_hello
763 .supported_versions()
764 .unwrap_or(server_hello.legacy_version)
765 } else {
766 server_hello.legacy_version
767 };
768
769 let version = match server_version {
770 TLSv1_3 if tls13_supported => TLSv1_3,
771 TLSv1_2 if config.supports_version(TLSv1_2) => {
772 if cx.data.early_data.is_enabled() && cx.common.early_traffic {
773 return Err(PeerMisbehaved::OfferedEarlyDataWithOldProtocolVersion.into());
776 }
777
778 if server_hello
779 .supported_versions()
780 .is_some()
781 {
782 return Err({
783 cx.common.send_fatal_alert(
784 AlertDescription::IllegalParameter,
785 PeerMisbehaved::SelectedTls12UsingTls13VersionExtension,
786 )
787 });
788 }
789
790 TLSv1_2
791 }
792 _ => {
793 let reason = match server_version {
794 TLSv1_2 | TLSv1_3 => PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig,
795 _ => PeerIncompatible::ServerDoesNotSupportTls12Or13,
796 };
797 return Err(cx
798 .common
799 .send_fatal_alert(AlertDescription::ProtocolVersion, reason));
800 }
801 };
802
803 if server_hello.compression_method != Compression::Null {
804 return Err({
805 cx.common.send_fatal_alert(
806 AlertDescription::IllegalParameter,
807 PeerMisbehaved::SelectedUnofferedCompression,
808 )
809 });
810 }
811
812 if server_hello.has_duplicate_extension() {
813 return Err(cx.common.send_fatal_alert(
814 AlertDescription::DecodeError,
815 PeerMisbehaved::DuplicateServerHelloExtensions,
816 ));
817 }
818
819 let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
820 if self
821 .input
822 .hello
823 .server_sent_unsolicited_extensions(&server_hello.extensions, &allowed_unsolicited)
824 {
825 return Err(cx.common.send_fatal_alert(
826 AlertDescription::UnsupportedExtension,
827 PeerMisbehaved::UnsolicitedServerHelloExtension,
828 ));
829 }
830
831 cx.common.negotiated_version = Some(version);
832
833 if !cx.common.is_tls13() {
835 process_alpn_protocol(
836 cx.common,
837 &self.input.hello.alpn_protocols,
838 server_hello.alpn_protocol(),
839 )?;
840 }
841
842 if let Some(point_fmts) = server_hello.ecpoints_extension() {
845 if !point_fmts.contains(&ECPointFormat::Uncompressed) {
846 return Err(cx.common.send_fatal_alert(
847 AlertDescription::HandshakeFailure,
848 PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
849 ));
850 }
851 }
852
853 let suite = config
854 .find_cipher_suite(server_hello.cipher_suite)
855 .ok_or_else(|| {
856 cx.common.send_fatal_alert(
857 AlertDescription::HandshakeFailure,
858 PeerMisbehaved::SelectedUnofferedCipherSuite,
859 )
860 })?;
861
862 if version != suite.version().version {
863 return Err({
864 cx.common.send_fatal_alert(
865 AlertDescription::IllegalParameter,
866 PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
867 )
868 });
869 }
870
871 match self.suite {
872 Some(prev_suite) if prev_suite != suite => {
873 return Err({
874 cx.common.send_fatal_alert(
875 AlertDescription::IllegalParameter,
876 PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
877 )
878 });
879 }
880 _ => {
881 debug!("Using ciphersuite {:?}", suite);
882 self.suite = Some(suite);
883 cx.common.suite = Some(suite);
884 }
885 }
886
887 let mut transcript = self
889 .transcript_buffer
890 .start_hash(suite.hash_provider());
891 transcript.add_message(&m);
892
893 let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
894 match suite {
897 SupportedCipherSuite::Tls13(suite) => {
898 #[allow(clippy::bind_instead_of_map)]
899 let resuming_session = self
900 .input
901 .resuming
902 .and_then(|resuming| match resuming.value {
903 ClientSessionValue::Tls13(inner) => Some(inner),
904 #[cfg(feature = "tls12")]
905 ClientSessionValue::Tls12(_) => None,
906 });
907
908 tls13::handle_server_hello(
909 self.input.config,
910 cx,
911 server_hello,
912 resuming_session,
913 self.input.server_name,
914 randoms,
915 suite,
916 transcript,
917 self.early_data_key_schedule,
918 self.input.hello,
919 self.offered_key_share.unwrap(),
921 self.input.sent_tls13_fake_ccs,
922 &m,
923 self.ech_state,
924 )
925 }
926 #[cfg(feature = "tls12")]
927 SupportedCipherSuite::Tls12(suite) => {
928 if self.input.resuming.is_none()
934 && !self.input.session_id.is_empty()
935 && self.input.session_id == server_hello.session_id
936 {
937 return Err({
938 cx.common.send_fatal_alert(
939 AlertDescription::IllegalParameter,
940 PeerMisbehaved::ServerEchoedCompatibilitySessionId,
941 )
942 });
943 }
944
945 let resuming_session = self
946 .input
947 .resuming
948 .and_then(|resuming| match resuming.value {
949 ClientSessionValue::Tls12(inner) => Some(inner),
950 ClientSessionValue::Tls13(_) => None,
951 });
952
953 tls12::CompleteServerHelloHandling {
954 config: self.input.config,
955 resuming_session,
956 server_name: self.input.server_name,
957 randoms,
958 using_ems: self.input.using_ems,
959 transcript,
960 }
961 .handle_server_hello(cx, suite, server_hello, tls13_supported)
962 }
963 }
964 }
965
966 fn into_owned(self: Box<Self>) -> NextState<'static> {
967 self
968 }
969}
970
971impl ExpectServerHelloOrHelloRetryRequest {
972 fn into_expect_server_hello(self) -> NextState<'static> {
973 Box::new(self.next)
974 }
975
976 fn handle_hello_retry_request(
977 mut self,
978 cx: &mut ClientContext<'_>,
979 m: Message<'_>,
980 ) -> NextStateOrError<'static> {
981 let hrr = require_handshake_msg!(
982 m,
983 HandshakeType::HelloRetryRequest,
984 HandshakePayload::HelloRetryRequest
985 )?;
986 trace!("Got HRR {:?}", hrr);
987
988 cx.common.check_aligned_handshake()?;
989
990 let cookie = hrr.cookie();
991 let req_group = hrr.requested_key_share_group();
992
993 let offered_key_share = self.next.offered_key_share.unwrap();
995
996 let config = &self.next.input.config;
999
1000 if let (None, Some(req_group)) = (cookie, req_group) {
1001 let offered_hybrid = offered_key_share
1002 .hybrid_component()
1003 .and_then(|(group_name, _)| {
1004 config.find_kx_group(group_name, ProtocolVersion::TLSv1_3)
1005 })
1006 .map(|skxg| skxg.name());
1007
1008 if req_group == offered_key_share.group() || Some(req_group) == offered_hybrid {
1009 return Err({
1010 cx.common.send_fatal_alert(
1011 AlertDescription::IllegalParameter,
1012 PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
1013 )
1014 });
1015 }
1016 }
1017
1018 if let Some(cookie) = cookie {
1020 if cookie.0.is_empty() {
1021 return Err({
1022 cx.common.send_fatal_alert(
1023 AlertDescription::IllegalParameter,
1024 PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
1025 )
1026 });
1027 }
1028 }
1029
1030 if hrr.has_unknown_extension() {
1032 return Err(cx.common.send_fatal_alert(
1033 AlertDescription::UnsupportedExtension,
1034 PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
1035 ));
1036 }
1037
1038 if hrr.has_duplicate_extension() {
1040 return Err({
1041 cx.common.send_fatal_alert(
1042 AlertDescription::IllegalParameter,
1043 PeerMisbehaved::DuplicateHelloRetryRequestExtensions,
1044 )
1045 });
1046 }
1047
1048 if cookie.is_none() && req_group.is_none() {
1050 return Err({
1051 cx.common.send_fatal_alert(
1052 AlertDescription::IllegalParameter,
1053 PeerMisbehaved::IllegalHelloRetryRequestWithNoChanges,
1054 )
1055 });
1056 }
1057
1058 if hrr.session_id != self.next.input.session_id {
1072 return Err({
1073 cx.common.send_fatal_alert(
1074 AlertDescription::IllegalParameter,
1075 PeerMisbehaved::IllegalHelloRetryRequestWithWrongSessionId,
1076 )
1077 });
1078 }
1079
1080 match hrr.supported_versions() {
1082 Some(ProtocolVersion::TLSv1_3) => {
1083 cx.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
1084 }
1085 _ => {
1086 return Err({
1087 cx.common.send_fatal_alert(
1088 AlertDescription::IllegalParameter,
1089 PeerMisbehaved::IllegalHelloRetryRequestWithUnsupportedVersion,
1090 )
1091 });
1092 }
1093 }
1094
1095 let Some(cs) = config.find_cipher_suite(hrr.cipher_suite) else {
1097 return Err({
1098 cx.common.send_fatal_alert(
1099 AlertDescription::IllegalParameter,
1100 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
1101 )
1102 });
1103 };
1104
1105 if cx.data.ech_status == EchStatus::NotOffered && hrr.ech().is_some() {
1107 return Err({
1108 cx.common.send_fatal_alert(
1109 AlertDescription::UnsupportedExtension,
1110 PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
1111 )
1112 });
1113 }
1114
1115 cx.common.suite = Some(cs);
1117 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
1118
1119 match (self.next.ech_state.as_ref(), cs.tls13()) {
1121 (Some(ech_state), Some(tls13_cs)) => {
1122 if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? {
1123 cx.data.ech_status = EchStatus::Rejected;
1127 }
1128 }
1129 (Some(_), None) => {
1130 unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1131 }
1132 _ => {}
1133 };
1134
1135 let transcript = self
1137 .next
1138 .transcript_buffer
1139 .start_hash(cs.hash_provider());
1140 let mut transcript_buffer = transcript.into_hrr_buffer();
1141 transcript_buffer.add_message(&m);
1142
1143 if let Some(ech_state) = self.next.ech_state.as_mut() {
1146 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1147 }
1148
1149 if cx.data.early_data.is_enabled() {
1151 cx.data.early_data.rejected();
1152 }
1153
1154 let key_share = match req_group {
1155 Some(group) if group != offered_key_share.group() => {
1156 let Some(skxg) = config.find_kx_group(group, ProtocolVersion::TLSv1_3) else {
1157 return Err(cx.common.send_fatal_alert(
1158 AlertDescription::IllegalParameter,
1159 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1160 ));
1161 };
1162
1163 cx.common.kx_state = KxState::Start(skxg);
1164 skxg.start()?
1165 }
1166 _ => offered_key_share,
1167 };
1168
1169 emit_client_hello_for_retry(
1170 transcript_buffer,
1171 Some(hrr),
1172 Some(key_share),
1173 self.extra_exts,
1174 Some(cs),
1175 self.next.input,
1176 cx,
1177 self.next.ech_state,
1178 )
1179 }
1180}
1181
1182impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1183 fn handle<'m>(
1184 self: Box<Self>,
1185 cx: &mut ClientContext<'_>,
1186 m: Message<'m>,
1187 ) -> NextStateOrError<'m>
1188 where
1189 Self: 'm,
1190 {
1191 match m.payload {
1192 MessagePayload::Handshake {
1193 parsed:
1194 HandshakeMessagePayload {
1195 payload: HandshakePayload::ServerHello(..),
1196 ..
1197 },
1198 ..
1199 } => self
1200 .into_expect_server_hello()
1201 .handle(cx, m),
1202 MessagePayload::Handshake {
1203 parsed:
1204 HandshakeMessagePayload {
1205 payload: HandshakePayload::HelloRetryRequest(..),
1206 ..
1207 },
1208 ..
1209 } => self.handle_hello_retry_request(cx, m),
1210 payload => Err(inappropriate_handshake_message(
1211 &payload,
1212 &[ContentType::Handshake],
1213 &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1214 )),
1215 }
1216 }
1217
1218 fn into_owned(self: Box<Self>) -> NextState<'static> {
1219 self
1220 }
1221}
1222
1223fn process_cert_type_extension(
1224 common: &mut CommonState,
1225 client_expects: bool,
1226 server_negotiated: Option<CertificateType>,
1227 extension_type: ExtensionType,
1228) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
1229 match (client_expects, server_negotiated) {
1230 (true, Some(CertificateType::RawPublicKey)) => {
1231 Ok(Some((extension_type, CertificateType::RawPublicKey)))
1232 }
1233 (true, _) => Err(common.send_fatal_alert(
1234 AlertDescription::HandshakeFailure,
1235 Error::PeerIncompatible(PeerIncompatible::IncorrectCertificateTypeExtension),
1236 )),
1237 (_, Some(CertificateType::RawPublicKey)) => {
1238 unreachable!("Caught by `PeerMisbehaved::UnsolicitedEncryptedExtension`")
1239 }
1240 (_, _) => Ok(None),
1241 }
1242}
1243
1244enum ClientSessionValue {
1245 Tls13(persist::Tls13ClientSessionValue),
1246 #[cfg(feature = "tls12")]
1247 Tls12(persist::Tls12ClientSessionValue),
1248}
1249
1250impl ClientSessionValue {
1251 fn common(&self) -> &persist::ClientSessionCommon {
1252 match self {
1253 Self::Tls13(inner) => &inner.common,
1254 #[cfg(feature = "tls12")]
1255 Self::Tls12(inner) => &inner.common,
1256 }
1257 }
1258
1259 fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1260 match self {
1261 Self::Tls13(v) => Some(v),
1262 #[cfg(feature = "tls12")]
1263 Self::Tls12(_) => None,
1264 }
1265 }
1266
1267 fn compatible_config(
1268 self,
1269 server_cert_verifier: &Arc<dyn ServerCertVerifier>,
1270 client_creds: &Arc<dyn ResolvesClientCert>,
1271 ) -> Option<Self> {
1272 match &self {
1273 Self::Tls13(v) => v
1274 .compatible_config(server_cert_verifier, client_creds)
1275 .then_some(self),
1276 #[cfg(feature = "tls12")]
1277 Self::Tls12(v) => v
1278 .compatible_config(server_cert_verifier, client_creds)
1279 .then_some(self),
1280 }
1281 }
1282}
1283
1284impl Deref for ClientSessionValue {
1285 type Target = persist::ClientSessionCommon;
1286
1287 fn deref(&self) -> &Self::Target {
1288 self.common()
1289 }
1290}
1291
1292fn low_quality_integer_hash(mut x: u32) -> u32 {
1293 x = x
1294 .wrapping_add(0x7ed55d16)
1295 .wrapping_add(x << 12);
1296 x = (x ^ 0xc761c23c) ^ (x >> 19);
1297 x = x
1298 .wrapping_add(0x165667b1)
1299 .wrapping_add(x << 5);
1300 x = x.wrapping_add(0xd3a2646c) ^ (x << 9);
1301 x = x
1302 .wrapping_add(0xfd7046c5)
1303 .wrapping_add(x << 3);
1304 x = (x ^ 0xb55a4f09) ^ (x >> 16);
1305 x
1306}