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 key_share = KeyShareEntry::new(key_share.group(), key_share.pub_key());
308 exts.push(ClientExtension::KeyShare(vec![key_share]));
309 }
310
311 if let Some(cookie) = retryreq.and_then(HelloRetryRequest::cookie) {
312 exts.push(ClientExtension::Cookie(cookie.clone()));
313 }
314
315 if support_tls13 {
316 let psk_modes = vec![PSKKeyExchangeMode::PSK_DHE_KE];
319 exts.push(ClientExtension::PresharedKeyModes(psk_modes));
320 }
321
322 if !config.alpn_protocols.is_empty() {
323 exts.push(ClientExtension::Protocols(Vec::from_slices(
324 &config
325 .alpn_protocols
326 .iter()
327 .map(|proto| &proto[..])
328 .collect::<Vec<_>>(),
329 )));
330 }
331
332 input.hello.offered_cert_compression = if support_tls13 && !config.cert_decompressors.is_empty()
333 {
334 exts.push(ClientExtension::CertificateCompressionAlgorithms(
335 config
336 .cert_decompressors
337 .iter()
338 .map(|dec| dec.algorithm())
339 .collect(),
340 ));
341 true
342 } else {
343 false
344 };
345
346 if config
347 .client_auth_cert_resolver
348 .only_raw_public_keys()
349 {
350 exts.push(ClientExtension::ClientCertTypes(vec![
351 CertificateType::RawPublicKey,
352 ]));
353 }
354
355 if config
356 .verifier
357 .requires_raw_public_keys()
358 {
359 exts.push(ClientExtension::ServerCertTypes(vec![
360 CertificateType::RawPublicKey,
361 ]));
362 }
363
364 exts.extend(extra_exts.iter().cloned());
366
367 if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
371 if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
372 exts.push(prev_ech_ext);
373 }
374 }
375
376 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
378
379 exts.sort_by_cached_key(|new_ext| {
382 match (&cx.data.ech_status, new_ext) {
383 (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
385 (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
387 (_, ClientExtension::PresharedKey(..)) => return u32::MAX - 1,
389 _ => {}
390 };
391
392 let seed = (input.hello.extension_order_seed as u32) << 16
393 | (u16::from(new_ext.ext_type()) as u32);
394 match low_quality_integer_hash(seed) {
395 u32::MAX => 0,
396 key => key,
397 }
398 });
399
400 let mut cipher_suites: Vec<_> = config
401 .provider
402 .cipher_suites
403 .iter()
404 .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
405 true => Some(cs.suite()),
406 false => None,
407 })
408 .collect();
409 cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
411
412 let mut chp_payload = ClientHelloPayload {
413 client_version: ProtocolVersion::TLSv1_2,
414 random: input.random,
415 session_id: input.session_id,
416 cipher_suites,
417 compression_methods: vec![Compression::Null],
418 extensions: exts,
419 };
420
421 let ech_grease_ext = config
422 .ech_mode
423 .as_ref()
424 .and_then(|mode| match mode {
425 EchMode::Grease(cfg) => Some(cfg.grease_ext(
426 config.provider.secure_random,
427 input.server_name.clone(),
428 &chp_payload,
429 )),
430 _ => None,
431 });
432
433 match (cx.data.ech_status, &mut ech_state) {
434 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
437 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
439 cx.data.ech_status = EchStatus::Offered;
440 input.prev_ech_ext = chp_payload.extensions.last().cloned();
442 }
443 (EchStatus::NotOffered, None) => {
446 if let Some(grease_ext) = ech_grease_ext {
447 let grease_ext = grease_ext?;
449 chp_payload
450 .extensions
451 .push(grease_ext.clone());
452 cx.data.ech_status = EchStatus::Grease;
453 input.prev_ech_ext = Some(grease_ext);
456 }
457 }
458 _ => {}
459 }
460
461 input.hello.sent_extensions = chp_payload
463 .extensions
464 .iter()
465 .map(ClientExtension::ext_type)
466 .collect();
467
468 let mut chp = HandshakeMessagePayload {
469 typ: HandshakeType::ClientHello,
470 payload: HandshakePayload::ClientHello(chp_payload),
471 };
472
473 let early_key_schedule = match (ech_state.as_mut(), tls13_session) {
474 (Some(ech_state), Some(tls13_session)) => ech_state
477 .early_data_key_schedule
478 .take()
479 .map(|schedule| (tls13_session.suite(), schedule)),
480
481 (_, Some(tls13_session)) => Some((
484 tls13_session.suite(),
485 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
486 )),
487
488 _ => None,
490 };
491
492 let ch = Message {
493 version: match retryreq {
494 Some(_) => ProtocolVersion::TLSv1_2,
498 None => ProtocolVersion::TLSv1_0,
504 },
505 payload: MessagePayload::handshake(chp),
506 };
507
508 if retryreq.is_some() {
509 tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
512 }
513
514 trace!("Sending ClientHello {:#?}", ch);
515
516 transcript_buffer.add_message(&ch);
517 cx.common.send_msg(ch, false);
518
519 let early_key_schedule = early_key_schedule.map(|(resuming_suite, schedule)| {
521 if !cx.data.early_data.is_enabled() {
522 return schedule;
523 }
524
525 let (transcript_buffer, random) = match &ech_state {
526 Some(ech_state) => (
529 &ech_state.inner_hello_transcript,
530 &ech_state.inner_hello_random.0,
531 ),
532 None => (&transcript_buffer, &input.random.0),
533 };
534
535 tls13::derive_early_traffic_secret(
536 &*config.key_log,
537 cx,
538 resuming_suite,
539 &schedule,
540 &mut input.sent_tls13_fake_ccs,
541 transcript_buffer,
542 random,
543 );
544 schedule
545 });
546
547 let next = ExpectServerHello {
548 input,
549 transcript_buffer,
550 early_key_schedule,
551 offered_key_share: key_share,
552 suite,
553 ech_state,
554 };
555
556 Ok(if support_tls13 && retryreq.is_none() {
557 Box::new(ExpectServerHelloOrHelloRetryRequest { next, extra_exts })
558 } else {
559 Box::new(next)
560 })
561}
562
563fn prepare_resumption<'a>(
577 resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
578 exts: &mut Vec<ClientExtension>,
579 suite: Option<SupportedCipherSuite>,
580 cx: &mut ClientContext<'_>,
581 config: &ClientConfig,
582) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
583 let resuming = match resuming {
585 Some(resuming) if !resuming.ticket().is_empty() => resuming,
586 _ => {
587 if config.supports_version(ProtocolVersion::TLSv1_3)
588 || config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
589 {
590 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
592 }
593 return None;
594 }
595 };
596
597 let tls13 = match resuming.map(|csv| csv.tls13()) {
598 Some(tls13) => tls13,
599 None => {
600 if config.supports_version(ProtocolVersion::TLSv1_2)
602 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
603 {
604 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Offer(
605 Payload::new(resuming.ticket()),
606 )));
607 }
608 return None; }
610 };
611
612 if !config.supports_version(ProtocolVersion::TLSv1_3) {
613 return None;
614 }
615
616 let suite = match suite {
618 Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
619 #[cfg(feature = "tls12")]
620 Some(SupportedCipherSuite::Tls12(_)) => return None,
621 None => None,
622 };
623
624 if let Some(suite) = suite {
626 suite.can_resume_from(tls13.suite())?;
627 }
628
629 tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
630 Some(tls13)
631}
632
633pub(super) fn process_alpn_protocol(
634 common: &mut CommonState,
635 config: &ClientConfig,
636 proto: Option<&[u8]>,
637) -> Result<(), Error> {
638 common.alpn_protocol = proto.map(ToOwned::to_owned);
639
640 if let Some(alpn_protocol) = &common.alpn_protocol {
641 if !config
642 .alpn_protocols
643 .contains(alpn_protocol)
644 {
645 return Err(common.send_fatal_alert(
646 AlertDescription::IllegalParameter,
647 PeerMisbehaved::SelectedUnofferedApplicationProtocol,
648 ));
649 }
650 }
651
652 if common.is_quic() && common.alpn_protocol.is_none() && !config.alpn_protocols.is_empty() {
659 return Err(common.send_fatal_alert(
660 AlertDescription::NoApplicationProtocol,
661 Error::NoApplicationProtocol,
662 ));
663 }
664
665 debug!(
666 "ALPN protocol is {:?}",
667 common
668 .alpn_protocol
669 .as_ref()
670 .map(|v| bs_debug::BsDebug(v))
671 );
672 Ok(())
673}
674
675pub(super) fn process_server_cert_type_extension(
676 common: &mut CommonState,
677 config: &ClientConfig,
678 server_cert_extension: Option<&CertificateType>,
679) -> Result<(), Error> {
680 let requires_server_rpk = config
681 .verifier
682 .requires_raw_public_keys();
683 let server_offers_rpk = matches!(server_cert_extension, Some(CertificateType::RawPublicKey));
684
685 let raw_key_negotation_params = RawKeyNegotiationParams {
686 peer_supports_raw_key: server_offers_rpk,
687 local_expects_raw_key: requires_server_rpk,
688 extension_type: ExtensionType::ServerCertificateType,
689 };
690 match raw_key_negotation_params.validate_raw_key_negotiation() {
691 RawKeyNegotationResult::Err(err) => {
692 Err(common.send_fatal_alert(AlertDescription::HandshakeFailure, err))
693 }
694 _ => Ok(()),
695 }
696}
697
698pub(super) fn process_client_cert_type_extension(
699 common: &mut CommonState,
700 config: &ClientConfig,
701 client_cert_extension: Option<&CertificateType>,
702) -> Result<(), Error> {
703 let requires_client_rpk = config
704 .client_auth_cert_resolver
705 .only_raw_public_keys();
706 let server_allows_rpk = matches!(client_cert_extension, Some(CertificateType::RawPublicKey));
707
708 let raw_key_negotation_params = RawKeyNegotiationParams {
709 peer_supports_raw_key: server_allows_rpk,
710 local_expects_raw_key: requires_client_rpk,
711 extension_type: ExtensionType::ClientCertificateType,
712 };
713 match raw_key_negotation_params.validate_raw_key_negotiation() {
714 RawKeyNegotationResult::Err(err) => {
715 Err(common.send_fatal_alert(AlertDescription::HandshakeFailure, err))
716 }
717 _ => Ok(()),
718 }
719}
720
721impl State<ClientConnectionData> for ExpectServerHello {
722 fn handle<'m>(
723 mut self: Box<Self>,
724 cx: &mut ClientContext<'_>,
725 m: Message<'m>,
726 ) -> NextStateOrError<'m>
727 where
728 Self: 'm,
729 {
730 let server_hello =
731 require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
732 trace!("We got ServerHello {:#?}", server_hello);
733
734 use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
735 let config = &self.input.config;
736 let tls13_supported = config.supports_version(TLSv1_3);
737
738 let server_version = if server_hello.legacy_version == TLSv1_2 {
739 server_hello
740 .supported_versions()
741 .unwrap_or(server_hello.legacy_version)
742 } else {
743 server_hello.legacy_version
744 };
745
746 let version = match server_version {
747 TLSv1_3 if tls13_supported => TLSv1_3,
748 TLSv1_2 if config.supports_version(TLSv1_2) => {
749 if cx.data.early_data.is_enabled() && cx.common.early_traffic {
750 return Err(PeerMisbehaved::OfferedEarlyDataWithOldProtocolVersion.into());
753 }
754
755 if server_hello
756 .supported_versions()
757 .is_some()
758 {
759 return Err({
760 cx.common.send_fatal_alert(
761 AlertDescription::IllegalParameter,
762 PeerMisbehaved::SelectedTls12UsingTls13VersionExtension,
763 )
764 });
765 }
766
767 TLSv1_2
768 }
769 _ => {
770 let reason = match server_version {
771 TLSv1_2 | TLSv1_3 => PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig,
772 _ => PeerIncompatible::ServerDoesNotSupportTls12Or13,
773 };
774 return Err(cx
775 .common
776 .send_fatal_alert(AlertDescription::ProtocolVersion, reason));
777 }
778 };
779
780 if server_hello.compression_method != Compression::Null {
781 return Err({
782 cx.common.send_fatal_alert(
783 AlertDescription::IllegalParameter,
784 PeerMisbehaved::SelectedUnofferedCompression,
785 )
786 });
787 }
788
789 if server_hello.has_duplicate_extension() {
790 return Err(cx.common.send_fatal_alert(
791 AlertDescription::DecodeError,
792 PeerMisbehaved::DuplicateServerHelloExtensions,
793 ));
794 }
795
796 let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
797 if self
798 .input
799 .hello
800 .server_sent_unsolicited_extensions(&server_hello.extensions, &allowed_unsolicited)
801 {
802 return Err(cx.common.send_fatal_alert(
803 AlertDescription::UnsupportedExtension,
804 PeerMisbehaved::UnsolicitedServerHelloExtension,
805 ));
806 }
807
808 cx.common.negotiated_version = Some(version);
809
810 if !cx.common.is_tls13() {
812 process_alpn_protocol(cx.common, config, server_hello.alpn_protocol())?;
813 }
814
815 if let Some(point_fmts) = server_hello.ecpoints_extension() {
818 if !point_fmts.contains(&ECPointFormat::Uncompressed) {
819 return Err(cx.common.send_fatal_alert(
820 AlertDescription::HandshakeFailure,
821 PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
822 ));
823 }
824 }
825
826 let suite = config
827 .find_cipher_suite(server_hello.cipher_suite)
828 .ok_or_else(|| {
829 cx.common.send_fatal_alert(
830 AlertDescription::HandshakeFailure,
831 PeerMisbehaved::SelectedUnofferedCipherSuite,
832 )
833 })?;
834
835 if version != suite.version().version {
836 return Err({
837 cx.common.send_fatal_alert(
838 AlertDescription::IllegalParameter,
839 PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
840 )
841 });
842 }
843
844 match self.suite {
845 Some(prev_suite) if prev_suite != suite => {
846 return Err({
847 cx.common.send_fatal_alert(
848 AlertDescription::IllegalParameter,
849 PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
850 )
851 });
852 }
853 _ => {
854 debug!("Using ciphersuite {:?}", suite);
855 self.suite = Some(suite);
856 cx.common.suite = Some(suite);
857 }
858 }
859
860 let mut transcript = self
862 .transcript_buffer
863 .start_hash(suite.hash_provider());
864 transcript.add_message(&m);
865
866 let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
867 match suite {
870 SupportedCipherSuite::Tls13(suite) => {
871 #[allow(clippy::bind_instead_of_map)]
872 let resuming_session = self
873 .input
874 .resuming
875 .and_then(|resuming| match resuming.value {
876 ClientSessionValue::Tls13(inner) => Some(inner),
877 #[cfg(feature = "tls12")]
878 ClientSessionValue::Tls12(_) => None,
879 });
880
881 tls13::handle_server_hello(
882 self.input.config,
883 cx,
884 server_hello,
885 resuming_session,
886 self.input.server_name,
887 randoms,
888 suite,
889 transcript,
890 self.early_key_schedule,
891 self.input.hello,
892 self.offered_key_share.unwrap(),
894 self.input.sent_tls13_fake_ccs,
895 &m,
896 self.ech_state,
897 )
898 }
899 #[cfg(feature = "tls12")]
900 SupportedCipherSuite::Tls12(suite) => {
901 let resuming_session = self
902 .input
903 .resuming
904 .and_then(|resuming| match resuming.value {
905 ClientSessionValue::Tls12(inner) => Some(inner),
906 ClientSessionValue::Tls13(_) => None,
907 });
908
909 tls12::CompleteServerHelloHandling {
910 config: self.input.config,
911 resuming_session,
912 server_name: self.input.server_name,
913 randoms,
914 using_ems: self.input.using_ems,
915 transcript,
916 }
917 .handle_server_hello(cx, suite, server_hello, tls13_supported)
918 }
919 }
920 }
921
922 fn into_owned(self: Box<Self>) -> NextState<'static> {
923 self
924 }
925}
926
927impl ExpectServerHelloOrHelloRetryRequest {
928 fn into_expect_server_hello(self) -> NextState<'static> {
929 Box::new(self.next)
930 }
931
932 fn handle_hello_retry_request(
933 mut self,
934 cx: &mut ClientContext<'_>,
935 m: Message<'_>,
936 ) -> NextStateOrError<'static> {
937 let hrr = require_handshake_msg!(
938 m,
939 HandshakeType::HelloRetryRequest,
940 HandshakePayload::HelloRetryRequest
941 )?;
942 trace!("Got HRR {:?}", hrr);
943
944 cx.common.check_aligned_handshake()?;
945
946 let cookie = hrr.cookie();
947 let req_group = hrr.requested_key_share_group();
948
949 let offered_key_share = self.next.offered_key_share.unwrap();
951
952 if cookie.is_none() && req_group == Some(offered_key_share.group()) {
955 return Err({
956 cx.common.send_fatal_alert(
957 AlertDescription::IllegalParameter,
958 PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
959 )
960 });
961 }
962
963 if let Some(cookie) = cookie {
965 if cookie.0.is_empty() {
966 return Err({
967 cx.common.send_fatal_alert(
968 AlertDescription::IllegalParameter,
969 PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
970 )
971 });
972 }
973 }
974
975 if hrr.has_unknown_extension() {
977 return Err(cx.common.send_fatal_alert(
978 AlertDescription::UnsupportedExtension,
979 PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
980 ));
981 }
982
983 if hrr.has_duplicate_extension() {
985 return Err({
986 cx.common.send_fatal_alert(
987 AlertDescription::IllegalParameter,
988 PeerMisbehaved::DuplicateHelloRetryRequestExtensions,
989 )
990 });
991 }
992
993 if cookie.is_none() && req_group.is_none() {
995 return Err({
996 cx.common.send_fatal_alert(
997 AlertDescription::IllegalParameter,
998 PeerMisbehaved::IllegalHelloRetryRequestWithNoChanges,
999 )
1000 });
1001 }
1002
1003 if hrr.session_id != self.next.input.session_id {
1017 return Err({
1018 cx.common.send_fatal_alert(
1019 AlertDescription::IllegalParameter,
1020 PeerMisbehaved::IllegalHelloRetryRequestWithWrongSessionId,
1021 )
1022 });
1023 }
1024
1025 match hrr.supported_versions() {
1027 Some(ProtocolVersion::TLSv1_3) => {
1028 cx.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
1029 }
1030 _ => {
1031 return Err({
1032 cx.common.send_fatal_alert(
1033 AlertDescription::IllegalParameter,
1034 PeerMisbehaved::IllegalHelloRetryRequestWithUnsupportedVersion,
1035 )
1036 });
1037 }
1038 }
1039
1040 let config = &self.next.input.config;
1042 let cs = match config.find_cipher_suite(hrr.cipher_suite) {
1043 Some(cs) => cs,
1044 None => {
1045 return Err({
1046 cx.common.send_fatal_alert(
1047 AlertDescription::IllegalParameter,
1048 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
1049 )
1050 });
1051 }
1052 };
1053
1054 if cx.data.ech_status == EchStatus::NotOffered && hrr.ech().is_some() {
1056 return Err({
1057 cx.common.send_fatal_alert(
1058 AlertDescription::UnsupportedExtension,
1059 PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
1060 )
1061 });
1062 }
1063
1064 cx.common.suite = Some(cs);
1066 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
1067
1068 match (self.next.ech_state.as_ref(), cs.tls13()) {
1070 (Some(ech_state), Some(tls13_cs)) => {
1071 if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? {
1072 cx.data.ech_status = EchStatus::Rejected;
1076 }
1077 }
1078 (Some(_), None) => {
1079 unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1080 }
1081 _ => {}
1082 };
1083
1084 let transcript = self
1086 .next
1087 .transcript_buffer
1088 .start_hash(cs.hash_provider());
1089 let mut transcript_buffer = transcript.into_hrr_buffer();
1090 transcript_buffer.add_message(&m);
1091
1092 if let Some(ech_state) = self.next.ech_state.as_mut() {
1095 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1096 }
1097
1098 if cx.data.early_data.is_enabled() {
1100 cx.data.early_data.rejected();
1101 }
1102
1103 let key_share = match req_group {
1104 Some(group) if group != offered_key_share.group() => {
1105 let skxg = match config.find_kx_group(group, ProtocolVersion::TLSv1_3) {
1106 Some(skxg) => skxg,
1107 None => {
1108 return Err(cx.common.send_fatal_alert(
1109 AlertDescription::IllegalParameter,
1110 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1111 ));
1112 }
1113 };
1114
1115 cx.common.kx_state = KxState::Start(skxg);
1116 skxg.start()?
1117 }
1118 _ => offered_key_share,
1119 };
1120
1121 emit_client_hello_for_retry(
1122 transcript_buffer,
1123 Some(hrr),
1124 Some(key_share),
1125 self.extra_exts,
1126 Some(cs),
1127 self.next.input,
1128 cx,
1129 self.next.ech_state,
1130 )
1131 }
1132}
1133
1134impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1135 fn handle<'m>(
1136 self: Box<Self>,
1137 cx: &mut ClientContext<'_>,
1138 m: Message<'m>,
1139 ) -> NextStateOrError<'m>
1140 where
1141 Self: 'm,
1142 {
1143 match m.payload {
1144 MessagePayload::Handshake {
1145 parsed:
1146 HandshakeMessagePayload {
1147 payload: HandshakePayload::ServerHello(..),
1148 ..
1149 },
1150 ..
1151 } => self
1152 .into_expect_server_hello()
1153 .handle(cx, m),
1154 MessagePayload::Handshake {
1155 parsed:
1156 HandshakeMessagePayload {
1157 payload: HandshakePayload::HelloRetryRequest(..),
1158 ..
1159 },
1160 ..
1161 } => self.handle_hello_retry_request(cx, m),
1162 payload => Err(inappropriate_handshake_message(
1163 &payload,
1164 &[ContentType::Handshake],
1165 &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1166 )),
1167 }
1168 }
1169
1170 fn into_owned(self: Box<Self>) -> NextState<'static> {
1171 self
1172 }
1173}
1174
1175enum ClientSessionValue {
1176 Tls13(persist::Tls13ClientSessionValue),
1177 #[cfg(feature = "tls12")]
1178 Tls12(persist::Tls12ClientSessionValue),
1179}
1180
1181impl ClientSessionValue {
1182 fn common(&self) -> &persist::ClientSessionCommon {
1183 match self {
1184 Self::Tls13(inner) => &inner.common,
1185 #[cfg(feature = "tls12")]
1186 Self::Tls12(inner) => &inner.common,
1187 }
1188 }
1189
1190 fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1191 match self {
1192 Self::Tls13(v) => Some(v),
1193 #[cfg(feature = "tls12")]
1194 Self::Tls12(_) => None,
1195 }
1196 }
1197}
1198
1199impl Deref for ClientSessionValue {
1200 type Target = persist::ClientSessionCommon;
1201
1202 fn deref(&self) -> &Self::Target {
1203 self.common()
1204 }
1205}
1206
1207fn low_quality_integer_hash(mut x: u32) -> u32 {
1208 x = x
1209 .wrapping_add(0x7ed55d16)
1210 .wrapping_add(x << 12);
1211 x = (x ^ 0xc761c23c) ^ (x >> 19);
1212 x = x
1213 .wrapping_add(0x165667b1)
1214 .wrapping_add(x << 5);
1215 x = x.wrapping_add(0xd3a2646c) ^ (x << 9);
1216 x = x
1217 .wrapping_add(0xfd7046c5)
1218 .wrapping_add(x << 3);
1219 x = (x ^ 0xb55a4f09) ^ (x >> 16);
1220 x
1221}