1use crate::check::{inappropriate_handshake_message, inappropriate_message};
2use crate::common_state::{CommonState, Side, State};
3use crate::conn::ConnectionRandoms;
4use crate::enums::ProtocolVersion;
5use crate::enums::{AlertDescription, ContentType, HandshakeType};
6use crate::error::{Error, InvalidMessage, PeerMisbehaved};
7use crate::hash_hs::HandshakeHash;
8#[cfg(feature = "logging")]
9use crate::log::{debug, trace, warn};
10use crate::msgs::base::{Payload, PayloadU8};
11use crate::msgs::ccs::ChangeCipherSpecPayload;
12use crate::msgs::codec::Codec;
13use crate::msgs::handshake::{
14 CertificateChain, HandshakeMessagePayload, HandshakePayload, NewSessionTicketPayload,
15 ServerEcdhParams, SessionId,
16};
17use crate::msgs::message::{Message, MessagePayload};
18use crate::msgs::persist;
19use crate::sign::Signer;
20use crate::suites::{PartiallyExtractedSecrets, SupportedCipherSuite};
21use crate::tls12::{self, ConnectionSecrets, Tls12CipherSuite};
22use crate::verify::{self, DigitallySignedStruct};
23
24use super::client_conn::ClientConnectionData;
25use super::hs::ClientContext;
26use crate::client::common::ClientAuthDetails;
27use crate::client::common::ServerCertDetails;
28use crate::client::{hs, ClientConfig};
29
30use pki_types::{ServerName, UnixTime};
31use subtle::ConstantTimeEq;
32
33use alloc::borrow::ToOwned;
34use alloc::boxed::Box;
35use alloc::sync::Arc;
36use alloc::vec;
37use alloc::vec::Vec;
38
39pub(super) use server_hello::CompleteServerHelloHandling;
40
41mod server_hello {
42 use crate::msgs::enums::ExtensionType;
43 use crate::msgs::handshake::HasServerExtensions;
44 use crate::msgs::handshake::ServerHelloPayload;
45
46 use super::*;
47
48 pub(in crate::client) struct CompleteServerHelloHandling {
49 pub(in crate::client) config: Arc<ClientConfig>,
50 pub(in crate::client) resuming_session: Option<persist::Tls12ClientSessionValue>,
51 pub(in crate::client) server_name: ServerName<'static>,
52 pub(in crate::client) randoms: ConnectionRandoms,
53 pub(in crate::client) using_ems: bool,
54 pub(in crate::client) transcript: HandshakeHash,
55 }
56
57 impl CompleteServerHelloHandling {
58 pub(in crate::client) fn handle_server_hello(
59 mut self,
60 cx: &mut ClientContext,
61 suite: &'static Tls12CipherSuite,
62 server_hello: &ServerHelloPayload,
63 tls13_supported: bool,
64 ) -> hs::NextStateOrError {
65 self.randoms
66 .server
67 .clone_from_slice(&server_hello.random.0[..]);
68
69 // Look for TLS1.3 downgrade signal in server random
70 // both the server random and TLS12_DOWNGRADE_SENTINEL are
71 // public values and don't require constant time comparison
72 let has_downgrade_marker = self.randoms.server[24..] == tls12::DOWNGRADE_SENTINEL;
73 if tls13_supported && has_downgrade_marker {
74 return Err({
75 cx.common.send_fatal_alert(
76 AlertDescription::IllegalParameter,
77 PeerMisbehaved::AttemptedDowngradeToTls12WhenTls13IsSupported,
78 )
79 });
80 }
81
82 // Doing EMS?
83 self.using_ems = server_hello.ems_support_acked();
84
85 // Might the server send a ticket?
86 let must_issue_new_ticket = if server_hello
87 .find_extension(ExtensionType::SessionTicket)
88 .is_some()
89 {
90 debug!("Server supports tickets");
91 true
92 } else {
93 false
94 };
95
96 // Might the server send a CertificateStatus between Certificate and
97 // ServerKeyExchange?
98 let may_send_cert_status = server_hello
99 .find_extension(ExtensionType::StatusRequest)
100 .is_some();
101 if may_send_cert_status {
102 debug!("Server may staple OCSP response");
103 }
104
105 // See if we're successfully resuming.
106 if let Some(resuming) = self.resuming_session {
107 if resuming.session_id == server_hello.session_id {
108 debug!("Server agreed to resume");
109
110 // Is the server telling lies about the ciphersuite?
111 if resuming.suite() != suite {
112 return Err(PeerMisbehaved::ResumptionOfferedWithVariedCipherSuite.into());
113 }
114
115 // And about EMS support?
116 if resuming.extended_ms() != self.using_ems {
117 return Err(PeerMisbehaved::ResumptionOfferedWithVariedEms.into());
118 }
119
120 let secrets =
121 ConnectionSecrets::new_resume(self.randoms, suite, resuming.secret());
122 self.config.key_log.log(
123 "CLIENT_RANDOM",
124 &secrets.randoms.client,
125 &secrets.master_secret,
126 );
127 cx.common
128 .start_encryption_tls12(&secrets, Side::Client);
129
130 // Since we're resuming, we verified the certificate and
131 // proof of possession in the prior session.
132 cx.common.peer_certificates = Some(resuming.server_cert_chain().clone());
133 let cert_verified = verify::ServerCertVerified::assertion();
134 let sig_verified = verify::HandshakeSignatureValid::assertion();
135
136 return if must_issue_new_ticket {
137 Ok(Box::new(ExpectNewTicket {
138 config: self.config,
139 secrets,
140 resuming_session: Some(resuming),
141 session_id: server_hello.session_id,
142 server_name: self.server_name,
143 using_ems: self.using_ems,
144 transcript: self.transcript,
145 resuming: true,
146 cert_verified,
147 sig_verified,
148 }))
149 } else {
150 Ok(Box::new(ExpectCcs {
151 config: self.config,
152 secrets,
153 resuming_session: Some(resuming),
154 session_id: server_hello.session_id,
155 server_name: self.server_name,
156 using_ems: self.using_ems,
157 transcript: self.transcript,
158 ticket: None,
159 resuming: true,
160 cert_verified,
161 sig_verified,
162 }))
163 };
164 }
165 }
166
167 Ok(Box::new(ExpectCertificate {
168 config: self.config,
169 resuming_session: None,
170 session_id: server_hello.session_id,
171 server_name: self.server_name,
172 randoms: self.randoms,
173 using_ems: self.using_ems,
174 transcript: self.transcript,
175 suite,
176 may_send_cert_status,
177 must_issue_new_ticket,
178 }))
179 }
180 }
181}
182
183struct ExpectCertificate {
184 config: Arc<ClientConfig>,
185 resuming_session: Option<persist::Tls12ClientSessionValue>,
186 session_id: SessionId,
187 server_name: ServerName<'static>,
188 randoms: ConnectionRandoms,
189 using_ems: bool,
190 transcript: HandshakeHash,
191 pub(super) suite: &'static Tls12CipherSuite,
192 may_send_cert_status: bool,
193 must_issue_new_ticket: bool,
194}
195
196impl State<ClientConnectionData> for ExpectCertificate {
197 fn handle(
198 mut self: Box<Self>,
199 _cx: &mut ClientContext<'_>,
200 m: Message,
201 ) -> hs::NextStateOrError {
202 self.transcript.add_message(&m);
203 let server_cert_chain = require_handshake_msg_move!(
204 m,
205 HandshakeType::Certificate,
206 HandshakePayload::Certificate
207 )?;
208
209 if self.may_send_cert_status {
210 Ok(Box::new(ExpectCertificateStatusOrServerKx {
211 config: self.config,
212 resuming_session: self.resuming_session,
213 session_id: self.session_id,
214 server_name: self.server_name,
215 randoms: self.randoms,
216 using_ems: self.using_ems,
217 transcript: self.transcript,
218 suite: self.suite,
219 server_cert_chain,
220 must_issue_new_ticket: self.must_issue_new_ticket,
221 }))
222 } else {
223 let server_cert = ServerCertDetails::new(server_cert_chain, vec![]);
224
225 Ok(Box::new(ExpectServerKx {
226 config: self.config,
227 resuming_session: self.resuming_session,
228 session_id: self.session_id,
229 server_name: self.server_name,
230 randoms: self.randoms,
231 using_ems: self.using_ems,
232 transcript: self.transcript,
233 suite: self.suite,
234 server_cert,
235 must_issue_new_ticket: self.must_issue_new_ticket,
236 }))
237 }
238 }
239}
240
241struct ExpectCertificateStatusOrServerKx {
242 config: Arc<ClientConfig>,
243 resuming_session: Option<persist::Tls12ClientSessionValue>,
244 session_id: SessionId,
245 server_name: ServerName<'static>,
246 randoms: ConnectionRandoms,
247 using_ems: bool,
248 transcript: HandshakeHash,
249 suite: &'static Tls12CipherSuite,
250 server_cert_chain: CertificateChain,
251 must_issue_new_ticket: bool,
252}
253
254impl State<ClientConnectionData> for ExpectCertificateStatusOrServerKx {
255 fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
256 match m.payload {
257 MessagePayload::Handshake {
258 parsed:
259 HandshakeMessagePayload {
260 payload: HandshakePayload::ServerKeyExchange(..),
261 ..
262 },
263 ..
264 } => Box::new(ExpectServerKx {
265 config: self.config,
266 resuming_session: self.resuming_session,
267 session_id: self.session_id,
268 server_name: self.server_name,
269 randoms: self.randoms,
270 using_ems: self.using_ems,
271 transcript: self.transcript,
272 suite: self.suite,
273 server_cert: ServerCertDetails::new(self.server_cert_chain, vec![]),
274 must_issue_new_ticket: self.must_issue_new_ticket,
275 })
276 .handle(cx, m),
277 MessagePayload::Handshake {
278 parsed:
279 HandshakeMessagePayload {
280 payload: HandshakePayload::CertificateStatus(..),
281 ..
282 },
283 ..
284 } => Box::new(ExpectCertificateStatus {
285 config: self.config,
286 resuming_session: self.resuming_session,
287 session_id: self.session_id,
288 server_name: self.server_name,
289 randoms: self.randoms,
290 using_ems: self.using_ems,
291 transcript: self.transcript,
292 suite: self.suite,
293 server_cert_chain: self.server_cert_chain,
294 must_issue_new_ticket: self.must_issue_new_ticket,
295 })
296 .handle(cx, m),
297 payload => Err(inappropriate_handshake_message(
298 &payload,
299 &[ContentType::Handshake],
300 &[
301 HandshakeType::ServerKeyExchange,
302 HandshakeType::CertificateStatus,
303 ],
304 )),
305 }
306 }
307}
308
309struct ExpectCertificateStatus {
310 config: Arc<ClientConfig>,
311 resuming_session: Option<persist::Tls12ClientSessionValue>,
312 session_id: SessionId,
313 server_name: ServerName<'static>,
314 randoms: ConnectionRandoms,
315 using_ems: bool,
316 transcript: HandshakeHash,
317 suite: &'static Tls12CipherSuite,
318 server_cert_chain: CertificateChain,
319 must_issue_new_ticket: bool,
320}
321
322impl State<ClientConnectionData> for ExpectCertificateStatus {
323 fn handle(
324 mut self: Box<Self>,
325 _cx: &mut ClientContext<'_>,
326 m: Message,
327 ) -> hs::NextStateOrError {
328 self.transcript.add_message(&m);
329 let server_cert_ocsp_response = require_handshake_msg_move!(
330 m,
331 HandshakeType::CertificateStatus,
332 HandshakePayload::CertificateStatus
333 )?
334 .into_inner();
335
336 trace!(
337 "Server stapled OCSP response is {:?}",
338 &server_cert_ocsp_response
339 );
340
341 let server_cert = ServerCertDetails::new(self.server_cert_chain, server_cert_ocsp_response);
342
343 Ok(Box::new(ExpectServerKx {
344 config: self.config,
345 resuming_session: self.resuming_session,
346 session_id: self.session_id,
347 server_name: self.server_name,
348 randoms: self.randoms,
349 using_ems: self.using_ems,
350 transcript: self.transcript,
351 suite: self.suite,
352 server_cert,
353 must_issue_new_ticket: self.must_issue_new_ticket,
354 }))
355 }
356}
357
358struct ExpectServerKx {
359 config: Arc<ClientConfig>,
360 resuming_session: Option<persist::Tls12ClientSessionValue>,
361 session_id: SessionId,
362 server_name: ServerName<'static>,
363 randoms: ConnectionRandoms,
364 using_ems: bool,
365 transcript: HandshakeHash,
366 suite: &'static Tls12CipherSuite,
367 server_cert: ServerCertDetails,
368 must_issue_new_ticket: bool,
369}
370
371impl State<ClientConnectionData> for ExpectServerKx {
372 fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
373 let opaque_kx = require_handshake_msg!(
374 m,
375 HandshakeType::ServerKeyExchange,
376 HandshakePayload::ServerKeyExchange
377 )?;
378 self.transcript.add_message(&m);
379
380 let ecdhe = opaque_kx
381 .unwrap_given_kxa(self.suite.kx)
382 .ok_or_else(|| {
383 cx.common.send_fatal_alert(
384 AlertDescription::DecodeError,
385 InvalidMessage::MissingKeyExchange,
386 )
387 })?;
388
389 // Save the signature and signed parameters for later verification.
390 let mut kx_params = Vec::new();
391 ecdhe.params.encode(&mut kx_params);
392 let server_kx = ServerKxDetails::new(kx_params, ecdhe.dss);
393
394 #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
395 {
396 debug!("ECDHE curve is {:?}", ecdhe.params.curve_params);
397 }
398
399 Ok(Box::new(ExpectServerDoneOrCertReq {
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: self.server_cert,
409 server_kx,
410 must_issue_new_ticket: self.must_issue_new_ticket,
411 }))
412 }
413}
414
415fn emit_certificate(
416 transcript: &mut HandshakeHash,
417 cert_chain: CertificateChain,
418 common: &mut CommonState,
419) {
420 let cert: Message = Message {
421 version: ProtocolVersion::TLSv1_2,
422 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
423 typ: HandshakeType::Certificate,
424 payload: HandshakePayload::Certificate(cert_chain),
425 }),
426 };
427
428 transcript.add_message(&cert);
429 common.send_msg(m:cert, must_encrypt:false);
430}
431
432fn emit_clientkx(transcript: &mut HandshakeHash, common: &mut CommonState, pub_key: &[u8]) {
433 let mut buf: Vec = Vec::new();
434 let ecpoint: PayloadU8 = PayloadU8::new(bytes:Vec::from(pub_key));
435 ecpoint.encode(&mut buf);
436 let pubkey: Payload = Payload::new(bytes:buf);
437
438 let ckx: Message = Message {
439 version: ProtocolVersion::TLSv1_2,
440 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
441 typ: HandshakeType::ClientKeyExchange,
442 payload: HandshakePayload::ClientKeyExchange(pubkey),
443 }),
444 };
445
446 transcript.add_message(&ckx);
447 common.send_msg(m:ckx, must_encrypt:false);
448}
449
450fn emit_certverify(
451 transcript: &mut HandshakeHash,
452 signer: &dyn Signer,
453 common: &mut CommonState,
454) -> Result<(), Error> {
455 let message: Vec = transcript
456 .take_handshake_buf()
457 .ok_or_else(|| Error::General("Expected transcript".to_owned()))?;
458
459 let scheme: SignatureScheme = signer.scheme();
460 let sig: Vec = signer.sign(&message)?;
461 let body: DigitallySignedStruct = DigitallySignedStruct::new(scheme, sig);
462
463 let m: Message = Message {
464 version: ProtocolVersion::TLSv1_2,
465 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
466 typ: HandshakeType::CertificateVerify,
467 payload: HandshakePayload::CertificateVerify(body),
468 }),
469 };
470
471 transcript.add_message(&m);
472 common.send_msg(m, must_encrypt:false);
473 Ok(())
474}
475
476fn emit_ccs(common: &mut CommonState) {
477 let ccs: Message = Message {
478 version: ProtocolVersion::TLSv1_2,
479 payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
480 };
481
482 common.send_msg(m:ccs, must_encrypt:false);
483}
484
485fn emit_finished(
486 secrets: &ConnectionSecrets,
487 transcript: &mut HandshakeHash,
488 common: &mut CommonState,
489) {
490 let vh: Output = transcript.get_current_hash();
491 let verify_data: Vec = secrets.client_verify_data(&vh);
492 let verify_data_payload: Payload = Payload::new(bytes:verify_data);
493
494 let f: Message = Message {
495 version: ProtocolVersion::TLSv1_2,
496 payload: MessagePayload::handshake(parsed:HandshakeMessagePayload {
497 typ: HandshakeType::Finished,
498 payload: HandshakePayload::Finished(verify_data_payload),
499 }),
500 };
501
502 transcript.add_message(&f);
503 common.send_msg(m:f, must_encrypt:true);
504}
505
506struct ServerKxDetails {
507 kx_params: Vec<u8>,
508 kx_sig: DigitallySignedStruct,
509}
510
511impl ServerKxDetails {
512 fn new(params: Vec<u8>, sig: DigitallySignedStruct) -> Self {
513 Self {
514 kx_params: params,
515 kx_sig: sig,
516 }
517 }
518}
519
520// --- Either a CertificateRequest, or a ServerHelloDone. ---
521// Existence of the CertificateRequest tells us the server is asking for
522// client auth. Otherwise we go straight to ServerHelloDone.
523struct ExpectServerDoneOrCertReq {
524 config: Arc<ClientConfig>,
525 resuming_session: Option<persist::Tls12ClientSessionValue>,
526 session_id: SessionId,
527 server_name: ServerName<'static>,
528 randoms: ConnectionRandoms,
529 using_ems: bool,
530 transcript: HandshakeHash,
531 suite: &'static Tls12CipherSuite,
532 server_cert: ServerCertDetails,
533 server_kx: ServerKxDetails,
534 must_issue_new_ticket: bool,
535}
536
537impl State<ClientConnectionData> for ExpectServerDoneOrCertReq {
538 fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
539 if matches!(
540 m.payload,
541 MessagePayload::Handshake {
542 parsed: HandshakeMessagePayload {
543 payload: HandshakePayload::CertificateRequest(_),
544 ..
545 },
546 ..
547 }
548 ) {
549 Box::new(ExpectCertificateRequest {
550 config: self.config,
551 resuming_session: self.resuming_session,
552 session_id: self.session_id,
553 server_name: self.server_name,
554 randoms: self.randoms,
555 using_ems: self.using_ems,
556 transcript: self.transcript,
557 suite: self.suite,
558 server_cert: self.server_cert,
559 server_kx: self.server_kx,
560 must_issue_new_ticket: self.must_issue_new_ticket,
561 })
562 .handle(cx, m)
563 } else {
564 self.transcript.abandon_client_auth();
565
566 Box::new(ExpectServerDone {
567 config: self.config,
568 resuming_session: self.resuming_session,
569 session_id: self.session_id,
570 server_name: self.server_name,
571 randoms: self.randoms,
572 using_ems: self.using_ems,
573 transcript: self.transcript,
574 suite: self.suite,
575 server_cert: self.server_cert,
576 server_kx: self.server_kx,
577 client_auth: None,
578 must_issue_new_ticket: self.must_issue_new_ticket,
579 })
580 .handle(cx, m)
581 }
582 }
583}
584
585struct ExpectCertificateRequest {
586 config: Arc<ClientConfig>,
587 resuming_session: Option<persist::Tls12ClientSessionValue>,
588 session_id: SessionId,
589 server_name: ServerName<'static>,
590 randoms: ConnectionRandoms,
591 using_ems: bool,
592 transcript: HandshakeHash,
593 suite: &'static Tls12CipherSuite,
594 server_cert: ServerCertDetails,
595 server_kx: ServerKxDetails,
596 must_issue_new_ticket: bool,
597}
598
599impl State<ClientConnectionData> for ExpectCertificateRequest {
600 fn handle(
601 mut self: Box<Self>,
602 _cx: &mut ClientContext<'_>,
603 m: Message,
604 ) -> hs::NextStateOrError {
605 let certreq = require_handshake_msg!(
606 m,
607 HandshakeType::CertificateRequest,
608 HandshakePayload::CertificateRequest
609 )?;
610 self.transcript.add_message(&m);
611 debug!("Got CertificateRequest {:?}", certreq);
612
613 // The RFC jovially describes the design here as 'somewhat complicated'
614 // and 'somewhat underspecified'. So thanks for that.
615 //
616 // We ignore certreq.certtypes as a result, since the information it contains
617 // is entirely duplicated in certreq.sigschemes.
618
619 const NO_CONTEXT: Option<Vec<u8>> = None; // TLS 1.2 doesn't use a context.
620 let client_auth = ClientAuthDetails::resolve(
621 self.config
622 .client_auth_cert_resolver
623 .as_ref(),
624 Some(&certreq.canames),
625 &certreq.sigschemes,
626 NO_CONTEXT,
627 );
628
629 Ok(Box::new(ExpectServerDone {
630 config: self.config,
631 resuming_session: self.resuming_session,
632 session_id: self.session_id,
633 server_name: self.server_name,
634 randoms: self.randoms,
635 using_ems: self.using_ems,
636 transcript: self.transcript,
637 suite: self.suite,
638 server_cert: self.server_cert,
639 server_kx: self.server_kx,
640 client_auth: Some(client_auth),
641 must_issue_new_ticket: self.must_issue_new_ticket,
642 }))
643 }
644}
645
646struct ExpectServerDone {
647 config: Arc<ClientConfig>,
648 resuming_session: Option<persist::Tls12ClientSessionValue>,
649 session_id: SessionId,
650 server_name: ServerName<'static>,
651 randoms: ConnectionRandoms,
652 using_ems: bool,
653 transcript: HandshakeHash,
654 suite: &'static Tls12CipherSuite,
655 server_cert: ServerCertDetails,
656 server_kx: ServerKxDetails,
657 client_auth: Option<ClientAuthDetails>,
658 must_issue_new_ticket: bool,
659}
660
661impl State<ClientConnectionData> for ExpectServerDone {
662 fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
663 match m.payload {
664 MessagePayload::Handshake {
665 parsed:
666 HandshakeMessagePayload {
667 payload: HandshakePayload::ServerHelloDone,
668 ..
669 },
670 ..
671 } => {}
672 payload => {
673 return Err(inappropriate_handshake_message(
674 &payload,
675 &[ContentType::Handshake],
676 &[HandshakeType::ServerHelloDone],
677 ));
678 }
679 }
680
681 let mut st = *self;
682 st.transcript.add_message(&m);
683
684 cx.common.check_aligned_handshake()?;
685
686 trace!("Server cert is {:?}", st.server_cert.cert_chain);
687 debug!("Server DNS name is {:?}", st.server_name);
688
689 let suite = st.suite;
690
691 // 1. Verify the cert chain.
692 // 2. Verify any SCTs provided with the certificate.
693 // 3. Verify that the top certificate signed their kx.
694 // 4. If doing client auth, send our Certificate.
695 // 5. Complete the key exchange:
696 // a) generate our kx pair
697 // b) emit a ClientKeyExchange containing it
698 // c) if doing client auth, emit a CertificateVerify
699 // d) emit a CCS
700 // e) derive the shared keys, and start encryption
701 // 6. emit a Finished, our first encrypted message under the new keys.
702
703 // 1.
704 let (end_entity, intermediates) = st
705 .server_cert
706 .cert_chain
707 .split_first()
708 .ok_or(Error::NoCertificatesPresented)?;
709 let cert_verified = st
710 .config
711 .verifier
712 .verify_server_cert(
713 end_entity,
714 intermediates,
715 &st.server_name,
716 &st.server_cert.ocsp_response,
717 UnixTime::now(),
718 )
719 .map_err(|err| {
720 cx.common
721 .send_cert_verify_error_alert(err)
722 })?;
723
724 // 3.
725 // Build up the contents of the signed message.
726 // It's ClientHello.random || ServerHello.random || ServerKeyExchange.params
727 let sig_verified = {
728 let mut message = Vec::new();
729 message.extend_from_slice(&st.randoms.client);
730 message.extend_from_slice(&st.randoms.server);
731 message.extend_from_slice(&st.server_kx.kx_params);
732
733 // Check the signature is compatible with the ciphersuite.
734 let sig = &st.server_kx.kx_sig;
735 if !SupportedCipherSuite::from(suite).usable_for_signature_algorithm(sig.scheme.sign())
736 {
737 warn!(
738 "peer signed kx with wrong algorithm (got {:?} expect {:?})",
739 sig.scheme.sign(),
740 suite.sign
741 );
742 return Err(PeerMisbehaved::SignedKxWithWrongAlgorithm.into());
743 }
744
745 st.config
746 .verifier
747 .verify_tls12_signature(&message, &st.server_cert.cert_chain[0], sig)
748 .map_err(|err| {
749 cx.common
750 .send_cert_verify_error_alert(err)
751 })?
752 };
753 cx.common.peer_certificates = Some(st.server_cert.cert_chain);
754
755 // 4.
756 if let Some(client_auth) = &st.client_auth {
757 let certs = match client_auth {
758 ClientAuthDetails::Empty { .. } => CertificateChain::default(),
759 ClientAuthDetails::Verify { certkey, .. } => CertificateChain(certkey.cert.clone()),
760 };
761 emit_certificate(&mut st.transcript, certs, cx.common);
762 }
763
764 // 5a.
765 let ecdh_params =
766 tls12::decode_ecdh_params::<ServerEcdhParams>(cx.common, &st.server_kx.kx_params)?;
767 let named_group = ecdh_params.curve_params.named_group;
768 let skxg = match st.config.find_kx_group(named_group) {
769 Some(skxg) => skxg,
770 None => {
771 return Err(PeerMisbehaved::SelectedUnofferedKxGroup.into());
772 }
773 };
774 let kx = skxg
775 .start()
776 .map_err(|_| Error::FailedToGetRandomBytes)?;
777
778 // 5b.
779 let mut transcript = st.transcript;
780 emit_clientkx(&mut transcript, cx.common, kx.pub_key());
781 // Note: EMS handshake hash only runs up to ClientKeyExchange.
782 let ems_seed = st
783 .using_ems
784 .then(|| transcript.get_current_hash());
785
786 // 5c.
787 if let Some(ClientAuthDetails::Verify { signer, .. }) = &st.client_auth {
788 emit_certverify(&mut transcript, signer.as_ref(), cx.common)?;
789 }
790
791 // 5d.
792 emit_ccs(cx.common);
793
794 // 5e. Now commit secrets.
795 let secrets = ConnectionSecrets::from_key_exchange(
796 kx,
797 &ecdh_params.public.0,
798 ems_seed,
799 st.randoms,
800 suite,
801 )?;
802
803 st.config.key_log.log(
804 "CLIENT_RANDOM",
805 &secrets.randoms.client,
806 &secrets.master_secret,
807 );
808 cx.common
809 .start_encryption_tls12(&secrets, Side::Client);
810 cx.common
811 .record_layer
812 .start_encrypting();
813
814 // 6.
815 emit_finished(&secrets, &mut transcript, cx.common);
816
817 if st.must_issue_new_ticket {
818 Ok(Box::new(ExpectNewTicket {
819 config: st.config,
820 secrets,
821 resuming_session: st.resuming_session,
822 session_id: st.session_id,
823 server_name: st.server_name,
824 using_ems: st.using_ems,
825 transcript,
826 resuming: false,
827 cert_verified,
828 sig_verified,
829 }))
830 } else {
831 Ok(Box::new(ExpectCcs {
832 config: st.config,
833 secrets,
834 resuming_session: st.resuming_session,
835 session_id: st.session_id,
836 server_name: st.server_name,
837 using_ems: st.using_ems,
838 transcript,
839 ticket: None,
840 resuming: false,
841 cert_verified,
842 sig_verified,
843 }))
844 }
845 }
846}
847
848struct ExpectNewTicket {
849 config: Arc<ClientConfig>,
850 secrets: ConnectionSecrets,
851 resuming_session: Option<persist::Tls12ClientSessionValue>,
852 session_id: SessionId,
853 server_name: ServerName<'static>,
854 using_ems: bool,
855 transcript: HandshakeHash,
856 resuming: bool,
857 cert_verified: verify::ServerCertVerified,
858 sig_verified: verify::HandshakeSignatureValid,
859}
860
861impl State<ClientConnectionData> for ExpectNewTicket {
862 fn handle(
863 mut self: Box<Self>,
864 _cx: &mut ClientContext<'_>,
865 m: Message,
866 ) -> hs::NextStateOrError {
867 self.transcript.add_message(&m);
868
869 let nst = require_handshake_msg_move!(
870 m,
871 HandshakeType::NewSessionTicket,
872 HandshakePayload::NewSessionTicket
873 )?;
874
875 Ok(Box::new(ExpectCcs {
876 config: self.config,
877 secrets: self.secrets,
878 resuming_session: self.resuming_session,
879 session_id: self.session_id,
880 server_name: self.server_name,
881 using_ems: self.using_ems,
882 transcript: self.transcript,
883 ticket: Some(nst),
884 resuming: self.resuming,
885 cert_verified: self.cert_verified,
886 sig_verified: self.sig_verified,
887 }))
888 }
889}
890
891// -- Waiting for their CCS --
892struct ExpectCcs {
893 config: Arc<ClientConfig>,
894 secrets: ConnectionSecrets,
895 resuming_session: Option<persist::Tls12ClientSessionValue>,
896 session_id: SessionId,
897 server_name: ServerName<'static>,
898 using_ems: bool,
899 transcript: HandshakeHash,
900 ticket: Option<NewSessionTicketPayload>,
901 resuming: bool,
902 cert_verified: verify::ServerCertVerified,
903 sig_verified: verify::HandshakeSignatureValid,
904}
905
906impl State<ClientConnectionData> for ExpectCcs {
907 fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
908 match m.payload {
909 MessagePayload::ChangeCipherSpec(..) => {}
910 payload => {
911 return Err(inappropriate_message(
912 &payload,
913 &[ContentType::ChangeCipherSpec],
914 ));
915 }
916 }
917 // CCS should not be received interleaved with fragmented handshake-level
918 // message.
919 cx.common.check_aligned_handshake()?;
920
921 // Note: msgs layer validates trivial contents of CCS.
922 cx.common
923 .record_layer
924 .start_decrypting();
925
926 Ok(Box::new(ExpectFinished {
927 config: self.config,
928 secrets: self.secrets,
929 resuming_session: self.resuming_session,
930 session_id: self.session_id,
931 server_name: self.server_name,
932 using_ems: self.using_ems,
933 transcript: self.transcript,
934 ticket: self.ticket,
935 resuming: self.resuming,
936 cert_verified: self.cert_verified,
937 sig_verified: self.sig_verified,
938 }))
939 }
940}
941
942struct ExpectFinished {
943 config: Arc<ClientConfig>,
944 resuming_session: Option<persist::Tls12ClientSessionValue>,
945 session_id: SessionId,
946 server_name: ServerName<'static>,
947 using_ems: bool,
948 transcript: HandshakeHash,
949 ticket: Option<NewSessionTicketPayload>,
950 secrets: ConnectionSecrets,
951 resuming: bool,
952 cert_verified: verify::ServerCertVerified,
953 sig_verified: verify::HandshakeSignatureValid,
954}
955
956impl ExpectFinished {
957 // -- Waiting for their finished --
958 fn save_session(&mut self, cx: &ClientContext<'_>) {
959 // Save a ticket. If we got a new ticket, save that. Otherwise, save the
960 // original ticket again.
961 let (mut ticket, lifetime) = match self.ticket.take() {
962 Some(nst) => (nst.ticket.0, nst.lifetime_hint),
963 None => (Vec::new(), 0),
964 };
965
966 if ticket.is_empty() {
967 if let Some(resuming_session) = &mut self.resuming_session {
968 ticket = resuming_session.take_ticket();
969 }
970 }
971
972 if self.session_id.is_empty() && ticket.is_empty() {
973 debug!("Session not saved: server didn't allocate id or ticket");
974 return;
975 }
976
977 let session_value = persist::Tls12ClientSessionValue::new(
978 self.secrets.suite(),
979 self.session_id,
980 ticket,
981 self.secrets.master_secret(),
982 cx.common
983 .peer_certificates
984 .clone()
985 .unwrap_or_default(),
986 UnixTime::now(),
987 lifetime,
988 self.using_ems,
989 );
990
991 self.config
992 .resumption
993 .store
994 .set_tls12_session(self.server_name.clone(), session_value);
995 }
996}
997
998impl State<ClientConnectionData> for ExpectFinished {
999 fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
1000 let mut st = *self;
1001 let finished =
1002 require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?;
1003
1004 cx.common.check_aligned_handshake()?;
1005
1006 // Work out what verify_data we expect.
1007 let vh = st.transcript.get_current_hash();
1008 let expect_verify_data = st.secrets.server_verify_data(&vh);
1009
1010 // Constant-time verification of this is relatively unimportant: they only
1011 // get one chance. But it can't hurt.
1012 let _fin_verified = match ConstantTimeEq::ct_eq(&expect_verify_data[..], &finished.0).into()
1013 {
1014 true => verify::FinishedMessageVerified::assertion(),
1015 false => {
1016 return Err(cx
1017 .common
1018 .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError));
1019 }
1020 };
1021
1022 // Hash this message too.
1023 st.transcript.add_message(&m);
1024
1025 st.save_session(cx);
1026
1027 if st.resuming {
1028 emit_ccs(cx.common);
1029 cx.common
1030 .record_layer
1031 .start_encrypting();
1032 emit_finished(&st.secrets, &mut st.transcript, cx.common);
1033 }
1034
1035 cx.common.start_traffic();
1036 Ok(Box::new(ExpectTraffic {
1037 secrets: st.secrets,
1038 _cert_verified: st.cert_verified,
1039 _sig_verified: st.sig_verified,
1040 _fin_verified,
1041 }))
1042 }
1043
1044 // we could not decrypt the encrypted handshake message with session resumption
1045 // this might mean that the ticket was invalid for some reason, so we remove it
1046 // from the store to restart a session from scratch
1047 fn handle_decrypt_error(&self) {
1048 if self.resuming {
1049 self.config
1050 .resumption
1051 .store
1052 .remove_tls12_session(&self.server_name);
1053 }
1054 }
1055}
1056
1057// -- Traffic transit state --
1058struct ExpectTraffic {
1059 secrets: ConnectionSecrets,
1060 _cert_verified: verify::ServerCertVerified,
1061 _sig_verified: verify::HandshakeSignatureValid,
1062 _fin_verified: verify::FinishedMessageVerified,
1063}
1064
1065impl State<ClientConnectionData> for ExpectTraffic {
1066 fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError {
1067 match m.payload {
1068 MessagePayload::ApplicationData(payload) => cx
1069 .common
1070 .take_received_plaintext(payload),
1071 payload => {
1072 return Err(inappropriate_message(
1073 &payload,
1074 &[ContentType::ApplicationData],
1075 ));
1076 }
1077 }
1078 Ok(self)
1079 }
1080
1081 fn export_keying_material(
1082 &self,
1083 output: &mut [u8],
1084 label: &[u8],
1085 context: Option<&[u8]>,
1086 ) -> Result<(), Error> {
1087 self.secrets
1088 .export_keying_material(output, label, context);
1089 Ok(())
1090 }
1091
1092 fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> {
1093 self.secrets
1094 .extract_secrets(Side::Client)
1095 }
1096}
1097