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) previous_hello: Option<PreviousClientHello>,
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 previous_hello: None,
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, cx.common.protocol);
355 let tls12_enabled = self
356 .config
357 .supports_version(ProtocolVersion::TLSv1_2, cx.common.protocol)
358 && !self.previous_hello.is_some();
359
360 let version = if let Some(versions) = &client_hello.supported_versions {
362 if versions.tls13 && tls13_enabled {
363 ProtocolVersion::TLSv1_3
364 } else if !versions.tls12 || !tls12_enabled {
365 return Err(cx.common.send_fatal_alert(
366 AlertDescription::ProtocolVersion,
367 PeerIncompatible::Tls12NotOfferedOrEnabled,
368 ));
369 } else if cx.common.is_quic() {
370 return Err(cx.common.send_fatal_alert(
371 AlertDescription::ProtocolVersion,
372 PeerIncompatible::Tls13RequiredForQuic,
373 ));
374 } else {
375 ProtocolVersion::TLSv1_2
376 }
377 } else if u16::from(client_hello.client_version) < u16::from(ProtocolVersion::TLSv1_2) {
378 return Err(cx.common.send_fatal_alert(
379 AlertDescription::ProtocolVersion,
380 PeerIncompatible::Tls12NotOffered,
381 ));
382 } else if cx.common.is_quic() {
383 return Err(cx.common.send_fatal_alert(
384 AlertDescription::ProtocolVersion,
385 PeerIncompatible::Tls13RequiredForQuic,
386 ));
387 } else if !tls12_enabled && tls13_enabled {
388 return Err(cx.common.send_fatal_alert(
389 AlertDescription::ProtocolVersion,
390 PeerIncompatible::SupportedVersionsExtensionRequired,
391 ));
392 } else {
393 ProtocolVersion::TLSv1_2
394 };
395
396 cx.common.negotiated_version = Some(version);
397
398 let client_suites = self
404 .config
405 .provider
406 .cipher_suites
407 .iter()
408 .copied()
409 .filter(|scs| {
410 client_hello
411 .cipher_suites
412 .contains(&scs.suite())
413 })
414 .collect::<Vec<_>>();
415
416 sig_schemes
417 .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
418
419 let certificate_authorities = match version {
421 ProtocolVersion::TLSv1_2 => None,
422 _ => client_hello
423 .certificate_authority_names
424 .as_deref(),
425 };
426 let certkey = {
428 let client_hello = ClientHello {
429 server_name: &cx.data.sni,
430 signature_schemes: &sig_schemes,
431 alpn: client_hello.protocols.as_ref(),
432 client_cert_types: client_hello
433 .client_certificate_types
434 .as_deref(),
435 server_cert_types: client_hello
436 .server_certificate_types
437 .as_deref(),
438 cipher_suites: &client_hello.cipher_suites,
439 certificate_authorities,
440 named_groups: client_hello.named_groups.as_deref(),
441 };
442 trace!("Resolving server certificate: {client_hello:#?}");
443
444 let certkey = self
445 .config
446 .cert_resolver
447 .resolve(client_hello);
448
449 certkey.ok_or_else(|| {
450 cx.common.send_fatal_alert(
451 AlertDescription::AccessDenied,
452 Error::General("no server certificate chain resolved".to_owned()),
453 )
454 })?
455 };
456 let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
457
458 let (suite, skxg) = self
459 .choose_suite_and_kx_group(
460 version,
461 certkey.get_key().algorithm(),
462 cx.common.protocol,
463 client_hello
464 .named_groups
465 .as_deref()
466 .unwrap_or_default(),
467 &client_hello.cipher_suites,
468 )
469 .map_err(|incompat| {
470 cx.common
471 .send_fatal_alert(AlertDescription::HandshakeFailure, incompat)
472 })?;
473
474 if let Some(PreviousClientHello {
477 suite: before_retry,
478 ..
479 }) = self.previous_hello
480 {
481 if before_retry != suite.suite() {
482 return Err(cx.common.send_fatal_alert(
483 AlertDescription::IllegalParameter,
484 PeerMisbehaved::CipherSuiteDifferedOnRetry,
485 ));
486 }
487 }
488
489 debug!("decided upon suite {suite:?}");
490 cx.common.suite = Some(suite);
491 cx.common.kx_state = KxState::Start(skxg);
492
493 let starting_hash = suite.hash_provider();
495 let transcript = match self.transcript {
496 HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
497 HandshakeHashOrBuffer::Hash(inner)
498 if inner.algorithm() == starting_hash.algorithm() =>
499 {
500 inner
501 }
502 _ => {
503 return Err(cx.common.send_fatal_alert(
504 AlertDescription::IllegalParameter,
505 PeerMisbehaved::HandshakeHashVariedAfterRetry,
506 ));
507 }
508 };
509
510 let randoms = ConnectionRandoms::new(
512 client_hello.random,
513 Random::new(self.config.provider.secure_random)?,
514 );
515 match suite {
516 SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
517 config: self.config,
518 transcript,
519 suite,
520 randoms,
521 previous_hello: self.previous_hello,
522 send_tickets: self.send_tickets,
523 extra_exts: self.extra_exts,
524 }
525 .handle_client_hello(cx, certkey, m, client_hello, skxg, sig_schemes),
526 #[cfg(feature = "tls12")]
527 SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
528 config: self.config,
529 transcript,
530 session_id: self.session_id,
531 suite,
532 using_ems: self.using_ems,
533 randoms,
534 send_ticket: self.send_tickets > 0,
535 extra_exts: self.extra_exts,
536 }
537 .handle_client_hello(
538 cx,
539 certkey,
540 m,
541 client_hello,
542 skxg,
543 sig_schemes,
544 tls13_enabled,
545 ),
546 }
547 }
548
549 fn choose_suite_and_kx_group(
550 &self,
551 selected_version: ProtocolVersion,
552 sig_key_algorithm: SignatureAlgorithm,
553 protocol: Protocol,
554 client_groups: &[NamedGroup],
555 client_suites: &[CipherSuite],
556 ) -> Result<(SupportedCipherSuite, &'static dyn SupportedKxGroup), PeerIncompatible> {
557 let mut ecdhe_possible = false;
560 let mut ffdhe_possible = false;
561 let mut ffdhe_offered = false;
562 let mut supported_groups = Vec::with_capacity(client_groups.len());
563
564 for offered_group in client_groups {
565 let supported = self
566 .config
567 .provider
568 .kx_groups
569 .iter()
570 .find(|skxg| {
571 skxg.usable_for_version(selected_version) && skxg.name() == *offered_group
572 });
573
574 match offered_group.key_exchange_algorithm() {
575 KeyExchangeAlgorithm::DHE => {
576 ffdhe_possible |= supported.is_some();
577 ffdhe_offered = true;
578 }
579 KeyExchangeAlgorithm::ECDHE => {
580 ecdhe_possible |= supported.is_some();
581 }
582 }
583
584 supported_groups.push(supported);
585 }
586
587 let first_supported_dhe_kxg = if selected_version == ProtocolVersion::TLSv1_2 {
588 let first_supported_dhe_kxg = self
590 .config
591 .provider
592 .kx_groups
593 .iter()
594 .find(|skxg| skxg.name().key_exchange_algorithm() == KeyExchangeAlgorithm::DHE);
595 ffdhe_possible |= !ffdhe_offered && first_supported_dhe_kxg.is_some();
596 first_supported_dhe_kxg
597 } else {
598 None
600 };
601
602 if !ecdhe_possible && !ffdhe_possible {
603 return Err(PeerIncompatible::NoKxGroupsInCommon);
604 }
605
606 let mut suitable_suites_iter = self
607 .config
608 .provider
609 .cipher_suites
610 .iter()
611 .filter(|suite| {
612 suite.usable_for_signature_algorithm(sig_key_algorithm)
614 && suite.version().version == selected_version
616 && suite.usable_for_protocol(protocol)
618 && (ecdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::ECDHE)
620 || ffdhe_possible && suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE))
621 });
622
623 let suite = if self.config.ignore_client_order {
630 suitable_suites_iter.find(|suite| client_suites.contains(&suite.suite()))
631 } else {
632 let suitable_suites = suitable_suites_iter.collect::<Vec<_>>();
633 client_suites
634 .iter()
635 .find_map(|client_suite| {
636 suitable_suites
637 .iter()
638 .find(|x| *client_suite == x.suite())
639 })
640 .copied()
641 }
642 .ok_or(PeerIncompatible::NoCipherSuitesInCommon)?;
643
644 let maybe_skxg = supported_groups
647 .iter()
648 .find_map(|maybe_skxg| match maybe_skxg {
649 Some(skxg) => suite
650 .usable_for_kx_algorithm(skxg.name().key_exchange_algorithm())
651 .then_some(*skxg),
652 None => None,
653 });
654
655 if selected_version == ProtocolVersion::TLSv1_3 {
656 return Ok((*suite, *maybe_skxg.unwrap()));
658 }
659
660 match maybe_skxg {
663 Some(skxg) => Ok((*suite, *skxg)),
664 None if suite.usable_for_kx_algorithm(KeyExchangeAlgorithm::DHE) => {
665 if let Some(server_selected_ffdhe_skxg) = first_supported_dhe_kxg {
668 Ok((*suite, *server_selected_ffdhe_skxg))
669 } else {
670 Err(PeerIncompatible::NoKxGroupsInCommon)
671 }
672 }
673 None => Err(PeerIncompatible::NoKxGroupsInCommon),
674 }
675 }
676}
677
678pub(super) struct PreviousClientHello {
679 pub(super) offered_psk: bool,
680 pub(super) suite: CipherSuite,
681}
682
683impl State<ServerConnectionData> for ExpectClientHello {
684 fn handle<'m>(
685 self: Box<Self>,
686 cx: &mut ServerContext<'_>,
687 m: Message<'m>,
688 ) -> NextStateOrError<'m>
689 where
690 Self: 'm,
691 {
692 let (client_hello, sig_schemes) =
693 process_client_hello(&m, self.previous_hello.is_some(), cx)?;
694 self.with_certified_key(sig_schemes, client_hello, &m, cx)
695 }
696
697 fn into_owned(self: Box<Self>) -> NextState<'static> {
698 self
699 }
700}
701
702pub(super) fn process_client_hello<'m>(
712 m: &'m Message<'m>,
713 done_retry: bool,
714 cx: &mut ServerContext<'_>,
715) -> Result<(&'m ClientHelloPayload, Vec<SignatureScheme>), Error> {
716 let client_hello =
717 require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
718 trace!("we got a clienthello {client_hello:?}");
719
720 if !client_hello
721 .compression_methods
722 .contains(&Compression::Null)
723 {
724 return Err(cx.common.send_fatal_alert(
725 AlertDescription::IllegalParameter,
726 PeerIncompatible::NullCompressionRequired,
727 ));
728 }
729
730 cx.common.check_aligned_handshake()?;
732
733 let sni = match &client_hello.server_name {
748 Some(ServerNamePayload::SingleDnsName(dns_name)) => Some(dns_name.to_lowercase_owned()),
749 Some(ServerNamePayload::IpAddress) => None,
750 Some(ServerNamePayload::Invalid) => {
751 return Err(cx.common.send_fatal_alert(
752 AlertDescription::IllegalParameter,
753 PeerMisbehaved::ServerNameMustContainOneHostName,
754 ));
755 }
756 None => None,
757 };
758
759 if let (Some(sni), false) = (&sni, done_retry) {
761 assert!(cx.data.sni.is_none());
764 cx.data.sni = Some(sni.clone());
765 } else if cx.data.sni != sni {
766 return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
767 }
768
769 let sig_schemes = client_hello
770 .signature_schemes
771 .as_ref()
772 .ok_or_else(|| {
773 cx.common.send_fatal_alert(
774 AlertDescription::HandshakeFailure,
775 PeerIncompatible::SignatureAlgorithmsExtensionRequired,
776 )
777 })?;
778
779 Ok((client_hello, sig_schemes.to_owned()))
780}
781
782pub(crate) enum HandshakeHashOrBuffer {
783 Buffer(HandshakeHashBuffer),
784 Hash(HandshakeHash),
785}