1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4
5use pki_types::DnsName;
6
7use super::server_conn::ServerConnectionData;
8#[cfg(feature = "tls12")]
9use super::tls12;
10use crate::common_state::{KxState, Protocol, State};
11use crate::conn::ConnectionRandoms;
12use crate::crypto::SupportedKxGroup;
13use crate::enums::{
14 AlertDescription, CipherSuite, HandshakeType, ProtocolVersion, SignatureAlgorithm,
15 SignatureScheme,
16};
17use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
18use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
19use crate::log::{debug, trace};
20use crate::msgs::enums::{CertificateType, Compression, ExtensionType, NamedGroup};
21#[cfg(feature = "tls12")]
22use crate::msgs::handshake::SessionId;
23use crate::msgs::handshake::{
24 ClientHelloPayload, HandshakePayload, KeyExchangeAlgorithm, Random, ServerExtension,
25 ServerNamePayload, SingleProtocolName,
26};
27use crate::msgs::message::{Message, MessagePayload};
28use crate::msgs::persist;
29use crate::server::common::ActiveCertifiedKey;
30use crate::server::{ClientHello, ServerConfig, tls13};
31use crate::sync::Arc;
32use crate::{SupportedCipherSuite, suites};
33
34pub(super) type NextState<'a> = Box<dyn State<ServerConnectionData> + 'a>;
35pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
36pub(super) type ServerContext<'a> = crate::common_state::Context<'a, ServerConnectionData>;
37
38pub(super) fn can_resume(
39 suite: SupportedCipherSuite,
40 sni: &Option<DnsName<'_>>,
41 using_ems: bool,
42 resumedata: &persist::ServerSessionValue,
43) -> bool {
44 resumedata.cipher_suite == suite.suite()
55 && (resumedata.extended_ms == using_ems || (resumedata.extended_ms && !using_ems))
56 && &resumedata.sni == sni
57}
58
59#[derive(Default)]
60pub(super) struct ExtensionProcessing {
61 pub(super) exts: Vec<ServerExtension>,
63 #[cfg(feature = "tls12")]
64 pub(super) send_ticket: bool,
65}
66
67impl ExtensionProcessing {
68 pub(super) fn new() -> Self {
69 Default::default()
70 }
71
72 pub(super) fn process_common(
73 &mut self,
74 config: &ServerConfig,
75 cx: &mut ServerContext<'_>,
76 ocsp_response: &mut Option<&[u8]>,
77 hello: &ClientHelloPayload,
78 resumedata: Option<&persist::ServerSessionValue>,
79 extra_exts: Vec<ServerExtension>,
80 ) -> Result<(), Error> {
81 let our_protocols = &config.alpn_protocols;
83 let maybe_their_protocols = hello.alpn_extension();
84 if let Some(their_protocols) = maybe_their_protocols {
85 cx.common.alpn_protocol = our_protocols
86 .iter()
87 .find(|ours| {
88 their_protocols
89 .iter()
90 .any(|theirs| theirs.as_ref() == ours.as_slice())
91 })
92 .cloned();
93 if let Some(selected_protocol) = &cx.common.alpn_protocol {
94 debug!("Chosen ALPN protocol {:?}", selected_protocol);
95 self.exts
96 .push(ServerExtension::Protocols(SingleProtocolName::new(
97 selected_protocol.clone(),
98 )));
99 } else if !our_protocols.is_empty() {
100 return Err(cx.common.send_fatal_alert(
101 AlertDescription::NoApplicationProtocol,
102 Error::NoApplicationProtocol,
103 ));
104 }
105 }
106
107 if cx.common.is_quic() {
108 if cx.common.alpn_protocol.is_none()
116 && (!our_protocols.is_empty() || maybe_their_protocols.is_some())
117 {
118 return Err(cx.common.send_fatal_alert(
119 AlertDescription::NoApplicationProtocol,
120 Error::NoApplicationProtocol,
121 ));
122 }
123
124 match hello.quic_params_extension() {
125 Some(params) => cx.common.quic.params = Some(params),
126 None => {
127 return Err(cx
128 .common
129 .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
130 }
131 }
132 }
133
134 let for_resume = resumedata.is_some();
135 if !for_resume && hello.sni_extension().is_some() {
137 self.exts
138 .push(ServerExtension::ServerNameAck);
139 }
140
141 if !for_resume
145 && hello
146 .find_extension(ExtensionType::StatusRequest)
147 .is_some()
148 {
149 if ocsp_response.is_some() && !cx.common.is_tls13() {
150 self.exts
152 .push(ServerExtension::CertificateStatusAck);
153 }
154 } else {
155 ocsp_response.take();
157 }
158
159 self.validate_server_cert_type_extension(hello, config, cx)?;
160 self.validate_client_cert_type_extension(hello, config, cx)?;
161
162 self.exts.extend(extra_exts);
163
164 Ok(())
165 }
166
167 #[cfg(feature = "tls12")]
168 pub(super) fn process_tls12(
169 &mut self,
170 config: &ServerConfig,
171 hello: &ClientHelloPayload,
172 using_ems: bool,
173 ) {
174 let secure_reneg_offered = hello
177 .find_extension(ExtensionType::RenegotiationInfo)
178 .is_some()
179 || hello
180 .cipher_suites
181 .contains(&CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
182
183 if secure_reneg_offered {
184 self.exts
185 .push(ServerExtension::make_empty_renegotiation_info());
186 }
187
188 if hello
192 .find_extension(ExtensionType::SessionTicket)
193 .is_some()
194 && config.ticketer.enabled()
195 {
196 self.send_ticket = true;
197 self.exts
198 .push(ServerExtension::SessionTicketAck);
199 }
200
201 if using_ems {
203 self.exts
204 .push(ServerExtension::ExtendedMasterSecretAck);
205 }
206 }
207
208 fn validate_server_cert_type_extension(
209 &mut self,
210 hello: &ClientHelloPayload,
211 config: &ServerConfig,
212 cx: &mut ServerContext<'_>,
213 ) -> Result<(), Error> {
214 let client_supports = hello
215 .server_certificate_extension()
216 .map(|certificate_types| certificate_types.to_vec())
217 .unwrap_or_default();
218
219 self.process_cert_type_extension(
220 client_supports,
221 config
222 .cert_resolver
223 .only_raw_public_keys(),
224 ExtensionType::ServerCertificateType,
225 cx,
226 )
227 }
228
229 fn validate_client_cert_type_extension(
230 &mut self,
231 hello: &ClientHelloPayload,
232 config: &ServerConfig,
233 cx: &mut ServerContext<'_>,
234 ) -> Result<(), Error> {
235 let client_supports = hello
236 .client_certificate_extension()
237 .map(|certificate_types| certificate_types.to_vec())
238 .unwrap_or_default();
239
240 self.process_cert_type_extension(
241 client_supports,
242 config
243 .verifier
244 .requires_raw_public_keys(),
245 ExtensionType::ClientCertificateType,
246 cx,
247 )
248 }
249
250 fn process_cert_type_extension(
251 &mut self,
252 client_supports: Vec<CertificateType>,
253 requires_raw_keys: bool,
254 extension_type: ExtensionType,
255 cx: &mut ServerContext<'_>,
256 ) -> Result<(), Error> {
257 debug_assert!(
258 extension_type == ExtensionType::ClientCertificateType
259 || extension_type == ExtensionType::ServerCertificateType
260 );
261 let raw_key_negotation_result = match (
262 requires_raw_keys,
263 client_supports.contains(&CertificateType::RawPublicKey),
264 client_supports.contains(&CertificateType::X509),
265 ) {
266 (true, true, _) => Ok((extension_type, CertificateType::RawPublicKey)),
267 (false, _, true) => Ok((extension_type, CertificateType::X509)),
268 (false, true, false) => Err(Error::PeerIncompatible(
269 PeerIncompatible::IncorrectCertificateTypeExtension,
270 )),
271 (true, false, _) => Err(Error::PeerIncompatible(
272 PeerIncompatible::IncorrectCertificateTypeExtension,
273 )),
274 (false, false, false) => return Ok(()),
275 };
276
277 match raw_key_negotation_result {
278 Ok((ExtensionType::ClientCertificateType, cert_type)) => {
279 self.exts
280 .push(ServerExtension::ClientCertType(cert_type));
281 }
282 Ok((ExtensionType::ServerCertificateType, cert_type)) => {
283 self.exts
284 .push(ServerExtension::ServerCertType(cert_type));
285 }
286 Err(err) => {
287 return Err(cx
288 .common
289 .send_fatal_alert(AlertDescription::HandshakeFailure, err));
290 }
291 Ok((_, _)) => unreachable!(),
292 }
293 Ok(())
294 }
295}
296
297pub(super) struct ExpectClientHello {
298 pub(super) config: Arc<ServerConfig>,
299 pub(super) extra_exts: Vec<ServerExtension>,
300 pub(super) transcript: HandshakeHashOrBuffer,
301 #[cfg(feature = "tls12")]
302 pub(super) session_id: SessionId,
303 #[cfg(feature = "tls12")]
304 pub(super) using_ems: bool,
305 pub(super) done_retry: bool,
306 pub(super) send_tickets: usize,
307}
308
309impl ExpectClientHello {
310 pub(super) fn new(config: Arc<ServerConfig>, extra_exts: Vec<ServerExtension>) -> Self {
311 let mut transcript_buffer = HandshakeHashBuffer::new();
312
313 if config.verifier.offer_client_auth() {
314 transcript_buffer.set_client_auth_enabled();
315 }
316
317 Self {
318 config,
319 extra_exts,
320 transcript: HandshakeHashOrBuffer::Buffer(transcript_buffer),
321 #[cfg(feature = "tls12")]
322 session_id: SessionId::empty(),
323 #[cfg(feature = "tls12")]
324 using_ems: false,
325 done_retry: false,
326 send_tickets: 0,
327 }
328 }
329
330 pub(super) fn with_certified_key(
332 self,
333 mut sig_schemes: Vec<SignatureScheme>,
334 client_hello: &ClientHelloPayload,
335 m: &Message<'_>,
336 cx: &mut ServerContext<'_>,
337 ) -> NextStateOrError<'static> {
338 let tls13_enabled = self
339 .config
340 .supports_version(ProtocolVersion::TLSv1_3);
341 let tls12_enabled = self
342 .config
343 .supports_version(ProtocolVersion::TLSv1_2);
344
345 let maybe_versions_ext = client_hello.versions_extension();
347 let version = if let Some(versions) = maybe_versions_ext {
348 if versions.tls13 && tls13_enabled {
349 ProtocolVersion::TLSv1_3
350 } else if !versions.tls12 || !tls12_enabled {
351 return Err(cx.common.send_fatal_alert(
352 AlertDescription::ProtocolVersion,
353 PeerIncompatible::Tls12NotOfferedOrEnabled,
354 ));
355 } else if cx.common.is_quic() {
356 return Err(cx.common.send_fatal_alert(
357 AlertDescription::ProtocolVersion,
358 PeerIncompatible::Tls13RequiredForQuic,
359 ));
360 } else {
361 ProtocolVersion::TLSv1_2
362 }
363 } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
364 return Err(cx.common.send_fatal_alert(
365 AlertDescription::ProtocolVersion,
366 PeerIncompatible::Tls12NotOffered,
367 ));
368 } else if !tls12_enabled && tls13_enabled {
369 return Err(cx.common.send_fatal_alert(
370 AlertDescription::ProtocolVersion,
371 PeerIncompatible::SupportedVersionsExtensionRequired,
372 ));
373 } else if cx.common.is_quic() {
374 return Err(cx.common.send_fatal_alert(
375 AlertDescription::ProtocolVersion,
376 PeerIncompatible::Tls13RequiredForQuic,
377 ));
378 } else {
379 ProtocolVersion::TLSv1_2
380 };
381
382 cx.common.negotiated_version = Some(version);
383
384 let client_suites = self
390 .config
391 .provider
392 .cipher_suites
393 .iter()
394 .copied()
395 .filter(|scs| {
396 client_hello
397 .cipher_suites
398 .contains(&scs.suite())
399 })
400 .collect::<Vec<_>>();
401
402 sig_schemes
403 .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
404
405 let certificate_authorities = match version {
407 ProtocolVersion::TLSv1_2 => None,
408 _ => client_hello.certificate_authorities_extension(),
409 };
410 let certkey = {
412 let client_hello = ClientHello {
413 server_name: &cx.data.sni,
414 signature_schemes: &sig_schemes,
415 alpn: client_hello.alpn_extension(),
416 client_cert_types: client_hello.server_certificate_extension(),
417 server_cert_types: client_hello.client_certificate_extension(),
418 cipher_suites: &client_hello.cipher_suites,
419 certificate_authorities,
420 };
421 trace!("Resolving server certificate: {client_hello:#?}");
422
423 let certkey = self
424 .config
425 .cert_resolver
426 .resolve(client_hello);
427
428 certkey.ok_or_else(|| {
429 cx.common.send_fatal_alert(
430 AlertDescription::AccessDenied,
431 Error::General("no server certificate chain resolved".to_owned()),
432 )
433 })?
434 };
435 let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
436
437 let (suite, skxg) = self
438 .choose_suite_and_kx_group(
439 version,
440 certkey.get_key().algorithm(),
441 cx.common.protocol,
442 client_hello
443 .namedgroups_extension()
444 .unwrap_or(&[]),
445 &client_hello.cipher_suites,
446 )
447 .map_err(|incompat| {
448 cx.common
449 .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
450 })?;
451
452 debug!("decided upon suite {:?}", suite);
453 cx.common.suite = Some(suite);
454 cx.common.kx_state = KxState::Start(skxg);
455
456 let starting_hash = suite.hash_provider();
458 let transcript = match self.transcript {
459 HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
460 HandshakeHashOrBuffer::Hash(inner)
461 if inner.algorithm() == starting_hash.algorithm() =>
462 {
463 inner
464 }
465 _ => {
466 return Err(cx.common.send_fatal_alert(
467 AlertDescription::IllegalParameter,
468 PeerMisbehaved::HandshakeHashVariedAfterRetry,
469 ));
470 }
471 };
472
473 let randoms = ConnectionRandoms::new(
475 client_hello.random,
476 Random::new(self.config.provider.secure_random)?,
477 );
478 match suite {
479 SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
480 config: self.config,
481 transcript,
482 suite,
483 randoms,
484 done_retry: self.done_retry,
485 send_tickets: self.send_tickets,
486 extra_exts: self.extra_exts,
487 }
488 .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
489 #[cfg(feature = "tls12")]
490 SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
491 config: self.config,
492 transcript,
493 session_id: self.session_id,
494 suite,
495 using_ems: self.using_ems,
496 randoms,
497 send_ticket: self.send_tickets > 0,
498 extra_exts: self.extra_exts,
499 }
500 .handle_client_hello(
501 cx,
502 certkey,
503 m,
504 client_hello,
505 skxg,
506 sig_schemes,
507 tls13_enabled,
508 ),
509 }
510 }
511
512 fn choose_suite_and_kx_group(
513 &self,
514 selected_version: ProtocolVersion,
515 sig_key_algorithm: SignatureAlgorithm,
516 protocol: Protocol,
517 client_groups: &[NamedGroup],
518 client_suites: &[CipherSuite],
519 ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
520 let mut ecdhe_possible = false;
523 let mut ffdhe_possible = false;
524 let mut ffdhe_offered = false;
525 let mut supported_groups = Vec::with_capacity(client_groups.len());
526
527 for offered_group in client_groups {
528 let supported = self
529 .config
530 .provider
531 .kx_groups
532 .iter()
533 .find(|skxg| {
534 skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
535 });
536
537 match offered_group.key_exchange_algorithm() {
538 KeyExchangeAlgorithm::DHE => {
539 ffdhe_possible |= supported.is_some();
540 ffdhe_offered = true;
541 }
542 KeyExchangeAlgorithm::ECDHE => {
543 ecdhe_possible |= supported.is_some();
544 }
545 }
546
547 supported_groups.push(supported);
548 }
549
550 let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
551 let first_supported_dhe_kxg = self
553 .config
554 .provider
555 .kx_groups
556 .iter()
557 .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
558 ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
559 first_supported_dhe_kxg
560 } else {
561 None
563 };
564
565 if !ecdhe_possible && !ffdhe_possible {
566 return Err(PeerIncompatible::NoKxGroupsInCommon);
567 }
568
569 let mut suitable_suites_iter = self
570 .config
571 .provider
572 .cipher_suites
573 .iter()
574 .filter(|suite| {
575 suite.usable_for_signature_algorithm(sig_key_algorithm)
577 && suite.version().version == selected_version
579 && suite.usable_for_protocol(protocol)
581 && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
583 || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
584 });
585
586 let suite = if self.config.ignore_client_order {
593 suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
594 } else {
595 let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
596 client_suites
597 .iter()
598 .find_map(|client_suite| {
599 suitable_suites
600 .iter()
601 .find(|x| *client_suite == x.suite())
602 })
603 .copied()
604 }
605 .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
606
607 let maybe_skxg = supported_groups
610 .iter()
611 .find_map(|maybe_skxg| match maybe_skxg {
612 Some(skxg) => suite
613 .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
614 .then_some(*skxg),
615 None => None,
616 });
617
618 if selected_version == ProtocolVersion::TLSv1_3 {
619 return Ok((*suite, *maybe_skxg.unwrap()));
621 }
622
623 match maybe_skxg {
626 Some(skxg) => Ok((*suite, *skxg)),
627 None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
628 if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
631 Ok((*suite, *server_selected_ffdhe_skxg))
632 } else {
633 Err(PeerIncompatible::NoKxGroupsInCommon)
634 }
635 }
636 None => Err(PeerIncompatible::NoKxGroupsInCommon),
637 }
638 }
639}
640
641impl State<ServerConnectionData> for ExpectClientHello {
642 fn handle<'m>(
643 self: Box<Self>,
644 cx: &mut ServerContext<'_>,
645 m: Message<'m>,
646 ) -> NextStateOrError<'m>
647 where
648 Self: 'm,
649 {
650 let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
651 self.with_certified_key(sig_schemes, client_hello, &m, cx)
652 }
653
654 fn into_owned(self: Box<Self>) -> NextState<'static> {
655 self
656 }
657}
658
659pub(super) fn process_client_hello<'m>(
669 m: &'m Message<'m>,
670 done_retry: bool,
671 cx: &mut ServerContext<'_>,
672) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
673 let client_hello =
674 require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
675 trace!("we got a clienthello {:?}", client_hello);
676
677 if !client_hello
678 .compression_methods
679 .contains(&Compression::Null)
680 {
681 return Err(cx.common.send_fatal_alert(
682 AlertDescription::IllegalParameter,
683 PeerIncompatible::NullCompressionRequired,
684 ));
685 }
686
687 if client_hello.has_duplicate_extension() {
688 return Err(cx.common.send_fatal_alert(
689 AlertDescription::DecodeError,
690 PeerMisbehaved::DuplicateClientHelloExtensions,
691 ));
692 }
693
694 cx.common.check_aligned_handshake()?;
696
697 let sni: Option<DnsName<'_>> = match client_hello.sni_extension() {
712 Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
713 Some(ServerNamePayload::IpAddress) => None,
714 Some(ServerNamePayload::Invalid) => {
715 return Err(cx.common.send_fatal_alert(
716 AlertDescription::IllegalParameter,
717 PeerMisbehaved::ServerNameMustContainOneHostName,
718 ));
719 }
720 None => None,
721 };
722
723 if let (Some(sni), false) = (&sni, done_retry) {
725 assert!(cx.data.sni.is_none());
728 cx.data.sni = Some(sni.clone());
729 } else if cx.data.sni != sni {
730 return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
731 }
732
733 let sig_schemes = client_hello
734 .sigalgs_extension()
735 .ok_or_else(|| {
736 cx.common.send_fatal_alert(
737 AlertDescription::HandshakeFailure,
738 PeerIncompatible::SignatureAlgorithmsExtensionRequired,
739 )
740 })?;
741
742 Ok((client_hello, sig_schemes.to_owned()))
743}
744
745pub(crate) enum HandshakeHashOrBuffer {
746 Buffer(HandshakeHashBuffer),
747 Hash(HandshakeHash),
748}