1 | use crate::check::inappropriate_handshake_message; |
2 | use crate::check::inappropriate_message; |
3 | use crate::common_state::Protocol; |
4 | use crate::common_state::{CommonState, Side, State}; |
5 | use crate::conn::ConnectionRandoms; |
6 | use crate::enums::ProtocolVersion; |
7 | use crate::enums::{AlertDescription, ContentType, HandshakeType}; |
8 | use crate::error::{Error, PeerIncompatible, PeerMisbehaved}; |
9 | use crate::hash_hs::HandshakeHash; |
10 | #[cfg (feature = "logging" )] |
11 | use crate::log::{debug, trace, warn}; |
12 | use crate::msgs::codec::Codec; |
13 | use crate::msgs::enums::KeyUpdateRequest; |
14 | use crate::msgs::handshake::CertificateChain; |
15 | use crate::msgs::handshake::HandshakeMessagePayload; |
16 | use crate::msgs::handshake::HandshakePayload; |
17 | use crate::msgs::handshake::{NewSessionTicketExtension, NewSessionTicketPayloadTls13}; |
18 | use crate::msgs::message::{Message, MessagePayload}; |
19 | use crate::msgs::persist; |
20 | use crate::rand; |
21 | use crate::server::ServerConfig; |
22 | use crate::suites::PartiallyExtractedSecrets; |
23 | use crate::tls13::construct_client_verify_message; |
24 | use crate::tls13::construct_server_verify_message; |
25 | use crate::tls13::key_schedule::{KeyScheduleTraffic, KeyScheduleTrafficWithClientFinishedPending}; |
26 | use crate::tls13::Tls13CipherSuite; |
27 | use crate::verify; |
28 | |
29 | use super::hs::{self, HandshakeHashOrBuffer, ServerContext}; |
30 | use super::server_conn::ServerConnectionData; |
31 | |
32 | use alloc::borrow::ToOwned; |
33 | use alloc::boxed::Box; |
34 | use alloc::sync::Arc; |
35 | use alloc::vec; |
36 | use alloc::vec::Vec; |
37 | |
38 | use pki_types::{CertificateDer, UnixTime}; |
39 | use subtle::ConstantTimeEq; |
40 | |
41 | pub(super) use client_hello::CompleteClientHelloHandling; |
42 | |
43 | mod client_hello { |
44 | use crate::crypto::SupportedKxGroup; |
45 | use crate::enums::SignatureScheme; |
46 | use crate::msgs::base::{Payload, PayloadU8}; |
47 | use crate::msgs::ccs::ChangeCipherSpecPayload; |
48 | use crate::msgs::enums::NamedGroup; |
49 | use crate::msgs::enums::{Compression, PSKKeyExchangeMode}; |
50 | use crate::msgs::handshake::CertReqExtension; |
51 | use crate::msgs::handshake::CertificateEntry; |
52 | use crate::msgs::handshake::CertificateExtension; |
53 | use crate::msgs::handshake::CertificatePayloadTls13; |
54 | use crate::msgs::handshake::CertificateRequestPayloadTls13; |
55 | use crate::msgs::handshake::CertificateStatus; |
56 | use crate::msgs::handshake::ClientHelloPayload; |
57 | use crate::msgs::handshake::HelloRetryExtension; |
58 | use crate::msgs::handshake::HelloRetryRequest; |
59 | use crate::msgs::handshake::KeyShareEntry; |
60 | use crate::msgs::handshake::Random; |
61 | use crate::msgs::handshake::ServerExtension; |
62 | use crate::msgs::handshake::ServerHelloPayload; |
63 | use crate::msgs::handshake::SessionId; |
64 | use crate::server::common::ActiveCertifiedKey; |
65 | use crate::sign; |
66 | use crate::tls13::key_schedule::{ |
67 | KeyScheduleEarly, KeyScheduleHandshake, KeySchedulePreHandshake, |
68 | }; |
69 | use crate::verify::DigitallySignedStruct; |
70 | |
71 | use super::*; |
72 | |
73 | #[derive (PartialEq)] |
74 | pub(super) enum EarlyDataDecision { |
75 | Disabled, |
76 | RequestedButRejected, |
77 | Accepted, |
78 | } |
79 | |
80 | pub(in crate::server) struct CompleteClientHelloHandling { |
81 | pub(in crate::server) config: Arc<ServerConfig>, |
82 | pub(in crate::server) transcript: HandshakeHash, |
83 | pub(in crate::server) suite: &'static Tls13CipherSuite, |
84 | pub(in crate::server) randoms: ConnectionRandoms, |
85 | pub(in crate::server) done_retry: bool, |
86 | pub(in crate::server) send_tickets: usize, |
87 | pub(in crate::server) extra_exts: Vec<ServerExtension>, |
88 | } |
89 | |
90 | fn max_early_data_size(configured: u32) -> usize { |
91 | if configured != 0 { |
92 | configured as usize |
93 | } else { |
94 | // The relevant max_early_data_size may in fact be unknowable: if |
95 | // we (the server) have turned off early_data but the client has |
96 | // a stale ticket from when we allowed early_data: we'll naturally |
97 | // reject early_data but need an upper bound on the amount of data |
98 | // to drop. |
99 | // |
100 | // Use a single maximum-sized message. |
101 | 16384 |
102 | } |
103 | } |
104 | |
105 | impl CompleteClientHelloHandling { |
106 | fn check_binder( |
107 | &self, |
108 | suite: &'static Tls13CipherSuite, |
109 | client_hello: &Message, |
110 | psk: &[u8], |
111 | binder: &[u8], |
112 | ) -> bool { |
113 | let binder_plaintext = match &client_hello.payload { |
114 | MessagePayload::Handshake { parsed, .. } => { |
115 | parsed.get_encoding_for_binder_signing() |
116 | } |
117 | _ => unreachable!(), |
118 | }; |
119 | |
120 | let handshake_hash = self |
121 | .transcript |
122 | .get_hash_given(&binder_plaintext); |
123 | |
124 | let key_schedule = KeyScheduleEarly::new(suite, psk); |
125 | let real_binder = |
126 | key_schedule.resumption_psk_binder_key_and_sign_verify_data(&handshake_hash); |
127 | |
128 | ConstantTimeEq::ct_eq(real_binder.as_ref(), binder).into() |
129 | } |
130 | |
131 | fn attempt_tls13_ticket_decryption( |
132 | &mut self, |
133 | ticket: &[u8], |
134 | ) -> Option<persist::ServerSessionValue> { |
135 | if self.config.ticketer.enabled() { |
136 | self.config |
137 | .ticketer |
138 | .decrypt(ticket) |
139 | .and_then(|plain| persist::ServerSessionValue::read_bytes(&plain).ok()) |
140 | } else { |
141 | self.config |
142 | .session_storage |
143 | .take(ticket) |
144 | .and_then(|plain| persist::ServerSessionValue::read_bytes(&plain).ok()) |
145 | } |
146 | } |
147 | |
148 | pub(in crate::server) fn handle_client_hello( |
149 | mut self, |
150 | cx: &mut ServerContext<'_>, |
151 | server_key: ActiveCertifiedKey, |
152 | chm: &Message, |
153 | client_hello: &ClientHelloPayload, |
154 | mut sigschemes_ext: Vec<SignatureScheme>, |
155 | ) -> hs::NextStateOrError { |
156 | if client_hello.compression_methods.len() != 1 { |
157 | return Err(cx.common.send_fatal_alert( |
158 | AlertDescription::IllegalParameter, |
159 | PeerMisbehaved::OfferedIncorrectCompressions, |
160 | )); |
161 | } |
162 | |
163 | let groups_ext = client_hello |
164 | .get_namedgroups_extension() |
165 | .ok_or_else(|| { |
166 | cx.common.send_fatal_alert( |
167 | AlertDescription::HandshakeFailure, |
168 | PeerIncompatible::NamedGroupsExtensionRequired, |
169 | ) |
170 | })?; |
171 | |
172 | sigschemes_ext.retain(SignatureScheme::supported_in_tls13); |
173 | |
174 | let shares_ext = client_hello |
175 | .get_keyshare_extension() |
176 | .ok_or_else(|| { |
177 | cx.common.send_fatal_alert( |
178 | AlertDescription::HandshakeFailure, |
179 | PeerIncompatible::KeyShareExtensionRequired, |
180 | ) |
181 | })?; |
182 | |
183 | if client_hello.has_keyshare_extension_with_duplicates() { |
184 | return Err(cx.common.send_fatal_alert( |
185 | AlertDescription::IllegalParameter, |
186 | PeerMisbehaved::OfferedDuplicateKeyShares, |
187 | )); |
188 | } |
189 | |
190 | let early_data_requested = client_hello.early_data_extension_offered(); |
191 | |
192 | // EarlyData extension is illegal in second ClientHello |
193 | if self.done_retry && early_data_requested { |
194 | return Err({ |
195 | cx.common.send_fatal_alert( |
196 | AlertDescription::IllegalParameter, |
197 | PeerMisbehaved::EarlyDataAttemptedInSecondClientHello, |
198 | ) |
199 | }); |
200 | } |
201 | |
202 | // choose a share that we support |
203 | let chosen_share_and_kxg = self |
204 | .config |
205 | .provider |
206 | .kx_groups |
207 | .iter() |
208 | .find_map(|group| { |
209 | shares_ext |
210 | .iter() |
211 | .find(|share| share.group == group.name()) |
212 | .map(|share| (share, *group)) |
213 | }); |
214 | |
215 | let chosen_share_and_kxg = match chosen_share_and_kxg { |
216 | Some(s) => s, |
217 | None => { |
218 | // We don't have a suitable key share. Choose a suitable group and |
219 | // send a HelloRetryRequest. |
220 | let retry_group_maybe = self |
221 | .config |
222 | .provider |
223 | .kx_groups |
224 | .iter() |
225 | .find(|group| groups_ext.contains(&group.name())) |
226 | .cloned(); |
227 | |
228 | self.transcript.add_message(chm); |
229 | |
230 | if let Some(group) = retry_group_maybe { |
231 | if self.done_retry { |
232 | return Err(cx.common.send_fatal_alert( |
233 | AlertDescription::IllegalParameter, |
234 | PeerMisbehaved::RefusedToFollowHelloRetryRequest, |
235 | )); |
236 | } |
237 | |
238 | emit_hello_retry_request( |
239 | &mut self.transcript, |
240 | self.suite, |
241 | client_hello.session_id, |
242 | cx.common, |
243 | group.name(), |
244 | ); |
245 | emit_fake_ccs(cx.common); |
246 | |
247 | let skip_early_data = max_early_data_size(self.config.max_early_data_size); |
248 | |
249 | let next = Box::new(hs::ExpectClientHello { |
250 | config: self.config, |
251 | transcript: HandshakeHashOrBuffer::Hash(self.transcript), |
252 | #[cfg (feature = "tls12" )] |
253 | session_id: SessionId::empty(), |
254 | #[cfg (feature = "tls12" )] |
255 | using_ems: false, |
256 | done_retry: true, |
257 | send_tickets: self.send_tickets, |
258 | extra_exts: self.extra_exts, |
259 | }); |
260 | |
261 | return if early_data_requested { |
262 | Ok(Box::new(ExpectAndSkipRejectedEarlyData { |
263 | skip_data_left: skip_early_data, |
264 | next, |
265 | })) |
266 | } else { |
267 | Ok(next) |
268 | }; |
269 | } |
270 | |
271 | return Err(cx.common.send_fatal_alert( |
272 | AlertDescription::HandshakeFailure, |
273 | PeerIncompatible::NoKxGroupsInCommon, |
274 | )); |
275 | } |
276 | }; |
277 | |
278 | let mut chosen_psk_index = None; |
279 | let mut resumedata = None; |
280 | |
281 | if let Some(psk_offer) = client_hello.get_psk() { |
282 | if !client_hello.check_psk_ext_is_last() { |
283 | return Err(cx.common.send_fatal_alert( |
284 | AlertDescription::IllegalParameter, |
285 | PeerMisbehaved::PskExtensionMustBeLast, |
286 | )); |
287 | } |
288 | |
289 | // "A client MUST provide a "psk_key_exchange_modes" extension if it |
290 | // offers a "pre_shared_key" extension. If clients offer |
291 | // "pre_shared_key" without a "psk_key_exchange_modes" extension, |
292 | // servers MUST abort the handshake." - RFC8446 4.2.9 |
293 | if client_hello.get_psk_modes().is_none() { |
294 | return Err(cx.common.send_fatal_alert( |
295 | AlertDescription::MissingExtension, |
296 | PeerMisbehaved::MissingPskModesExtension, |
297 | )); |
298 | } |
299 | |
300 | if psk_offer.binders.is_empty() { |
301 | return Err(cx.common.send_fatal_alert( |
302 | AlertDescription::DecodeError, |
303 | PeerMisbehaved::MissingBinderInPskExtension, |
304 | )); |
305 | } |
306 | |
307 | if psk_offer.binders.len() != psk_offer.identities.len() { |
308 | return Err(cx.common.send_fatal_alert( |
309 | AlertDescription::IllegalParameter, |
310 | PeerMisbehaved::PskExtensionWithMismatchedIdsAndBinders, |
311 | )); |
312 | } |
313 | |
314 | for (i, psk_id) in psk_offer.identities.iter().enumerate() { |
315 | let resume = match self |
316 | .attempt_tls13_ticket_decryption(&psk_id.identity.0) |
317 | .map(|resumedata| { |
318 | resumedata.set_freshness(psk_id.obfuscated_ticket_age, UnixTime::now()) |
319 | }) |
320 | .filter(|resumedata| { |
321 | hs::can_resume(self.suite.into(), &cx.data.sni, false, resumedata) |
322 | }) { |
323 | Some(resume) => resume, |
324 | None => continue, |
325 | }; |
326 | |
327 | if !self.check_binder( |
328 | self.suite, |
329 | chm, |
330 | &resume.master_secret.0, |
331 | psk_offer.binders[i].as_ref(), |
332 | ) { |
333 | return Err(cx.common.send_fatal_alert( |
334 | AlertDescription::DecryptError, |
335 | PeerMisbehaved::IncorrectBinder, |
336 | )); |
337 | } |
338 | |
339 | chosen_psk_index = Some(i); |
340 | resumedata = Some(resume); |
341 | break; |
342 | } |
343 | } |
344 | |
345 | if !client_hello.psk_mode_offered(PSKKeyExchangeMode::PSK_DHE_KE) { |
346 | debug!("Client unwilling to resume, DHE_KE not offered" ); |
347 | self.send_tickets = 0; |
348 | chosen_psk_index = None; |
349 | resumedata = None; |
350 | } else { |
351 | self.send_tickets = self.config.send_tls13_tickets; |
352 | } |
353 | |
354 | if let Some(ref resume) = resumedata { |
355 | cx.data.received_resumption_data = Some(resume.application_data.0.clone()); |
356 | cx.common.peer_certificates = resume.client_cert_chain.clone(); |
357 | } |
358 | |
359 | let full_handshake = resumedata.is_none(); |
360 | self.transcript.add_message(chm); |
361 | let key_schedule = emit_server_hello( |
362 | &mut self.transcript, |
363 | &self.randoms, |
364 | self.suite, |
365 | cx, |
366 | &client_hello.session_id, |
367 | chosen_share_and_kxg, |
368 | chosen_psk_index, |
369 | resumedata |
370 | .as_ref() |
371 | .map(|x| &x.master_secret.0[..]), |
372 | &self.config, |
373 | )?; |
374 | if !self.done_retry { |
375 | emit_fake_ccs(cx.common); |
376 | } |
377 | |
378 | let mut ocsp_response = server_key.get_ocsp(); |
379 | let doing_early_data = emit_encrypted_extensions( |
380 | &mut self.transcript, |
381 | self.suite, |
382 | cx, |
383 | &mut ocsp_response, |
384 | client_hello, |
385 | resumedata.as_ref(), |
386 | self.extra_exts, |
387 | &self.config, |
388 | )?; |
389 | |
390 | let doing_client_auth = if full_handshake { |
391 | let client_auth = |
392 | emit_certificate_req_tls13(&mut self.transcript, cx, &self.config)?; |
393 | emit_certificate_tls13( |
394 | &mut self.transcript, |
395 | cx.common, |
396 | server_key.get_cert(), |
397 | ocsp_response, |
398 | ); |
399 | emit_certificate_verify_tls13( |
400 | &mut self.transcript, |
401 | cx.common, |
402 | server_key.get_key(), |
403 | &sigschemes_ext, |
404 | )?; |
405 | client_auth |
406 | } else { |
407 | false |
408 | }; |
409 | |
410 | // If we're not doing early data, then the next messages we receive |
411 | // are encrypted with the handshake keys. |
412 | match doing_early_data { |
413 | EarlyDataDecision::Disabled => { |
414 | key_schedule.set_handshake_decrypter(None, cx.common); |
415 | cx.data.early_data.reject(); |
416 | } |
417 | EarlyDataDecision::RequestedButRejected => { |
418 | debug!("Client requested early_data, but not accepted: switching to handshake keys with trial decryption" ); |
419 | key_schedule.set_handshake_decrypter( |
420 | Some(max_early_data_size(self.config.max_early_data_size)), |
421 | cx.common, |
422 | ); |
423 | cx.data.early_data.reject(); |
424 | } |
425 | EarlyDataDecision::Accepted => { |
426 | cx.data |
427 | .early_data |
428 | .accept(self.config.max_early_data_size as usize); |
429 | } |
430 | } |
431 | |
432 | cx.common.check_aligned_handshake()?; |
433 | let key_schedule_traffic = emit_finished_tls13( |
434 | &mut self.transcript, |
435 | &self.randoms, |
436 | cx, |
437 | key_schedule, |
438 | &self.config, |
439 | ); |
440 | |
441 | if !doing_client_auth && self.config.send_half_rtt_data { |
442 | // Application data can be sent immediately after Finished, in one |
443 | // flight. However, if client auth is enabled, we don't want to send |
444 | // application data to an unauthenticated peer. |
445 | cx.common.start_outgoing_traffic(); |
446 | } |
447 | |
448 | if doing_client_auth { |
449 | Ok(Box::new(ExpectCertificate { |
450 | config: self.config, |
451 | transcript: self.transcript, |
452 | suite: self.suite, |
453 | key_schedule: key_schedule_traffic, |
454 | send_tickets: self.send_tickets, |
455 | })) |
456 | } else if doing_early_data == EarlyDataDecision::Accepted && !cx.common.is_quic() { |
457 | // Not used for QUIC: RFC 9001 §8.3: Clients MUST NOT send the EndOfEarlyData |
458 | // message. A server MUST treat receipt of a CRYPTO frame in a 0-RTT packet as a |
459 | // connection error of type PROTOCOL_VIOLATION. |
460 | Ok(Box::new(ExpectEarlyData { |
461 | config: self.config, |
462 | transcript: self.transcript, |
463 | suite: self.suite, |
464 | key_schedule: key_schedule_traffic, |
465 | send_tickets: self.send_tickets, |
466 | })) |
467 | } else { |
468 | Ok(Box::new(ExpectFinished { |
469 | config: self.config, |
470 | transcript: self.transcript, |
471 | suite: self.suite, |
472 | key_schedule: key_schedule_traffic, |
473 | send_tickets: self.send_tickets, |
474 | })) |
475 | } |
476 | } |
477 | } |
478 | |
479 | fn emit_server_hello( |
480 | transcript: &mut HandshakeHash, |
481 | randoms: &ConnectionRandoms, |
482 | suite: &'static Tls13CipherSuite, |
483 | cx: &mut ServerContext<'_>, |
484 | session_id: &SessionId, |
485 | share_and_kxgroup: (&KeyShareEntry, &'static dyn SupportedKxGroup), |
486 | chosen_psk_idx: Option<usize>, |
487 | resuming_psk: Option<&[u8]>, |
488 | config: &ServerConfig, |
489 | ) -> Result<KeyScheduleHandshake, Error> { |
490 | let mut extensions = Vec::new(); |
491 | |
492 | // Prepare key exchange; the caller already found the matching SupportedKxGroup |
493 | let (share, kxgroup) = share_and_kxgroup; |
494 | debug_assert_eq!(kxgroup.name(), share.group); |
495 | let kx = kxgroup |
496 | .start() |
497 | .map_err(|_| Error::FailedToGetRandomBytes)?; |
498 | |
499 | let kse = KeyShareEntry::new(share.group, kx.pub_key()); |
500 | extensions.push(ServerExtension::KeyShare(kse)); |
501 | extensions.push(ServerExtension::SupportedVersions(ProtocolVersion::TLSv1_3)); |
502 | |
503 | if let Some(psk_idx) = chosen_psk_idx { |
504 | extensions.push(ServerExtension::PresharedKey(psk_idx as u16)); |
505 | } |
506 | |
507 | let sh = Message { |
508 | version: ProtocolVersion::TLSv1_2, |
509 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
510 | typ: HandshakeType::ServerHello, |
511 | payload: HandshakePayload::ServerHello(ServerHelloPayload { |
512 | legacy_version: ProtocolVersion::TLSv1_2, |
513 | random: Random::from(randoms.server), |
514 | session_id: *session_id, |
515 | cipher_suite: suite.common.suite, |
516 | compression_method: Compression::Null, |
517 | extensions, |
518 | }), |
519 | }), |
520 | }; |
521 | |
522 | cx.common.check_aligned_handshake()?; |
523 | |
524 | let client_hello_hash = transcript.get_hash_given(&[]); |
525 | |
526 | trace!("sending server hello {:?}" , sh); |
527 | transcript.add_message(&sh); |
528 | cx.common.send_msg(sh, false); |
529 | |
530 | // Start key schedule |
531 | let key_schedule_pre_handshake = if let Some(psk) = resuming_psk { |
532 | let early_key_schedule = KeyScheduleEarly::new(suite, psk); |
533 | early_key_schedule.client_early_traffic_secret( |
534 | &client_hello_hash, |
535 | &*config.key_log, |
536 | &randoms.client, |
537 | cx.common, |
538 | ); |
539 | |
540 | KeySchedulePreHandshake::from(early_key_schedule) |
541 | } else { |
542 | KeySchedulePreHandshake::new(suite) |
543 | }; |
544 | |
545 | // Do key exchange |
546 | let key_schedule = key_schedule_pre_handshake.into_handshake(kx, &share.payload.0)?; |
547 | |
548 | let handshake_hash = transcript.get_current_hash(); |
549 | let key_schedule = key_schedule.derive_server_handshake_secrets( |
550 | handshake_hash, |
551 | &*config.key_log, |
552 | &randoms.client, |
553 | cx.common, |
554 | ); |
555 | |
556 | Ok(key_schedule) |
557 | } |
558 | |
559 | fn emit_fake_ccs(common: &mut CommonState) { |
560 | if common.is_quic() { |
561 | return; |
562 | } |
563 | let m = Message { |
564 | version: ProtocolVersion::TLSv1_2, |
565 | payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}), |
566 | }; |
567 | common.send_msg(m, false); |
568 | } |
569 | |
570 | fn emit_hello_retry_request( |
571 | transcript: &mut HandshakeHash, |
572 | suite: &'static Tls13CipherSuite, |
573 | session_id: SessionId, |
574 | common: &mut CommonState, |
575 | group: NamedGroup, |
576 | ) { |
577 | let mut req = HelloRetryRequest { |
578 | legacy_version: ProtocolVersion::TLSv1_2, |
579 | session_id, |
580 | cipher_suite: suite.common.suite, |
581 | extensions: Vec::new(), |
582 | }; |
583 | |
584 | req.extensions |
585 | .push(HelloRetryExtension::KeyShare(group)); |
586 | req.extensions |
587 | .push(HelloRetryExtension::SupportedVersions( |
588 | ProtocolVersion::TLSv1_3, |
589 | )); |
590 | |
591 | let m = Message { |
592 | version: ProtocolVersion::TLSv1_2, |
593 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
594 | typ: HandshakeType::HelloRetryRequest, |
595 | payload: HandshakePayload::HelloRetryRequest(req), |
596 | }), |
597 | }; |
598 | |
599 | trace!("Requesting retry {:?}" , m); |
600 | transcript.rollup_for_hrr(); |
601 | transcript.add_message(&m); |
602 | common.send_msg(m, false); |
603 | } |
604 | |
605 | fn decide_if_early_data_allowed( |
606 | cx: &mut ServerContext<'_>, |
607 | client_hello: &ClientHelloPayload, |
608 | resumedata: Option<&persist::ServerSessionValue>, |
609 | suite: &'static Tls13CipherSuite, |
610 | config: &ServerConfig, |
611 | ) -> EarlyDataDecision { |
612 | let early_data_requested = client_hello.early_data_extension_offered(); |
613 | let rejected_or_disabled = match early_data_requested { |
614 | true => EarlyDataDecision::RequestedButRejected, |
615 | false => EarlyDataDecision::Disabled, |
616 | }; |
617 | |
618 | let resume = match resumedata { |
619 | Some(resume) => resume, |
620 | None => { |
621 | // never any early data if not resuming. |
622 | return rejected_or_disabled; |
623 | } |
624 | }; |
625 | |
626 | /* Non-zero max_early_data_size controls whether early_data is allowed at all. |
627 | * We also require stateful resumption. */ |
628 | let early_data_configured = config.max_early_data_size > 0 && !config.ticketer.enabled(); |
629 | |
630 | /* "For PSKs provisioned via NewSessionTicket, a server MUST validate |
631 | * that the ticket age for the selected PSK identity (computed by |
632 | * subtracting ticket_age_add from PskIdentity.obfuscated_ticket_age |
633 | * modulo 2^32) is within a small tolerance of the time since the ticket |
634 | * was issued (see Section 8)." -- this is implemented in ServerSessionValue::set_freshness() |
635 | * and related. |
636 | * |
637 | * "In order to accept early data, the server [...] MUST verify that the |
638 | * following values are the same as those associated with the |
639 | * selected PSK: |
640 | * |
641 | * - The TLS version number |
642 | * - The selected cipher suite |
643 | * - The selected ALPN [RFC7301] protocol, if any" |
644 | * |
645 | * (RFC8446, 4.2.10) */ |
646 | let early_data_possible = early_data_requested |
647 | && resume.is_fresh() |
648 | && Some(resume.version) == cx.common.negotiated_version |
649 | && resume.cipher_suite == suite.common.suite |
650 | && resume.alpn.as_ref().map(|x| &x.0) == cx.common.alpn_protocol.as_ref(); |
651 | |
652 | if early_data_configured && early_data_possible && !cx.data.early_data.was_rejected() { |
653 | EarlyDataDecision::Accepted |
654 | } else { |
655 | if cx.common.is_quic() { |
656 | // Clobber value set in tls13::emit_server_hello |
657 | cx.common.quic.early_secret = None; |
658 | } |
659 | |
660 | rejected_or_disabled |
661 | } |
662 | } |
663 | |
664 | fn emit_encrypted_extensions( |
665 | transcript: &mut HandshakeHash, |
666 | suite: &'static Tls13CipherSuite, |
667 | cx: &mut ServerContext<'_>, |
668 | ocsp_response: &mut Option<&[u8]>, |
669 | hello: &ClientHelloPayload, |
670 | resumedata: Option<&persist::ServerSessionValue>, |
671 | extra_exts: Vec<ServerExtension>, |
672 | config: &ServerConfig, |
673 | ) -> Result<EarlyDataDecision, Error> { |
674 | let mut ep = hs::ExtensionProcessing::new(); |
675 | ep.process_common(config, cx, ocsp_response, hello, resumedata, extra_exts)?; |
676 | |
677 | let early_data = decide_if_early_data_allowed(cx, hello, resumedata, suite, config); |
678 | if early_data == EarlyDataDecision::Accepted { |
679 | ep.exts.push(ServerExtension::EarlyData); |
680 | } |
681 | |
682 | let ee = Message { |
683 | version: ProtocolVersion::TLSv1_3, |
684 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
685 | typ: HandshakeType::EncryptedExtensions, |
686 | payload: HandshakePayload::EncryptedExtensions(ep.exts), |
687 | }), |
688 | }; |
689 | |
690 | trace!("sending encrypted extensions {:?}" , ee); |
691 | transcript.add_message(&ee); |
692 | cx.common.send_msg(ee, true); |
693 | Ok(early_data) |
694 | } |
695 | |
696 | fn emit_certificate_req_tls13( |
697 | transcript: &mut HandshakeHash, |
698 | cx: &mut ServerContext<'_>, |
699 | config: &ServerConfig, |
700 | ) -> Result<bool, Error> { |
701 | if !config.verifier.offer_client_auth() { |
702 | return Ok(false); |
703 | } |
704 | |
705 | let mut cr = CertificateRequestPayloadTls13 { |
706 | context: PayloadU8::empty(), |
707 | extensions: Vec::new(), |
708 | }; |
709 | |
710 | let schemes = config |
711 | .verifier |
712 | .supported_verify_schemes(); |
713 | cr.extensions |
714 | .push(CertReqExtension::SignatureAlgorithms(schemes.to_vec())); |
715 | |
716 | let authorities = config.verifier.root_hint_subjects(); |
717 | if !authorities.is_empty() { |
718 | cr.extensions |
719 | .push(CertReqExtension::AuthorityNames(authorities.to_vec())); |
720 | } |
721 | |
722 | let m = Message { |
723 | version: ProtocolVersion::TLSv1_3, |
724 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
725 | typ: HandshakeType::CertificateRequest, |
726 | payload: HandshakePayload::CertificateRequestTls13(cr), |
727 | }), |
728 | }; |
729 | |
730 | trace!("Sending CertificateRequest {:?}" , m); |
731 | transcript.add_message(&m); |
732 | cx.common.send_msg(m, true); |
733 | Ok(true) |
734 | } |
735 | |
736 | fn emit_certificate_tls13( |
737 | transcript: &mut HandshakeHash, |
738 | common: &mut CommonState, |
739 | cert_chain: &[CertificateDer<'static>], |
740 | ocsp_response: Option<&[u8]>, |
741 | ) { |
742 | let mut cert_entries = vec![]; |
743 | for cert in cert_chain { |
744 | let entry = CertificateEntry { |
745 | cert: cert.to_owned(), |
746 | exts: Vec::new(), |
747 | }; |
748 | |
749 | cert_entries.push(entry); |
750 | } |
751 | |
752 | if let Some(end_entity_cert) = cert_entries.first_mut() { |
753 | // Apply OCSP response to first certificate (we don't support OCSP |
754 | // except for leaf certs). |
755 | if let Some(ocsp) = ocsp_response { |
756 | let cst = CertificateStatus::new(ocsp.to_owned()); |
757 | end_entity_cert |
758 | .exts |
759 | .push(CertificateExtension::CertificateStatus(cst)); |
760 | } |
761 | } |
762 | |
763 | let cert_body = CertificatePayloadTls13::new(cert_entries); |
764 | let c = Message { |
765 | version: ProtocolVersion::TLSv1_3, |
766 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
767 | typ: HandshakeType::Certificate, |
768 | payload: HandshakePayload::CertificateTls13(cert_body), |
769 | }), |
770 | }; |
771 | |
772 | trace!("sending certificate {:?}" , c); |
773 | transcript.add_message(&c); |
774 | common.send_msg(c, true); |
775 | } |
776 | |
777 | fn emit_certificate_verify_tls13( |
778 | transcript: &mut HandshakeHash, |
779 | common: &mut CommonState, |
780 | signing_key: &dyn sign::SigningKey, |
781 | schemes: &[SignatureScheme], |
782 | ) -> Result<(), Error> { |
783 | let message = construct_server_verify_message(&transcript.get_current_hash()); |
784 | |
785 | let signer = signing_key |
786 | .choose_scheme(schemes) |
787 | .ok_or_else(|| { |
788 | common.send_fatal_alert( |
789 | AlertDescription::HandshakeFailure, |
790 | PeerIncompatible::NoSignatureSchemesInCommon, |
791 | ) |
792 | })?; |
793 | |
794 | let scheme = signer.scheme(); |
795 | let sig = signer.sign(&message)?; |
796 | |
797 | let cv = DigitallySignedStruct::new(scheme, sig); |
798 | |
799 | let m = Message { |
800 | version: ProtocolVersion::TLSv1_3, |
801 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
802 | typ: HandshakeType::CertificateVerify, |
803 | payload: HandshakePayload::CertificateVerify(cv), |
804 | }), |
805 | }; |
806 | |
807 | trace!("sending certificate-verify {:?}" , m); |
808 | transcript.add_message(&m); |
809 | common.send_msg(m, true); |
810 | Ok(()) |
811 | } |
812 | |
813 | fn emit_finished_tls13( |
814 | transcript: &mut HandshakeHash, |
815 | randoms: &ConnectionRandoms, |
816 | cx: &mut ServerContext<'_>, |
817 | key_schedule: KeyScheduleHandshake, |
818 | config: &ServerConfig, |
819 | ) -> KeyScheduleTrafficWithClientFinishedPending { |
820 | let handshake_hash = transcript.get_current_hash(); |
821 | let verify_data = key_schedule.sign_server_finish(&handshake_hash); |
822 | let verify_data_payload = Payload::new(verify_data.as_ref()); |
823 | |
824 | let m = Message { |
825 | version: ProtocolVersion::TLSv1_3, |
826 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
827 | typ: HandshakeType::Finished, |
828 | payload: HandshakePayload::Finished(verify_data_payload), |
829 | }), |
830 | }; |
831 | |
832 | trace!("sending finished {:?}" , m); |
833 | transcript.add_message(&m); |
834 | let hash_at_server_fin = transcript.get_current_hash(); |
835 | cx.common.send_msg(m, true); |
836 | |
837 | // Now move to application data keys. Read key change is deferred until |
838 | // the Finish message is received & validated. |
839 | key_schedule.into_traffic_with_client_finished_pending( |
840 | hash_at_server_fin, |
841 | &*config.key_log, |
842 | &randoms.client, |
843 | cx.common, |
844 | ) |
845 | } |
846 | } |
847 | |
848 | struct ExpectAndSkipRejectedEarlyData { |
849 | skip_data_left: usize, |
850 | next: Box<hs::ExpectClientHello>, |
851 | } |
852 | |
853 | impl State<ServerConnectionData> for ExpectAndSkipRejectedEarlyData { |
854 | fn handle(mut self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
855 | /* "The server then ignores early data by skipping all records with an external |
856 | * content type of "application_data" (indicating that they are encrypted), |
857 | * up to the configured max_early_data_size." |
858 | * (RFC8446, 14.2.10) */ |
859 | if let MessagePayload::ApplicationData(ref skip_data: &Payload) = m.payload { |
860 | if skip_data.0.len() <= self.skip_data_left { |
861 | self.skip_data_left -= skip_data.0.len(); |
862 | return Ok(self); |
863 | } |
864 | } |
865 | |
866 | self.next.handle(cx, message:m) |
867 | } |
868 | } |
869 | |
870 | struct ExpectCertificate { |
871 | config: Arc<ServerConfig>, |
872 | transcript: HandshakeHash, |
873 | suite: &'static Tls13CipherSuite, |
874 | key_schedule: KeyScheduleTrafficWithClientFinishedPending, |
875 | send_tickets: usize, |
876 | } |
877 | |
878 | impl State<ServerConnectionData> for ExpectCertificate { |
879 | fn handle(mut self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
880 | self.transcript.add_message(&m); |
881 | let certp = require_handshake_msg_move!( |
882 | m, |
883 | HandshakeType::Certificate, |
884 | HandshakePayload::CertificateTls13 |
885 | )?; |
886 | |
887 | // We don't send any CertificateRequest extensions, so any extensions |
888 | // here are illegal. |
889 | if certp.any_entry_has_extension() { |
890 | return Err(PeerMisbehaved::UnsolicitedCertExtension.into()); |
891 | } |
892 | |
893 | let client_cert = certp.convert(); |
894 | |
895 | let mandatory = self |
896 | .config |
897 | .verifier |
898 | .client_auth_mandatory(); |
899 | |
900 | let (end_entity, intermediates) = match client_cert.split_first() { |
901 | None => { |
902 | if !mandatory { |
903 | debug!("client auth requested but no certificate supplied" ); |
904 | self.transcript.abandon_client_auth(); |
905 | return Ok(Box::new(ExpectFinished { |
906 | config: self.config, |
907 | suite: self.suite, |
908 | key_schedule: self.key_schedule, |
909 | transcript: self.transcript, |
910 | send_tickets: self.send_tickets, |
911 | })); |
912 | } |
913 | |
914 | return Err(cx.common.send_fatal_alert( |
915 | AlertDescription::CertificateRequired, |
916 | Error::NoCertificatesPresented, |
917 | )); |
918 | } |
919 | Some(chain) => chain, |
920 | }; |
921 | |
922 | self.config |
923 | .verifier |
924 | .verify_client_cert(end_entity, intermediates, UnixTime::now()) |
925 | .map_err(|err| { |
926 | cx.common |
927 | .send_cert_verify_error_alert(err) |
928 | })?; |
929 | |
930 | Ok(Box::new(ExpectCertificateVerify { |
931 | config: self.config, |
932 | suite: self.suite, |
933 | transcript: self.transcript, |
934 | key_schedule: self.key_schedule, |
935 | client_cert, |
936 | send_tickets: self.send_tickets, |
937 | })) |
938 | } |
939 | } |
940 | |
941 | struct ExpectCertificateVerify { |
942 | config: Arc<ServerConfig>, |
943 | transcript: HandshakeHash, |
944 | suite: &'static Tls13CipherSuite, |
945 | key_schedule: KeyScheduleTrafficWithClientFinishedPending, |
946 | client_cert: CertificateChain, |
947 | send_tickets: usize, |
948 | } |
949 | |
950 | impl State<ServerConnectionData> for ExpectCertificateVerify { |
951 | fn handle(mut self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
952 | let rc = { |
953 | let sig = require_handshake_msg!( |
954 | m, |
955 | HandshakeType::CertificateVerify, |
956 | HandshakePayload::CertificateVerify |
957 | )?; |
958 | let handshake_hash = self.transcript.get_current_hash(); |
959 | self.transcript.abandon_client_auth(); |
960 | let certs = &self.client_cert; |
961 | let msg = construct_client_verify_message(&handshake_hash); |
962 | |
963 | self.config |
964 | .verifier |
965 | .verify_tls13_signature(&msg, &certs[0], sig) |
966 | }; |
967 | |
968 | if let Err(e) = rc { |
969 | return Err(cx |
970 | .common |
971 | .send_cert_verify_error_alert(e)); |
972 | } |
973 | |
974 | trace!("client CertificateVerify OK" ); |
975 | cx.common.peer_certificates = Some(self.client_cert); |
976 | |
977 | self.transcript.add_message(&m); |
978 | Ok(Box::new(ExpectFinished { |
979 | config: self.config, |
980 | suite: self.suite, |
981 | key_schedule: self.key_schedule, |
982 | transcript: self.transcript, |
983 | send_tickets: self.send_tickets, |
984 | })) |
985 | } |
986 | } |
987 | |
988 | // --- Process (any number of) early ApplicationData messages, |
989 | // followed by a terminating handshake EndOfEarlyData message --- |
990 | |
991 | struct ExpectEarlyData { |
992 | config: Arc<ServerConfig>, |
993 | transcript: HandshakeHash, |
994 | suite: &'static Tls13CipherSuite, |
995 | key_schedule: KeyScheduleTrafficWithClientFinishedPending, |
996 | send_tickets: usize, |
997 | } |
998 | |
999 | impl State<ServerConnectionData> for ExpectEarlyData { |
1000 | fn handle(mut self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
1001 | match m.payload { |
1002 | MessagePayload::ApplicationData(payload) => { |
1003 | match cx |
1004 | .data |
1005 | .early_data |
1006 | .take_received_plaintext(payload) |
1007 | { |
1008 | true => Ok(self), |
1009 | false => Err(cx.common.send_fatal_alert( |
1010 | AlertDescription::UnexpectedMessage, |
1011 | PeerMisbehaved::TooMuchEarlyDataReceived, |
1012 | )), |
1013 | } |
1014 | } |
1015 | MessagePayload::Handshake { |
1016 | parsed: |
1017 | HandshakeMessagePayload { |
1018 | typ: HandshakeType::EndOfEarlyData, |
1019 | payload: HandshakePayload::EndOfEarlyData, |
1020 | }, |
1021 | .. |
1022 | } => { |
1023 | self.key_schedule |
1024 | .update_decrypter(cx.common); |
1025 | self.transcript.add_message(&m); |
1026 | Ok(Box::new(ExpectFinished { |
1027 | config: self.config, |
1028 | suite: self.suite, |
1029 | key_schedule: self.key_schedule, |
1030 | transcript: self.transcript, |
1031 | send_tickets: self.send_tickets, |
1032 | })) |
1033 | } |
1034 | payload => Err(inappropriate_handshake_message( |
1035 | &payload, |
1036 | &[ContentType::ApplicationData, ContentType::Handshake], |
1037 | &[HandshakeType::EndOfEarlyData], |
1038 | )), |
1039 | } |
1040 | } |
1041 | } |
1042 | |
1043 | // --- Process client's Finished --- |
1044 | fn get_server_session_value( |
1045 | transcript: &HandshakeHash, |
1046 | suite: &'static Tls13CipherSuite, |
1047 | key_schedule: &KeyScheduleTraffic, |
1048 | cx: &ServerContext<'_>, |
1049 | nonce: &[u8], |
1050 | time_now: UnixTime, |
1051 | age_obfuscation_offset: u32, |
1052 | ) -> persist::ServerSessionValue { |
1053 | let version: ProtocolVersion = ProtocolVersion::TLSv1_3; |
1054 | |
1055 | let handshake_hash: Output = transcript.get_current_hash(); |
1056 | let secret: OkmBlock = |
1057 | key_schedule.resumption_master_secret_and_derive_ticket_psk(&handshake_hash, nonce); |
1058 | |
1059 | persist::ServerSessionValue::new( |
1060 | sni:cx.data.sni.as_ref(), |
1061 | v:version, |
1062 | cs:suite.common.suite, |
1063 | ms:secret.as_ref(), |
1064 | client_cert_chain:cx.common.peer_certificates.clone(), |
1065 | alpn:cx.common.alpn_protocol.clone(), |
1066 | application_data:cx.data.resumption_data.clone(), |
1067 | creation_time:time_now, |
1068 | age_obfuscation_offset, |
1069 | ) |
1070 | } |
1071 | |
1072 | struct ExpectFinished { |
1073 | config: Arc<ServerConfig>, |
1074 | transcript: HandshakeHash, |
1075 | suite: &'static Tls13CipherSuite, |
1076 | key_schedule: KeyScheduleTrafficWithClientFinishedPending, |
1077 | send_tickets: usize, |
1078 | } |
1079 | |
1080 | impl ExpectFinished { |
1081 | fn emit_ticket( |
1082 | transcript: &HandshakeHash, |
1083 | suite: &'static Tls13CipherSuite, |
1084 | cx: &mut ServerContext<'_>, |
1085 | key_schedule: &KeyScheduleTraffic, |
1086 | config: &ServerConfig, |
1087 | ) -> Result<(), Error> { |
1088 | let secure_random = config.provider.secure_random; |
1089 | let nonce = rand::random_vec(secure_random, 32)?; |
1090 | let age_add = rand::random_u32(secure_random)?; |
1091 | let plain = get_server_session_value( |
1092 | transcript, |
1093 | suite, |
1094 | key_schedule, |
1095 | cx, |
1096 | &nonce, |
1097 | UnixTime::now(), |
1098 | age_add, |
1099 | ) |
1100 | .get_encoding(); |
1101 | |
1102 | let stateless = config.ticketer.enabled(); |
1103 | let (ticket, lifetime) = if stateless { |
1104 | let ticket = match config.ticketer.encrypt(&plain) { |
1105 | Some(t) => t, |
1106 | None => return Ok(()), |
1107 | }; |
1108 | (ticket, config.ticketer.lifetime()) |
1109 | } else { |
1110 | let id = rand::random_vec(secure_random, 32)?; |
1111 | let stored = config |
1112 | .session_storage |
1113 | .put(id.clone(), plain); |
1114 | if !stored { |
1115 | trace!("resumption not available; not issuing ticket" ); |
1116 | return Ok(()); |
1117 | } |
1118 | let stateful_lifetime = 24 * 60 * 60; // this is a bit of a punt |
1119 | (id, stateful_lifetime) |
1120 | }; |
1121 | |
1122 | let mut payload = NewSessionTicketPayloadTls13::new(lifetime, age_add, nonce, ticket); |
1123 | |
1124 | if config.max_early_data_size > 0 { |
1125 | if !stateless { |
1126 | payload |
1127 | .exts |
1128 | .push(NewSessionTicketExtension::EarlyData( |
1129 | config.max_early_data_size, |
1130 | )); |
1131 | } else { |
1132 | // We implement RFC8446 section 8.1: by enforcing that 0-RTT is |
1133 | // only possible if using stateful resumption |
1134 | warn!("early_data with stateless resumption is not allowed" ); |
1135 | } |
1136 | } |
1137 | |
1138 | let m = Message { |
1139 | version: ProtocolVersion::TLSv1_3, |
1140 | payload: MessagePayload::handshake(HandshakeMessagePayload { |
1141 | typ: HandshakeType::NewSessionTicket, |
1142 | payload: HandshakePayload::NewSessionTicketTls13(payload), |
1143 | }), |
1144 | }; |
1145 | |
1146 | trace!("sending new ticket {:?} (stateless: {})" , m, stateless); |
1147 | cx.common.send_msg(m, true); |
1148 | Ok(()) |
1149 | } |
1150 | } |
1151 | |
1152 | impl State<ServerConnectionData> for ExpectFinished { |
1153 | fn handle(mut self: Box<Self>, cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
1154 | let finished = |
1155 | require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?; |
1156 | |
1157 | let handshake_hash = self.transcript.get_current_hash(); |
1158 | let (key_schedule_traffic, expect_verify_data) = self |
1159 | .key_schedule |
1160 | .sign_client_finish(&handshake_hash, cx.common); |
1161 | |
1162 | let fin = match ConstantTimeEq::ct_eq(expect_verify_data.as_ref(), &finished.0[..]).into() { |
1163 | true => verify::FinishedMessageVerified::assertion(), |
1164 | false => { |
1165 | return Err(cx |
1166 | .common |
1167 | .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError)); |
1168 | } |
1169 | }; |
1170 | |
1171 | // Note: future derivations include Client Finished, but not the |
1172 | // main application data keying. |
1173 | self.transcript.add_message(&m); |
1174 | |
1175 | cx.common.check_aligned_handshake()?; |
1176 | |
1177 | for _ in 0..self.send_tickets { |
1178 | Self::emit_ticket( |
1179 | &self.transcript, |
1180 | self.suite, |
1181 | cx, |
1182 | &key_schedule_traffic, |
1183 | &self.config, |
1184 | )?; |
1185 | } |
1186 | |
1187 | // Application data may now flow, even if we have client auth enabled. |
1188 | cx.common.start_traffic(); |
1189 | |
1190 | Ok(match cx.common.is_quic() { |
1191 | true => Box::new(ExpectQuicTraffic { |
1192 | key_schedule: key_schedule_traffic, |
1193 | _fin_verified: fin, |
1194 | }), |
1195 | false => Box::new(ExpectTraffic { |
1196 | key_schedule: key_schedule_traffic, |
1197 | _fin_verified: fin, |
1198 | }), |
1199 | }) |
1200 | } |
1201 | } |
1202 | |
1203 | // --- Process traffic --- |
1204 | struct ExpectTraffic { |
1205 | key_schedule: KeyScheduleTraffic, |
1206 | _fin_verified: verify::FinishedMessageVerified, |
1207 | } |
1208 | |
1209 | impl ExpectTraffic { |
1210 | fn handle_key_update( |
1211 | &mut self, |
1212 | common: &mut CommonState, |
1213 | key_update_request: &KeyUpdateRequest, |
1214 | ) -> Result<(), Error> { |
1215 | if let Protocol::Quic = common.protocol { |
1216 | return Err(common.send_fatal_alert( |
1217 | AlertDescription::UnexpectedMessage, |
1218 | PeerMisbehaved::KeyUpdateReceivedInQuicConnection, |
1219 | )); |
1220 | } |
1221 | |
1222 | common.check_aligned_handshake()?; |
1223 | |
1224 | if common.should_update_key(key_update_request)? { |
1225 | self.key_schedule |
1226 | .update_encrypter_and_notify(common); |
1227 | } |
1228 | |
1229 | // Update our read-side keys. |
1230 | self.key_schedule |
1231 | .update_decrypter(common); |
1232 | Ok(()) |
1233 | } |
1234 | } |
1235 | |
1236 | impl State<ServerConnectionData> for ExpectTraffic { |
1237 | fn handle(mut self: Box<Self>, cx: &mut ServerContext, m: Message) -> hs::NextStateOrError { |
1238 | match m.payload { |
1239 | MessagePayload::ApplicationData(payload) => cx |
1240 | .common |
1241 | .take_received_plaintext(payload), |
1242 | MessagePayload::Handshake { |
1243 | parsed: |
1244 | HandshakeMessagePayload { |
1245 | payload: HandshakePayload::KeyUpdate(key_update), |
1246 | .. |
1247 | }, |
1248 | .. |
1249 | } => self.handle_key_update(cx.common, &key_update)?, |
1250 | payload => { |
1251 | return Err(inappropriate_handshake_message( |
1252 | &payload, |
1253 | &[ContentType::ApplicationData, ContentType::Handshake], |
1254 | &[HandshakeType::KeyUpdate], |
1255 | )); |
1256 | } |
1257 | } |
1258 | |
1259 | Ok(self) |
1260 | } |
1261 | |
1262 | fn export_keying_material( |
1263 | &self, |
1264 | output: &mut [u8], |
1265 | label: &[u8], |
1266 | context: Option<&[u8]>, |
1267 | ) -> Result<(), Error> { |
1268 | self.key_schedule |
1269 | .export_keying_material(output, label, context) |
1270 | } |
1271 | |
1272 | fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> { |
1273 | self.key_schedule |
1274 | .extract_secrets(Side::Server) |
1275 | } |
1276 | } |
1277 | |
1278 | struct ExpectQuicTraffic { |
1279 | key_schedule: KeyScheduleTraffic, |
1280 | _fin_verified: verify::FinishedMessageVerified, |
1281 | } |
1282 | |
1283 | impl State<ServerConnectionData> for ExpectQuicTraffic { |
1284 | fn handle(self: Box<Self>, _cx: &mut ServerContext<'_>, m: Message) -> hs::NextStateOrError { |
1285 | // reject all messages |
1286 | Err(inappropriate_message(&m.payload, &[])) |
1287 | } |
1288 | |
1289 | fn export_keying_material( |
1290 | &self, |
1291 | output: &mut [u8], |
1292 | label: &[u8], |
1293 | context: Option<&[u8]>, |
1294 | ) -> Result<(), Error> { |
1295 | self.key_schedule |
1296 | .export_keying_material(out:output, label, context) |
1297 | } |
1298 | } |
1299 | |