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, ExtensionType};
31use crate::msgs::handshake::{
32 CertificateStatusRequest, ClientExtensions, ClientExtensionsInput, ClientHelloPayload,
33 ClientSessionTicket, ClientTicketRequest, EncryptedClientHello, HandshakeMessagePayload,
34 HandshakePayload, HelloRetryRequest, KeyShareEntry, ProtocolName, PskKeyExchangeModes, Random,
35 ServerNamePayload, SessionId, SupportedEcPointFormats, SupportedProtocolVersions,
36 TransportParameters,
37};
38use crate::msgs::message::{Message, MessagePayload};
39use crate::msgs::persist;
40use crate::sync::Arc;
41use crate::tls13::key_schedule::KeyScheduleEarly;
42use crate::verify::ServerCertVerifier;
43
44pub(super) type NextState<'a> = Box<dyn State<ClientConnectionData> + 'a>;
45pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
46pub(super) type ClientContext<'a> = crate::common_state::Context<'a, ClientConnectionData>;
47
48struct ExpectServerHello {
49 input: ClientHelloInput,
50 transcript_buffer: HandshakeHashBuffer,
51 early_data_key_schedule: Option<KeyScheduleEarly>,
59 offered_key_share: Option<Box<dyn ActiveKeyExchange>>,
60 suite: Option<SupportedCipherSuite>,
61 ech_state: Option<EchState>,
62}
63
64struct ExpectServerHelloOrHelloRetryRequest {
65 next: ExpectServerHello,
66 extra_exts: ClientExtensionsInput<'static>,
67}
68
69pub(super) struct ClientHelloInput {
70 pub(super) config: Arc<ClientConfig>,
71 pub(super) resuming: Option<persist::Retrieved<ClientSessionValue>>,
72 pub(super) random: Random,
73 pub(super) sent_tls13_fake_ccs: bool,
74 pub(super) hello: ClientHelloDetails,
75 pub(super) session_id: SessionId,
76 pub(super) server_name: ServerName<'static>,
77 pub(super) prev_ech_ext: Option<EncryptedClientHello>,
78}
79
80impl ClientHelloInput {
81 pub(super) fn new(
82 server_name: ServerName<'static>,
83 extra_exts: &ClientExtensionsInput<'_>,
84 cx: &mut ClientContext<'_>,
85 config: Arc<ClientConfig>,
86 ) -> Result<Self, Error> {
87 let mut resuming = ClientSessionValue::retrieve(&server_name, &config, cx);
88 let session_id = match &mut resuming {
89 Some(_resuming) => {
90 debug!("Resuming session");
91 match &mut _resuming.value {
92 #[cfg(feature = "tls12")]
93 ClientSessionValue::Tls12(inner) => {
94 if !inner.ticket().0.is_empty() {
98 inner.session_id = SessionId::random(config.provider.secure_random)?;
99 }
100 Some(inner.session_id)
101 }
102 _ => None,
103 }
104 }
105 _ => {
106 debug!("Not resuming any session");
107 None
108 }
109 };
110
111 let session_id = match session_id {
114 Some(session_id) => session_id,
115 None if cx.common.is_quic() => SessionId::empty(),
116 None if !config.supports_version(ProtocolVersion::TLSv1_3, cx.common.protocol) => {
117 SessionId::empty()
118 }
119 None => SessionId::random(config.provider.secure_random)?,
120 };
121
122 let hello = ClientHelloDetails::new(
123 extra_exts
124 .protocols
125 .clone()
126 .unwrap_or_default(),
127 crate::rand::random_u16(config.provider.secure_random)?,
128 );
129
130 Ok(Self {
131 resuming,
132 random: Random::new(config.provider.secure_random)?,
133 sent_tls13_fake_ccs: false,
134 hello,
135 session_id,
136 server_name,
137 prev_ech_ext: None,
138 config,
139 })
140 }
141
142 pub(super) fn start_handshake(
143 self,
144 extra_exts: ClientExtensionsInput<'static>,
145 cx: &mut ClientContext<'_>,
146 ) -> NextStateOrError<'static> {
147 let mut transcript_buffer = HandshakeHashBuffer::new();
148 if self
149 .config
150 .client_auth_cert_resolver
151 .has_certs()
152 {
153 transcript_buffer.set_client_auth_enabled();
154 }
155
156 let key_share = if self.config.needs_key_share() {
157 Some(tls13::initial_key_share(
158 &self.config,
159 &self.server_name,
160 &mut cx.common.kx_state,
161 )?)
162 } else {
163 None
164 };
165
166 let ech_state = match self.config.ech_mode.as_ref() {
167 Some(EchMode::Enable(ech_config)) => {
168 Some(ech_config.state(self.server_name.clone(), &self.config)?)
169 }
170 _ => None,
171 };
172
173 emit_client_hello_for_retry(
174 transcript_buffer,
175 None,
176 key_share,
177 extra_exts,
178 None,
179 self,
180 cx,
181 ech_state,
182 )
183 }
184}
185
186fn emit_client_hello_for_retry(
192 mut transcript_buffer: HandshakeHashBuffer,
193 retryreq: Option<&HelloRetryRequest>,
194 key_share: Option<Box<dyn ActiveKeyExchange>>,
195 extra_exts: ClientExtensionsInput<'static>,
196 suite: Option<SupportedCipherSuite>,
197 mut input: ClientHelloInput,
198 cx: &mut ClientContext<'_>,
199 mut ech_state: Option<EchState>,
200) -> NextStateOrError<'static> {
201 let config = &input.config;
202 let forbids_tls12 = cx.common.is_quic() || ech_state.is_some();
205
206 let supported_versions = SupportedProtocolVersions {
207 tls12: config.supports_version(ProtocolVersion::TLSv1_2, cx.common.protocol)
208 && !forbids_tls12,
209 tls13: config.supports_version(ProtocolVersion::TLSv1_3, cx.common.protocol),
210 };
211
212 assert!(supported_versions.any(|_| true));
214
215 let mut exts = Box::new(ClientExtensions {
216 named_groups: Some(
218 config
219 .provider
220 .kx_groups
221 .iter()
222 .filter(|skxg| supported_versions.any(|v| skxg.usable_for_version(v)))
223 .map(|skxg| skxg.name())
224 .collect(),
225 ),
226 supported_versions: Some(supported_versions),
227 signature_schemes: Some(
228 config
229 .verifier
230 .supported_verify_schemes(),
231 ),
232 extended_master_secret_request: Some(()),
233 certificate_status_request: Some(CertificateStatusRequest::build_ocsp()),
234 protocols: extra_exts.protocols.clone(),
235 ..Default::default()
236 });
237
238 if !config
239 .crypto_provider()
240 .cipher_suites
241 .iter()
242 .any(|cs| cs.tls13().is_some())
243 {
244 if let Some(schemes) = &mut exts.signature_schemes {
245 schemes.retain(|scheme| scheme.algorithm().is_some());
246 }
247 }
248
249 match extra_exts.transport_parameters.clone() {
250 Some(TransportParameters::Quic(v)) => exts.transport_parameters = Some(v),
251 Some(TransportParameters::QuicDraft(v)) => exts.transport_parameters_draft = Some(v),
252 None => {}
253 };
254
255 if supported_versions.tls13 {
256 if let Some(cas_extension) = config.verifier.root_hint_subjects() {
257 exts.certificate_authority_names = Some(cas_extension.to_owned());
258 }
259 }
260
261 if config
263 .provider
264 .kx_groups
265 .iter()
266 .any(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::ECDHE)
267 {
268 exts.ec_point_formats = Some(SupportedEcPointFormats::default());
269 }
270
271 exts.server_name = match (ech_state.as_ref(), config.enable_sni) {
272 (Some(ech_state), _) => Some(ServerNamePayload::from(&ech_state.outer_name)),
277
278 (None, true) => match &input.server_name {
281 ServerName::DnsName(dns_name) => Some(ServerNamePayload::from(dns_name)),
282 _ => None,
283 },
284
285 (None, false) => None,
287 };
288
289 if let Some(key_share) = &key_share {
290 debug_assert!(supported_versions.tls13);
291 let mut shares = vec![KeyShareEntry::new(key_share.group(), key_share.pub_key())];
292
293 if !retryreq
294 .map(|rr| rr.key_share.is_some())
295 .unwrap_or_default()
296 {
297 if let Some((component_group, component_share)) =
302 key_share
303 .hybrid_component()
304 .filter(|(group, _)| {
305 config
306 .find_kx_group(*group, ProtocolVersion::TLSv1_3)
307 .is_some()
308 })
309 {
310 shares.push(KeyShareEntry::new(component_group, component_share));
311 }
312 }
313
314 exts.key_shares = Some(shares);
315 }
316
317 if let Some(cookie) = retryreq.and_then(|hrr| hrr.cookie.as_ref()) {
318 exts.cookie = Some(cookie.clone());
319 }
320
321 if supported_versions.tls13 {
322 exts.preshared_key_modes = Some(PskKeyExchangeModes {
325 psk: false,
326 psk_dhe: true,
327 });
328
329 if let Some(ticket_req) = &config.send_ticket_request {
330 exts.ticket_request = Some(ClientTicketRequest {
331 new_session_count: ticket_req.new_session_count,
332 resumption_count: ticket_req.resumption_count,
333 });
334 }
335 }
336
337 input.hello.offered_cert_compression =
338 if supported_versions.tls13 && !config.cert_decompressors.is_empty() {
339 exts.certificate_compression_algorithms = Some(
340 config
341 .cert_decompressors
342 .iter()
343 .map(|dec| dec.algorithm())
344 .collect(),
345 );
346 true
347 } else {
348 false
349 };
350
351 if config
352 .client_auth_cert_resolver
353 .only_raw_public_keys()
354 {
355 exts.client_certificate_types = Some(vec![CertificateType::RawPublicKey]);
356 }
357
358 if config
359 .verifier
360 .requires_raw_public_keys()
361 {
362 exts.server_certificate_types = Some(vec![CertificateType::RawPublicKey]);
363 }
364
365 if matches!(cx.data.ech_status, EchStatus::Rejected | EchStatus::Grease) & retryreq.is_some() {
369 if let Some(prev_ech_ext) = input.prev_ech_ext.take() {
370 exts.encrypted_client_hello = Some(prev_ech_ext);
371 }
372 }
373
374 let tls13_session = prepare_resumption(&input.resuming, &mut exts, suite, cx, config);
376
377 exts.order_seed = input.hello.extension_order_seed;
380
381 let mut cipher_suites: Vec<_> = config
382 .provider
383 .cipher_suites
384 .iter()
385 .filter_map(|cs| match cs.usable_for_protocol(cx.common.protocol) {
386 true => Some(cs.suite()),
387 false => None,
388 })
389 .collect();
390
391 if supported_versions.tls12 {
392 cipher_suites.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
394 }
395
396 let mut chp_payload = ClientHelloPayload {
397 client_version: ProtocolVersion::TLSv1_2,
398 random: input.random,
399 session_id: input.session_id,
400 cipher_suites,
401 compression_methods: vec![Compression::Null],
402 extensions: exts,
403 };
404
405 let ech_grease_ext = config
406 .ech_mode
407 .as_ref()
408 .and_then(|mode| match mode {
409 EchMode::Grease(cfg) => Some(cfg.grease_ext(
410 config.provider.secure_random,
411 input.server_name.clone(),
412 &chp_payload,
413 )),
414 _ => None,
415 });
416
417 match (cx.data.ech_status, &mut ech_state) {
418 (EchStatus::NotOffered | EchStatus::Offered, Some(ech_state)) => {
421 chp_payload = ech_state.ech_hello(chp_payload, retryreq, &tls13_session)?;
423 cx.data.ech_status = EchStatus::Offered;
424 input.prev_ech_ext = chp_payload
426 .encrypted_client_hello
427 .clone();
428 }
429 (EchStatus::NotOffered, None) => {
432 if let Some(grease_ext) = ech_grease_ext {
433 let grease_ext = grease_ext?;
435 chp_payload.encrypted_client_hello = Some(grease_ext.clone());
436 cx.data.ech_status = EchStatus::Grease;
437 input.prev_ech_ext = Some(grease_ext);
440 }
441 }
442 _ => {}
443 }
444
445 input.hello.sent_extensions = chp_payload.collect_used();
447 input.hello.offered_cipher_suites = chp_payload.cipher_suites.clone();
448
449 let mut chp = HandshakeMessagePayload(HandshakePayload::ClientHello(chp_payload));
450
451 let tls13_early_data_key_schedule = match (ech_state.as_mut(), tls13_session) {
452 (Some(ech_state), Some(tls13_session)) => ech_state
455 .early_data_key_schedule
456 .take()
457 .map(|schedule| (tls13_session.suite(), schedule)),
458
459 (_, Some(tls13_session)) => Some((
462 tls13_session.suite(),
463 tls13::fill_in_psk_binder(&tls13_session, &transcript_buffer, &mut chp),
464 )),
465
466 _ => None,
468 };
469
470 let ch = Message {
471 version: match retryreq {
472 Some(_) => ProtocolVersion::TLSv1_2,
476 None => ProtocolVersion::TLSv1_0,
482 },
483 payload: MessagePayload::handshake(chp),
484 };
485
486 if retryreq.is_some() {
487 tls13::emit_fake_ccs(&mut input.sent_tls13_fake_ccs, cx.common);
490 }
491
492 trace!("Sending ClientHello {ch:#?}");
493
494 transcript_buffer.add_message(&ch);
495 cx.common.send_msg(ch, false);
496
497 let early_data_key_schedule =
499 tls13_early_data_key_schedule.map(|(resuming_suite, schedule)| {
500 if !cx.data.early_data.is_enabled() {
501 return schedule;
502 }
503
504 let (transcript_buffer, random) = match &ech_state {
505 Some(ech_state) => (
508 &ech_state.inner_hello_transcript,
509 &ech_state.inner_hello_random.0,
510 ),
511 None => (&transcript_buffer, &input.random.0),
512 };
513
514 tls13::derive_early_traffic_secret(
515 &*config.key_log,
516 cx,
517 resuming_suite.common.hash_provider,
518 &schedule,
519 &mut input.sent_tls13_fake_ccs,
520 transcript_buffer,
521 random,
522 );
523 schedule
524 });
525
526 let next = ExpectServerHello {
527 input,
528 transcript_buffer,
529 early_data_key_schedule,
530 offered_key_share: key_share,
531 suite,
532 ech_state,
533 };
534
535 Ok(if supported_versions.tls13 && retryreq.is_none() {
536 Box::new(ExpectServerHelloOrHelloRetryRequest {
537 next,
538 extra_exts: extra_exts.into_owned(),
539 })
540 } else {
541 Box::new(next)
542 })
543}
544
545fn prepare_resumption<'a>(
561 resuming: &'a Option<persist::Retrieved<ClientSessionValue>>,
562 exts: &mut ClientExtensions<'_>,
563 suite: Option<SupportedCipherSuite>,
564 cx: &mut ClientContext<'_>,
565 config: &ClientConfig,
566) -> Option<persist::Retrieved<&'a persist::Tls13ClientSessionValue>> {
567 let resuming = match resuming {
569 Some(resuming) if !resuming.ticket().is_empty() => resuming,
570 _ => {
571 if config.supports_version(ProtocolVersion::TLSv1_2, cx.common.protocol)
572 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
573 {
574 exts.session_ticket = Some(ClientSessionTicket::Request);
576 }
577 return None;
578 }
579 };
580
581 let Some(tls13) = resuming.map(|csv| csv.tls13()) else {
582 if config.supports_version(ProtocolVersion::TLSv1_2, cx.common.protocol)
584 && config.resumption.tls12_resumption == Tls12Resumption::SessionIdOrTickets
585 {
586 exts.session_ticket = Some(ClientSessionTicket::Offer(Payload::new(resuming.ticket())));
587 }
588 return None; };
590
591 if !config.supports_version(ProtocolVersion::TLSv1_3, cx.common.protocol) {
592 return None;
593 }
594
595 let suite = match suite {
597 Some(SupportedCipherSuite::Tls13(suite)) => Some(suite),
598 #[cfg(feature = "tls12")]
599 Some(SupportedCipherSuite::Tls12(_)) => return None,
600 None => None,
601 };
602
603 if let Some(suite) = suite {
605 suite.can_resume_from(tls13.suite())?;
606 }
607
608 tls13::prepare_resumption(config, cx, &tls13, exts, suite.is_some());
609 Some(tls13)
610}
611
612pub(super) fn process_alpn_protocol(
613 common: &mut CommonState,
614 offered_protocols: &[ProtocolName],
615 selected: Option<&ProtocolName>,
616 check_selected_offered: bool,
617) -> Result<(), Error> {
618 common.alpn_protocol = selected.map(ToOwned::to_owned);
619
620 if let Some(alpn_protocol) = &common.alpn_protocol {
621 if check_selected_offered && !offered_protocols.contains(alpn_protocol) {
622 return Err(common.send_fatal_alert(
623 AlertDescription::IllegalParameter,
624 PeerMisbehaved::SelectedUnofferedApplicationProtocol,
625 ));
626 }
627 }
628
629 if common.is_quic() && common.alpn_protocol.is_none() && !offered_protocols.is_empty() {
636 return Err(common.send_fatal_alert(
637 AlertDescription::NoApplicationProtocol,
638 Error::NoApplicationProtocol,
639 ));
640 }
641
642 debug!(
643 "ALPN protocol is {:?}",
644 common
645 .alpn_protocol
646 .as_ref()
647 .map(|v| bs_debug::BsDebug(v.as_ref()))
648 );
649 Ok(())
650}
651
652pub(super) fn process_server_cert_type_extension(
653 common: &mut CommonState,
654 config: &ClientConfig,
655 server_cert_extension: Option<&CertificateType>,
656) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
657 process_cert_type_extension(
658 common,
659 config
660 .verifier
661 .requires_raw_public_keys(),
662 server_cert_extension.copied(),
663 ExtensionType::ServerCertificateType,
664 )
665}
666
667pub(super) fn process_client_cert_type_extension(
668 common: &mut CommonState,
669 config: &ClientConfig,
670 client_cert_extension: Option<&CertificateType>,
671) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
672 process_cert_type_extension(
673 common,
674 config
675 .client_auth_cert_resolver
676 .only_raw_public_keys(),
677 client_cert_extension.copied(),
678 ExtensionType::ClientCertificateType,
679 )
680}
681
682impl State<ClientConnectionData> for ExpectServerHello {
683 fn handle<'m>(
684 mut self: Box<Self>,
685 cx: &mut ClientContext<'_>,
686 m: Message<'m>,
687 ) -> NextStateOrError<'m>
688 where
689 Self: 'm,
690 {
691 let server_hello =
692 require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
693 trace!("We got ServerHello {server_hello:#?}");
694
695 use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
696 let config = &self.input.config;
697 let tls13_supported = config.supports_version(TLSv1_3, cx.common.protocol);
698
699 let server_version = if server_hello.legacy_version == TLSv1_2 {
700 server_hello
701 .selected_version
702 .unwrap_or(server_hello.legacy_version)
703 } else {
704 server_hello.legacy_version
705 };
706
707 let version = match server_version {
708 TLSv1_3 if tls13_supported => TLSv1_3,
709 TLSv1_2 if config.supports_version(TLSv1_2, cx.common.protocol) => {
710 if cx.data.early_data.is_enabled() && cx.common.early_traffic {
711 return Err(PeerMisbehaved::OfferedEarlyDataWithOldProtocolVersion.into());
714 }
715
716 if server_hello.selected_version.is_some() {
717 return Err({
718 cx.common.send_fatal_alert(
719 AlertDescription::IllegalParameter,
720 PeerMisbehaved::SelectedTls12UsingTls13VersionExtension,
721 )
722 });
723 }
724
725 TLSv1_2
726 }
727 _ => {
728 let reason = match server_version {
729 TLSv1_2 | TLSv1_3 => PeerIncompatible::ServerTlsVersionIsDisabledByOurConfig,
730 _ => PeerIncompatible::ServerDoesNotSupportTls12Or13,
731 };
732 return Err(cx
733 .common
734 .send_fatal_alert(AlertDescription::ProtocolVersion, reason));
735 }
736 };
737
738 if server_hello.compression_method != Compression::Null {
739 return Err({
740 cx.common.send_fatal_alert(
741 AlertDescription::IllegalParameter,
742 PeerMisbehaved::SelectedUnofferedCompression,
743 )
744 });
745 }
746
747 let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
748 if self
749 .input
750 .hello
751 .server_sent_unsolicited_extensions(server_hello, &allowed_unsolicited)
752 {
753 return Err(cx.common.send_fatal_alert(
754 AlertDescription::UnsupportedExtension,
755 PeerMisbehaved::UnsolicitedServerHelloExtension,
756 ));
757 }
758
759 cx.common.negotiated_version = Some(version);
760
761 if !cx.common.is_tls13() {
763 process_alpn_protocol(
764 cx.common,
765 &self.input.hello.alpn_protocols,
766 server_hello
767 .selected_protocol
768 .as_ref()
769 .map(|s| s.as_ref()),
770 self.input.config.check_selected_alpn,
771 )?;
772 }
773
774 if let Some(point_fmts) = &server_hello.ec_point_formats {
777 if !point_fmts.uncompressed {
778 return Err(cx.common.send_fatal_alert(
779 AlertDescription::HandshakeFailure,
780 PeerMisbehaved::ServerHelloMustOfferUncompressedEcPoints,
781 ));
782 }
783 }
784
785 let Some(Some(suite)) = self
786 .input
787 .hello
788 .offered_cipher_suites
789 .contains(&server_hello.cipher_suite)
790 .then(|| config.find_cipher_suite(server_hello.cipher_suite, cx.common.protocol))
791 else {
792 return Err(cx.common.send_fatal_alert(
793 AlertDescription::HandshakeFailure,
794 PeerMisbehaved::SelectedUnofferedCipherSuite,
795 ));
796 };
797
798 if version != suite.version().version {
799 return Err({
800 cx.common.send_fatal_alert(
801 AlertDescription::IllegalParameter,
802 PeerMisbehaved::SelectedUnusableCipherSuiteForVersion,
803 )
804 });
805 }
806
807 match self.suite {
808 Some(prev_suite) if prev_suite != suite => {
809 return Err({
810 cx.common.send_fatal_alert(
811 AlertDescription::IllegalParameter,
812 PeerMisbehaved::SelectedDifferentCipherSuiteAfterRetry,
813 )
814 });
815 }
816 _ => {
817 debug!("Using ciphersuite {suite:?}");
818 self.suite = Some(suite);
819 cx.common.suite = Some(suite);
820 }
821 }
822
823 let mut transcript = self
825 .transcript_buffer
826 .start_hash(suite.hash_provider());
827 transcript.add_message(&m);
828
829 let randoms = ConnectionRandoms::new(self.input.random, server_hello.random);
830 match suite {
833 SupportedCipherSuite::Tls13(suite) => {
834 tls13::handle_server_hello(
835 cx,
836 server_hello,
837 randoms,
838 suite,
839 transcript,
840 self.early_data_key_schedule,
841 self.offered_key_share.unwrap(),
843 &m,
844 self.ech_state,
845 self.input,
846 )
847 }
848 #[cfg(feature = "tls12")]
849 SupportedCipherSuite::Tls12(suite) => tls12::CompleteServerHelloHandling {
850 randoms,
851 transcript,
852 input: self.input,
853 }
854 .handle_server_hello(cx, suite, server_hello, tls13_supported),
855 }
856 }
857
858 fn into_owned(self: Box<Self>) -> NextState<'static> {
859 self
860 }
861}
862
863impl ExpectServerHelloOrHelloRetryRequest {
864 fn into_expect_server_hello(self) -> NextState<'static> {
865 Box::new(self.next)
866 }
867
868 fn handle_hello_retry_request(
869 mut self,
870 cx: &mut ClientContext<'_>,
871 m: Message<'_>,
872 ) -> NextStateOrError<'static> {
873 let hrr = require_handshake_msg!(
874 m,
875 HandshakeType::HelloRetryRequest,
876 HandshakePayload::HelloRetryRequest
877 )?;
878 trace!("Got HRR {hrr:?}");
879
880 cx.common.check_aligned_handshake()?;
881
882 let offered_key_share = self.next.offered_key_share.unwrap();
884
885 let config = &self.next.input.config;
888
889 if let (None, Some(req_group)) = (&hrr.cookie, hrr.key_share) {
890 let offered_hybrid = offered_key_share
891 .hybrid_component()
892 .and_then(|(group_name, _)| {
893 config.find_kx_group(group_name, ProtocolVersion::TLSv1_3)
894 })
895 .map(|skxg| skxg.name());
896
897 if req_group == offered_key_share.group() || Some(req_group) == offered_hybrid {
898 return Err({
899 cx.common.send_fatal_alert(
900 AlertDescription::IllegalParameter,
901 PeerMisbehaved::IllegalHelloRetryRequestWithOfferedGroup,
902 )
903 });
904 }
905 }
906
907 if let Some(cookie) = &hrr.cookie {
909 if cookie.0.is_empty() {
910 return Err({
911 cx.common.send_fatal_alert(
912 AlertDescription::IllegalParameter,
913 PeerMisbehaved::IllegalHelloRetryRequestWithEmptyCookie,
914 )
915 });
916 }
917 }
918
919 if hrr.cookie.is_none() && hrr.key_share.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 Some(cs) = config.find_cipher_suite(hrr.cipher_suite, cx.common.protocol) else {
968 return Err({
969 cx.common.send_fatal_alert(
970 AlertDescription::IllegalParameter,
971 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedCipherSuite,
972 )
973 });
974 };
975
976 if cx.data.ech_status == EchStatus::NotOffered && hrr.encrypted_client_hello.is_some() {
978 return Err({
979 cx.common.send_fatal_alert(
980 AlertDescription::UnsupportedExtension,
981 PeerMisbehaved::IllegalHelloRetryRequestWithInvalidEch,
982 )
983 });
984 }
985
986 cx.common.suite = Some(cs);
988 cx.common.handshake_kind = Some(HandshakeKind::FullWithHelloRetryRequest);
989
990 match (self.next.ech_state.as_ref(), cs.tls13()) {
992 (Some(ech_state), Some(tls13_cs))
996 if !ech_state.confirm_hrr_acceptance(hrr, tls13_cs, cx.common)? =>
997 {
998 cx.data.ech_status = EchStatus::Rejected
999 }
1000 (Some(_), None) => {
1001 unreachable!("ECH state should only be set when TLS 1.3 was negotiated")
1002 }
1003 _ => {}
1004 };
1005
1006 let transcript = self
1008 .next
1009 .transcript_buffer
1010 .start_hash(cs.hash_provider());
1011 let mut transcript_buffer = transcript.into_hrr_buffer();
1012 transcript_buffer.add_message(&m);
1013
1014 if let Some(ech_state) = self.next.ech_state.as_mut() {
1017 ech_state.transcript_hrr_update(cs.hash_provider(), &m);
1018 }
1019
1020 if cx.data.early_data.is_enabled() {
1022 cx.data.early_data.rejected();
1023 }
1024
1025 let key_share = match hrr.key_share {
1026 Some(group) if group != offered_key_share.group() => {
1027 let Some(skxg) = config.find_kx_group(group, ProtocolVersion::TLSv1_3) else {
1028 return Err(cx.common.send_fatal_alert(
1029 AlertDescription::IllegalParameter,
1030 PeerMisbehaved::IllegalHelloRetryRequestWithUnofferedNamedGroup,
1031 ));
1032 };
1033
1034 cx.common.kx_state = KxState::Start(skxg);
1035 skxg.start()?
1036 }
1037 _ => offered_key_share,
1038 };
1039
1040 emit_client_hello_for_retry(
1041 transcript_buffer,
1042 Some(hrr),
1043 Some(key_share),
1044 self.extra_exts,
1045 Some(cs),
1046 self.next.input,
1047 cx,
1048 self.next.ech_state,
1049 )
1050 }
1051}
1052
1053impl State<ClientConnectionData> for ExpectServerHelloOrHelloRetryRequest {
1054 fn handle<'m>(
1055 self: Box<Self>,
1056 cx: &mut ClientContext<'_>,
1057 m: Message<'m>,
1058 ) -> NextStateOrError<'m>
1059 where
1060 Self: 'm,
1061 {
1062 match m.payload {
1063 MessagePayload::Handshake {
1064 parsed: HandshakeMessagePayload(HandshakePayload::ServerHello(..)),
1065 ..
1066 } => self
1067 .into_expect_server_hello()
1068 .handle(cx, m),
1069 MessagePayload::Handshake {
1070 parsed: HandshakeMessagePayload(HandshakePayload::HelloRetryRequest(..)),
1071 ..
1072 } => self.handle_hello_retry_request(cx, m),
1073 payload => Err(inappropriate_handshake_message(
1074 &payload,
1075 &[ContentType::Handshake],
1076 &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
1077 )),
1078 }
1079 }
1080
1081 fn into_owned(self: Box<Self>) -> NextState<'static> {
1082 self
1083 }
1084}
1085
1086fn process_cert_type_extension(
1087 common: &mut CommonState,
1088 client_expects: bool,
1089 server_negotiated: Option<CertificateType>,
1090 extension_type: ExtensionType,
1091) -> Result<Option<(ExtensionType, CertificateType)>, Error> {
1092 match (client_expects, server_negotiated) {
1093 (true, Some(CertificateType::RawPublicKey)) => {
1094 Ok(Some((extension_type, CertificateType::RawPublicKey)))
1095 }
1096 (true, _) => Err(common.send_fatal_alert(
1097 AlertDescription::HandshakeFailure,
1098 Error::PeerIncompatible(PeerIncompatible::IncorrectCertificateTypeExtension),
1099 )),
1100 (_, Some(CertificateType::RawPublicKey)) => {
1101 unreachable!("Caught by `PeerMisbehaved::UnsolicitedEncryptedExtension`")
1102 }
1103 (_, _) => Ok(None),
1104 }
1105}
1106
1107pub(super) enum ClientSessionValue {
1108 Tls13(persist::Tls13ClientSessionValue),
1109 #[cfg(feature = "tls12")]
1110 Tls12(persist::Tls12ClientSessionValue),
1111}
1112
1113impl ClientSessionValue {
1114 fn retrieve(
1115 server_name: &ServerName<'static>,
1116 config: &ClientConfig,
1117 cx: &mut ClientContext<'_>,
1118 ) -> Option<persist::Retrieved<Self>> {
1119 let found = config
1120 .resumption
1121 .store
1122 .take_tls13_ticket(server_name)
1123 .map(ClientSessionValue::Tls13)
1124 .or_else(|| {
1125 #[cfg(feature = "tls12")]
1126 {
1127 config
1128 .resumption
1129 .store
1130 .tls12_session(server_name)
1131 .map(ClientSessionValue::Tls12)
1132 }
1133
1134 #[cfg(not(feature = "tls12"))]
1135 None
1136 })
1137 .and_then(|resuming| {
1138 resuming.compatible_config(&config.verifier, &config.client_auth_cert_resolver)
1139 })
1140 .and_then(|resuming| {
1141 let now = config
1142 .current_time()
1143 .map_err(|_err| debug!("Could not get current time: {_err}"))
1144 .ok()?;
1145
1146 let retrieved = persist::Retrieved::new(resuming, now);
1147 match retrieved.has_expired() {
1148 false => Some(retrieved),
1149 true => None,
1150 }
1151 })
1152 .or_else(|| {
1153 debug!("No cached session for {server_name:?}");
1154 None
1155 });
1156
1157 if let Some(resuming) = &found {
1158 if cx.common.is_quic() {
1159 cx.common.quic.params = resuming
1160 .tls13()
1161 .map(|v| v.quic_params());
1162 }
1163 }
1164
1165 found
1166 }
1167
1168 fn common(&self) -> &persist::ClientSessionCommon {
1169 match self {
1170 Self::Tls13(inner) => &inner.common,
1171 #[cfg(feature = "tls12")]
1172 Self::Tls12(inner) => &inner.common,
1173 }
1174 }
1175
1176 fn tls13(&self) -> Option<&persist::Tls13ClientSessionValue> {
1177 match self {
1178 Self::Tls13(v) => Some(v),
1179 #[cfg(feature = "tls12")]
1180 Self::Tls12(_) => None,
1181 }
1182 }
1183
1184 fn compatible_config(
1185 self,
1186 server_cert_verifier: &Arc<dyn ServerCertVerifier>,
1187 client_creds: &Arc<dyn ResolvesClientCert>,
1188 ) -> Option<Self> {
1189 match &self {
1190 Self::Tls13(v) => v
1191 .compatible_config(server_cert_verifier, client_creds)
1192 .then_some(self),
1193 #[cfg(feature = "tls12")]
1194 Self::Tls12(v) => v
1195 .compatible_config(server_cert_verifier, client_creds)
1196 .then_some(self),
1197 }
1198 }
1199}
1200
1201impl Deref for ClientSessionValue {
1202 type Target = persist::ClientSessionCommon;
1203
1204 fn deref(&self) -> &Self::Target {
1205 self.common()
1206 }
1207}