1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::sync::Arc;
4use alloc::vec;
5use alloc::vec::Vec;
6
7use pki_types::ServerName;
8pub(super) use server_hello::CompleteServerHelloHandling;
9use subtle::ConstantTimeEq;
10
11use super::client_conn::ClientConnectionData;
12use super::hs::ClientContext;
13use crate::check::{inappropriate_handshake_message, inappropriate_message};
14use crate::client::common::{ClientAuthDetails, ServerCertDetails};
15use crate::client::{hs, ClientConfig};
16use crate::common_state::{CommonState, HandshakeKind, KxState, Side, State};
17use crate::conn::ConnectionRandoms;
18use crate::crypto::KeyExchangeAlgorithm;
19use crate::enums::{AlertDescription, ContentType, HandshakeType, ProtocolVersion};
20use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved};
21use crate::hash_hs::HandshakeHash;
22use crate::log::{debug, trace, warn};
23use crate::msgs::base::{Payload, PayloadU16, PayloadU8};
24use crate::msgs::ccs::ChangeCipherSpecPayload;
25use crate::msgs::handshake::{
26 CertificateChain, ClientDhParams, ClientEcdhParams, ClientKeyExchangeParams,
27 HandshakeMessagePayload, HandshakePayload, NewSessionTicketPayload, ServerKeyExchangeParams,
28 SessionId,
29};
30use crate::msgs::message::{Message, MessagePayload};
31use crate::msgs::persist;
32use crate::sign::Signer;
33use crate::suites::{PartiallyExtractedSecrets, SupportedCipherSuite};
34use crate::tls12::{self, ConnectionSecrets, Tls12CipherSuite};
35use crate::verify::{self, DigitallySignedStruct};
36
37mod server_hello {
38 use super::*;
39 use crate::msgs::enums::ExtensionType;
40 use crate::msgs::handshake::{HasServerExtensions, ServerHelloPayload};
41
42 pub(in crate::client) struct CompleteServerHelloHandling {
43 pub(in crate::client) config: Arc<ClientConfig>,
44 pub(in crate::client) resuming_session: Option<persist::Tls12ClientSessionValue>,
45 pub(in crate::client) server_name: ServerName<'static>,
46 pub(in crate::client) randoms: ConnectionRandoms,
47 pub(in crate::client) using_ems: bool,
48 pub(in crate::client) transcript: HandshakeHash,
49 }
50
51 impl CompleteServerHelloHandling {
52 pub(in crate::client) fn handle_server_hello(
53 mut self,
54 cx: &mut ClientContext<'_>,
55 suite: &'static Tls12CipherSuite,
56 server_hello: &ServerHelloPayload,
57 tls13_supported: bool,
58 ) -> hs::NextStateOrError<'static> {
59 self.randoms
60 .server
61 .clone_from_slice(&server_hello.random.0[..]);
62
63 let has_downgrade_marker = self.randoms.server[24..] == tls12::DOWNGRADE_SENTINEL;
67 if tls13_supported && has_downgrade_marker {
68 return Err({
69 cx.common.send_fatal_alert(
70 AlertDescription::IllegalParameter,
71 PeerMisbehaved::AttemptedDowngradeToTls12WhenTls13IsSupported,
72 )
73 });
74 }
75
76 self.using_ems = server_hello.ems_support_acked();
78 if self.config.require_ems && !self.using_ems {
79 return Err({
80 cx.common.send_fatal_alert(
81 AlertDescription::HandshakeFailure,
82 PeerIncompatible::ExtendedMasterSecretExtensionRequired,
83 )
84 });
85 }
86
87 let must_issue_new_ticket = if server_hello
89 .find_extension(ExtensionType::SessionTicket)
90 .is_some()
91 {
92 debug!("Server supports tickets");
93 true
94 } else {
95 false
96 };
97
98 let may_send_cert_status = server_hello
101 .find_extension(ExtensionType::StatusRequest)
102 .is_some();
103 if may_send_cert_status {
104 debug!("Server may staple OCSP response");
105 }
106
107 if let Some(resuming) = self.resuming_session {
109 if resuming.session_id == server_hello.session_id {
110 debug!("Server agreed to resume");
111
112 if resuming.suite() != suite {
114 return Err(PeerMisbehaved::ResumptionOfferedWithVariedCipherSuite.into());
115 }
116
117 if resuming.extended_ms() != self.using_ems {
119 return Err(PeerMisbehaved::ResumptionOfferedWithVariedEms.into());
120 }
121
122 let secrets =
123 ConnectionSecrets::new_resume(self.randoms, suite, resuming.secret());
124 self.config.key_log.log(
125 "CLIENT_RANDOM",
126 &secrets.randoms.client,
127 &secrets.master_secret,
128 );
129 cx.common
130 .start_encryption_tls12(&secrets, Side::Client);
131
132 cx.common.peer_certificates = Some(
135 resuming
136 .server_cert_chain()
137 .clone()
138 .into_owned(),
139 );
140 cx.common.handshake_kind = Some(HandshakeKind::Resumed);
141 let cert_verified = verify::ServerCertVerified::assertion();
142 let sig_verified = verify::HandshakeSignatureValid::assertion();
143
144 return if must_issue_new_ticket {
145 Ok(Box::new(ExpectNewTicket {
146 config: self.config,
147 secrets,
148 resuming_session: Some(resuming),
149 session_id: server_hello.session_id,
150 server_name: self.server_name,
151 using_ems: self.using_ems,
152 transcript: self.transcript,
153 resuming: true,
154 cert_verified,
155 sig_verified,
156 }))
157 } else {
158 Ok(Box::new(ExpectCcs {
159 config: self.config,
160 secrets,
161 resuming_session: Some(resuming),
162 session_id: server_hello.session_id,
163 server_name: self.server_name,
164 using_ems: self.using_ems,
165 transcript: self.transcript,
166 ticket: None,
167 resuming: true,
168 cert_verified,
169 sig_verified,
170 }))
171 };
172 }
173 }
174
175 cx.common.handshake_kind = Some(HandshakeKind::Full);
176 Ok(Box::new(ExpectCertificate {
177 config: self.config,
178 resuming_session: None,
179 session_id: server_hello.session_id,
180 server_name: self.server_name,
181 randoms: self.randoms,
182 using_ems: self.using_ems,
183 transcript: self.transcript,
184 suite,
185 may_send_cert_status,
186 must_issue_new_ticket,
187 }))
188 }
189 }
190}
191
192struct ExpectCertificate {
193 config: Arc<ClientConfig>,
194 resuming_session: Option<persist::Tls12ClientSessionValue>,
195 session_id: SessionId,
196 server_name: ServerName<'static>,
197 randoms: ConnectionRandoms,
198 using_ems: bool,
199 transcript: HandshakeHash,
200 pub(super) suite: &'static Tls12CipherSuite,
201 may_send_cert_status: bool,
202 must_issue_new_ticket: bool,
203}
204
205impl State<ClientConnectionData> for ExpectCertificate {
206 fn handle<'m>(
207 mut self: Box<Self>,
208 _cx: &mut ClientContext<'_>,
209 m: Message<'m>,
210 ) -> hs::NextStateOrError<'m>
211 where
212 Self: 'm,
213 {
214 self.transcript.add_message(&m);
215 let server_cert_chain = require_handshake_msg_move!(
216 m,
217 HandshakeType::Certificate,
218 HandshakePayload::Certificate
219 )?;
220
221 if self.may_send_cert_status {
222 Ok(Box::new(ExpectCertificateStatusOrServerKx {
223 config: self.config,
224 resuming_session: self.resuming_session,
225 session_id: self.session_id,
226 server_name: self.server_name,
227 randoms: self.randoms,
228 using_ems: self.using_ems,
229 transcript: self.transcript,
230 suite: self.suite,
231 server_cert_chain,
232 must_issue_new_ticket: self.must_issue_new_ticket,
233 }))
234 } else {
235 let server_cert = ServerCertDetails::new(server_cert_chain, vec![]);
236
237 Ok(Box::new(ExpectServerKx {
238 config: self.config,
239 resuming_session: self.resuming_session,
240 session_id: self.session_id,
241 server_name: self.server_name,
242 randoms: self.randoms,
243 using_ems: self.using_ems,
244 transcript: self.transcript,
245 suite: self.suite,
246 server_cert,
247 must_issue_new_ticket: self.must_issue_new_ticket,
248 }))
249 }
250 }
251
252 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
253 self
254 }
255}
256
257struct ExpectCertificateStatusOrServerKx<'m> {
258 config: Arc<ClientConfig>,
259 resuming_session: Option<persist::Tls12ClientSessionValue>,
260 session_id: SessionId,
261 server_name: ServerName<'static>,
262 randoms: ConnectionRandoms,
263 using_ems: bool,
264 transcript: HandshakeHash,
265 suite: &'static Tls12CipherSuite,
266 server_cert_chain: CertificateChain<'m>,
267 must_issue_new_ticket: bool,
268}
269
270impl State<ClientConnectionData> for ExpectCertificateStatusOrServerKx<'_> {
271 fn handle<'m>(
272 self: Box<Self>,
273 cx: &mut ClientContext<'_>,
274 m: Message<'m>,
275 ) -> hs::NextStateOrError<'m>
276 where
277 Self: 'm,
278 {
279 match m.payload {
280 MessagePayload::Handshake {
281 parsed:
282 HandshakeMessagePayload {
283 payload: HandshakePayload::ServerKeyExchange(..),
284 ..
285 },
286 ..
287 } => Box::new(ExpectServerKx {
288 config: self.config,
289 resuming_session: self.resuming_session,
290 session_id: self.session_id,
291 server_name: self.server_name,
292 randoms: self.randoms,
293 using_ems: self.using_ems,
294 transcript: self.transcript,
295 suite: self.suite,
296 server_cert: ServerCertDetails::new(self.server_cert_chain, vec![]),
297 must_issue_new_ticket: self.must_issue_new_ticket,
298 })
299 .handle(cx, m),
300 MessagePayload::Handshake {
301 parsed:
302 HandshakeMessagePayload {
303 payload: HandshakePayload::CertificateStatus(..),
304 ..
305 },
306 ..
307 } => Box::new(ExpectCertificateStatus {
308 config: self.config,
309 resuming_session: self.resuming_session,
310 session_id: self.session_id,
311 server_name: self.server_name,
312 randoms: self.randoms,
313 using_ems: self.using_ems,
314 transcript: self.transcript,
315 suite: self.suite,
316 server_cert_chain: self.server_cert_chain,
317 must_issue_new_ticket: self.must_issue_new_ticket,
318 })
319 .handle(cx, m),
320 payload => Err(inappropriate_handshake_message(
321 &payload,
322 &[ContentType::Handshake],
323 &[
324 HandshakeType::ServerKeyExchange,
325 HandshakeType::CertificateStatus,
326 ],
327 )),
328 }
329 }
330
331 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
332 Box::new(ExpectCertificateStatusOrServerKx {
333 config: self.config,
334 resuming_session: self.resuming_session,
335 session_id: self.session_id,
336 server_name: self.server_name,
337 randoms: self.randoms,
338 using_ems: self.using_ems,
339 transcript: self.transcript,
340 suite: self.suite,
341 server_cert_chain: self.server_cert_chain.into_owned(),
342 must_issue_new_ticket: self.must_issue_new_ticket,
343 })
344 }
345}
346
347struct ExpectCertificateStatus<'a> {
348 config: Arc<ClientConfig>,
349 resuming_session: Option<persist::Tls12ClientSessionValue>,
350 session_id: SessionId,
351 server_name: ServerName<'static>,
352 randoms: ConnectionRandoms,
353 using_ems: bool,
354 transcript: HandshakeHash,
355 suite: &'static Tls12CipherSuite,
356 server_cert_chain: CertificateChain<'a>,
357 must_issue_new_ticket: bool,
358}
359
360impl State<ClientConnectionData> for ExpectCertificateStatus<'_> {
361 fn handle<'m>(
362 mut self: Box<Self>,
363 _cx: &mut ClientContext<'_>,
364 m: Message<'m>,
365 ) -> hs::NextStateOrError<'m>
366 where
367 Self: 'm,
368 {
369 self.transcript.add_message(&m);
370 let server_cert_ocsp_response = require_handshake_msg_move!(
371 m,
372 HandshakeType::CertificateStatus,
373 HandshakePayload::CertificateStatus
374 )?
375 .into_inner();
376
377 trace!(
378 "Server stapled OCSP response is {:?}",
379 &server_cert_ocsp_response
380 );
381
382 let server_cert = ServerCertDetails::new(self.server_cert_chain, server_cert_ocsp_response);
383
384 Ok(Box::new(ExpectServerKx {
385 config: self.config,
386 resuming_session: self.resuming_session,
387 session_id: self.session_id,
388 server_name: self.server_name,
389 randoms: self.randoms,
390 using_ems: self.using_ems,
391 transcript: self.transcript,
392 suite: self.suite,
393 server_cert,
394 must_issue_new_ticket: self.must_issue_new_ticket,
395 }))
396 }
397
398 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
399 Box::new(ExpectCertificateStatus {
400 config: self.config,
401 resuming_session: self.resuming_session,
402 session_id: self.session_id,
403 server_name: self.server_name,
404 randoms: self.randoms,
405 using_ems: self.using_ems,
406 transcript: self.transcript,
407 suite: self.suite,
408 server_cert_chain: self.server_cert_chain.into_owned(),
409 must_issue_new_ticket: self.must_issue_new_ticket,
410 })
411 }
412}
413
414struct ExpectServerKx<'a> {
415 config: Arc<ClientConfig>,
416 resuming_session: Option<persist::Tls12ClientSessionValue>,
417 session_id: SessionId,
418 server_name: ServerName<'static>,
419 randoms: ConnectionRandoms,
420 using_ems: bool,
421 transcript: HandshakeHash,
422 suite: &'static Tls12CipherSuite,
423 server_cert: ServerCertDetails<'a>,
424 must_issue_new_ticket: bool,
425}
426
427impl State<ClientConnectionData> for ExpectServerKx<'_> {
428 fn handle<'m>(
429 mut self: Box<Self>,
430 cx: &mut ClientContext<'_>,
431 m: Message<'m>,
432 ) -> hs::NextStateOrError<'m>
433 where
434 Self: 'm,
435 {
436 let opaque_kx = require_handshake_msg!(
437 m,
438 HandshakeType::ServerKeyExchange,
439 HandshakePayload::ServerKeyExchange
440 )?;
441 self.transcript.add_message(&m);
442
443 let kx = opaque_kx
444 .unwrap_given_kxa(self.suite.kx)
445 .ok_or_else(|| {
446 cx.common.send_fatal_alert(
447 AlertDescription::DecodeError,
448 InvalidMessage::MissingKeyExchange,
449 )
450 })?;
451
452 let mut kx_params = Vec::new();
454 kx.params.encode(&mut kx_params);
455 let server_kx = ServerKxDetails::new(kx_params, kx.dss);
456
457 #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
458 {
459 match &kx.params {
460 ServerKeyExchangeParams::Ecdh(ecdhe) => {
461 debug!("ECDHE curve is {:?}", ecdhe.curve_params)
462 }
463 ServerKeyExchangeParams::Dh(dhe) => {
464 debug!("DHE params are p = {:?}, g = {:?}", dhe.dh_p, dhe.dh_g)
465 }
466 }
467 }
468
469 Ok(Box::new(ExpectServerDoneOrCertReq {
470 config: self.config,
471 resuming_session: self.resuming_session,
472 session_id: self.session_id,
473 server_name: self.server_name,
474 randoms: self.randoms,
475 using_ems: self.using_ems,
476 transcript: self.transcript,
477 suite: self.suite,
478 server_cert: self.server_cert,
479 server_kx,
480 must_issue_new_ticket: self.must_issue_new_ticket,
481 }))
482 }
483
484 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
485 Box::new(ExpectServerKx {
486 config: self.config,
487 resuming_session: self.resuming_session,
488 session_id: self.session_id,
489 server_name: self.server_name,
490 randoms: self.randoms,
491 using_ems: self.using_ems,
492 transcript: self.transcript,
493 suite: self.suite,
494 server_cert: self.server_cert.into_owned(),
495 must_issue_new_ticket: self.must_issue_new_ticket,
496 })
497 }
498}
499
500fn emit_certificate(
501 transcript: &mut HandshakeHash,
502 cert_chain: CertificateChain<'static>,
503 common: &mut CommonState,
504) {
505 let cert = Message {
506 version: ProtocolVersion::TLSv1_2,
507 payload: MessagePayload::handshake(HandshakeMessagePayload {
508 typ: HandshakeType::Certificate,
509 payload: HandshakePayload::Certificate(cert_chain),
510 }),
511 };
512
513 transcript.add_message(&cert);
514 common.send_msg(cert, false);
515}
516
517fn emit_client_kx(
518 transcript: &mut HandshakeHash,
519 kxa: KeyExchangeAlgorithm,
520 common: &mut CommonState,
521 pub_key: &[u8],
522) {
523 let mut buf = Vec::new();
524 match kxa {
525 KeyExchangeAlgorithm::ECDHE => ClientKeyExchangeParams::Ecdh(ClientEcdhParams {
526 public: PayloadU8::new(pub_key.to_vec()),
527 }),
528 KeyExchangeAlgorithm::DHE => ClientKeyExchangeParams::Dh(ClientDhParams {
529 public: PayloadU16::new(pub_key.to_vec()),
530 }),
531 }
532 .encode(&mut buf);
533 let pubkey = Payload::new(buf);
534
535 let ckx = Message {
536 version: ProtocolVersion::TLSv1_2,
537 payload: MessagePayload::handshake(HandshakeMessagePayload {
538 typ: HandshakeType::ClientKeyExchange,
539 payload: HandshakePayload::ClientKeyExchange(pubkey),
540 }),
541 };
542
543 transcript.add_message(&ckx);
544 common.send_msg(ckx, false);
545}
546
547fn emit_certverify(
548 transcript: &mut HandshakeHash,
549 signer: &dyn Signer,
550 common: &mut CommonState,
551) -> Result<(), Error> {
552 let message = transcript
553 .take_handshake_buf()
554 .ok_or_else(|| Error::General("Expected transcript".to_owned()))?;
555
556 let scheme = signer.scheme();
557 let sig = signer.sign(&message)?;
558 let body = DigitallySignedStruct::new(scheme, sig);
559
560 let m = Message {
561 version: ProtocolVersion::TLSv1_2,
562 payload: MessagePayload::handshake(HandshakeMessagePayload {
563 typ: HandshakeType::CertificateVerify,
564 payload: HandshakePayload::CertificateVerify(body),
565 }),
566 };
567
568 transcript.add_message(&m);
569 common.send_msg(m, false);
570 Ok(())
571}
572
573fn emit_ccs(common: &mut CommonState) {
574 let ccs = Message {
575 version: ProtocolVersion::TLSv1_2,
576 payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
577 };
578
579 common.send_msg(ccs, false);
580}
581
582fn emit_finished(
583 secrets: &ConnectionSecrets,
584 transcript: &mut HandshakeHash,
585 common: &mut CommonState,
586) {
587 let vh = transcript.current_hash();
588 let verify_data = secrets.client_verify_data(&vh);
589 let verify_data_payload = Payload::new(verify_data);
590
591 let f = Message {
592 version: ProtocolVersion::TLSv1_2,
593 payload: MessagePayload::handshake(HandshakeMessagePayload {
594 typ: HandshakeType::Finished,
595 payload: HandshakePayload::Finished(verify_data_payload),
596 }),
597 };
598
599 transcript.add_message(&f);
600 common.send_msg(f, true);
601}
602
603struct ServerKxDetails {
604 kx_params: Vec<u8>,
605 kx_sig: DigitallySignedStruct,
606}
607
608impl ServerKxDetails {
609 fn new(params: Vec<u8>, sig: DigitallySignedStruct) -> Self {
610 Self {
611 kx_params: params,
612 kx_sig: sig,
613 }
614 }
615}
616
617struct ExpectServerDoneOrCertReq<'a> {
621 config: Arc<ClientConfig>,
622 resuming_session: Option<persist::Tls12ClientSessionValue>,
623 session_id: SessionId,
624 server_name: ServerName<'static>,
625 randoms: ConnectionRandoms,
626 using_ems: bool,
627 transcript: HandshakeHash,
628 suite: &'static Tls12CipherSuite,
629 server_cert: ServerCertDetails<'a>,
630 server_kx: ServerKxDetails,
631 must_issue_new_ticket: bool,
632}
633
634impl State<ClientConnectionData> for ExpectServerDoneOrCertReq<'_> {
635 fn handle<'m>(
636 mut self: Box<Self>,
637 cx: &mut ClientContext<'_>,
638 m: Message<'m>,
639 ) -> hs::NextStateOrError<'m>
640 where
641 Self: 'm,
642 {
643 if matches!(
644 m.payload,
645 MessagePayload::Handshake {
646 parsed: HandshakeMessagePayload {
647 payload: HandshakePayload::CertificateRequest(_),
648 ..
649 },
650 ..
651 }
652 ) {
653 Box::new(ExpectCertificateRequest {
654 config: self.config,
655 resuming_session: self.resuming_session,
656 session_id: self.session_id,
657 server_name: self.server_name,
658 randoms: self.randoms,
659 using_ems: self.using_ems,
660 transcript: self.transcript,
661 suite: self.suite,
662 server_cert: self.server_cert,
663 server_kx: self.server_kx,
664 must_issue_new_ticket: self.must_issue_new_ticket,
665 })
666 .handle(cx, m)
667 } else {
668 self.transcript.abandon_client_auth();
669
670 Box::new(ExpectServerDone {
671 config: self.config,
672 resuming_session: self.resuming_session,
673 session_id: self.session_id,
674 server_name: self.server_name,
675 randoms: self.randoms,
676 using_ems: self.using_ems,
677 transcript: self.transcript,
678 suite: self.suite,
679 server_cert: self.server_cert,
680 server_kx: self.server_kx,
681 client_auth: None,
682 must_issue_new_ticket: self.must_issue_new_ticket,
683 })
684 .handle(cx, m)
685 }
686 }
687
688 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
689 Box::new(ExpectServerDoneOrCertReq {
690 config: self.config,
691 resuming_session: self.resuming_session,
692 session_id: self.session_id,
693 server_name: self.server_name,
694 randoms: self.randoms,
695 using_ems: self.using_ems,
696 transcript: self.transcript,
697 suite: self.suite,
698 server_cert: self.server_cert.into_owned(),
699 server_kx: self.server_kx,
700 must_issue_new_ticket: self.must_issue_new_ticket,
701 })
702 }
703}
704
705struct ExpectCertificateRequest<'a> {
706 config: Arc<ClientConfig>,
707 resuming_session: Option<persist::Tls12ClientSessionValue>,
708 session_id: SessionId,
709 server_name: ServerName<'static>,
710 randoms: ConnectionRandoms,
711 using_ems: bool,
712 transcript: HandshakeHash,
713 suite: &'static Tls12CipherSuite,
714 server_cert: ServerCertDetails<'a>,
715 server_kx: ServerKxDetails,
716 must_issue_new_ticket: bool,
717}
718
719impl State<ClientConnectionData> for ExpectCertificateRequest<'_> {
720 fn handle<'m>(
721 mut self: Box<Self>,
722 _cx: &mut ClientContext<'_>,
723 m: Message<'m>,
724 ) -> hs::NextStateOrError<'m>
725 where
726 Self: 'm,
727 {
728 let certreq = require_handshake_msg!(
729 m,
730 HandshakeType::CertificateRequest,
731 HandshakePayload::CertificateRequest
732 )?;
733 self.transcript.add_message(&m);
734 debug!("Got CertificateRequest {:?}", certreq);
735
736 const NO_CONTEXT: Option<Vec<u8>> = None; let no_compression = None; let client_auth = ClientAuthDetails::resolve(
745 self.config
746 .client_auth_cert_resolver
747 .as_ref(),
748 Some(&certreq.canames),
749 &certreq.sigschemes,
750 NO_CONTEXT,
751 no_compression,
752 );
753
754 Ok(Box::new(ExpectServerDone {
755 config: self.config,
756 resuming_session: self.resuming_session,
757 session_id: self.session_id,
758 server_name: self.server_name,
759 randoms: self.randoms,
760 using_ems: self.using_ems,
761 transcript: self.transcript,
762 suite: self.suite,
763 server_cert: self.server_cert,
764 server_kx: self.server_kx,
765 client_auth: Some(client_auth),
766 must_issue_new_ticket: self.must_issue_new_ticket,
767 }))
768 }
769
770 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
771 Box::new(ExpectCertificateRequest {
772 config: self.config,
773 resuming_session: self.resuming_session,
774 session_id: self.session_id,
775 server_name: self.server_name,
776 randoms: self.randoms,
777 using_ems: self.using_ems,
778 transcript: self.transcript,
779 suite: self.suite,
780 server_cert: self.server_cert.into_owned(),
781 server_kx: self.server_kx,
782 must_issue_new_ticket: self.must_issue_new_ticket,
783 })
784 }
785}
786
787struct ExpectServerDone<'a> {
788 config: Arc<ClientConfig>,
789 resuming_session: Option<persist::Tls12ClientSessionValue>,
790 session_id: SessionId,
791 server_name: ServerName<'static>,
792 randoms: ConnectionRandoms,
793 using_ems: bool,
794 transcript: HandshakeHash,
795 suite: &'static Tls12CipherSuite,
796 server_cert: ServerCertDetails<'a>,
797 server_kx: ServerKxDetails,
798 client_auth: Option<ClientAuthDetails>,
799 must_issue_new_ticket: bool,
800}
801
802impl State<ClientConnectionData> for ExpectServerDone<'_> {
803 fn handle<'m>(
804 self: Box<Self>,
805 cx: &mut ClientContext<'_>,
806 m: Message<'m>,
807 ) -> hs::NextStateOrError<'m>
808 where
809 Self: 'm,
810 {
811 match m.payload {
812 MessagePayload::Handshake {
813 parsed:
814 HandshakeMessagePayload {
815 payload: HandshakePayload::ServerHelloDone,
816 ..
817 },
818 ..
819 } => {}
820 payload => {
821 return Err(inappropriate_handshake_message(
822 &payload,
823 &[ContentType::Handshake],
824 &[HandshakeType::ServerHelloDone],
825 ));
826 }
827 }
828
829 let mut st = *self;
830 st.transcript.add_message(&m);
831
832 cx.common.check_aligned_handshake()?;
833
834 trace!("Server cert is {:?}", st.server_cert.cert_chain);
835 debug!("Server DNS name is {:?}", st.server_name);
836
837 let suite = st.suite;
838
839 let (end_entity, intermediates) = st
853 .server_cert
854 .cert_chain
855 .split_first()
856 .ok_or(Error::NoCertificatesPresented)?;
857
858 let now = st.config.current_time()?;
859
860 let cert_verified = st
861 .config
862 .verifier
863 .verify_server_cert(
864 end_entity,
865 intermediates,
866 &st.server_name,
867 &st.server_cert.ocsp_response,
868 now,
869 )
870 .map_err(|err| {
871 cx.common
872 .send_cert_verify_error_alert(err)
873 })?;
874
875 let sig_verified = {
879 let mut message = Vec::new();
880 message.extend_from_slice(&st.randoms.client);
881 message.extend_from_slice(&st.randoms.server);
882 message.extend_from_slice(&st.server_kx.kx_params);
883
884 let sig = &st.server_kx.kx_sig;
886 if !SupportedCipherSuite::from(suite)
887 .usable_for_signature_algorithm(sig.scheme.algorithm())
888 {
889 warn!(
890 "peer signed kx with wrong algorithm (got {:?} expect {:?})",
891 sig.scheme.algorithm(),
892 suite.sign
893 );
894 return Err(PeerMisbehaved::SignedKxWithWrongAlgorithm.into());
895 }
896
897 st.config
898 .verifier
899 .verify_tls12_signature(&message, end_entity, sig)
900 .map_err(|err| {
901 cx.common
902 .send_cert_verify_error_alert(err)
903 })?
904 };
905 cx.common.peer_certificates = Some(st.server_cert.cert_chain.into_owned());
906
907 if let Some(client_auth) = &st.client_auth {
909 let certs = match client_auth {
910 ClientAuthDetails::Empty { .. } => CertificateChain::default(),
911 ClientAuthDetails::Verify { certkey, .. } => CertificateChain(certkey.cert.clone()),
912 };
913 emit_certificate(&mut st.transcript, certs, cx.common);
914 }
915
916 let kx_params = tls12::decode_kx_params::<ServerKeyExchangeParams>(
918 st.suite.kx,
919 cx.common,
920 &st.server_kx.kx_params,
921 )?;
922 let maybe_skxg = match &kx_params {
923 ServerKeyExchangeParams::Ecdh(ecdh) => st
924 .config
925 .find_kx_group(ecdh.curve_params.named_group, ProtocolVersion::TLSv1_2),
926 ServerKeyExchangeParams::Dh(dh) => {
927 let ffdhe_group = dh.as_ffdhe_group();
928
929 st.config
930 .provider
931 .kx_groups
932 .iter()
933 .find(|kxg| kxg.ffdhe_group() == Some(ffdhe_group))
934 .copied()
935 }
936 };
937 let Some(skxg) = maybe_skxg else {
938 return Err(cx.common.send_fatal_alert(
939 AlertDescription::IllegalParameter,
940 PeerMisbehaved::SelectedUnofferedKxGroup,
941 ));
942 };
943 cx.common.kx_state = KxState::Start(skxg);
944 let kx = skxg.start()?;
945
946 let mut transcript = st.transcript;
948 emit_client_kx(&mut transcript, st.suite.kx, cx.common, kx.pub_key());
949 let ems_seed = st
951 .using_ems
952 .then(|| transcript.current_hash());
953
954 if let Some(ClientAuthDetails::Verify { signer, .. }) = &st.client_auth {
956 emit_certverify(&mut transcript, signer.as_ref(), cx.common)?;
957 }
958
959 let secrets = ConnectionSecrets::from_key_exchange(
963 kx,
964 kx_params.pub_key(),
965 ems_seed,
966 st.randoms,
967 suite,
968 )
969 .map_err(|err| {
970 cx.common
971 .send_fatal_alert(AlertDescription::IllegalParameter, err)
972 })?;
973 cx.common.kx_state.complete();
974
975 emit_ccs(cx.common);
977
978 st.config.key_log.log(
980 "CLIENT_RANDOM",
981 &secrets.randoms.client,
982 &secrets.master_secret,
983 );
984 cx.common
985 .start_encryption_tls12(&secrets, Side::Client);
986 cx.common
987 .record_layer
988 .start_encrypting();
989
990 emit_finished(&secrets, &mut transcript, cx.common);
992
993 if st.must_issue_new_ticket {
994 Ok(Box::new(ExpectNewTicket {
995 config: st.config,
996 secrets,
997 resuming_session: st.resuming_session,
998 session_id: st.session_id,
999 server_name: st.server_name,
1000 using_ems: st.using_ems,
1001 transcript,
1002 resuming: false,
1003 cert_verified,
1004 sig_verified,
1005 }))
1006 } else {
1007 Ok(Box::new(ExpectCcs {
1008 config: st.config,
1009 secrets,
1010 resuming_session: st.resuming_session,
1011 session_id: st.session_id,
1012 server_name: st.server_name,
1013 using_ems: st.using_ems,
1014 transcript,
1015 ticket: None,
1016 resuming: false,
1017 cert_verified,
1018 sig_verified,
1019 }))
1020 }
1021 }
1022
1023 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1024 Box::new(ExpectServerDone {
1025 config: self.config,
1026 resuming_session: self.resuming_session,
1027 session_id: self.session_id,
1028 server_name: self.server_name,
1029 randoms: self.randoms,
1030 using_ems: self.using_ems,
1031 transcript: self.transcript,
1032 suite: self.suite,
1033 server_cert: self.server_cert.into_owned(),
1034 server_kx: self.server_kx,
1035 client_auth: self.client_auth,
1036 must_issue_new_ticket: self.must_issue_new_ticket,
1037 })
1038 }
1039}
1040
1041struct ExpectNewTicket {
1042 config: Arc<ClientConfig>,
1043 secrets: ConnectionSecrets,
1044 resuming_session: Option<persist::Tls12ClientSessionValue>,
1045 session_id: SessionId,
1046 server_name: ServerName<'static>,
1047 using_ems: bool,
1048 transcript: HandshakeHash,
1049 resuming: bool,
1050 cert_verified: verify::ServerCertVerified,
1051 sig_verified: verify::HandshakeSignatureValid,
1052}
1053
1054impl State<ClientConnectionData> for ExpectNewTicket {
1055 fn handle<'m>(
1056 mut self: Box<Self>,
1057 _cx: &mut ClientContext<'_>,
1058 m: Message<'m>,
1059 ) -> hs::NextStateOrError<'m>
1060 where
1061 Self: 'm,
1062 {
1063 self.transcript.add_message(&m);
1064
1065 let nst = require_handshake_msg_move!(
1066 m,
1067 HandshakeType::NewSessionTicket,
1068 HandshakePayload::NewSessionTicket
1069 )?;
1070
1071 Ok(Box::new(ExpectCcs {
1072 config: self.config,
1073 secrets: self.secrets,
1074 resuming_session: self.resuming_session,
1075 session_id: self.session_id,
1076 server_name: self.server_name,
1077 using_ems: self.using_ems,
1078 transcript: self.transcript,
1079 ticket: Some(nst),
1080 resuming: self.resuming,
1081 cert_verified: self.cert_verified,
1082 sig_verified: self.sig_verified,
1083 }))
1084 }
1085
1086 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1087 self
1088 }
1089}
1090
1091struct ExpectCcs {
1093 config: Arc<ClientConfig>,
1094 secrets: ConnectionSecrets,
1095 resuming_session: Option<persist::Tls12ClientSessionValue>,
1096 session_id: SessionId,
1097 server_name: ServerName<'static>,
1098 using_ems: bool,
1099 transcript: HandshakeHash,
1100 ticket: Option<NewSessionTicketPayload>,
1101 resuming: bool,
1102 cert_verified: verify::ServerCertVerified,
1103 sig_verified: verify::HandshakeSignatureValid,
1104}
1105
1106impl State<ClientConnectionData> for ExpectCcs {
1107 fn handle<'m>(
1108 self: Box<Self>,
1109 cx: &mut ClientContext<'_>,
1110 m: Message<'m>,
1111 ) -> hs::NextStateOrError<'m>
1112 where
1113 Self: 'm,
1114 {
1115 match m.payload {
1116 MessagePayload::ChangeCipherSpec(..) => {}
1117 payload => {
1118 return Err(inappropriate_message(
1119 &payload,
1120 &[ContentType::ChangeCipherSpec],
1121 ));
1122 }
1123 }
1124 cx.common.check_aligned_handshake()?;
1127
1128 cx.common
1130 .record_layer
1131 .start_decrypting();
1132
1133 Ok(Box::new(ExpectFinished {
1134 config: self.config,
1135 secrets: self.secrets,
1136 resuming_session: self.resuming_session,
1137 session_id: self.session_id,
1138 server_name: self.server_name,
1139 using_ems: self.using_ems,
1140 transcript: self.transcript,
1141 ticket: self.ticket,
1142 resuming: self.resuming,
1143 cert_verified: self.cert_verified,
1144 sig_verified: self.sig_verified,
1145 }))
1146 }
1147
1148 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1149 self
1150 }
1151}
1152
1153struct ExpectFinished {
1154 config: Arc<ClientConfig>,
1155 resuming_session: Option<persist::Tls12ClientSessionValue>,
1156 session_id: SessionId,
1157 server_name: ServerName<'static>,
1158 using_ems: bool,
1159 transcript: HandshakeHash,
1160 ticket: Option<NewSessionTicketPayload>,
1161 secrets: ConnectionSecrets,
1162 resuming: bool,
1163 cert_verified: verify::ServerCertVerified,
1164 sig_verified: verify::HandshakeSignatureValid,
1165}
1166
1167impl ExpectFinished {
1168 fn save_session(&mut self, cx: &ClientContext<'_>) {
1170 let (mut ticket, lifetime) = match self.ticket.take() {
1173 Some(nst) => (nst.ticket, nst.lifetime_hint),
1174 None => (Arc::new(PayloadU16::empty()), 0),
1175 };
1176
1177 if ticket.0.is_empty() {
1178 if let Some(resuming_session) = &mut self.resuming_session {
1179 ticket = resuming_session.ticket();
1180 }
1181 }
1182
1183 if self.session_id.is_empty() && ticket.0.is_empty() {
1184 debug!("Session not saved: server didn't allocate id or ticket");
1185 return;
1186 }
1187
1188 let Ok(now) = self.config.current_time() else {
1189 debug!("Could not get current time");
1190 return;
1191 };
1192
1193 let session_value = persist::Tls12ClientSessionValue::new(
1194 self.secrets.suite(),
1195 self.session_id,
1196 ticket,
1197 self.secrets.master_secret(),
1198 cx.common
1199 .peer_certificates
1200 .clone()
1201 .unwrap_or_default(),
1202 now,
1203 lifetime,
1204 self.using_ems,
1205 );
1206
1207 self.config
1208 .resumption
1209 .store
1210 .set_tls12_session(self.server_name.clone(), session_value);
1211 }
1212}
1213
1214impl State<ClientConnectionData> for ExpectFinished {
1215 fn handle<'m>(
1216 self: Box<Self>,
1217 cx: &mut ClientContext<'_>,
1218 m: Message<'m>,
1219 ) -> hs::NextStateOrError<'m>
1220 where
1221 Self: 'm,
1222 {
1223 let mut st = *self;
1224 let finished =
1225 require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?;
1226
1227 cx.common.check_aligned_handshake()?;
1228
1229 let vh = st.transcript.current_hash();
1231 let expect_verify_data = st.secrets.server_verify_data(&vh);
1232
1233 let _fin_verified =
1236 match ConstantTimeEq::ct_eq(&expect_verify_data[..], finished.bytes()).into() {
1237 true => verify::FinishedMessageVerified::assertion(),
1238 false => {
1239 return Err(cx
1240 .common
1241 .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError));
1242 }
1243 };
1244
1245 st.transcript.add_message(&m);
1247
1248 st.save_session(cx);
1249
1250 if st.resuming {
1251 emit_ccs(cx.common);
1252 cx.common
1253 .record_layer
1254 .start_encrypting();
1255 emit_finished(&st.secrets, &mut st.transcript, cx.common);
1256 }
1257
1258 cx.common
1259 .start_traffic(&mut cx.sendable_plaintext);
1260 Ok(Box::new(ExpectTraffic {
1261 secrets: st.secrets,
1262 _cert_verified: st.cert_verified,
1263 _sig_verified: st.sig_verified,
1264 _fin_verified,
1265 }))
1266 }
1267
1268 fn handle_decrypt_error(&self) {
1272 if self.resuming {
1273 self.config
1274 .resumption
1275 .store
1276 .remove_tls12_session(&self.server_name);
1277 }
1278 }
1279
1280 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1281 self
1282 }
1283}
1284
1285struct ExpectTraffic {
1287 secrets: ConnectionSecrets,
1288 _cert_verified: verify::ServerCertVerified,
1289 _sig_verified: verify::HandshakeSignatureValid,
1290 _fin_verified: verify::FinishedMessageVerified,
1291}
1292
1293impl State<ClientConnectionData> for ExpectTraffic {
1294 fn handle<'m>(
1295 self: Box<Self>,
1296 cx: &mut ClientContext<'_>,
1297 m: Message<'m>,
1298 ) -> hs::NextStateOrError<'m>
1299 where
1300 Self: 'm,
1301 {
1302 match m.payload {
1303 MessagePayload::ApplicationData(payload) => cx
1304 .common
1305 .take_received_plaintext(payload),
1306 payload => {
1307 return Err(inappropriate_message(
1308 &payload,
1309 &[ContentType::ApplicationData],
1310 ));
1311 }
1312 }
1313 Ok(self)
1314 }
1315
1316 fn export_keying_material(
1317 &self,
1318 output: &mut [u8],
1319 label: &[u8],
1320 context: Option<&[u8]>,
1321 ) -> Result<(), Error> {
1322 self.secrets
1323 .export_keying_material(output, label, context);
1324 Ok(())
1325 }
1326
1327 fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> {
1328 self.secrets
1329 .extract_secrets(Side::Client)
1330 }
1331
1332 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1333 self
1334 }
1335}