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, CertificateType, CipherSuite, HandshakeType, ProtocolVersion,
15 SignatureAlgorithm, SignatureScheme,
16};
17use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
18use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
19use crate::log::{debug, trace};
20use crate::msgs::enums::{Compression, ExtensionType, NamedGroup};
21#[cfg(feature = "tls12")]
22use crate::msgs::handshake::SessionId;
23use crate::msgs::handshake::{
24 ClientHelloPayload, HandshakePayload, KeyExchangeAlgorithm, ProtocolName, Random,
25 ServerExtensions, ServerExtensionsInput, ServerNamePayload, SingleProtocolName,
26 TransportParameters,
27};
28use crate::msgs::message::{Message, MessagePayload};
29use crate::msgs::persist;
30use crate::server::common::ActiveCertifiedKey;
31use crate::server::{ClientHello, ServerConfig, tls13};
32use crate::sync::Arc;
33use crate::{SupportedCipherSuite, suites};
34
35pub(super) type NextState<'a> = Box<dyn State<ServerConnectionData> + 'a>;
36pub(super) type NextStateOrError<'a> = Result<NextState<'a>, Error>;
37pub(super) type ServerContext<'a> = crate::common_state::Context<'a, ServerConnectionData>;
38
39pub(super) fn can_resume(
40 suite: SupportedCipherSuite,
41 sni: &Option<DnsName<'_>>,
42 using_ems: bool,
43 resumedata: &persist::ServerSessionValue,
44) -> bool {
45 resumedata.cipher_suite == suite.suite()
56 && (resumedata.extended_ms == using_ems || (resumedata.extended_ms && !using_ems))
57 && &resumedata.sni == sni
58}
59
60#[derive(Default)]
61pub(super) struct ExtensionProcessing {
62 pub(super) extensions: Box<ServerExtensions<'static>>,
64 #[cfg(feature = "tls12")]
65 pub(super) send_ticket: bool,
66}
67
68impl ExtensionProcessing {
69 pub(super) fn new(extra_exts: ServerExtensionsInput<'static>) -> Self {
70 let ServerExtensionsInput {
71 transport_parameters,
72 } = extra_exts;
73
74 let mut extensions = Box::new(ServerExtensions::default());
75 match transport_parameters {
76 Some(TransportParameters::Quic(v)) => extensions.transport_parameters = Some(v),
77 Some(TransportParameters::QuicDraft(v)) => {
78 extensions.transport_parameters_draft = Some(v)
79 }
80 None => {}
81 }
82
83 Self {
84 extensions,
85 #[cfg(feature = "tls12")]
86 send_ticket: false,
87 }
88 }
89
90 pub(super) fn process_common(
91 &mut self,
92 config: &ServerConfig,
93 cx: &mut ServerContext<'_>,
94 ocsp_response: &mut Option<&[u8]>,
95 hello: &ClientHelloPayload,
96 resumedata: Option<&persist::ServerSessionValue>,
97 ) -> Result<(), Error> {
98 let our_protocols = &config.alpn_protocols;
100 if let Some(their_protocols) = &hello.protocols {
101 cx.common.alpn_protocol = our_protocols
102 .iter()
103 .find(|ours| {
104 their_protocols
105 .iter()
106 .any(|theirs| theirs.as_ref() == ours.as_slice())
107 })
108 .map(|bytes| ProtocolName::from(bytes.clone()));
109 if let Some(selected_protocol) = &cx.common.alpn_protocol {
110 debug!("Chosen ALPN protocol {selected_protocol:?}");
111
112 self.extensions.selected_protocol =
113 Some(SingleProtocolName::new(selected_protocol.clone()));
114 } else if !our_protocols.is_empty() {
115 return Err(cx.common.send_fatal_alert(
116 AlertDescription::NoApplicationProtocol,
117 Error::NoApplicationProtocol,
118 ));
119 }
120 }
121
122 if cx.common.is_quic() {
123 if cx.common.alpn_protocol.is_none()
131 && (!our_protocols.is_empty() || hello.protocols.is_some())
132 {
133 return Err(cx.common.send_fatal_alert(
134 AlertDescription::NoApplicationProtocol,
135 Error::NoApplicationProtocol,
136 ));
137 }
138
139 let transport_params = hello
140 .transport_parameters
141 .as_ref()
142 .or(hello
143 .transport_parameters_draft
144 .as_ref());
145 match transport_params {
146 Some(params) => cx.common.quic.params = Some(params.to_owned().into_vec()),
147 None => {
148 return Err(cx
149 .common
150 .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
151 }
152 }
153 }
154
155 let for_resume = resumedata.is_some();
156 if let (false, Some(ServerNamePayload::SingleDnsName(_))) = (for_resume, &hello.server_name)
158 {
159 self.extensions.server_name_ack = Some(());
160 }
161
162 if !for_resume
166 && hello
167 .certificate_status_request
168 .is_some()
169 {
170 if ocsp_response.is_some() && !cx.common.is_tls13() {
171 self.extensions
173 .certificate_status_request_ack = Some(());
174 }
175 } else {
176 ocsp_response.take();
178 }
179
180 self.validate_server_cert_type_extension(hello, config, cx)?;
181 self.validate_client_cert_type_extension(hello, config, cx)?;
182
183 Ok(())
184 }
185
186 #[cfg(feature = "tls12")]
187 pub(super) fn process_tls12(
188 &mut self,
189 config: &ServerConfig,
190 hello: &ClientHelloPayload,
191 using_ems: bool,
192 ) {
193 use crate::msgs::base::PayloadU8;
197 let secure_reneg_offered = hello.renegotiation_info.is_some()
198 || hello
199 .cipher_suites
200 .contains(&CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
201
202 if secure_reneg_offered {
203 self.extensions.renegotiation_info = Some(PayloadU8::new(Vec::new()));
204 }
205
206 if hello.session_ticket.is_some() && config.ticketer.enabled() {
210 self.send_ticket = true;
211 self.extensions.session_ticket_ack = Some(());
212 }
213
214 if using_ems {
216 self.extensions
217 .extended_master_secret_ack = Some(());
218 }
219 }
220
221 fn validate_server_cert_type_extension(
222 &mut self,
223 hello: &ClientHelloPayload,
224 config: &ServerConfig,
225 cx: &mut ServerContext<'_>,
226 ) -> Result<(), Error> {
227 let client_supports = hello
228 .server_certificate_types
229 .as_deref()
230 .unwrap_or_default();
231
232 self.process_cert_type_extension(
233 client_supports,
234 config
235 .cert_resolver
236 .only_raw_public_keys(),
237 ExtensionType::ServerCertificateType,
238 cx,
239 )
240 }
241
242 fn validate_client_cert_type_extension(
243 &mut self,
244 hello: &ClientHelloPayload,
245 config: &ServerConfig,
246 cx: &mut ServerContext<'_>,
247 ) -> Result<(), Error> {
248 let client_supports = hello
249 .client_certificate_types
250 .as_deref()
251 .unwrap_or_default();
252
253 self.process_cert_type_extension(
254 client_supports,
255 config
256 .verifier
257 .requires_raw_public_keys(),
258 ExtensionType::ClientCertificateType,
259 cx,
260 )
261 }
262
263 fn process_cert_type_extension(
264 &mut self,
265 client_supports: &[CertificateType],
266 requires_raw_keys: bool,
267 extension_type: ExtensionType,
268 cx: &mut ServerContext<'_>,
269 ) -> Result<(), Error> {
270 debug_assert!(
271 extension_type == ExtensionType::ClientCertificateType
272 || extension_type == ExtensionType::ServerCertificateType
273 );
274 let raw_key_negotation_result = match (
275 requires_raw_keys,
276 client_supports.contains(&CertificateType::RawPublicKey),
277 client_supports.contains(&CertificateType::X509),
278 ) {
279 (true, true, _) => Ok((extension_type, CertificateType::RawPublicKey)),
280 (false, _, true) => Ok((extension_type, CertificateType::X509)),
281 (false, true, false) => Err(Error::PeerIncompatible(
282 PeerIncompatible::IncorrectCertificateTypeExtension,
283 )),
284 (true, false, _) => Err(Error::PeerIncompatible(
285 PeerIncompatible::IncorrectCertificateTypeExtension,
286 )),
287 (false, false, false) => return Ok(()),
288 };
289
290 match raw_key_negotation_result {
291 Ok((ExtensionType::ClientCertificateType, cert_type)) => {
292 self.extensions.client_certificate_type = Some(cert_type);
293 }
294 Ok((ExtensionType::ServerCertificateType, cert_type)) => {
295 self.extensions.server_certificate_type = Some(cert_type);
296 }
297 Err(err) => {
298 return Err(cx
299 .common
300 .send_fatal_alert(AlertDescription::HandshakeFailure, err));
301 }
302 Ok((_, _)) => unreachable!(),
303 }
304 Ok(())
305 }
306}
307
308pub(super) struct ExpectClientHello {
309 pub(super) config: Arc<ServerConfig>,
310 pub(super) extra_exts: ServerExtensionsInput<'static>,
311 pub(super) transcript: HandshakeHashOrBuffer,
312 #[cfg(feature = "tls12")]
313 pub(super) session_id: SessionId,
314 #[cfg(feature = "tls12")]
315 pub(super) using_ems: bool,
316 pub(super) done_retry: bool,
317 pub(super) send_tickets: usize,
318}
319
320impl ExpectClientHello {
321 pub(super) fn new(
322 config: Arc<ServerConfig>,
323 extra_exts: ServerExtensionsInput<'static>,
324 ) -> Self {
325 let mut transcript_buffer = HandshakeHashBuffer::new();
326
327 if config.verifier.offer_client_auth() {
328 transcript_buffer.set_client_auth_enabled();
329 }
330
331 Self {
332 config,
333 extra_exts,
334 transcript: HandshakeHashOrBuffer::Buffer(transcript_buffer),
335 #[cfg(feature = "tls12")]
336 session_id: SessionId::empty(),
337 #[cfg(feature = "tls12")]
338 using_ems: false,
339 done_retry: false,
340 send_tickets: 0,
341 }
342 }
343
344 pub(super) fn with_certified_key(
346 self,
347 mut sig_schemes: Vec<SignatureScheme>,
348 client_hello: &ClientHelloPayload,
349 m: &Message<'_>,
350 cx: &mut ServerContext<'_>,
351 ) -> NextStateOrError<'static> {
352 let tls13_enabled = self
353 .config
354 .supports_version(ProtocolVersion::TLSv1_3);
355 let tls12_enabled = self
356 .config
357 .supports_version(ProtocolVersion::TLSv1_2);
358
359 let version = if let Some(versions) = &client_hello.supported_versions {
361 if versions.tls13 && tls13_enabled {
362 ProtocolVersion::TLSv1_3
363 } else if !versions.tls12 || !tls12_enabled {
364 return Err(cx.common.send_fatal_alert(
365 AlertDescription::ProtocolVersion,
366 PeerIncompatible::Tls12NotOfferedOrEnabled,
367 ));
368 } else if cx.common.is_quic() {
369 return Err(cx.common.send_fatal_alert(
370 AlertDescription::ProtocolVersion,
371 PeerIncompatible::Tls13RequiredForQuic,
372 ));
373 } else {
374 ProtocolVersion::TLSv1_2
375 }
376 } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
377 return Err(cx.common.send_fatal_alert(
378 AlertDescription::ProtocolVersion,
379 PeerIncompatible::Tls12NotOffered,
380 ));
381 } else if !tls12_enabled && tls13_enabled {
382 return Err(cx.common.send_fatal_alert(
383 AlertDescription::ProtocolVersion,
384 PeerIncompatible::SupportedVersionsExtensionRequired,
385 ));
386 } else if cx.common.is_quic() {
387 return Err(cx.common.send_fatal_alert(
388 AlertDescription::ProtocolVersion,
389 PeerIncompatible::Tls13RequiredForQuic,
390 ));
391 } else {
392 ProtocolVersion::TLSv1_2
393 };
394
395 cx.common.negotiated_version = Some(version);
396
397 let client_suites = self
403 .config
404 .provider
405 .cipher_suites
406 .iter()
407 .copied()
408 .filter(|scs| {
409 client_hello
410 .cipher_suites
411 .contains(&scs.suite())
412 })
413 .collect::<Vec<_>>();
414
415 sig_schemes
416 .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
417
418 let certificate_authorities = match version {
420 ProtocolVersion::TLSv1_2 => None,
421 _ => client_hello
422 .certificate_authority_names
423 .as_deref(),
424 };
425 let certkey = {
427 let client_hello = ClientHello {
428 server_name: &cx.data.sni,
429 signature_schemes: &sig_schemes,
430 alpn: client_hello.protocols.as_ref(),
431 client_cert_types: client_hello
432 .client_certificate_types
433 .as_deref(),
434 server_cert_types: client_hello
435 .server_certificate_types
436 .as_deref(),
437 cipher_suites: &client_hello.cipher_suites,
438 certificate_authorities,
439 named_groups: client_hello.named_groups.as_deref(),
440 };
441 trace!("Resolving server certificate: {client_hello:#?}");
442
443 let certkey = self
444 .config
445 .cert_resolver
446 .resolve(client_hello);
447
448 certkey.ok_or_else(|| {
449 cx.common.send_fatal_alert(
450 AlertDescription::AccessDenied,
451 Error::General("no server certificate chain resolved".to_owned()),
452 )
453 })?
454 };
455 let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
456
457 let (suite, skxg) = self
458 .choose_suite_and_kx_group(
459 version,
460 certkey.get_key().algorithm(),
461 cx.common.protocol,
462 client_hello
463 .named_groups
464 .as_deref()
465 .unwrap_or_default(),
466 &client_hello.cipher_suites,
467 )
468 .map_err(|incompat| {
469 cx.common
470 .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
471 })?;
472
473 debug!("decided upon suite {suite:?}");
474 cx.common.suite = Some(suite);
475 cx.common.kx_state = KxState::Start(skxg);
476
477 let starting_hash = suite.hash_provider();
479 let transcript = match self.transcript {
480 HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
481 HandshakeHashOrBuffer::Hash(inner)
482 if inner.algorithm() == starting_hash.algorithm() =>
483 {
484 inner
485 }
486 _ => {
487 return Err(cx.common.send_fatal_alert(
488 AlertDescription::IllegalParameter,
489 PeerMisbehaved::HandshakeHashVariedAfterRetry,
490 ));
491 }
492 };
493
494 let randoms = ConnectionRandoms::new(
496 client_hello.random,
497 Random::new(self.config.provider.secure_random)?,
498 );
499 match suite {
500 SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
501 config: self.config,
502 transcript,
503 suite,
504 randoms,
505 done_retry: self.done_retry,
506 send_tickets: self.send_tickets,
507 extra_exts: self.extra_exts,
508 }
509 .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
510 #[cfg(feature = "tls12")]
511 SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
512 config: self.config,
513 transcript,
514 session_id: self.session_id,
515 suite,
516 using_ems: self.using_ems,
517 randoms,
518 send_ticket: self.send_tickets > 0,
519 extra_exts: self.extra_exts,
520 }
521 .handle_client_hello(
522 cx,
523 certkey,
524 m,
525 client_hello,
526 skxg,
527 sig_schemes,
528 tls13_enabled,
529 ),
530 }
531 }
532
533 fn choose_suite_and_kx_group(
534 &self,
535 selected_version: ProtocolVersion,
536 sig_key_algorithm: SignatureAlgorithm,
537 protocol: Protocol,
538 client_groups: &[NamedGroup],
539 client_suites: &[CipherSuite],
540 ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
541 let mut ecdhe_possible = false;
544 let mut ffdhe_possible = false;
545 let mut ffdhe_offered = false;
546 let mut supported_groups = Vec::with_capacity(client_groups.len());
547
548 for offered_group in client_groups {
549 let supported = self
550 .config
551 .provider
552 .kx_groups
553 .iter()
554 .find(|skxg| {
555 skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
556 });
557
558 match offered_group.key_exchange_algorithm() {
559 KeyExchangeAlgorithm::DHE => {
560 ffdhe_possible |= supported.is_some();
561 ffdhe_offered = true;
562 }
563 KeyExchangeAlgorithm::ECDHE => {
564 ecdhe_possible |= supported.is_some();
565 }
566 }
567
568 supported_groups.push(supported);
569 }
570
571 let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
572 let first_supported_dhe_kxg = self
574 .config
575 .provider
576 .kx_groups
577 .iter()
578 .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
579 ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
580 first_supported_dhe_kxg
581 } else {
582 None
584 };
585
586 if !ecdhe_possible && !ffdhe_possible {
587 return Err(PeerIncompatible::NoKxGroupsInCommon);
588 }
589
590 let mut suitable_suites_iter = self
591 .config
592 .provider
593 .cipher_suites
594 .iter()
595 .filter(|suite| {
596 suite.usable_for_signature_algorithm(sig_key_algorithm)
598 && suite.version().version == selected_version
600 && suite.usable_for_protocol(protocol)
602 && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
604 || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
605 });
606
607 let suite = if self.config.ignore_client_order {
614 suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
615 } else {
616 let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
617 client_suites
618 .iter()
619 .find_map(|client_suite| {
620 suitable_suites
621 .iter()
622 .find(|x| *client_suite == x.suite())
623 })
624 .copied()
625 }
626 .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
627
628 let maybe_skxg = supported_groups
631 .iter()
632 .find_map(|maybe_skxg| match maybe_skxg {
633 Some(skxg) => suite
634 .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
635 .then_some(*skxg),
636 None => None,
637 });
638
639 if selected_version == ProtocolVersion::TLSv1_3 {
640 return Ok((*suite, *maybe_skxg.unwrap()));
642 }
643
644 match maybe_skxg {
647 Some(skxg) => Ok((*suite, *skxg)),
648 None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
649 if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
652 Ok((*suite, *server_selected_ffdhe_skxg))
653 } else {
654 Err(PeerIncompatible::NoKxGroupsInCommon)
655 }
656 }
657 None => Err(PeerIncompatible::NoKxGroupsInCommon),
658 }
659 }
660}
661
662impl State<ServerConnectionData> for ExpectClientHello {
663 fn handle<'m>(
664 self: Box<Self>,
665 cx: &mut ServerContext<'_>,
666 m: Message<'m>,
667 ) -> NextStateOrError<'m>
668 where
669 Self: 'm,
670 {
671 let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
672 self.with_certified_key(sig_schemes, client_hello, &m, cx)
673 }
674
675 fn into_owned(self: Box<Self>) -> NextState<'static> {
676 self
677 }
678}
679
680pub(super) fn process_client_hello<'m>(
690 m: &'m Message<'m>,
691 done_retry: bool,
692 cx: &mut ServerContext<'_>,
693) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
694 let client_hello =
695 require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
696 trace!("we got a clienthello {client_hello:?}");
697
698 if !client_hello
699 .compression_methods
700 .contains(&Compression::Null)
701 {
702 return Err(cx.common.send_fatal_alert(
703 AlertDescription::IllegalParameter,
704 PeerIncompatible::NullCompressionRequired,
705 ));
706 }
707
708 cx.common.check_aligned_handshake()?;
710
711 let sni = match &client_hello.server_name {
726 Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
727 Some(ServerNamePayload::IpAddress) => None,
728 Some(ServerNamePayload::Invalid) => {
729 return Err(cx.common.send_fatal_alert(
730 AlertDescription::IllegalParameter,
731 PeerMisbehaved::ServerNameMustContainOneHostName,
732 ));
733 }
734 None => None,
735 };
736
737 if let (Some(sni), false) = (&sni, done_retry) {
739 assert!(cx.data.sni.is_none());
742 cx.data.sni = Some(sni.clone());
743 } else if cx.data.sni != sni {
744 return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
745 }
746
747 let sig_schemes = client_hello
748 .signature_schemes
749 .as_ref()
750 .ok_or_else(|| {
751 cx.common.send_fatal_alert(
752 AlertDescription::HandshakeFailure,
753 PeerIncompatible::SignatureAlgorithmsExtensionRequired,
754 )
755 })?;
756
757 Ok((client_hello, sig_schemes.to_owned()))
758}
759
760pub(crate) enum HandshakeHashOrBuffer {
761 Buffer(HandshakeHashBuffer),
762 Hash(HandshakeHash),
763}