1 | use alloc::borrow::ToOwned; |
2 | use alloc::boxed::Box; |
3 | use alloc::vec; |
4 | use alloc::vec::Vec; |
5 | |
6 | use pki_types::ServerName; |
7 | pub(super) use server_hello::CompleteServerHelloHandling; |
8 | use subtle::ConstantTimeEq; |
9 | |
10 | use super::client_conn::ClientConnectionData; |
11 | use super::hs::ClientContext; |
12 | use crate::check::{inappropriate_handshake_message, inappropriate_message}; |
13 | use crate::client::common::{ClientAuthDetails, ServerCertDetails}; |
14 | use crate::client::{ClientConfig, hs}; |
15 | use crate::common_state::{CommonState, HandshakeKind, KxState, Side, State}; |
16 | use crate::conn::ConnectionRandoms; |
17 | use crate::crypto::KeyExchangeAlgorithm; |
18 | use crate::enums::{AlertDescription, ContentType, HandshakeType, ProtocolVersion}; |
19 | use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved}; |
20 | use crate::hash_hs::HandshakeHash; |
21 | use crate::log::{debug, trace, warn}; |
22 | use crate::msgs::base::{Payload, PayloadU8, PayloadU16}; |
23 | use crate::msgs::ccs::ChangeCipherSpecPayload; |
24 | use crate::msgs::handshake::{ |
25 | CertificateChain, ClientDhParams, ClientEcdhParams, ClientKeyExchangeParams, |
26 | HandshakeMessagePayload, HandshakePayload, NewSessionTicketPayload, ServerKeyExchangeParams, |
27 | SessionId, |
28 | }; |
29 | use crate::msgs::message::{Message, MessagePayload}; |
30 | use crate::msgs::persist; |
31 | use crate::sign::Signer; |
32 | use crate::suites::{PartiallyExtractedSecrets, SupportedCipherSuite}; |
33 | use crate::sync::Arc; |
34 | use crate::tls12::{self, ConnectionSecrets, Tls12CipherSuite}; |
35 | use crate::verify::{self, DigitallySignedStruct}; |
36 | |
37 | mod 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 | |
192 | struct 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 | |
205 | impl 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 | |
257 | struct 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 | |
270 | impl 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 | |
347 | struct 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 | |
360 | impl 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 | |
414 | struct 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 | |
427 | impl 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 | |
500 | fn 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 | |
517 | fn 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 | |
547 | fn 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 | |
573 | fn 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 | |
582 | fn 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 | |
603 | struct ServerKxDetails { |
604 | kx_params: Vec<u8>, |
605 | kx_sig: DigitallySignedStruct, |
606 | } |
607 | |
608 | impl 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. |
620 | struct 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 | |
634 | impl 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 | |
705 | struct 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 | |
719 | impl 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 | |
787 | struct 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 | |
802 | impl 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 | |
1041 | struct 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 | |
1054 | impl 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 -- |
1092 | struct 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 | |
1106 | impl 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 | |
1153 | struct 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 | |
1167 | impl 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 | |
1216 | impl 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 -- |
1288 | struct ExpectTraffic { |
1289 | secrets: ConnectionSecrets, |
1290 | _cert_verified: verify::ServerCertVerified, |
1291 | _sig_verified: verify::HandshakeSignatureValid, |
1292 | _fin_verified: verify::FinishedMessageVerified, |
1293 | } |
1294 | |
1295 | impl 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 | |