1 | use crate::check::inappropriate_handshake_message; |
2 | use crate::common_state::Protocol; |
3 | use crate::common_state::{CommonState, Side, State}; |
4 | use crate::conn::ConnectionRandoms; |
5 | use crate::crypto; |
6 | use crate::crypto::ActiveKeyExchange; |
7 | use crate::enums::{ |
8 | AlertDescription, ContentType, HandshakeType, ProtocolVersion, SignatureScheme, |
9 | }; |
10 | use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved}; |
11 | use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer}; |
12 | #[cfg (feature = "logging" )] |
13 | use crate::log::{debug, trace, warn}; |
14 | use crate::msgs::base::{Payload, PayloadU8}; |
15 | use crate::msgs::ccs::ChangeCipherSpecPayload; |
16 | use crate::msgs::enums::ExtensionType; |
17 | use crate::msgs::enums::KeyUpdateRequest; |
18 | use crate::msgs::handshake::NewSessionTicketPayloadTls13; |
19 | use crate::msgs::handshake::{CertificateEntry, CertificatePayloadTls13}; |
20 | use crate::msgs::handshake::{ClientExtension, ServerExtension}; |
21 | use crate::msgs::handshake::{HandshakeMessagePayload, HandshakePayload}; |
22 | use crate::msgs::handshake::{HasServerExtensions, ServerHelloPayload}; |
23 | use crate::msgs::handshake::{PresharedKeyIdentity, PresharedKeyOffer}; |
24 | use crate::msgs::message::{Message, MessagePayload}; |
25 | use crate::msgs::persist; |
26 | use crate::sign::{CertifiedKey, Signer}; |
27 | use crate::suites::PartiallyExtractedSecrets; |
28 | use crate::tls13::construct_client_verify_message; |
29 | use crate::tls13::construct_server_verify_message; |
30 | use crate::tls13::key_schedule::{ |
31 | KeyScheduleEarly, KeyScheduleHandshake, KeySchedulePreHandshake, KeyScheduleTraffic, |
32 | }; |
33 | use crate::tls13::Tls13CipherSuite; |
34 | use crate::verify::{self, DigitallySignedStruct}; |
35 | use crate::KeyLog; |
36 | |
37 | use super::client_conn::ClientConnectionData; |
38 | use super::hs::ClientContext; |
39 | use crate::client::common::ServerCertDetails; |
40 | use crate::client::common::{ClientAuthDetails, ClientHelloDetails}; |
41 | use crate::client::{hs, ClientConfig, ClientSessionStore}; |
42 | |
43 | use pki_types::{ServerName, UnixTime}; |
44 | use subtle::ConstantTimeEq; |
45 | |
46 | use alloc::boxed::Box; |
47 | use alloc::sync::Arc; |
48 | use alloc::vec; |
49 | use alloc::vec::Vec; |
50 | |
51 | // Extensions we expect in plaintext in the ServerHello. |
52 | static ALLOWED_PLAINTEXT_EXTS: &[ExtensionType] = &[ |
53 | ExtensionType::KeyShare, |
54 | ExtensionType::PreSharedKey, |
55 | ExtensionType::SupportedVersions, |
56 | ]; |
57 | |
58 | // Only the intersection of things we offer, and those disallowed |
59 | // in TLS1.3 |
60 | static DISALLOWED_TLS13_EXTS: &[ExtensionType] = &[ |
61 | ExtensionType::ECPointFormats, |
62 | ExtensionType::SessionTicket, |
63 | ExtensionType::RenegotiationInfo, |
64 | ExtensionType::ExtendedMasterSecret, |
65 | ]; |
66 | |
67 | pub(super) fn handle_server_hello( |
68 | config: Arc<ClientConfig>, |
69 | cx: &mut ClientContext, |
70 | server_hello: &ServerHelloPayload, |
71 | mut resuming_session: Option<persist::Tls13ClientSessionValue>, |
72 | server_name: ServerName<'static>, |
73 | randoms: ConnectionRandoms, |
74 | suite: &'static Tls13CipherSuite, |
75 | transcript: HandshakeHash, |
76 | early_key_schedule: Option<KeyScheduleEarly>, |
77 | hello: ClientHelloDetails, |
78 | our_key_share: Box<dyn ActiveKeyExchange>, |
79 | mut sent_tls13_fake_ccs: bool, |
80 | ) -> hs::NextStateOrError { |
81 | validate_server_hello(cx.common, server_hello)?; |
82 | |
83 | let their_key_share = server_hello |
84 | .get_key_share() |
85 | .ok_or_else(|| { |
86 | cx.common.send_fatal_alert( |
87 | AlertDescription::MissingExtension, |
88 | PeerMisbehaved::MissingKeyShare, |
89 | ) |
90 | })?; |
91 | |
92 | if our_key_share.group() != their_key_share.group { |
93 | return Err({ |
94 | cx.common.send_fatal_alert( |
95 | AlertDescription::IllegalParameter, |
96 | PeerMisbehaved::WrongGroupForKeyShare, |
97 | ) |
98 | }); |
99 | } |
100 | |
101 | let key_schedule_pre_handshake = if let (Some(selected_psk), Some(early_key_schedule)) = |
102 | (server_hello.get_psk_index(), early_key_schedule) |
103 | { |
104 | if let Some(ref resuming) = resuming_session { |
105 | let resuming_suite = match suite.can_resume_from(resuming.suite()) { |
106 | Some(resuming) => resuming, |
107 | None => { |
108 | return Err({ |
109 | cx.common.send_fatal_alert( |
110 | AlertDescription::IllegalParameter, |
111 | PeerMisbehaved::ResumptionOfferedWithIncompatibleCipherSuite, |
112 | ) |
113 | }); |
114 | } |
115 | }; |
116 | |
117 | // If the server varies the suite here, we will have encrypted early data with |
118 | // the wrong suite. |
119 | if cx.data.early_data.is_enabled() && resuming_suite != suite { |
120 | return Err({ |
121 | cx.common.send_fatal_alert( |
122 | AlertDescription::IllegalParameter, |
123 | PeerMisbehaved::EarlyDataOfferedWithVariedCipherSuite, |
124 | ) |
125 | }); |
126 | } |
127 | |
128 | if selected_psk != 0 { |
129 | return Err({ |
130 | cx.common.send_fatal_alert( |
131 | AlertDescription::IllegalParameter, |
132 | PeerMisbehaved::SelectedInvalidPsk, |
133 | ) |
134 | }); |
135 | } |
136 | |
137 | debug!("Resuming using PSK" ); |
138 | // The key schedule has been initialized and set in fill_in_psk_binder() |
139 | } else { |
140 | return Err(PeerMisbehaved::SelectedUnofferedPsk.into()); |
141 | } |
142 | KeySchedulePreHandshake::from(early_key_schedule) |
143 | } else { |
144 | debug!("Not resuming" ); |
145 | // Discard the early data key schedule. |
146 | cx.data.early_data.rejected(); |
147 | cx.common.early_traffic = false; |
148 | resuming_session.take(); |
149 | KeySchedulePreHandshake::new(suite) |
150 | }; |
151 | |
152 | let key_schedule = |
153 | key_schedule_pre_handshake.into_handshake(our_key_share, &their_key_share.payload.0)?; |
154 | |
155 | // Remember what KX group the server liked for next time. |
156 | config |
157 | .resumption |
158 | .store |
159 | .set_kx_hint(server_name.clone(), their_key_share.group); |
160 | |
161 | // If we change keying when a subsequent handshake message is being joined, |
162 | // the two halves will have different record layer protections. Disallow this. |
163 | cx.common.check_aligned_handshake()?; |
164 | |
165 | let hash_at_client_recvd_server_hello = transcript.get_current_hash(); |
166 | let key_schedule = key_schedule.derive_client_handshake_secrets( |
167 | cx.data.early_data.is_enabled(), |
168 | hash_at_client_recvd_server_hello, |
169 | suite, |
170 | &*config.key_log, |
171 | &randoms.client, |
172 | cx.common, |
173 | ); |
174 | |
175 | emit_fake_ccs(&mut sent_tls13_fake_ccs, cx.common); |
176 | |
177 | Ok(Box::new(ExpectEncryptedExtensions { |
178 | config, |
179 | resuming_session, |
180 | server_name, |
181 | randoms, |
182 | suite, |
183 | transcript, |
184 | key_schedule, |
185 | hello, |
186 | })) |
187 | } |
188 | |
189 | fn validate_server_hello( |
190 | common: &mut CommonState, |
191 | server_hello: &ServerHelloPayload, |
192 | ) -> Result<(), Error> { |
193 | for ext: &ServerExtension in &server_hello.extensions { |
194 | if !ALLOWED_PLAINTEXT_EXTS.contains(&ext.get_type()) { |
195 | return Err(common.send_fatal_alert( |
196 | desc:AlertDescription::UnsupportedExtension, |
197 | err:PeerMisbehaved::UnexpectedCleartextExtension, |
198 | )); |
199 | } |
200 | } |
201 | |
202 | Ok(()) |
203 | } |
204 | |
205 | pub(super) fn initial_key_share( |
206 | config: &ClientConfig, |
207 | server_name: &ServerName<'_>, |
208 | ) -> Result<Box<dyn ActiveKeyExchange>, Error> { |
209 | let group: &dyn SupportedKxGroup = configOption<&dyn SupportedKxGroup> |
210 | .resumption |
211 | .store |
212 | .kx_hint(server_name) |
213 | .and_then(|group_name: NamedGroup| config.find_kx_group(group_name)) |
214 | .unwrap_or_else(|| { |
215 | config |
216 | .provider |
217 | .kx_groups |
218 | .iter() |
219 | .copied() |
220 | .next() |
221 | .expect(msg:"No kx groups configured" ) |
222 | }); |
223 | |
224 | group |
225 | .start() |
226 | .map_err(|_| Error::FailedToGetRandomBytes) |
227 | } |
228 | |
229 | /// This implements the horrifying TLS1.3 hack where PSK binders have a |
230 | /// data dependency on the message they are contained within. |
231 | pub(super) fn fill_in_psk_binder( |
232 | resuming: &persist::Tls13ClientSessionValue, |
233 | transcript: &HandshakeHashBuffer, |
234 | hmp: &mut HandshakeMessagePayload, |
235 | ) -> KeyScheduleEarly { |
236 | // We need to know the hash function of the suite we're trying to resume into. |
237 | let suite: &Tls13CipherSuite = resuming.suite(); |
238 | let suite_hash: &dyn Hash = suite.common.hash_provider; |
239 | |
240 | // The binder is calculated over the clienthello, but doesn't include itself or its |
241 | // length, or the length of its container. |
242 | let binder_plaintext: Vec = hmp.get_encoding_for_binder_signing(); |
243 | let handshake_hash: Output = transcript.get_hash_given(provider:suite_hash, &binder_plaintext); |
244 | |
245 | // Run a fake key_schedule to simulate what the server will do if it chooses |
246 | // to resume. |
247 | let key_schedule: KeyScheduleEarly = KeyScheduleEarly::new(suite, resuming.secret()); |
248 | let real_binder: Tag = key_schedule.resumption_psk_binder_key_and_sign_verify_data(&handshake_hash); |
249 | |
250 | if let HandshakePayload::ClientHello(ref mut ch: &mut ClientHelloPayload) = hmp.payload { |
251 | ch.set_psk_binder(real_binder.as_ref()); |
252 | }; |
253 | |
254 | key_schedule |
255 | } |
256 | |
257 | pub(super) fn prepare_resumption( |
258 | config: &ClientConfig, |
259 | cx: &mut ClientContext<'_>, |
260 | resuming_session: &persist::Retrieved<&persist::Tls13ClientSessionValue>, |
261 | exts: &mut Vec<ClientExtension>, |
262 | doing_retry: bool, |
263 | ) { |
264 | let resuming_suite = resuming_session.suite(); |
265 | cx.common.suite = Some(resuming_suite.into()); |
266 | cx.data.resumption_ciphersuite = Some(resuming_suite.into()); |
267 | // The EarlyData extension MUST be supplied together with the |
268 | // PreSharedKey extension. |
269 | let max_early_data_size = resuming_session.max_early_data_size(); |
270 | if config.enable_early_data && max_early_data_size > 0 && !doing_retry { |
271 | cx.data |
272 | .early_data |
273 | .enable(max_early_data_size as usize); |
274 | exts.push(ClientExtension::EarlyData); |
275 | } |
276 | |
277 | // Finally, and only for TLS1.3 with a ticket resumption, include a binder |
278 | // for our ticket. This must go last. |
279 | // |
280 | // Include an empty binder. It gets filled in below because it depends on |
281 | // the message it's contained in (!!!). |
282 | let obfuscated_ticket_age = resuming_session.obfuscated_ticket_age(); |
283 | |
284 | let binder_len = resuming_suite |
285 | .common |
286 | .hash_provider |
287 | .output_len(); |
288 | let binder = vec![0u8; binder_len]; |
289 | |
290 | let psk_identity = |
291 | PresharedKeyIdentity::new(resuming_session.ticket().to_vec(), obfuscated_ticket_age); |
292 | let psk_ext = PresharedKeyOffer::new(psk_identity, binder); |
293 | exts.push(ClientExtension::PresharedKey(psk_ext)); |
294 | } |
295 | |
296 | pub(super) fn derive_early_traffic_secret( |
297 | key_log: &dyn KeyLog, |
298 | cx: &mut ClientContext<'_>, |
299 | resuming_suite: &'static Tls13CipherSuite, |
300 | early_key_schedule: &KeyScheduleEarly, |
301 | sent_tls13_fake_ccs: &mut bool, |
302 | transcript_buffer: &HandshakeHashBuffer, |
303 | client_random: &[u8; 32], |
304 | ) { |
305 | // For middlebox compatibility |
306 | emit_fake_ccs(sent_tls13_fake_ccs, cx.common); |
307 | |
308 | let client_hello_hash: Output = |
309 | transcript_buffer.get_hash_given(resuming_suite.common.hash_provider, &[]); |
310 | early_key_schedule.client_early_traffic_secret( |
311 | &client_hello_hash, |
312 | key_log, |
313 | client_random, |
314 | cx.common, |
315 | ); |
316 | |
317 | // Now the client can send encrypted early data |
318 | cx.common.early_traffic = true; |
319 | trace!("Starting early data traffic" ); |
320 | } |
321 | |
322 | pub(super) fn emit_fake_ccs(sent_tls13_fake_ccs: &mut bool, common: &mut CommonState) { |
323 | if common.is_quic() { |
324 | return; |
325 | } |
326 | |
327 | if core::mem::replace(dest:sent_tls13_fake_ccs, src:true) { |
328 | return; |
329 | } |
330 | |
331 | let m: Message = Message { |
332 | version: ProtocolVersion::TLSv1_2, |
333 | payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}), |
334 | }; |
335 | common.send_msg(m, must_encrypt:false); |
336 | } |
337 | |
338 | fn validate_encrypted_extensions( |
339 | common: &mut CommonState, |
340 | hello: &ClientHelloDetails, |
341 | exts: &Vec<ServerExtension>, |
342 | ) -> Result<(), Error> { |
343 | if exts.has_duplicate_extension() { |
344 | return Err(common.send_fatal_alert( |
345 | AlertDescription::DecodeError, |
346 | PeerMisbehaved::DuplicateEncryptedExtensions, |
347 | )); |
348 | } |
349 | |
350 | if hello.server_sent_unsolicited_extensions(exts, &[]) { |
351 | return Err(common.send_fatal_alert( |
352 | AlertDescription::UnsupportedExtension, |
353 | PeerMisbehaved::UnsolicitedEncryptedExtension, |
354 | )); |
355 | } |
356 | |
357 | for ext in exts { |
358 | if ALLOWED_PLAINTEXT_EXTS.contains(&ext.get_type()) |
359 | || DISALLOWED_TLS13_EXTS.contains(&ext.get_type()) |
360 | { |
361 | return Err(common.send_fatal_alert( |
362 | AlertDescription::UnsupportedExtension, |
363 | PeerMisbehaved::DisallowedEncryptedExtension, |
364 | )); |
365 | } |
366 | } |
367 | |
368 | Ok(()) |
369 | } |
370 | |
371 | struct ExpectEncryptedExtensions { |
372 | config: Arc<ClientConfig>, |
373 | resuming_session: Option<persist::Tls13ClientSessionValue>, |
374 | server_name: ServerName<'static>, |
375 | randoms: ConnectionRandoms, |
376 | suite: &'static Tls13CipherSuite, |
377 | transcript: HandshakeHash, |
378 | key_schedule: KeyScheduleHandshake, |
379 | hello: ClientHelloDetails, |
380 | } |
381 | |
382 | impl State<ClientConnectionData> for ExpectEncryptedExtensions { |
383 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
384 | let exts = require_handshake_msg!( |
385 | m, |
386 | HandshakeType::EncryptedExtensions, |
387 | HandshakePayload::EncryptedExtensions |
388 | )?; |
389 | debug!("TLS1.3 encrypted extensions: {:?}" , exts); |
390 | self.transcript.add_message(&m); |
391 | |
392 | validate_encrypted_extensions(cx.common, &self.hello, exts)?; |
393 | hs::process_alpn_protocol(cx.common, &self.config, exts.get_alpn_protocol())?; |
394 | |
395 | // QUIC transport parameters |
396 | if cx.common.is_quic() { |
397 | match exts.get_quic_params_extension() { |
398 | Some(params) => cx.common.quic.params = Some(params), |
399 | None => { |
400 | return Err(cx |
401 | .common |
402 | .missing_extension(PeerMisbehaved::MissingQuicTransportParameters)); |
403 | } |
404 | } |
405 | } |
406 | |
407 | if let Some(resuming_session) = self.resuming_session { |
408 | let was_early_traffic = cx.common.early_traffic; |
409 | if was_early_traffic { |
410 | if exts.early_data_extension_offered() { |
411 | cx.data.early_data.accepted(); |
412 | } else { |
413 | cx.data.early_data.rejected(); |
414 | cx.common.early_traffic = false; |
415 | } |
416 | } |
417 | |
418 | if was_early_traffic && !cx.common.early_traffic { |
419 | // If no early traffic, set the encryption key for handshakes |
420 | self.key_schedule |
421 | .set_handshake_encrypter(cx.common); |
422 | } |
423 | |
424 | cx.common.peer_certificates = Some( |
425 | resuming_session |
426 | .server_cert_chain() |
427 | .clone(), |
428 | ); |
429 | |
430 | // We *don't* reverify the certificate chain here: resumption is a |
431 | // continuation of the previous session in terms of security policy. |
432 | let cert_verified = verify::ServerCertVerified::assertion(); |
433 | let sig_verified = verify::HandshakeSignatureValid::assertion(); |
434 | Ok(Box::new(ExpectFinished { |
435 | config: self.config, |
436 | server_name: self.server_name, |
437 | randoms: self.randoms, |
438 | suite: self.suite, |
439 | transcript: self.transcript, |
440 | key_schedule: self.key_schedule, |
441 | client_auth: None, |
442 | cert_verified, |
443 | sig_verified, |
444 | })) |
445 | } else { |
446 | if exts.early_data_extension_offered() { |
447 | return Err(PeerMisbehaved::EarlyDataExtensionWithoutResumption.into()); |
448 | } |
449 | Ok(Box::new(ExpectCertificateOrCertReq { |
450 | config: self.config, |
451 | server_name: self.server_name, |
452 | randoms: self.randoms, |
453 | suite: self.suite, |
454 | transcript: self.transcript, |
455 | key_schedule: self.key_schedule, |
456 | })) |
457 | } |
458 | } |
459 | } |
460 | |
461 | struct ExpectCertificateOrCertReq { |
462 | config: Arc<ClientConfig>, |
463 | server_name: ServerName<'static>, |
464 | randoms: ConnectionRandoms, |
465 | suite: &'static Tls13CipherSuite, |
466 | transcript: HandshakeHash, |
467 | key_schedule: KeyScheduleHandshake, |
468 | } |
469 | |
470 | impl State<ClientConnectionData> for ExpectCertificateOrCertReq { |
471 | fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
472 | match m.payload { |
473 | MessagePayload::Handshake { |
474 | parsed: |
475 | HandshakeMessagePayload { |
476 | payload: HandshakePayload::CertificateTls13(..), |
477 | .. |
478 | }, |
479 | .. |
480 | } => Box::new(ExpectCertificate { |
481 | config: self.config, |
482 | server_name: self.server_name, |
483 | randoms: self.randoms, |
484 | suite: self.suite, |
485 | transcript: self.transcript, |
486 | key_schedule: self.key_schedule, |
487 | client_auth: None, |
488 | }) |
489 | .handle(cx, m), |
490 | MessagePayload::Handshake { |
491 | parsed: |
492 | HandshakeMessagePayload { |
493 | payload: HandshakePayload::CertificateRequestTls13(..), |
494 | .. |
495 | }, |
496 | .. |
497 | } => Box::new(ExpectCertificateRequest { |
498 | config: self.config, |
499 | server_name: self.server_name, |
500 | randoms: self.randoms, |
501 | suite: self.suite, |
502 | transcript: self.transcript, |
503 | key_schedule: self.key_schedule, |
504 | }) |
505 | .handle(cx, m), |
506 | payload => Err(inappropriate_handshake_message( |
507 | &payload, |
508 | &[ContentType::Handshake], |
509 | &[ |
510 | HandshakeType::Certificate, |
511 | HandshakeType::CertificateRequest, |
512 | ], |
513 | )), |
514 | } |
515 | } |
516 | } |
517 | |
518 | // TLS1.3 version of CertificateRequest handling. We then move to expecting the server |
519 | // Certificate. Unfortunately the CertificateRequest type changed in an annoying way |
520 | // in TLS1.3. |
521 | struct ExpectCertificateRequest { |
522 | config: Arc<ClientConfig>, |
523 | server_name: ServerName<'static>, |
524 | randoms: ConnectionRandoms, |
525 | suite: &'static Tls13CipherSuite, |
526 | transcript: HandshakeHash, |
527 | key_schedule: KeyScheduleHandshake, |
528 | } |
529 | |
530 | impl State<ClientConnectionData> for ExpectCertificateRequest { |
531 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
532 | let certreq = &require_handshake_msg!( |
533 | m, |
534 | HandshakeType::CertificateRequest, |
535 | HandshakePayload::CertificateRequestTls13 |
536 | )?; |
537 | self.transcript.add_message(&m); |
538 | debug!("Got CertificateRequest {:?}" , certreq); |
539 | |
540 | // Fortunately the problems here in TLS1.2 and prior are corrected in |
541 | // TLS1.3. |
542 | |
543 | // Must be empty during handshake. |
544 | if !certreq.context.0.is_empty() { |
545 | warn!("Server sent non-empty certreq context" ); |
546 | return Err(cx.common.send_fatal_alert( |
547 | AlertDescription::DecodeError, |
548 | InvalidMessage::InvalidCertRequest, |
549 | )); |
550 | } |
551 | |
552 | let no_sigschemes = Vec::new(); |
553 | let compat_sigschemes = certreq |
554 | .get_sigalgs_extension() |
555 | .unwrap_or(&no_sigschemes) |
556 | .iter() |
557 | .cloned() |
558 | .filter(SignatureScheme::supported_in_tls13) |
559 | .collect::<Vec<SignatureScheme>>(); |
560 | |
561 | if compat_sigschemes.is_empty() { |
562 | return Err(cx.common.send_fatal_alert( |
563 | AlertDescription::HandshakeFailure, |
564 | PeerIncompatible::NoCertificateRequestSignatureSchemesInCommon, |
565 | )); |
566 | } |
567 | |
568 | let client_auth = ClientAuthDetails::resolve( |
569 | self.config |
570 | .client_auth_cert_resolver |
571 | .as_ref(), |
572 | certreq.get_authorities_extension(), |
573 | &compat_sigschemes, |
574 | Some(certreq.context.0.clone()), |
575 | ); |
576 | |
577 | Ok(Box::new(ExpectCertificate { |
578 | config: self.config, |
579 | server_name: self.server_name, |
580 | randoms: self.randoms, |
581 | suite: self.suite, |
582 | transcript: self.transcript, |
583 | key_schedule: self.key_schedule, |
584 | client_auth: Some(client_auth), |
585 | })) |
586 | } |
587 | } |
588 | |
589 | struct ExpectCertificate { |
590 | config: Arc<ClientConfig>, |
591 | server_name: ServerName<'static>, |
592 | randoms: ConnectionRandoms, |
593 | suite: &'static Tls13CipherSuite, |
594 | transcript: HandshakeHash, |
595 | key_schedule: KeyScheduleHandshake, |
596 | client_auth: Option<ClientAuthDetails>, |
597 | } |
598 | |
599 | impl State<ClientConnectionData> for ExpectCertificate { |
600 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
601 | self.transcript.add_message(&m); |
602 | let cert_chain = require_handshake_msg_move!( |
603 | m, |
604 | HandshakeType::Certificate, |
605 | HandshakePayload::CertificateTls13 |
606 | )?; |
607 | |
608 | // This is only non-empty for client auth. |
609 | if !cert_chain.context.0.is_empty() { |
610 | return Err(cx.common.send_fatal_alert( |
611 | AlertDescription::DecodeError, |
612 | InvalidMessage::InvalidCertRequest, |
613 | )); |
614 | } |
615 | |
616 | if cert_chain.any_entry_has_duplicate_extension() |
617 | || cert_chain.any_entry_has_unknown_extension() |
618 | { |
619 | return Err(cx.common.send_fatal_alert( |
620 | AlertDescription::UnsupportedExtension, |
621 | PeerMisbehaved::BadCertChainExtensions, |
622 | )); |
623 | } |
624 | let end_entity_ocsp = cert_chain.get_end_entity_ocsp(); |
625 | let server_cert = ServerCertDetails::new(cert_chain.convert(), end_entity_ocsp); |
626 | |
627 | Ok(Box::new(ExpectCertificateVerify { |
628 | config: self.config, |
629 | server_name: self.server_name, |
630 | randoms: self.randoms, |
631 | suite: self.suite, |
632 | transcript: self.transcript, |
633 | key_schedule: self.key_schedule, |
634 | server_cert, |
635 | client_auth: self.client_auth, |
636 | })) |
637 | } |
638 | } |
639 | |
640 | // --- TLS1.3 CertificateVerify --- |
641 | struct ExpectCertificateVerify { |
642 | config: Arc<ClientConfig>, |
643 | server_name: ServerName<'static>, |
644 | randoms: ConnectionRandoms, |
645 | suite: &'static Tls13CipherSuite, |
646 | transcript: HandshakeHash, |
647 | key_schedule: KeyScheduleHandshake, |
648 | server_cert: ServerCertDetails, |
649 | client_auth: Option<ClientAuthDetails>, |
650 | } |
651 | |
652 | impl State<ClientConnectionData> for ExpectCertificateVerify { |
653 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
654 | let cert_verify = require_handshake_msg!( |
655 | m, |
656 | HandshakeType::CertificateVerify, |
657 | HandshakePayload::CertificateVerify |
658 | )?; |
659 | |
660 | trace!("Server cert is {:?}" , self.server_cert.cert_chain); |
661 | |
662 | // 1. Verify the certificate chain. |
663 | let (end_entity, intermediates) = self |
664 | .server_cert |
665 | .cert_chain |
666 | .split_first() |
667 | .ok_or(Error::NoCertificatesPresented)?; |
668 | let cert_verified = self |
669 | .config |
670 | .verifier |
671 | .verify_server_cert( |
672 | end_entity, |
673 | intermediates, |
674 | &self.server_name, |
675 | &self.server_cert.ocsp_response, |
676 | UnixTime::now(), |
677 | ) |
678 | .map_err(|err| { |
679 | cx.common |
680 | .send_cert_verify_error_alert(err) |
681 | })?; |
682 | |
683 | // 2. Verify their signature on the handshake. |
684 | let handshake_hash = self.transcript.get_current_hash(); |
685 | let sig_verified = self |
686 | .config |
687 | .verifier |
688 | .verify_tls13_signature( |
689 | &construct_server_verify_message(&handshake_hash), |
690 | &self.server_cert.cert_chain[0], |
691 | cert_verify, |
692 | ) |
693 | .map_err(|err| { |
694 | cx.common |
695 | .send_cert_verify_error_alert(err) |
696 | })?; |
697 | |
698 | cx.common.peer_certificates = Some(self.server_cert.cert_chain); |
699 | self.transcript.add_message(&m); |
700 | |
701 | Ok(Box::new(ExpectFinished { |
702 | config: self.config, |
703 | server_name: self.server_name, |
704 | randoms: self.randoms, |
705 | suite: self.suite, |
706 | transcript: self.transcript, |
707 | key_schedule: self.key_schedule, |
708 | client_auth: self.client_auth, |
709 | cert_verified, |
710 | sig_verified, |
711 | })) |
712 | } |
713 | } |
714 | |
715 | fn emit_certificate_tls13( |
716 | transcript: &mut HandshakeHash, |
717 | certkey: Option<&CertifiedKey>, |
718 | auth_context: Option<Vec<u8>>, |
719 | common: &mut CommonState, |
720 | ) { |
721 | let context = auth_context.unwrap_or_default(); |
722 | |
723 | let mut cert_payload = CertificatePayloadTls13 { |
724 | context: PayloadU8::new(context), |
725 | entries: Vec::new(), |
726 | }; |
727 | |
728 | if let Some(certkey) = certkey { |
729 | for cert in &certkey.cert { |
730 | cert_payload |
731 | .entries |
732 | .push(CertificateEntry::new(cert.clone())); |
733 | } |
734 | } |
735 | |
736 | let m = Message { |
737 | version: ProtocolVersion::TLSv1_3, |
738 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
739 | typ: HandshakeType::Certificate, |
740 | payload: HandshakePayload::CertificateTls13(cert_payload), |
741 | }), |
742 | }; |
743 | transcript.add_message(&m); |
744 | common.send_msg(m, true); |
745 | } |
746 | |
747 | fn emit_certverify_tls13( |
748 | transcript: &mut HandshakeHash, |
749 | signer: &dyn Signer, |
750 | common: &mut CommonState, |
751 | ) -> Result<(), Error> { |
752 | let message: Vec = construct_client_verify_message(&transcript.get_current_hash()); |
753 | |
754 | let scheme: SignatureScheme = signer.scheme(); |
755 | let sig: Vec = signer.sign(&message)?; |
756 | let dss: DigitallySignedStruct = DigitallySignedStruct::new(scheme, sig); |
757 | |
758 | let m: Message = Message { |
759 | version: ProtocolVersion::TLSv1_3, |
760 | payload: MessagePayload::handshake(parsed:HandshakeMessagePayload { |
761 | typ: HandshakeType::CertificateVerify, |
762 | payload: HandshakePayload::CertificateVerify(dss), |
763 | }), |
764 | }; |
765 | |
766 | transcript.add_message(&m); |
767 | common.send_msg(m, must_encrypt:true); |
768 | Ok(()) |
769 | } |
770 | |
771 | fn emit_finished_tls13( |
772 | transcript: &mut HandshakeHash, |
773 | verify_data: &crypto::hmac::Tag, |
774 | common: &mut CommonState, |
775 | ) { |
776 | let verify_data_payload: Payload = Payload::new(bytes:verify_data.as_ref()); |
777 | |
778 | let m: Message = Message { |
779 | version: ProtocolVersion::TLSv1_3, |
780 | payload: MessagePayload::handshake(parsed:HandshakeMessagePayload { |
781 | typ: HandshakeType::Finished, |
782 | payload: HandshakePayload::Finished(verify_data_payload), |
783 | }), |
784 | }; |
785 | |
786 | transcript.add_message(&m); |
787 | common.send_msg(m, must_encrypt:true); |
788 | } |
789 | |
790 | fn emit_end_of_early_data_tls13(transcript: &mut HandshakeHash, common: &mut CommonState) { |
791 | if common.is_quic() { |
792 | return; |
793 | } |
794 | |
795 | let m: Message = Message { |
796 | version: ProtocolVersion::TLSv1_3, |
797 | payload: MessagePayload::handshake(parsed:HandshakeMessagePayload { |
798 | typ: HandshakeType::EndOfEarlyData, |
799 | payload: HandshakePayload::EndOfEarlyData, |
800 | }), |
801 | }; |
802 | |
803 | transcript.add_message(&m); |
804 | common.send_msg(m, must_encrypt:true); |
805 | } |
806 | |
807 | struct ExpectFinished { |
808 | config: Arc<ClientConfig>, |
809 | server_name: ServerName<'static>, |
810 | randoms: ConnectionRandoms, |
811 | suite: &'static Tls13CipherSuite, |
812 | transcript: HandshakeHash, |
813 | key_schedule: KeyScheduleHandshake, |
814 | client_auth: Option<ClientAuthDetails>, |
815 | cert_verified: verify::ServerCertVerified, |
816 | sig_verified: verify::HandshakeSignatureValid, |
817 | } |
818 | |
819 | impl State<ClientConnectionData> for ExpectFinished { |
820 | fn handle(self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
821 | let mut st = *self; |
822 | let finished = |
823 | require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?; |
824 | |
825 | let handshake_hash = st.transcript.get_current_hash(); |
826 | let expect_verify_data = st |
827 | .key_schedule |
828 | .sign_server_finish(&handshake_hash); |
829 | |
830 | let fin = match ConstantTimeEq::ct_eq(expect_verify_data.as_ref(), &finished.0).into() { |
831 | true => verify::FinishedMessageVerified::assertion(), |
832 | false => { |
833 | return Err(cx |
834 | .common |
835 | .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError)); |
836 | } |
837 | }; |
838 | |
839 | st.transcript.add_message(&m); |
840 | |
841 | let hash_after_handshake = st.transcript.get_current_hash(); |
842 | /* The EndOfEarlyData message to server is still encrypted with early data keys, |
843 | * but appears in the transcript after the server Finished. */ |
844 | if cx.common.early_traffic { |
845 | emit_end_of_early_data_tls13(&mut st.transcript, cx.common); |
846 | cx.common.early_traffic = false; |
847 | cx.data.early_data.finished(); |
848 | st.key_schedule |
849 | .set_handshake_encrypter(cx.common); |
850 | } |
851 | |
852 | /* Send our authentication/finished messages. These are still encrypted |
853 | * with our handshake keys. */ |
854 | if let Some(client_auth) = st.client_auth { |
855 | match client_auth { |
856 | ClientAuthDetails::Empty { |
857 | auth_context_tls13: auth_context, |
858 | } => { |
859 | emit_certificate_tls13(&mut st.transcript, None, auth_context, cx.common); |
860 | } |
861 | ClientAuthDetails::Verify { |
862 | certkey, |
863 | signer, |
864 | auth_context_tls13: auth_context, |
865 | } => { |
866 | emit_certificate_tls13( |
867 | &mut st.transcript, |
868 | Some(&certkey), |
869 | auth_context, |
870 | cx.common, |
871 | ); |
872 | emit_certverify_tls13(&mut st.transcript, signer.as_ref(), cx.common)?; |
873 | } |
874 | } |
875 | } |
876 | |
877 | let (key_schedule_pre_finished, verify_data) = st |
878 | .key_schedule |
879 | .into_pre_finished_client_traffic( |
880 | hash_after_handshake, |
881 | st.transcript.get_current_hash(), |
882 | &*st.config.key_log, |
883 | &st.randoms.client, |
884 | ); |
885 | |
886 | emit_finished_tls13(&mut st.transcript, &verify_data, cx.common); |
887 | |
888 | /* We're now sure this server supports TLS1.3. But if we run out of TLS1.3 tickets |
889 | * when connecting to it again, we definitely don't want to attempt a TLS1.2 resumption. */ |
890 | st.config |
891 | .resumption |
892 | .store |
893 | .remove_tls12_session(&st.server_name); |
894 | |
895 | /* Now move to our application traffic keys. */ |
896 | cx.common.check_aligned_handshake()?; |
897 | let key_schedule_traffic = key_schedule_pre_finished.into_traffic(cx.common); |
898 | cx.common.start_traffic(); |
899 | |
900 | let st = ExpectTraffic { |
901 | session_storage: Arc::clone(&st.config.resumption.store), |
902 | server_name: st.server_name, |
903 | suite: st.suite, |
904 | transcript: st.transcript, |
905 | key_schedule: key_schedule_traffic, |
906 | _cert_verified: st.cert_verified, |
907 | _sig_verified: st.sig_verified, |
908 | _fin_verified: fin, |
909 | }; |
910 | |
911 | Ok(match cx.common.is_quic() { |
912 | true => Box::new(ExpectQuicTraffic(st)), |
913 | false => Box::new(st), |
914 | }) |
915 | } |
916 | } |
917 | |
918 | // -- Traffic transit state (TLS1.3) -- |
919 | // In this state we can be sent tickets, key updates, |
920 | // and application data. |
921 | struct ExpectTraffic { |
922 | session_storage: Arc<dyn ClientSessionStore>, |
923 | server_name: ServerName<'static>, |
924 | suite: &'static Tls13CipherSuite, |
925 | transcript: HandshakeHash, |
926 | key_schedule: KeyScheduleTraffic, |
927 | _cert_verified: verify::ServerCertVerified, |
928 | _sig_verified: verify::HandshakeSignatureValid, |
929 | _fin_verified: verify::FinishedMessageVerified, |
930 | } |
931 | |
932 | impl ExpectTraffic { |
933 | fn handle_new_ticket_tls13( |
934 | &mut self, |
935 | cx: &mut ClientContext<'_>, |
936 | nst: &NewSessionTicketPayloadTls13, |
937 | ) -> Result<(), Error> { |
938 | if nst.has_duplicate_extension() { |
939 | return Err(cx.common.send_fatal_alert( |
940 | AlertDescription::IllegalParameter, |
941 | PeerMisbehaved::DuplicateNewSessionTicketExtensions, |
942 | )); |
943 | } |
944 | |
945 | let handshake_hash = self.transcript.get_current_hash(); |
946 | let secret = self |
947 | .key_schedule |
948 | .resumption_master_secret_and_derive_ticket_psk(&handshake_hash, &nst.nonce.0); |
949 | |
950 | #[allow (unused_mut)] |
951 | let mut value = persist::Tls13ClientSessionValue::new( |
952 | self.suite, |
953 | nst.ticket.0.clone(), |
954 | secret.as_ref(), |
955 | cx.common |
956 | .peer_certificates |
957 | .clone() |
958 | .unwrap_or_default(), |
959 | UnixTime::now(), |
960 | nst.lifetime, |
961 | nst.age_add, |
962 | nst.get_max_early_data_size() |
963 | .unwrap_or_default(), |
964 | ); |
965 | |
966 | if cx.common.is_quic() { |
967 | if let Some(sz) = nst.get_max_early_data_size() { |
968 | if sz != 0 && sz != 0xffff_ffff { |
969 | return Err(PeerMisbehaved::InvalidMaxEarlyDataSize.into()); |
970 | } |
971 | } |
972 | |
973 | if let Some(ref quic_params) = &cx.common.quic.params { |
974 | value.set_quic_params(quic_params); |
975 | } |
976 | } |
977 | |
978 | self.session_storage |
979 | .insert_tls13_ticket(self.server_name.clone(), value); |
980 | Ok(()) |
981 | } |
982 | |
983 | fn handle_key_update( |
984 | &mut self, |
985 | common: &mut CommonState, |
986 | key_update_request: &KeyUpdateRequest, |
987 | ) -> Result<(), Error> { |
988 | if let Protocol::Quic = common.protocol { |
989 | return Err(common.send_fatal_alert( |
990 | AlertDescription::UnexpectedMessage, |
991 | PeerMisbehaved::KeyUpdateReceivedInQuicConnection, |
992 | )); |
993 | } |
994 | |
995 | // Mustn't be interleaved with other handshake messages. |
996 | common.check_aligned_handshake()?; |
997 | |
998 | if common.should_update_key(key_update_request)? { |
999 | self.key_schedule |
1000 | .update_encrypter_and_notify(common); |
1001 | } |
1002 | |
1003 | // Update our read-side keys. |
1004 | self.key_schedule |
1005 | .update_decrypter(common); |
1006 | Ok(()) |
1007 | } |
1008 | } |
1009 | |
1010 | impl State<ClientConnectionData> for ExpectTraffic { |
1011 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
1012 | match m.payload { |
1013 | MessagePayload::ApplicationData(payload) => cx |
1014 | .common |
1015 | .take_received_plaintext(payload), |
1016 | MessagePayload::Handshake { |
1017 | parsed: |
1018 | HandshakeMessagePayload { |
1019 | payload: HandshakePayload::NewSessionTicketTls13(ref new_ticket), |
1020 | .. |
1021 | }, |
1022 | .. |
1023 | } => self.handle_new_ticket_tls13(cx, new_ticket)?, |
1024 | MessagePayload::Handshake { |
1025 | parsed: |
1026 | HandshakeMessagePayload { |
1027 | payload: HandshakePayload::KeyUpdate(ref key_update), |
1028 | .. |
1029 | }, |
1030 | .. |
1031 | } => self.handle_key_update(cx.common, key_update)?, |
1032 | payload => { |
1033 | return Err(inappropriate_handshake_message( |
1034 | &payload, |
1035 | &[ContentType::ApplicationData, ContentType::Handshake], |
1036 | &[HandshakeType::NewSessionTicket, HandshakeType::KeyUpdate], |
1037 | )); |
1038 | } |
1039 | } |
1040 | |
1041 | Ok(self) |
1042 | } |
1043 | |
1044 | fn export_keying_material( |
1045 | &self, |
1046 | output: &mut [u8], |
1047 | label: &[u8], |
1048 | context: Option<&[u8]>, |
1049 | ) -> Result<(), Error> { |
1050 | self.key_schedule |
1051 | .export_keying_material(output, label, context) |
1052 | } |
1053 | |
1054 | fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> { |
1055 | self.key_schedule |
1056 | .extract_secrets(Side::Client) |
1057 | } |
1058 | } |
1059 | |
1060 | struct ExpectQuicTraffic(ExpectTraffic); |
1061 | |
1062 | impl State<ClientConnectionData> for ExpectQuicTraffic { |
1063 | fn handle(mut self: Box<Self>, cx: &mut ClientContext<'_>, m: Message) -> hs::NextStateOrError { |
1064 | let nst: &NewSessionTicketPayloadTls13 = require_handshake_msg!( |
1065 | m, |
1066 | HandshakeType::NewSessionTicket, |
1067 | HandshakePayload::NewSessionTicketTls13 |
1068 | )?; |
1069 | self.0 |
1070 | .handle_new_ticket_tls13(cx, nst)?; |
1071 | Ok(self) |
1072 | } |
1073 | |
1074 | fn export_keying_material( |
1075 | &self, |
1076 | output: &mut [u8], |
1077 | label: &[u8], |
1078 | context: Option<&[u8]>, |
1079 | ) -> Result<(), Error> { |
1080 | self.0 |
1081 | .export_keying_material(output, label, context) |
1082 | } |
1083 | } |
1084 | |