1use crate::common_state::State;
2use crate::conn::ConnectionRandoms;
3use crate::dns_name::DnsName;
4#[cfg(feature = "tls12")]
5use crate::enums::CipherSuite;
6use crate::enums::{AlertDescription, HandshakeType, ProtocolVersion, SignatureScheme};
7use crate::error::{Error, PeerIncompatible, PeerMisbehaved};
8use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
9#[cfg(feature = "logging")]
10use crate::log::{debug, trace};
11use crate::msgs::enums::{Compression, ExtensionType};
12#[cfg(feature = "tls12")]
13use crate::msgs::handshake::SessionId;
14use crate::msgs::handshake::{ClientHelloPayload, Random, ServerExtension};
15use crate::msgs::handshake::{ConvertProtocolNameList, ConvertServerNameList, HandshakePayload};
16use crate::msgs::message::{Message, MessagePayload};
17use crate::msgs::persist;
18use crate::server::{ClientHello, ServerConfig};
19use crate::suites;
20use crate::SupportedCipherSuite;
21
22use super::server_conn::ServerConnectionData;
23#[cfg(feature = "tls12")]
24use super::tls12;
25use crate::server::common::ActiveCertifiedKey;
26use crate::server::tls13;
27
28use std::sync::Arc;
29
30pub(super) type NextState = Box<dyn State<ServerConnectionData>>;
31pub(super) type NextStateOrError = Result<NextState, Error>;
32pub(super) type ServerContext<'a> = crate::common_state::Context<'a, ServerConnectionData>;
33
34pub(super) fn can_resume(
35 suite: SupportedCipherSuite,
36 sni: &Option<DnsName>,
37 using_ems: bool,
38 resumedata: &persist::ServerSessionValue,
39) -> bool {
40 resumedata.cipher_suite == suite.suite()
48 && (resumedata.extended_ms == using_ems || (resumedata.extended_ms && !using_ems))
49 && &resumedata.sni == sni
50}
51
52#[derive(Default)]
53pub(super) struct ExtensionProcessing {
54 pub(super) exts: Vec<ServerExtension>,
56 #[cfg(feature = "tls12")]
57 pub(super) send_ticket: bool,
58}
59
60impl ExtensionProcessing {
61 pub(super) fn new() -> Self {
62 Default::default()
63 }
64
65 pub(super) fn process_common(
66 &mut self,
67 config: &ServerConfig,
68 cx: &mut ServerContext<'_>,
69 ocsp_response: &mut Option<&[u8]>,
70 sct_list: &mut Option<&[u8]>,
71 hello: &ClientHelloPayload,
72 resumedata: Option<&persist::ServerSessionValue>,
73 extra_exts: Vec<ServerExtension>,
74 ) -> Result<(), Error> {
75 let our_protocols = &config.alpn_protocols;
77 let maybe_their_protocols = hello.get_alpn_extension();
78 if let Some(their_protocols) = maybe_their_protocols {
79 let their_protocols = their_protocols.to_slices();
80
81 if their_protocols
82 .iter()
83 .any(|protocol| protocol.is_empty())
84 {
85 return Err(PeerMisbehaved::OfferedEmptyApplicationProtocol.into());
86 }
87
88 cx.common.alpn_protocol = our_protocols
89 .iter()
90 .find(|protocol| their_protocols.contains(&protocol.as_slice()))
91 .cloned();
92 if let Some(ref selected_protocol) = cx.common.alpn_protocol {
93 debug!("Chosen ALPN protocol {:?}", selected_protocol);
94 self.exts
95 .push(ServerExtension::make_alpn(&[selected_protocol]));
96 } else if !our_protocols.is_empty() {
97 return Err(cx.common.send_fatal_alert(
98 AlertDescription::NoApplicationProtocol,
99 Error::NoApplicationProtocol,
100 ));
101 }
102 }
103
104 #[cfg(feature = "quic")]
105 {
106 if cx.common.is_quic() {
107 if cx.common.alpn_protocol.is_none()
115 && (!our_protocols.is_empty() || maybe_their_protocols.is_some())
116 {
117 return Err(cx.common.send_fatal_alert(
118 AlertDescription::NoApplicationProtocol,
119 Error::NoApplicationProtocol,
120 ));
121 }
122
123 match hello.get_quic_params_extension() {
124 Some(params) => cx.common.quic.params = Some(params),
125 None => {
126 return Err(cx
127 .common
128 .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
129 }
130 }
131 }
132 }
133
134 let for_resume = resumedata.is_some();
135 if !for_resume && hello.get_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 if !for_resume
160 && hello
161 .find_extension(ExtensionType::SCT)
162 .is_some()
163 {
164 if !cx.common.is_tls13() {
165 if let Some(sct_list) = sct_list.take() {
168 self.exts
169 .push(ServerExtension::make_sct(sct_list.to_vec()));
170 }
171 }
172 } else {
173 sct_list.take();
175 }
176
177 self.exts.extend(extra_exts);
178
179 Ok(())
180 }
181
182 #[cfg(feature = "tls12")]
183 pub(super) fn process_tls12(
184 &mut self,
185 config: &ServerConfig,
186 hello: &ClientHelloPayload,
187 using_ems: bool,
188 ) {
189 let secure_reneg_offered = hello
192 .find_extension(ExtensionType::RenegotiationInfo)
193 .is_some()
194 || hello
195 .cipher_suites
196 .contains(&CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
197
198 if secure_reneg_offered {
199 self.exts
200 .push(ServerExtension::make_empty_renegotiation_info());
201 }
202
203 if hello
207 .find_extension(ExtensionType::SessionTicket)
208 .is_some()
209 && config.ticketer.enabled()
210 {
211 self.send_ticket = true;
212 self.exts
213 .push(ServerExtension::SessionTicketAck);
214 }
215
216 if using_ems {
218 self.exts
219 .push(ServerExtension::ExtendedMasterSecretAck);
220 }
221 }
222}
223
224pub(super) struct ExpectClientHello {
225 pub(super) config: Arc<ServerConfig>,
226 pub(super) extra_exts: Vec<ServerExtension>,
227 pub(super) transcript: HandshakeHashOrBuffer,
228 #[cfg(feature = "tls12")]
229 pub(super) session_id: SessionId,
230 #[cfg(feature = "tls12")]
231 pub(super) using_ems: bool,
232 pub(super) done_retry: bool,
233 pub(super) send_tickets: usize,
234}
235
236impl ExpectClientHello {
237 pub(super) fn new(config: Arc<ServerConfig>, extra_exts: Vec<ServerExtension>) -> Self {
238 let mut transcript_buffer = HandshakeHashBuffer::new();
239
240 if config.verifier.offer_client_auth() {
241 transcript_buffer.set_client_auth_enabled();
242 }
243
244 Self {
245 config,
246 extra_exts,
247 transcript: HandshakeHashOrBuffer::Buffer(transcript_buffer),
248 #[cfg(feature = "tls12")]
249 session_id: SessionId::empty(),
250 #[cfg(feature = "tls12")]
251 using_ems: false,
252 done_retry: false,
253 send_tickets: 0,
254 }
255 }
256
257 pub(super) fn with_certified_key(
259 self,
260 mut sig_schemes: Vec<SignatureScheme>,
261 client_hello: &ClientHelloPayload,
262 m: &Message,
263 cx: &mut ServerContext<'_>,
264 ) -> NextStateOrError {
265 let tls13_enabled = self
266 .config
267 .supports_version(ProtocolVersion::TLSv1_3);
268 let tls12_enabled = self
269 .config
270 .supports_version(ProtocolVersion::TLSv1_2);
271
272 let maybe_versions_ext = client_hello.get_versions_extension();
274 let version = if let Some(versions) = maybe_versions_ext {
275 if versions.contains(&ProtocolVersion::TLSv1_3) && tls13_enabled {
276 ProtocolVersion::TLSv1_3
277 } else if !versions.contains(&ProtocolVersion::TLSv1_2) || !tls12_enabled {
278 return Err(cx.common.send_fatal_alert(
279 AlertDescription::ProtocolVersion,
280 PeerIncompatible::Tls12NotOfferedOrEnabled,
281 ));
282 } else if cx.common.is_quic() {
283 return Err(cx.common.send_fatal_alert(
284 AlertDescription::ProtocolVersion,
285 PeerIncompatible::Tls13RequiredForQuic,
286 ));
287 } else {
288 ProtocolVersion::TLSv1_2
289 }
290 } else if client_hello.client_version.get_u16() < ProtocolVersion::TLSv1_2.get_u16() {
291 return Err(cx.common.send_fatal_alert(
292 AlertDescription::ProtocolVersion,
293 PeerIncompatible::Tls12NotOffered,
294 ));
295 } else if !tls12_enabled && tls13_enabled {
296 return Err(cx.common.send_fatal_alert(
297 AlertDescription::ProtocolVersion,
298 PeerIncompatible::SupportedVersionsExtensionRequired,
299 ));
300 } else if cx.common.is_quic() {
301 return Err(cx.common.send_fatal_alert(
302 AlertDescription::ProtocolVersion,
303 PeerIncompatible::Tls13RequiredForQuic,
304 ));
305 } else {
306 ProtocolVersion::TLSv1_2
307 };
308
309 cx.common.negotiated_version = Some(version);
310
311 let client_suites = self
317 .config
318 .cipher_suites
319 .iter()
320 .copied()
321 .filter(|scs| {
322 client_hello
323 .cipher_suites
324 .contains(&scs.suite())
325 })
326 .collect::<Vec<_>>();
327
328 sig_schemes
329 .retain(|scheme| suites::compatible_sigscheme_for_suites(*scheme, &client_suites));
330
331 let certkey = {
333 let client_hello = ClientHello::new(
334 &cx.data.sni,
335 &sig_schemes,
336 client_hello.get_alpn_extension(),
337 &client_hello.cipher_suites,
338 );
339
340 let certkey = self
341 .config
342 .cert_resolver
343 .resolve(client_hello);
344
345 certkey.ok_or_else(|| {
346 cx.common.send_fatal_alert(
347 AlertDescription::AccessDenied,
348 Error::General("no server certificate chain resolved".to_owned()),
349 )
350 })?
351 };
352 let certkey = ActiveCertifiedKey::from_certified_key(&certkey);
353
354 let suitable_suites =
357 suites::reduce_given_sigalg(&self.config.cipher_suites, certkey.get_key().algorithm());
358
359 let suitable_suites = suites::reduce_given_version(&suitable_suites, version);
361
362 let suite = if self.config.ignore_client_order {
363 suites::choose_ciphersuite_preferring_server(
364 &client_hello.cipher_suites,
365 &suitable_suites,
366 )
367 } else {
368 suites::choose_ciphersuite_preferring_client(
369 &client_hello.cipher_suites,
370 &suitable_suites,
371 )
372 }
373 .ok_or_else(|| {
374 cx.common.send_fatal_alert(
375 AlertDescription::HandshakeFailure,
376 PeerIncompatible::NoCipherSuitesInCommon,
377 )
378 })?;
379
380 debug!("decided upon suite {:?}", suite);
381 cx.common.suite = Some(suite);
382
383 let starting_hash = suite.hash_algorithm();
385 let transcript = match self.transcript {
386 HandshakeHashOrBuffer::Buffer(inner) => inner.start_hash(starting_hash),
387 HandshakeHashOrBuffer::Hash(inner) if inner.algorithm() == starting_hash => inner,
388 _ => {
389 return Err(cx.common.send_fatal_alert(
390 AlertDescription::IllegalParameter,
391 PeerMisbehaved::HandshakeHashVariedAfterRetry,
392 ));
393 }
394 };
395
396 let randoms = ConnectionRandoms::new(client_hello.random, Random::new()?);
398 match suite {
399 SupportedCipherSuite::Tls13(suite) => tls13::CompleteClientHelloHandling {
400 config: self.config,
401 transcript,
402 suite,
403 randoms,
404 done_retry: self.done_retry,
405 send_tickets: self.send_tickets,
406 extra_exts: self.extra_exts,
407 }
408 .handle_client_hello(cx, certkey, m, client_hello, sig_schemes),
409 #[cfg(feature = "tls12")]
410 SupportedCipherSuite::Tls12(suite) => tls12::CompleteClientHelloHandling {
411 config: self.config,
412 transcript,
413 session_id: self.session_id,
414 suite,
415 using_ems: self.using_ems,
416 randoms,
417 send_ticket: self.send_tickets > 0,
418 extra_exts: self.extra_exts,
419 }
420 .handle_client_hello(
421 cx,
422 certkey,
423 m,
424 client_hello,
425 sig_schemes,
426 tls13_enabled,
427 ),
428 }
429 }
430}
431
432impl State<ServerConnectionData> for ExpectClientHello {
433 fn handle(self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> NextStateOrError {
434 let (client_hello, sig_schemes) = process_client_hello(&m, self.done_retry, cx)?;
435 self.with_certified_key(sig_schemes, client_hello, &m, cx)
436 }
437}
438
439pub(super) fn process_client_hello<'a>(
447 m: &'a Message,
448 done_retry: bool,
449 cx: &mut ServerContext,
450) -> Result<(&'a ClientHelloPayload, Vec<SignatureScheme>), Error> {
451 let client_hello =
452 require_handshake_msg!(m, HandshakeType::ClientHello, HandshakePayload::ClientHello)?;
453 trace!("we got a clienthello {:?}", client_hello);
454
455 if !client_hello
456 .compression_methods
457 .contains(&Compression::Null)
458 {
459 return Err(cx.common.send_fatal_alert(
460 AlertDescription::IllegalParameter,
461 PeerIncompatible::NullCompressionRequired,
462 ));
463 }
464
465 if client_hello.has_duplicate_extension() {
466 return Err(cx.common.send_fatal_alert(
467 AlertDescription::DecodeError,
468 PeerMisbehaved::DuplicateClientHelloExtensions,
469 ));
470 }
471
472 cx.common.check_aligned_handshake()?;
474
475 let sni: Option<DnsName> = match client_hello.get_sni_extension() {
481 Some(sni) => {
482 if sni.has_duplicate_names_for_type() {
483 return Err(cx.common.send_fatal_alert(
484 AlertDescription::DecodeError,
485 PeerMisbehaved::DuplicateServerNameTypes,
486 ));
487 }
488
489 if let Some(hostname) = sni.get_single_hostname() {
490 Some(hostname.to_lowercase_owned())
491 } else {
492 return Err(cx.common.send_fatal_alert(
493 AlertDescription::IllegalParameter,
494 PeerMisbehaved::ServerNameMustContainOneHostName,
495 ));
496 }
497 }
498 None => None,
499 };
500
501 if let (Some(sni), false) = (&sni, done_retry) {
503 assert!(cx.data.sni.is_none());
506 cx.data.sni = Some(sni.clone());
507 } else if cx.data.sni != sni {
508 return Err(PeerMisbehaved::ServerNameDifferedOnRetry.into());
509 }
510
511 let sig_schemes = client_hello
512 .get_sigalgs_extension()
513 .ok_or_else(|| {
514 cx.common.send_fatal_alert(
515 AlertDescription::HandshakeFailure,
516 PeerIncompatible::SignatureAlgorithmsExtensionRequired,
517 )
518 })?;
519
520 Ok((client_hello, sig_schemes.to_owned()))
521}
522
523#[allow(clippy::large_enum_variant)]
524pub(crate) enum HandshakeHashOrBuffer {
525 Buffer(HandshakeHashBuffer),
526 Hash(HandshakeHash),
527}