1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::vec;
4use alloc::vec::Vec;
5
6use pki_types::ServerName;
7pub(super) use server_hello::CompleteServerHelloHandling;
8use subtle::ConstantTimeEq;
9
10use super::client_conn::ClientConnectionData;
11use super::hs::ClientContext;
12use crate::check::{inappropriate_handshake_message, inappropriate_message};
13use crate::client::common::{ClientAuthDetails, ServerCertDetails};
14use crate::client::{ClientConfig, hs};
15use crate::common_state::{CommonState, HandshakeKind, KxState, Side, State};
16use crate::conn::ConnectionRandoms;
17use crate::crypto::KeyExchangeAlgorithm;
18use crate::enums::{AlertDescription, ContentType, HandshakeType, ProtocolVersion};
19use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved};
20use crate::hash_hs::HandshakeHash;
21use crate::log::{debug, trace, warn};
22use crate::msgs::base::{Payload, PayloadU8, PayloadU16};
23use crate::msgs::ccs::ChangeCipherSpecPayload;
24use crate::msgs::handshake::{
25 CertificateChain, ClientDhParams, ClientEcdhParams, ClientKeyExchangeParams,
26 HandshakeMessagePayload, HandshakePayload, NewSessionTicketPayload, ServerKeyExchangeParams,
27 SessionId,
28};
29use crate::msgs::message::{Message, MessagePayload};
30use crate::msgs::persist;
31use crate::sign::Signer;
32use crate::suites::{PartiallyExtractedSecrets, SupportedCipherSuite};
33use crate::sync::Arc;
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 // Look for TLS1.3 downgrade signal in server random
64 // both the server random and TLS12_DOWNGRADE_SENTINEL are
65 // public values and don't require constant time comparison
66 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 // Doing EMS?
77 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 // Might the server send a ticket?
88 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 // Might the server send a CertificateStatus between Certificate and
99 // ServerKeyExchange?
100 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 // See if we're successfully resuming.
108 if let Some(resuming) = self.resuming_session {
109 if resuming.session_id == server_hello.session_id {
110 debug!("Server agreed to resume");
111
112 // Is the server telling lies about the ciphersuite?
113 if resuming.suite() != suite {
114 return Err(PeerMisbehaved::ResumptionOfferedWithVariedCipherSuite.into());
115 }
116
117 // And about EMS support?
118 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 // Since we're resuming, we verified the certificate and
133 // proof of possession in the prior session.
134 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 // Save the signature and signed parameters for later verification.
453 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<'_> = Message {
506 version: ProtocolVersion::TLSv1_2,
507 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
508 typ: HandshakeType::Certificate,
509 payload: HandshakePayload::Certificate(cert_chain),
510 }),
511 };
512
513 transcript.add_message(&cert);
514 common.send_msg(m:cert, must_encrypt: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 = Vec::new();
524 matchClientKeyExchangeParams kxa {
525 KeyExchangeAlgorithm::ECDHE => ClientKeyExchangeParams::Ecdh(ClientEcdhParams {
526 public: PayloadU8::new(bytes:pub_key.to_vec()),
527 }),
528 KeyExchangeAlgorithm::DHE => ClientKeyExchangeParams::Dh(ClientDhParams {
529 public: PayloadU16::new(bytes:pub_key.to_vec()),
530 }),
531 }
532 .encode(&mut buf);
533 let pubkey: Payload<'static> = Payload::new(bytes:buf);
534
535 let ckx: Message<'_> = Message {
536 version: ProtocolVersion::TLSv1_2,
537 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
538 typ: HandshakeType::ClientKeyExchange,
539 payload: HandshakePayload::ClientKeyExchange(pubkey),
540 }),
541 };
542
543 transcript.add_message(&ckx);
544 common.send_msg(m:ckx, must_encrypt:false);
545}
546
547fn emit_certverify(
548 transcript: &mut HandshakeHash,
549 signer: &dyn Signer,
550 common: &mut CommonState,
551) -> Result<(), Error> {
552 let message: Vec = transcript
553 .take_handshake_buf()
554 .ok_or_else(|| Error::General("Expected transcript".to_owned()))?;
555
556 let scheme: SignatureScheme = signer.scheme();
557 let sig: Vec = signer.sign(&message)?;
558 let body: DigitallySignedStruct = DigitallySignedStruct::new(scheme, sig);
559
560 let m: Message<'_> = Message {
561 version: ProtocolVersion::TLSv1_2,
562 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
563 typ: HandshakeType::CertificateVerify,
564 payload: HandshakePayload::CertificateVerify(body),
565 }),
566 };
567
568 transcript.add_message(&m);
569 common.send_msg(m, must_encrypt:false);
570 Ok(())
571}
572
573fn emit_ccs(common: &mut CommonState) {
574 let ccs: Message<'_> = Message {
575 version: ProtocolVersion::TLSv1_2,
576 payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
577 };
578
579 common.send_msg(m:ccs, must_encrypt:false);
580}
581
582fn emit_finished(
583 secrets: &ConnectionSecrets,
584 transcript: &mut HandshakeHash,
585 common: &mut CommonState,
586) {
587 let vh: Output = transcript.current_hash();
588 let verify_data: Vec = secrets.client_verify_data(&vh);
589 let verify_data_payload: Payload<'static> = Payload::new(bytes:verify_data);
590
591 let f: Message<'_> = Message {
592 version: ProtocolVersion::TLSv1_2,
593 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
594 typ: HandshakeType::Finished,
595 payload: HandshakePayload::Finished(verify_data_payload),
596 }),
597 };
598
599 transcript.add_message(&f);
600 common.send_msg(m:f, must_encrypt: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
617// --- Either a CertificateRequest, or a ServerHelloDone. ---
618// Existence of the CertificateRequest tells us the server is asking for
619// client auth. Otherwise we go straight to ServerHelloDone.
620struct 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 // The RFC jovially describes the design here as 'somewhat complicated'
737 // and 'somewhat underspecified'. So thanks for that.
738 //
739 // We ignore certreq.certtypes as a result, since the information it contains
740 // is entirely duplicated in certreq.sigschemes.
741
742 const NO_CONTEXT: Option<Vec<u8>> = None; // TLS 1.2 doesn't use a context.
743 let no_compression = None; // or compression
744 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 // 1. Verify the cert chain.
840 // 2. Verify that the top certificate signed their kx.
841 // 3. If doing client auth, send our Certificate.
842 // 4. Complete the key exchange:
843 // a) generate our kx pair
844 // b) emit a ClientKeyExchange containing it
845 // c) if doing client auth, emit a CertificateVerify
846 // d) derive the shared keys
847 // e) emit a CCS
848 // f) use the derived keys to start encryption
849 // 5. emit a Finished, our first encrypted message under the new keys.
850
851 // 1.
852 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 // 2.
876 // Build up the contents of the signed message.
877 // It's ClientHello.random || ServerHello.random || ServerKeyExchange.params
878 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 // Check the signature is compatible with the ciphersuite.
885 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 // 3.
908 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 // 4a.
917 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 // 4b.
947 let mut transcript = st.transcript;
948 emit_client_kx(&mut transcript, st.suite.kx, cx.common, kx.pub_key());
949 // Note: EMS handshake hash only runs up to ClientKeyExchange.
950 let ems_seed = st
951 .using_ems
952 .then(|| transcript.current_hash());
953
954 // 4c.
955 if let Some(ClientAuthDetails::Verify { signer, .. }) = &st.client_auth {
956 emit_certverify(&mut transcript, signer.as_ref(), cx.common)?;
957 }
958
959 // 4d. Derive secrets.
960 // An alert at this point will be sent in plaintext. That must happen
961 // prior to the CCS, or else the peer will try to decrypt it.
962 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 // 4e. CCS. We are definitely going to switch on encryption.
976 emit_ccs(cx.common);
977
978 // 4f. Now commit secrets.
979 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 // 5.
991 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
1091// -- Waiting for their CCS --
1092struct 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 // CCS should not be received interleaved with fragmented handshake-level
1125 // message.
1126 cx.common.check_aligned_handshake()?;
1127
1128 // Note: msgs layer validates trivial contents of CCS.
1129 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 // -- Waiting for their finished --
1169 fn save_session(&mut self, cx: &ClientContext<'_>) {
1170 // Save a ticket. If we got a new ticket, save that. Otherwise, save the
1171 // original ticket again.
1172 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 &self.config.verifier,
1203 &self.config.client_auth_cert_resolver,
1204 now,
1205 lifetime,
1206 self.using_ems,
1207 );
1208
1209 self.config
1210 .resumption
1211 .store
1212 .set_tls12_session(self.server_name.clone(), session_value);
1213 }
1214}
1215
1216impl State<ClientConnectionData> for ExpectFinished {
1217 fn handle<'m>(
1218 self: Box<Self>,
1219 cx: &mut ClientContext<'_>,
1220 m: Message<'m>,
1221 ) -> hs::NextStateOrError<'m>
1222 where
1223 Self: 'm,
1224 {
1225 let mut st = *self;
1226 let finished =
1227 require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?;
1228
1229 cx.common.check_aligned_handshake()?;
1230
1231 // Work out what verify_data we expect.
1232 let vh = st.transcript.current_hash();
1233 let expect_verify_data = st.secrets.server_verify_data(&vh);
1234
1235 // Constant-time verification of this is relatively unimportant: they only
1236 // get one chance. But it can't hurt.
1237 let _fin_verified =
1238 match ConstantTimeEq::ct_eq(&expect_verify_data[..], finished.bytes()).into() {
1239 true => verify::FinishedMessageVerified::assertion(),
1240 false => {
1241 return Err(cx
1242 .common
1243 .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError));
1244 }
1245 };
1246
1247 // Hash this message too.
1248 st.transcript.add_message(&m);
1249
1250 st.save_session(cx);
1251
1252 if st.resuming {
1253 emit_ccs(cx.common);
1254 cx.common
1255 .record_layer
1256 .start_encrypting();
1257 emit_finished(&st.secrets, &mut st.transcript, cx.common);
1258 }
1259
1260 cx.common
1261 .start_traffic(&mut cx.sendable_plaintext);
1262 Ok(Box::new(ExpectTraffic {
1263 secrets: st.secrets,
1264 _cert_verified: st.cert_verified,
1265 _sig_verified: st.sig_verified,
1266 _fin_verified,
1267 }))
1268 }
1269
1270 // we could not decrypt the encrypted handshake message with session resumption
1271 // this might mean that the ticket was invalid for some reason, so we remove it
1272 // from the store to restart a session from scratch
1273 fn handle_decrypt_error(&self) {
1274 if self.resuming {
1275 self.config
1276 .resumption
1277 .store
1278 .remove_tls12_session(&self.server_name);
1279 }
1280 }
1281
1282 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1283 self
1284 }
1285}
1286
1287// -- Traffic transit state --
1288struct ExpectTraffic {
1289 secrets: ConnectionSecrets,
1290 _cert_verified: verify::ServerCertVerified,
1291 _sig_verified: verify::HandshakeSignatureValid,
1292 _fin_verified: verify::FinishedMessageVerified,
1293}
1294
1295impl State<ClientConnectionData> for ExpectTraffic {
1296 fn handle<'m>(
1297 self: Box<Self>,
1298 cx: &mut ClientContext<'_>,
1299 m: Message<'m>,
1300 ) -> hs::NextStateOrError<'m>
1301 where
1302 Self: 'm,
1303 {
1304 match m.payload {
1305 MessagePayload::ApplicationData(payload) => cx
1306 .common
1307 .take_received_plaintext(payload),
1308 payload => {
1309 return Err(inappropriate_message(
1310 &payload,
1311 &[ContentType::ApplicationData],
1312 ));
1313 }
1314 }
1315 Ok(self)
1316 }
1317
1318 fn export_keying_material(
1319 &self,
1320 output: &mut [u8],
1321 label: &[u8],
1322 context: Option<&[u8]>,
1323 ) -> Result<(), Error> {
1324 self.secrets
1325 .export_keying_material(output, label, context);
1326 Ok(())
1327 }
1328
1329 fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> {
1330 self.secrets
1331 .extract_secrets(Side::Client)
1332 }
1333
1334 fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1335 self
1336 }
1337}
1338