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::{CommonState, HandshakeKind, KxState, State};
21use crate::conn::ConnectionRandoms;
22use crate::crypto::{ActiveKeyExchange, KeyExchangeAlgorithm};
23use crate::enums::{AlertDescription, CipherSuite, ContentType, HandshakeType, ProtocolVersion};
24use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
25use crate::hash_hs::HandshakeHashBuffer;
26use crate::log::{debug, trace};
27use crate::msgs::base::Payload;
28use crate::msgs::enums::{Compression, ECPointFormat, ExtensionType, PSKKeyExchangeMode};
29use crate::msgs::handshake::{
30 CertificateStatusRequest, ClientExtension, ClientHelloPayload, ClientSessionTicket,
31 ConvertProtocolNameList, HandshakeMessagePayload, HandshakePayload, HasServerExtensions,
32 HelloRetryRequest, KeyShareEntry, Random, SessionId,
33};
34use crate::msgs::message::{Message, MessagePayload};
35use crate::msgs::persist;
36use crate::tls13::key_schedule::KeyScheduleEarly;
37use crate::SupportedCipherSuite;
38
39pub(super) type NextState<'a> = Box<dyn State<ClientConnectionData> + 'a>;
40pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
41pub(super) type ClientContext<'a> = crate::common_state::Context<'a, ClientConnectionData>;
42
43fn find_session(
44 server_name: &ServerName<'static>,
45 config: &ClientConfig,
46 cx: &mut ClientContext<'_>,
47) -> Option<persist::Retrieved<ClientSessionValue>> {
48 let found = config
49 .resumption
50 .store
51 .take_tls13_ticket(server_name)
52 .map(ClientSessionValue::Tls13)
53 .or_else(|| {
54 #[cfg(feature = "tls12")]
55 {
56 config
57 .resumption
58 .store
59 .tls12_session(server_name)
60 .map(ClientSessionValue::Tls12)
61 }
62
63 #[cfg(not(feature = "tls12"))]
64 None
65 })
66 .and_then(|resuming| {
67 let now = config
68 .current_time()
69 .map_err(|_err| debug!("Could not get current time: {_err}"))
70 .ok()?;
71
72 let retrieved = persist::Retrieved::new(resuming, now);
73 match retrieved.has_expired() {
74 false => Some(retrieved),
75 true => None,
76 }
77 })
78 .or_else(|| {
79 debug!("No cached session for {:?}", server_name);
80 None
81 });
82
83 if let Some(resuming) = &found {
84 if cx.common.is_quic() {
85 cx.common.quic.params = resuming
86 .tls13()
87 .map(|v| v.quic_params());
88 }
89 }
90
91 found
92}
93
94pub(super) fn start_handshake(
95 server_name: ServerName<'static>,
96 extra_exts: Vec<ClientExtension>,
97 config: Arc<ClientConfig>,
98 cx: &mut ClientContext<'_>,
99) -> NextStateOrError<'static> {
100 let mut transcript_buffer = HandshakeHashBuffer::new();
101 if config
102 .client_auth_cert_resolver
103 .has_certs()
104 {
105 transcript_buffer.set_client_auth_enabled();
106 }
107
108 let mut resuming = find_session(&server_name, &config, cx);
109
110 let key_share = if config.supports_version(ProtocolVersion::TLSv1_3) {
111 Some(tls13::initial_key_share(
112 &config,
113 &server_name,
114 &mut cx.common.kx_state,
115 )?)
116 } else {
117 None
118 };
119
120 let session_id = if let Some(_resuming) = &mut resuming {
121 debug!("Resuming session");
122
123 match &mut _resuming.value {
124 #[cfg(feature = "tls12")]
125 ClientSessionValue::Tls12(inner) => {
126 if !inner.ticket().is_empty() {
130 inner.session_id = SessionId::random(config.provider.secure_random)?;
131 }
132 Some(inner.session_id)
133 }
134 _ => None,
135 }
136 } else {
137 debug!("Not resuming any session");
138 None
139 };
140
141 let session_id = match session_id {
144 Some(session_id) => session_id,
145 None if cx.common.is_quic() => SessionId::empty(),
146 None if !config.supports_version(ProtocolVersion::TLSv1_3) => SessionId::empty(),
147 None => SessionId::random(config.provider.secure_random)?,
148 };
149
150 let random = Random::new(config.provider.secure_random)?;
151 let extension_order_seed = crate::rand::random_u16(config.provider.secure_random)?;
152
153 let ech_state = match config.ech_mode.as_ref() {
154 Some(EchMode::Enable(ech_config)) => Some(EchState::new(
155 ech_config,
156 server_name.clone(),
157 config
158 .client_auth_cert_resolver
159 .has_certs(),
160 config.provider.secure_random,
161 config.enable_sni,
162 )?),
163 _ => None,
164 };
165
166 emit_client_hello_for_retry(
167 transcript_buffer,
168 None,
169 key_share,
170 extra_exts,
171 None,
172 ClientHelloInput {
173 config,
174 resuming,
175 random,
176 #[cfg(feature = "tls12")]
177 using_ems: false,
178 sent_tls13_fake_ccs: false,
179 hello: ClientHelloDetails::new(extension_order_seed),
180 session_id,
181 server_name,
182 prev_ech_ext: None,
183 },
184 cx,
185 ech_state,
186 )
187}
188
189struct ExpectServerHello {
190 input: ClientHelloInput,
191 transcript_buffer: HandshakeHashBuffer,
192 early_key_schedule: Option<KeyScheduleEarly>,
193 offered_key_share: Option<Box<dyn ActiveKeyExchange>>,
194 suite: Option<SupportedCipherSuite>,
195 ech_state: Option<EchState>,
196}
197
198struct ExpectServerHelloOrHelloRetryRequest {
199 next: ExpectServerHello,
200 extra_exts: Vec<ClientExtension>,
201}
202
203struct ClientHelloInput {
204 config: Arc<ClientConfig>,
205 resuming: Option<persist::Retrieved<ClientSessionValue>>,
206 random: Random,
207 #[cfg(feature = "tls12")]
208 using_ems: bool,
209 sent_tls13_fake_ccs: bool,
210 hello: ClientHelloDetails,
211 session_id: SessionId,
212 server_name: ServerName<'static>,
213 prev_ech_ext: Option<ClientExtension>,
214}
215
216fn emit_client_hello_for_retry(
217 mut transcript_buffer: HandshakeHashBuffer,
218 retryreq: Option<&HelloRetryRequest>,
219 key_share: Option<Box<dyn ActiveKeyExchange>>,
220 extra_exts: Vec<ClientExtension>,
221 suite: Option<SupportedCipherSuite>,
222 mut input: ClientHelloInput,
223 cx: &mut ClientContext<'_>,
224 mut ech_state: Option<EchState>,
225) -> NextStateOrError<'static> {
226 let config = &input.config;
227 let forbids_tls12 = cx.common.is_quic() || ech_state.is_some();
230 let support_tls12 = config.supports_version(ProtocolVersion::TLSv1_2) && !forbids_tls12;
231 let support_tls13 = config.supports_version(ProtocolVersion::TLSv1_3);
232
233 let mut supported_versions = Vec::new();
234 if support_tls13 {
235 supported_versions.push(ProtocolVersion::TLSv1_3);
236 }
237
238 if support_tls12 {
239 supported_versions.push(ProtocolVersion::TLSv1_2);
240 }
241
242 assert!(!supported_versions.is_empty());
244
245 let mut exts = vec![
246 ClientExtension::SupportedVersions(supported_versions),
247 ClientExtension::NamedGroups(
248 config
249 .provider
250 .kx_groups
251 .iter()
252 .map(|skxg| skxg.name())
253 .collect(),
254 ),
255 ClientExtension::SignatureAlgorithms(
256 config
257 .verifier
258 .supported_verify_schemes(),
259 ),
260 ClientExtension::ExtendedMasterSecretRequest,
261 ClientExtension::CertificateStatusRequest(CertificateStatusRequest::build_ocsp()),
262 ];
263
264 if config
266 .provider
267 .kx_groups
268 .iter()
269 .any(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::ECDHE)
270 {
271 exts.push(ClientExtension::EcPointFormats(
272 ECPointFormat::SUPPORTED.to_vec(),
273 ));
274 }
275
276 match (ech_state.as_ref(), config.enable_sni) {
277 (Some(ech_state), _) => exts.push(ClientExtension::make_sni(&ech_state.outer_name)),
282
283 (None, true) => {
286 if let ServerName::DnsName(dns_name) = &input.server_name {
287 exts.push(ClientExtension::make_sni(dns_name))
288 }
289 }
290
291 (None, false) => {}
293 };
294
295 if let Some(key_share) = &key_share {
296 debug_assert!(support_tls13);
297 let key_share = KeyShareEntry::new(key_share.group(), key_share.pub_key());
298 exts.push(ClientExtension::KeyShare(vec![key_share]));
299 }
300
301 if let Some(cookie) = retryreq.and_then(HelloRetryRequest::cookie) {
302 exts.push(ClientExtension::Cookie(cookie.clone()));
303 }
304
305 if support_tls13 {
306 let psk_modes = vec![PSKKeyExchangeMode::PSK_DHE_KE];
309 exts.push(ClientExtension::PresharedKeyModes(psk_modes));
310 }
311
312 if !config.alpn_protocols.is_empty() {
313 exts.push(ClientExtension::Protocols(Vec::from_slices(
314 &config
315 .alpn_protocols
316 .iter()
317 .map(|proto| &proto[..])
318 .collect::<Vec<_>>(),
319 )));
320 }
321
322 input.hello.offered_cert_compression = if support_tls13 && !config.cert_decompressors.is_empty()
323 {
324 exts.push(ClientExtension::CertificateCompressionAlgorithms(
325 config
326 .cert_decompressors
327 .iter()
328 .map(|dec| dec.algorithm())
329 .collect(),
330 ));
331 true
332 } else {
333 false
334 };
335
336 exts.extend(extra_exts.iter().cloned());
338
339 if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
343 if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
344 exts.push(prev_ech_ext);
345 }
346 }
347
348 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
350
351 exts.sort_by_cached_key(|new_ext| {
354 match (&cx.data.ech_status, new_ext) {
355 (EchStatus::NotOffered, ClientExtension::PresharedKey(..)) => return u32::MAX,
357 (_, ClientExtension::EncryptedClientHello(_)) => return u32::MAX,
359 (_, ClientExtension::PresharedKey(..)) => return u32::MAX - 1,
361 _ => {}
362 };
363
364 let seed = (input.hello.extension_order_seed as u32) << 16
365 | (u16::from(new_ext.ext_type()) as u32);
366 match low_quality_integer_hash(seed) {
367 u32::MAX => 0,
368 key => key,
369 }
370 });
371
372 let mut cipher_suites: Vec<_> = config
373 .provider
374 .cipher_suites
375 .iter()
376 .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
377 true => Some(cs.suite()),
378 false => None,
379 })
380 .collect();
381 cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
383
384 let mut chp_payload = ClientHelloPayload {
385 client_version: ProtocolVersion::TLSv1_2,
386 random: input.random,
387 session_id: input.session_id,
388 cipher_suites,
389 compression_methods: vec![Compression::Null],
390 extensions: exts,
391 };
392
393 let ech_grease_ext = config
394 .ech_mode
395 .as_ref()
396 .and_then(|mode| match mode {
397 EchMode::Grease(cfg) => Some(cfg.grease_ext(
398 config.provider.secure_random,
399 input.server_name.clone(),
400 &chp_payload,
401 )),
402 _ => None,
403 });
404
405 match (cx.data.ech_status, &mut ech_state) {
406 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
409 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
411 cx.data.ech_status = EchStatus::Offered;
412 input.prev_ech_ext = chp_payload.extensions.last().cloned();
414 }
415 (EchStatus::NotOffered, None) => {
418 if let Some(grease_ext) = ech_grease_ext {
419 let grease_ext = grease_ext?;
421 chp_payload
422 .extensions
423 .push(grease_ext.clone());
424 cx.data.ech_status = EchStatus::Grease;
425 input.prev_ech_ext = Some(grease_ext);
428 }
429 }
430 _ => {}
431 }
432
433 input.hello.sent_extensions = chp_payload
435 .extensions
436 .iter()
437 .map(ClientExtension::ext_type)
438 .collect();
439
440 let mut chp = HandshakeMessagePayload {
441 typ: HandshakeType::ClientHello,
442 payload: HandshakePayload::ClientHello(chp_payload),
443 };
444
445 let early_key_schedule = match (ech_state.as_mut(), tls13_session) {
446 (Some(ech_state), Some(tls13_session)) => ech_state
449 .early_data_key_schedule
450 .take()
451 .map(|schedule| (tls13_session.suite(), schedule)),
452
453 (_, Some(tls13_session)) => Some((
456 tls13_session.suite(),
457 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
458 )),
459
460 _ => None,
462 };
463
464 let ch = Message {
465 version: match retryreq {
466 Some(_) => ProtocolVersion::TLSv1_2,
470 None => ProtocolVersion::TLSv1_0,
476 },
477 payload: MessagePayload::handshake(chp),
478 };
479
480 if retryreq.is_some() {
481 tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
484 }
485
486 trace!("Sending ClientHello {:#?}", ch);
487
488 transcript_buffer.add_message(&ch);
489 cx.common.send_msg(ch, false);
490
491 let early_key_schedule = early_key_schedule.map(|(resuming_suite, schedule)| {
493 if !cx.data.early_data.is_enabled() {
494 return schedule;
495 }
496
497 let (transcript_buffer, random) = match &ech_state {
498 Some(ech_state) => (
501 &ech_state.inner_hello_transcript,
502 &ech_state.inner_hello_random.0,
503 ),
504 None => (&transcript_buffer, &input.random.0),
505 };
506
507 tls13::derive_early_traffic_secret(
508 &*config.key_log,
509 cx,
510 resuming_suite,
511 &schedule,
512 &mut input.sent_tls13_fake_ccs,
513 transcript_buffer,
514 random,
515 );
516 schedule
517 });
518
519 let next = ExpectServerHello {
520 input,
521 transcript_buffer,
522 early_key_schedule,
523 offered_key_share: key_share,
524 suite,
525 ech_state,
526 };
527
528 Ok(if support_tls13 && retryreq.is_none() {
529 Box::new(ExpectServerHelloOrHelloRetryRequest { next, extra_exts })
530 } else {
531 Box::new(next)
532 })
533}
534
535fn prepare_resumption<'a>(
549 resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
550 exts: &mut Vec<ClientExtension>,
551 suite: Option<SupportedCipherSuite>,
552 cx: &mut ClientContext<'_>,
553 config: &ClientConfig,
554) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
555 let resuming = match resuming {
557 Some(resuming) if !resuming.ticket().is_empty() => resuming,
558 _ => {
559 if config.supports_version(ProtocolVersion::TLSv1_3)
560 || config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
561 {
562 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Request));
564 }
565 return None;
566 }
567 };
568
569 let tls13 = match resuming.map(|csv| csv.tls13()) {
570 Some(tls13) => tls13,
571 None => {
572 if config.supports_version(ProtocolVersion::TLSv1_2)
574 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
575 {
576 exts.push(ClientExtension::SessionTicket(ClientSessionTicket::Offer(
577 Payload::new(resuming.ticket()),
578 )));
579 }
580 return None; }
582 };
583
584 if !config.supports_version(ProtocolVersion::TLSv1_3) {
585 return None;
586 }
587
588 let suite = match suite {
590 Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
591 #[cfg(feature = "tls12")]
592 Some(SupportedCipherSuite::Tls12(_)) => return None,
593 None => None,
594 };
595
596 if let Some(suite) = suite {
598 suite.can_resume_from(tls13.suite())?;
599 }
600
601 tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
602 Some(tls13)
603}
604
605pub(super) fn process_alpn_protocol(
606 common: &mut CommonState,
607 config: &ClientConfig,
608 proto: Option<&[u8]>,
609) -> Result<(), Error> {
610 common.alpn_protocol = proto.map(ToOwned::to_owned);
611
612 if let Some(alpn_protocol) = &common.alpn_protocol {
613 if !config
614 .alpn_protocols
615 .contains(alpn_protocol)
616 {
617 return Err(common.send_fatal_alert(
618 AlertDescription::IllegalParameter,
619 PeerMisbehaved::SelectedUnofferedApplicationProtocol,
620 ));
621 }
622 }
623
624 if common.is_quic() && common.alpn_protocol.is_none() && !config.alpn_protocols.is_empty() {
631 return Err(common.send_fatal_alert(
632 AlertDescription::NoApplicationProtocol,
633 Error::NoApplicationProtocol,
634 ));
635 }
636
637 debug!(
638 "ALPN protocol is {:?}",
639 common
640 .alpn_protocol
641 .as_ref()
642 .map(|v| bs_debug::BsDebug(v))
643 );
644 Ok(())
645}
646
647impl State<ClientConnectionData> for ExpectServerHello {
648 fn handle<'m>(
649 mut self: Box<Self>,
650 cx: &mut ClientContext<'_>,
651 m: Message<'m>,
652 ) -> NextStateOrError<'m>
653 where
654 Self: 'm,
655 {
656 let server_hello =
657 require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
658 trace!("We got ServerHello {:#?}", server_hello);
659
660 use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
661 let config = &self.input.config;
662 let tls13_supported = config.supports_version(TLSv1_3);
663
664 let server_version = if server_hello.legacy_version == TLSv1_2 {
665 server_hello
666 .supported_versions()
667 .unwrap_or(server_hello.legacy_version)
668 } else {
669 server_hello.legacy_version
670 };
671
672 let version = match server_version {
673 TLSv1_3 if tls13_supported => TLSv1_3,
674 TLSv1_2 if config.supports_version(TLSv1_2) => {
675 if cx.data.early_data.is_enabled() && cx.common.early_traffic {
676 return Err(PeerMisbehaved::OfferedEarlyDataWithOldProtocolVersion.into());
679 }
680
681 if server_hello
682 .supported_versions()
683 .is_some()
684 {
685 return Err({
686 cx.common.send_fatal_alert(
687 AlertDescription::IllegalParameter,
688 PeerMisbehaved::SelectedTls12UsingTls13VersionExtension,
689 )
690 });
691 }
692
693 TLSv1_2
694 }
695 _ => {
696 let reason = match server_version {
697 TLSv1_2 | TLSv1_3 => PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig,
698 _ => PeerIncompatible::ServerDoesNotSupportTls12Or13,
699 };
700 return Err(cx
701 .common
702 .send_fatal_alert(AlertDescription::ProtocolVersion, reason));
703 }
704 };
705
706 if server_hello.compression_method != Compression::Null {
707 return Err({
708 cx.common.send_fatal_alert(
709 AlertDescription::IllegalParameter,
710 PeerMisbehaved::SelectedUnofferedCompression,
711 )
712 });
713 }
714
715 if server_hello.has_duplicate_extension() {
716 return Err(cx.common.send_fatal_alert(
717 AlertDescription::DecodeError,
718 PeerMisbehaved::DuplicateServerHelloExtensions,
719 ));
720 }
721
722 let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
723 if self
724 .input
725 .hello
726 .server_sent_unsolicited_extensions(&server_hello.extensions, &allowed_unsolicited)
727 {
728 return Err(cx.common.send_fatal_alert(
729 AlertDescription::UnsupportedExtension,
730 PeerMisbehaved::UnsolicitedServerHelloExtension,
731 ));
732 }
733
734 cx.common.negotiated_version = Some(version);
735
736 if !cx.common.is_tls13() {
738 process_alpn_protocol(cx.common, config, server_hello.alpn_protocol())?;
739 }
740
741 if let Some(point_fmts) = server_hello.ecpoints_extension() {
744 if !point_fmts.contains(&ECPointFormat::Uncompressed) {
745 return Err(cx.common.send_fatal_alert(
746 AlertDescription::HandshakeFailure,
747 PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
748 ));
749 }
750 }
751
752 let suite = config
753 .find_cipher_suite(server_hello.cipher_suite)
754 .ok_or_else(|| {
755 cx.common.send_fatal_alert(
756 AlertDescription::HandshakeFailure,
757 PeerMisbehaved::SelectedUnofferedCipherSuite,
758 )
759 })?;
760
761 if version != suite.version().version {
762 return Err({
763 cx.common.send_fatal_alert(
764 AlertDescription::IllegalParameter,
765 PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
766 )
767 });
768 }
769
770 match self.suite {
771 Some(prev_suite) if prev_suite != suite => {
772 return Err({
773 cx.common.send_fatal_alert(
774 AlertDescription::IllegalParameter,
775 PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
776 )
777 });
778 }
779 _ => {
780 debug!("Using ciphersuite {:?}", suite);
781 self.suite = Some(suite);
782 cx.common.suite = Some(suite);
783 }
784 }
785
786 let mut transcript = self
788 .transcript_buffer
789 .start_hash(suite.hash_provider());
790 transcript.add_message(&m);
791
792 let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
793 match suite {
796 SupportedCipherSuite::Tls13(suite) => {
797 #[allow(clippy::bind_instead_of_map)]
798 let resuming_session = self
799 .input
800 .resuming
801 .and_then(|resuming| match resuming.value {
802 ClientSessionValue::Tls13(inner) => Some(inner),
803 #[cfg(feature = "tls12")]
804 ClientSessionValue::Tls12(_) => None,
805 });
806
807 tls13::handle_server_hello(
808 self.input.config,
809 cx,
810 server_hello,
811 resuming_session,
812 self.input.server_name,
813 randoms,
814 suite,
815 transcript,
816 self.early_key_schedule,
817 self.input.hello,
818 self.offered_key_share.unwrap(),
820 self.input.sent_tls13_fake_ccs,
821 &m,
822 self.ech_state,
823 )
824 }
825 #[cfg(feature = "tls12")]
826 SupportedCipherSuite::Tls12(suite) => {
827 let resuming_session = self
828 .input
829 .resuming
830 .and_then(|resuming| match resuming.value {
831 ClientSessionValue::Tls12(inner) => Some(inner),
832 ClientSessionValue::Tls13(_) => None,
833 });
834
835 tls12::CompleteServerHelloHandling {
836 config: self.input.config,
837 resuming_session,
838 server_name: self.input.server_name,
839 randoms,
840 using_ems: self.input.using_ems,
841 transcript,
842 }
843 .handle_server_hello(cx, suite, server_hello, tls13_supported)
844 }
845 }
846 }
847
848 fn into_owned(self: Box<Self>) -> NextState<'static> {
849 self
850 }
851}
852
853impl ExpectServerHelloOrHelloRetryRequest {
854 fn into_expect_server_hello(self) -> NextState<'static> {
855 Box::new(self.next)
856 }
857
858 fn handle_hello_retry_request(
859 mut self,
860 cx: &mut ClientContext<'_>,
861 m: Message<'_>,
862 ) -> NextStateOrError<'static> {
863 let hrr = require_handshake_msg!(
864 m,
865 HandshakeType::HelloRetryRequest,
866 HandshakePayload::HelloRetryRequest
867 )?;
868 trace!("Got HRR {:?}", hrr);
869
870 cx.common.check_aligned_handshake()?;
871
872 let cookie = hrr.cookie();
873 let req_group = hrr.requested_key_share_group();
874
875 let offered_key_share = self.next.offered_key_share.unwrap();
877
878 if cookie.is_none() && req_group == Some(offered_key_share.group()) {
881 return Err({
882 cx.common.send_fatal_alert(
883 AlertDescription::IllegalParameter,
884 PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
885 )
886 });
887 }
888
889 if let Some(cookie) = cookie {
891 if cookie.0.is_empty() {
892 return Err({
893 cx.common.send_fatal_alert(
894 AlertDescription::IllegalParameter,
895 PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
896 )
897 });
898 }
899 }
900
901 if hrr.has_unknown_extension() {
903 return Err(cx.common.send_fatal_alert(
904 AlertDescription::UnsupportedExtension,
905 PeerIncompatible::ServerSentHelloRetryRequestWithUnknownExtension,
906 ));
907 }
908
909 if hrr.has_duplicate_extension() {
911 return Err({
912 cx.common.send_fatal_alert(
913 AlertDescription::IllegalParameter,
914 PeerMisbehaved::DuplicateHelloRetryRequestExtensions,
915 )
916 });
917 }
918
919 if cookie.is_none() && req_group.is_none() {
921 return Err({
922 cx.common.send_fatal_alert(
923 AlertDescription::IllegalParameter,
924 PeerMisbehaved::IllegalHelloRetryRequestWithNoChanges,
925 )
926 });
927 }
928
929 if hrr.session_id != self.next.input.session_id {
943 return Err({
944 cx.common.send_fatal_alert(
945 AlertDescription::IllegalParameter,
946 PeerMisbehaved::IllegalHelloRetryRequestWithWrongSessionId,
947 )
948 });
949 }
950
951 match hrr.supported_versions() {
953 Some(ProtocolVersion::TLSv1_3) => {
954 cx.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
955 }
956 _ => {
957 return Err({
958 cx.common.send_fatal_alert(
959 AlertDescription::IllegalParameter,
960 PeerMisbehaved::IllegalHelloRetryRequestWithUnsupportedVersion,
961 )
962 });
963 }
964 }
965
966 let config = &self.next.input.config;
968 let cs = match config.find_cipher_suite(hrr.cipher_suite) {
969 Some(cs) => cs,
970 None => {
971 return Err({
972 cx.common.send_fatal_alert(
973 AlertDescription::IllegalParameter,
974 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
975 )
976 });
977 }
978 };
979
980 if cx.data.ech_status == EchStatus::NotOffered && hrr.ech().is_some() {
982 return Err({
983 cx.common.send_fatal_alert(
984 AlertDescription::UnsupportedExtension,
985 PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
986 )
987 });
988 }
989
990 cx.common.suite = Some(cs);
992 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
993
994 match (self.next.ech_state.as_ref(), cs.tls13()) {
996 (Some(ech_state), Some(tls13_cs)) => {
997 if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? {
998 cx.data.ech_status = EchStatus::Rejected;
1002 }
1003 }
1004 (Some(_), None) => {
1005 unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1006 }
1007 _ => {}
1008 };
1009
1010 let transcript = self
1012 .next
1013 .transcript_buffer
1014 .start_hash(cs.hash_provider());
1015 let mut transcript_buffer = transcript.into_hrr_buffer();
1016 transcript_buffer.add_message(&m);
1017
1018 if let Some(ech_state) = self.next.ech_state.as_mut() {
1021 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1022 }
1023
1024 if cx.data.early_data.is_enabled() {
1026 cx.data.early_data.rejected();
1027 }
1028
1029 let key_share = match req_group {
1030 Some(group) if group != offered_key_share.group() => {
1031 let skxg = match config.find_kx_group(group) {
1032 Some(skxg) => skxg,
1033 None => {
1034 return Err(cx.common.send_fatal_alert(
1035 AlertDescription::IllegalParameter,
1036 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1037 ));
1038 }
1039 };
1040
1041 cx.common.kx_state = KxState::Start(skxg);
1042 skxg.start()?
1043 }
1044 _ => offered_key_share,
1045 };
1046
1047 emit_client_hello_for_retry(
1048 transcript_buffer,
1049 Some(hrr),
1050 Some(key_share),
1051 self.extra_exts,
1052 Some(cs),
1053 self.next.input,
1054 cx,
1055 self.next.ech_state,
1056 )
1057 }
1058}
1059
1060impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1061 fn handle<'m>(
1062 self: Box<Self>,
1063 cx: &mut ClientContext<'_>,
1064 m: Message<'m>,
1065 ) -> NextStateOrError<'m>
1066 where
1067 Self: 'm,
1068 {
1069 match m.payload {
1070 MessagePayload::Handshake {
1071 parsed:
1072 HandshakeMessagePayload {
1073 payload: HandshakePayload::ServerHello(..),
1074 ..
1075 },
1076 ..
1077 } => self
1078 .into_expect_server_hello()
1079 .handle(cx, m),
1080 MessagePayload::Handshake {
1081 parsed:
1082 HandshakeMessagePayload {
1083 payload: HandshakePayload::HelloRetryRequest(..),
1084 ..
1085 },
1086 ..
1087 } => self.handle_hello_retry_request(cx, m),
1088 payload => Err(inappropriate_handshake_message(
1089 &payload,
1090 &[ContentType::Handshake],
1091 &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1092 )),
1093 }
1094 }
1095
1096 fn into_owned(self: Box<Self>) -> NextState<'static> {
1097 self
1098 }
1099}
1100
1101enum ClientSessionValue {
1102 Tls13(persist::Tls13ClientSessionValue),
1103 #[cfg(feature = "tls12")]
1104 Tls12(persist::Tls12ClientSessionValue),
1105}
1106
1107impl ClientSessionValue {
1108 fn common(&self) -> &persist::ClientSessionCommon {
1109 match self {
1110 Self::Tls13(inner) => &inner.common,
1111 #[cfg(feature = "tls12")]
1112 Self::Tls12(inner) => &inner.common,
1113 }
1114 }
1115
1116 fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1117 match self {
1118 Self::Tls13(v) => Some(v),
1119 #[cfg(feature = "tls12")]
1120 Self::Tls12(_) => None,
1121 }
1122 }
1123}
1124
1125impl Deref for ClientSessionValue {
1126 type Target = persist::ClientSessionCommon;
1127
1128 fn deref(&self) -> &Self::Target {
1129 self.common()
1130 }
1131}
1132
1133fn low_quality_integer_hash(mut x: u32) -> u32 {
1134 x = x
1135 .wrapping_add(0x7ed55d16)
1136 .wrapping_add(x << 12);
1137 x = (x ^ 0xc761c23c) ^ (x >> 19);
1138 x = x
1139 .wrapping_add(0x165667b1)
1140 .wrapping_add(x << 5);
1141 x = x.wrapping_add(0xd3a2646c) ^ (x << 9);
1142 x = x
1143 .wrapping_add(0xfd7046c5)
1144 .wrapping_add(x << 3);
1145 x = (x ^ 0xb55a4f09) ^ (x >> 16);
1146 x
1147}