xref: /webrtc/dtls/src/flight/flight4.rs (revision 5b6b0d60)
1 use super::flight6::*;
2 use super::*;
3 use crate::cipher_suite::*;
4 use crate::client_certificate_type::*;
5 use crate::compression_methods::*;
6 use crate::config::*;
7 use crate::content::*;
8 use crate::crypto::*;
9 use crate::curve::named_curve::*;
10 use crate::curve::*;
11 use crate::error::Error;
12 use crate::extension::extension_supported_elliptic_curves::*;
13 use crate::extension::extension_supported_point_formats::*;
14 use crate::extension::extension_use_extended_master_secret::*;
15 use crate::extension::extension_use_srtp::*;
16 use crate::extension::*;
17 use crate::handshake::handshake_message_certificate::*;
18 use crate::handshake::handshake_message_certificate_request::*;
19 use crate::handshake::handshake_message_server_hello::*;
20 use crate::handshake::handshake_message_server_hello_done::*;
21 use crate::handshake::handshake_message_server_key_exchange::*;
22 use crate::handshake::*;
23 use crate::prf::*;
24 use crate::record_layer::record_layer_header::*;
25 use crate::record_layer::*;
26 use crate::signature_hash_algorithm::*;
27 
28 use crate::extension::renegotiation_info::ExtensionRenegotiationInfo;
29 use async_trait::async_trait;
30 use log::*;
31 use std::fmt;
32 use std::io::BufWriter;
33 
34 #[derive(Debug, PartialEq)]
35 pub(crate) struct Flight4;
36 
37 impl fmt::Display for Flight4 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result38     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39         write!(f, "Flight 4")
40     }
41 }
42 
43 #[async_trait]
44 impl Flight for Flight4 {
parse( &self, tx: &mut mpsc::Sender<mpsc::Sender<()>>, state: &mut State, cache: &HandshakeCache, cfg: &HandshakeConfig, ) -> Result<Box<dyn Flight + Send + Sync>, (Option<Alert>, Option<Error>)>45     async fn parse(
46         &self,
47         tx: &mut mpsc::Sender<mpsc::Sender<()>>,
48         state: &mut State,
49         cache: &HandshakeCache,
50         cfg: &HandshakeConfig,
51     ) -> Result<Box<dyn Flight + Send + Sync>, (Option<Alert>, Option<Error>)> {
52         let (seq, msgs) = match cache
53             .full_pull_map(
54                 state.handshake_recv_sequence,
55                 &[
56                     HandshakeCachePullRule {
57                         typ: HandshakeType::Certificate,
58                         epoch: cfg.initial_epoch,
59                         is_client: true,
60                         optional: true,
61                     },
62                     HandshakeCachePullRule {
63                         typ: HandshakeType::ClientKeyExchange,
64                         epoch: cfg.initial_epoch,
65                         is_client: true,
66                         optional: false,
67                     },
68                     HandshakeCachePullRule {
69                         typ: HandshakeType::CertificateVerify,
70                         epoch: cfg.initial_epoch,
71                         is_client: true,
72                         optional: true,
73                     },
74                 ],
75             )
76             .await
77         {
78             Ok((seq, msgs)) => (seq, msgs),
79             Err(_) => return Err((None, None)),
80         };
81 
82         let client_key_exchange = if let Some(HandshakeMessage::ClientKeyExchange(h)) =
83             msgs.get(&HandshakeType::ClientKeyExchange)
84         {
85             h
86         } else {
87             return Err((
88                 Some(Alert {
89                     alert_level: AlertLevel::Fatal,
90                     alert_description: AlertDescription::InternalError,
91                 }),
92                 None,
93             ));
94         };
95 
96         if let Some(message) = msgs.get(&HandshakeType::Certificate) {
97             let h = match message {
98                 HandshakeMessage::Certificate(h) => h,
99                 _ => {
100                     return Err((
101                         Some(Alert {
102                             alert_level: AlertLevel::Fatal,
103                             alert_description: AlertDescription::InternalError,
104                         }),
105                         None,
106                     ))
107                 }
108             };
109 
110             state.peer_certificates = h.certificate.clone();
111             trace!(
112                 "[handshake] PeerCertificates4 {}",
113                 state.peer_certificates.len()
114             );
115         }
116 
117         if let Some(message) = msgs.get(&HandshakeType::CertificateVerify) {
118             let h = match message {
119                 HandshakeMessage::CertificateVerify(h) => h,
120                 _ => {
121                     return Err((
122                         Some(Alert {
123                             alert_level: AlertLevel::Fatal,
124                             alert_description: AlertDescription::InternalError,
125                         }),
126                         None,
127                     ))
128                 }
129             };
130 
131             if state.peer_certificates.is_empty() {
132                 return Err((
133                     Some(Alert {
134                         alert_level: AlertLevel::Fatal,
135                         alert_description: AlertDescription::NoCertificate,
136                     }),
137                     Some(Error::ErrCertificateVerifyNoCertificate),
138                 ));
139             }
140 
141             let plain_text = cache
142                 .pull_and_merge(&[
143                     HandshakeCachePullRule {
144                         typ: HandshakeType::ClientHello,
145                         epoch: cfg.initial_epoch,
146                         is_client: true,
147                         optional: false,
148                     },
149                     HandshakeCachePullRule {
150                         typ: HandshakeType::ServerHello,
151                         epoch: cfg.initial_epoch,
152                         is_client: false,
153                         optional: false,
154                     },
155                     HandshakeCachePullRule {
156                         typ: HandshakeType::Certificate,
157                         epoch: cfg.initial_epoch,
158                         is_client: false,
159                         optional: false,
160                     },
161                     HandshakeCachePullRule {
162                         typ: HandshakeType::ServerKeyExchange,
163                         epoch: cfg.initial_epoch,
164                         is_client: false,
165                         optional: false,
166                     },
167                     HandshakeCachePullRule {
168                         typ: HandshakeType::CertificateRequest,
169                         epoch: cfg.initial_epoch,
170                         is_client: false,
171                         optional: false,
172                     },
173                     HandshakeCachePullRule {
174                         typ: HandshakeType::ServerHelloDone,
175                         epoch: cfg.initial_epoch,
176                         is_client: false,
177                         optional: false,
178                     },
179                     HandshakeCachePullRule {
180                         typ: HandshakeType::Certificate,
181                         epoch: cfg.initial_epoch,
182                         is_client: true,
183                         optional: false,
184                     },
185                     HandshakeCachePullRule {
186                         typ: HandshakeType::ClientKeyExchange,
187                         epoch: cfg.initial_epoch,
188                         is_client: true,
189                         optional: false,
190                     },
191                 ])
192                 .await;
193 
194             // Verify that the pair of hash algorithm and signature is listed.
195             let mut valid_signature_scheme = false;
196             for ss in &cfg.local_signature_schemes {
197                 if ss.hash == h.algorithm.hash && ss.signature == h.algorithm.signature {
198                     valid_signature_scheme = true;
199                     break;
200                 }
201             }
202             if !valid_signature_scheme {
203                 return Err((
204                     Some(Alert {
205                         alert_level: AlertLevel::Fatal,
206                         alert_description: AlertDescription::InsufficientSecurity,
207                     }),
208                     Some(Error::ErrNoAvailableSignatureSchemes),
209                 ));
210             }
211 
212             if let Err(err) = verify_certificate_verify(
213                 &plain_text,
214                 &h.algorithm,
215                 &h.signature,
216                 &state.peer_certificates,
217                 cfg.insecure_verification,
218             ) {
219                 return Err((
220                     Some(Alert {
221                         alert_level: AlertLevel::Fatal,
222                         alert_description: AlertDescription::BadCertificate,
223                     }),
224                     Some(err),
225                 ));
226             }
227 
228             let mut chains = vec![];
229             let mut verified = false;
230             if cfg.client_auth as u8 >= ClientAuthType::VerifyClientCertIfGiven as u8 {
231                 if let Some(client_cert_verifier) = &cfg.client_cert_verifier {
232                     chains =
233                         match verify_client_cert(&state.peer_certificates, client_cert_verifier) {
234                             Ok(chains) => chains,
235                             Err(err) => {
236                                 return Err((
237                                     Some(Alert {
238                                         alert_level: AlertLevel::Fatal,
239                                         alert_description: AlertDescription::BadCertificate,
240                                     }),
241                                     Some(err),
242                                 ))
243                             }
244                         };
245                 } else {
246                     return Err((
247                         Some(Alert {
248                             alert_level: AlertLevel::Fatal,
249                             alert_description: AlertDescription::BadCertificate,
250                         }),
251                         Some(Error::ErrInvalidCertificate),
252                     ));
253                 }
254 
255                 verified = true
256             }
257             if let Some(verify_peer_certificate) = &cfg.verify_peer_certificate {
258                 if let Err(err) = verify_peer_certificate(&state.peer_certificates, &chains) {
259                     return Err((
260                         Some(Alert {
261                             alert_level: AlertLevel::Fatal,
262                             alert_description: AlertDescription::BadCertificate,
263                         }),
264                         Some(err),
265                     ));
266                 }
267             }
268             state.peer_certificates_verified = verified
269         } else if !state.peer_certificates.is_empty() {
270             // A certificate was received, but we haven't seen a CertificateVerify
271             // keep reading until we receieve one
272             return Err((None, None));
273         }
274 
275         {
276             let mut cipher_suite = state.cipher_suite.lock().await;
277             if let Some(cipher_suite) = &mut *cipher_suite {
278                 if !cipher_suite.is_initialized() {
279                     let mut server_random = vec![];
280                     {
281                         let mut writer = BufWriter::<&mut Vec<u8>>::new(server_random.as_mut());
282                         let _ = state.local_random.marshal(&mut writer);
283                     }
284                     let mut client_random = vec![];
285                     {
286                         let mut writer = BufWriter::<&mut Vec<u8>>::new(client_random.as_mut());
287                         let _ = state.remote_random.marshal(&mut writer);
288                     }
289 
290                     let mut pre_master_secret = vec![];
291                     if let Some(local_psk_callback) = &cfg.local_psk_callback {
292                         let psk = match local_psk_callback(&client_key_exchange.identity_hint) {
293                             Ok(psk) => psk,
294                             Err(err) => {
295                                 return Err((
296                                     Some(Alert {
297                                         alert_level: AlertLevel::Fatal,
298                                         alert_description: AlertDescription::InternalError,
299                                     }),
300                                     Some(err),
301                                 ))
302                             }
303                         };
304 
305                         state.identity_hint = client_key_exchange.identity_hint.clone();
306                         pre_master_secret = prf_psk_pre_master_secret(&psk);
307                     } else if let Some(local_keypair) = &state.local_keypair {
308                         pre_master_secret = match prf_pre_master_secret(
309                             &client_key_exchange.public_key,
310                             &local_keypair.private_key,
311                             local_keypair.curve,
312                         ) {
313                             Ok(pre_master_secret) => pre_master_secret,
314                             Err(err) => {
315                                 return Err((
316                                     Some(Alert {
317                                         alert_level: AlertLevel::Fatal,
318                                         alert_description: AlertDescription::IllegalParameter,
319                                     }),
320                                     Some(err),
321                                 ))
322                             }
323                         };
324                     }
325 
326                     if state.extended_master_secret {
327                         let hf = cipher_suite.hash_func();
328                         let session_hash =
329                             match cache.session_hash(hf, cfg.initial_epoch, &[]).await {
330                                 Ok(s) => s,
331                                 Err(err) => {
332                                     return Err((
333                                         Some(Alert {
334                                             alert_level: AlertLevel::Fatal,
335                                             alert_description: AlertDescription::InternalError,
336                                         }),
337                                         Some(err),
338                                     ))
339                                 }
340                             };
341 
342                         state.master_secret = match prf_extended_master_secret(
343                             &pre_master_secret,
344                             &session_hash,
345                             cipher_suite.hash_func(),
346                         ) {
347                             Ok(ms) => ms,
348                             Err(err) => {
349                                 return Err((
350                                     Some(Alert {
351                                         alert_level: AlertLevel::Fatal,
352                                         alert_description: AlertDescription::InternalError,
353                                     }),
354                                     Some(err),
355                                 ))
356                             }
357                         };
358                     } else {
359                         state.master_secret = match prf_master_secret(
360                             &pre_master_secret,
361                             &client_random,
362                             &server_random,
363                             cipher_suite.hash_func(),
364                         ) {
365                             Ok(ms) => ms,
366                             Err(err) => {
367                                 return Err((
368                                     Some(Alert {
369                                         alert_level: AlertLevel::Fatal,
370                                         alert_description: AlertDescription::InternalError,
371                                     }),
372                                     Some(err),
373                                 ))
374                             }
375                         };
376                     }
377 
378                     if let Err(err) = cipher_suite.init(
379                         &state.master_secret,
380                         &client_random,
381                         &server_random,
382                         false,
383                     ) {
384                         return Err((
385                             Some(Alert {
386                                 alert_level: AlertLevel::Fatal,
387                                 alert_description: AlertDescription::InternalError,
388                             }),
389                             Some(err),
390                         ));
391                     }
392                 }
393             }
394         }
395 
396         // Now, encrypted packets can be handled
397         let (done_tx, mut done_rx) = mpsc::channel(1);
398         if let Err(err) = tx.send(done_tx).await {
399             return Err((
400                 Some(Alert {
401                     alert_level: AlertLevel::Fatal,
402                     alert_description: AlertDescription::InternalError,
403                 }),
404                 Some(Error::Other(err.to_string())),
405             ));
406         }
407 
408         done_rx.recv().await;
409 
410         let (seq, msgs) = match cache
411             .full_pull_map(
412                 seq,
413                 &[HandshakeCachePullRule {
414                     typ: HandshakeType::Finished,
415                     epoch: cfg.initial_epoch + 1,
416                     is_client: true,
417                     optional: false,
418                 }],
419             )
420             .await
421         {
422             Ok((seq, msgs)) => (seq, msgs),
423             // No valid message received. Keep reading
424             Err(_) => return Err((None, None)),
425         };
426 
427         state.handshake_recv_sequence = seq;
428 
429         if let Some(HandshakeMessage::Finished(h)) = msgs.get(&HandshakeType::Finished) {
430             h
431         } else {
432             return Err((
433                 Some(Alert {
434                     alert_level: AlertLevel::Fatal,
435                     alert_description: AlertDescription::InternalError,
436                 }),
437                 None,
438             ));
439         };
440 
441         match cfg.client_auth {
442             ClientAuthType::RequireAnyClientCert => {
443                 trace!(
444                     "{} peer_certificates.len() {}",
445                     srv_cli_str(state.is_client),
446                     state.peer_certificates.len(),
447                 );
448                 if state.peer_certificates.is_empty() {
449                     return Err((
450                         Some(Alert {
451                             alert_level: AlertLevel::Fatal,
452                             alert_description: AlertDescription::NoCertificate,
453                         }),
454                         Some(Error::ErrClientCertificateRequired),
455                     ));
456                 }
457             }
458             ClientAuthType::VerifyClientCertIfGiven => {
459                 if !state.peer_certificates.is_empty() && !state.peer_certificates_verified {
460                     return Err((
461                         Some(Alert {
462                             alert_level: AlertLevel::Fatal,
463                             alert_description: AlertDescription::BadCertificate,
464                         }),
465                         Some(Error::ErrClientCertificateNotVerified),
466                     ));
467                 }
468             }
469             ClientAuthType::RequireAndVerifyClientCert => {
470                 if state.peer_certificates.is_empty() {
471                     return Err((
472                         Some(Alert {
473                             alert_level: AlertLevel::Fatal,
474                             alert_description: AlertDescription::NoCertificate,
475                         }),
476                         Some(Error::ErrClientCertificateRequired),
477                     ));
478                 }
479                 if !state.peer_certificates_verified {
480                     return Err((
481                         Some(Alert {
482                             alert_level: AlertLevel::Fatal,
483                             alert_description: AlertDescription::BadCertificate,
484                         }),
485                         Some(Error::ErrClientCertificateNotVerified),
486                     ));
487                 }
488             }
489             ClientAuthType::NoClientCert | ClientAuthType::RequestClientCert => {
490                 return Ok(Box::new(Flight6 {}) as Box<dyn Flight + Send + Sync>);
491             }
492         }
493 
494         Ok(Box::new(Flight6 {}) as Box<dyn Flight + Send + Sync>)
495     }
496 
generate( &self, state: &mut State, _cache: &HandshakeCache, cfg: &HandshakeConfig, ) -> Result<Vec<Packet>, (Option<Alert>, Option<Error>)>497     async fn generate(
498         &self,
499         state: &mut State,
500         _cache: &HandshakeCache,
501         cfg: &HandshakeConfig,
502     ) -> Result<Vec<Packet>, (Option<Alert>, Option<Error>)> {
503         let mut extensions = vec![Extension::RenegotiationInfo(ExtensionRenegotiationInfo {
504             renegotiated_connection: 0,
505         })];
506         if (cfg.extended_master_secret == ExtendedMasterSecretType::Request
507             || cfg.extended_master_secret == ExtendedMasterSecretType::Require)
508             && state.extended_master_secret
509         {
510             extensions.push(Extension::UseExtendedMasterSecret(
511                 ExtensionUseExtendedMasterSecret { supported: true },
512             ));
513         }
514 
515         if state.srtp_protection_profile != SrtpProtectionProfile::Unsupported {
516             extensions.push(Extension::UseSrtp(ExtensionUseSrtp {
517                 protection_profiles: vec![state.srtp_protection_profile],
518             }));
519         }
520 
521         if cfg.local_psk_callback.is_none() {
522             extensions.extend_from_slice(&[
523                 Extension::SupportedEllipticCurves(ExtensionSupportedEllipticCurves {
524                     elliptic_curves: vec![NamedCurve::P256, NamedCurve::X25519, NamedCurve::P384],
525                 }),
526                 Extension::SupportedPointFormats(ExtensionSupportedPointFormats {
527                     point_formats: vec![ELLIPTIC_CURVE_POINT_FORMAT_UNCOMPRESSED],
528                 }),
529             ]);
530         }
531 
532         let mut pkts = vec![Packet {
533             record: RecordLayer::new(
534                 PROTOCOL_VERSION1_2,
535                 0,
536                 Content::Handshake(Handshake::new(HandshakeMessage::ServerHello(
537                     HandshakeMessageServerHello {
538                         version: PROTOCOL_VERSION1_2,
539                         random: state.local_random.clone(),
540                         cipher_suite: {
541                             let cipher_suite = state.cipher_suite.lock().await;
542                             if let Some(cipher_suite) = &*cipher_suite {
543                                 cipher_suite.id()
544                             } else {
545                                 CipherSuiteId::Unsupported
546                             }
547                         },
548                         compression_method: default_compression_methods().ids[0],
549                         extensions,
550                     },
551                 ))),
552             ),
553             should_encrypt: false,
554             reset_local_sequence_number: false,
555         }];
556 
557         if cfg.local_psk_callback.is_none() {
558             let certificate = match cfg.get_certificate(&cfg.server_name) {
559                 Ok(cert) => cert,
560                 Err(err) => {
561                     return Err((
562                         Some(Alert {
563                             alert_level: AlertLevel::Fatal,
564                             alert_description: AlertDescription::HandshakeFailure,
565                         }),
566                         Some(err),
567                     ))
568                 }
569             };
570 
571             pkts.push(Packet {
572                 record: RecordLayer::new(
573                     PROTOCOL_VERSION1_2,
574                     0,
575                     Content::Handshake(Handshake::new(HandshakeMessage::Certificate(
576                         HandshakeMessageCertificate {
577                             certificate: certificate
578                                 .certificate
579                                 .iter()
580                                 .map(|x| x.0.clone())
581                                 .collect(),
582                         },
583                     ))),
584                 ),
585                 should_encrypt: false,
586                 reset_local_sequence_number: false,
587             });
588 
589             let mut server_random = vec![];
590             {
591                 let mut writer = BufWriter::<&mut Vec<u8>>::new(server_random.as_mut());
592                 let _ = state.local_random.marshal(&mut writer);
593             }
594             let mut client_random = vec![];
595             {
596                 let mut writer = BufWriter::<&mut Vec<u8>>::new(client_random.as_mut());
597                 let _ = state.remote_random.marshal(&mut writer);
598             }
599 
600             // Find compatible signature scheme
601             let signature_hash_algo = match select_signature_scheme(
602                 &cfg.local_signature_schemes,
603                 &certificate.private_key,
604             ) {
605                 Ok(s) => s,
606                 Err(err) => {
607                     return Err((
608                         Some(Alert {
609                             alert_level: AlertLevel::Fatal,
610                             alert_description: AlertDescription::InsufficientSecurity,
611                         }),
612                         Some(err),
613                     ))
614                 }
615             };
616 
617             if let Some(local_keypair) = &state.local_keypair {
618                 let signature = match generate_key_signature(
619                     &client_random,
620                     &server_random,
621                     &local_keypair.public_key,
622                     state.named_curve,
623                     &certificate.private_key, /*, signature_hash_algo.hash*/
624                 ) {
625                     Ok(s) => s,
626                     Err(err) => {
627                         return Err((
628                             Some(Alert {
629                                 alert_level: AlertLevel::Fatal,
630                                 alert_description: AlertDescription::InternalError,
631                             }),
632                             Some(err),
633                         ))
634                     }
635                 };
636 
637                 state.local_key_signature = signature;
638 
639                 pkts.push(Packet {
640                     record: RecordLayer::new(
641                         PROTOCOL_VERSION1_2,
642                         0,
643                         Content::Handshake(Handshake::new(HandshakeMessage::ServerKeyExchange(
644                             HandshakeMessageServerKeyExchange {
645                                 identity_hint: vec![],
646                                 elliptic_curve_type: EllipticCurveType::NamedCurve,
647                                 named_curve: state.named_curve,
648                                 public_key: local_keypair.public_key.clone(),
649                                 algorithm: SignatureHashAlgorithm {
650                                     hash: signature_hash_algo.hash,
651                                     signature: signature_hash_algo.signature,
652                                 },
653                                 signature: state.local_key_signature.clone(),
654                             },
655                         ))),
656                     ),
657                     should_encrypt: false,
658                     reset_local_sequence_number: false,
659                 });
660             }
661 
662             if cfg.client_auth as u8 > ClientAuthType::NoClientCert as u8 {
663                 pkts.push(Packet {
664                     record: RecordLayer::new(
665                         PROTOCOL_VERSION1_2,
666                         0,
667                         Content::Handshake(Handshake::new(HandshakeMessage::CertificateRequest(
668                             HandshakeMessageCertificateRequest {
669                                 certificate_types: vec![
670                                     ClientCertificateType::RsaSign,
671                                     ClientCertificateType::EcdsaSign,
672                                 ],
673                                 signature_hash_algorithms: cfg.local_signature_schemes.clone(),
674                             },
675                         ))),
676                     ),
677                     should_encrypt: false,
678                     reset_local_sequence_number: false,
679                 });
680             }
681         } else if let Some(local_psk_identity_hint) = &cfg.local_psk_identity_hint {
682             // To help the client in selecting which identity to use, the server
683             // can provide a "PSK identity hint" in the ServerKeyExchange message.
684             // If no hint is provided, the ServerKeyExchange message is omitted.
685             //
686             // https://tools.ietf.org/html/rfc4279#section-2
687             pkts.push(Packet {
688                 record: RecordLayer::new(
689                     PROTOCOL_VERSION1_2,
690                     0,
691                     Content::Handshake(Handshake::new(HandshakeMessage::ServerKeyExchange(
692                         HandshakeMessageServerKeyExchange {
693                             identity_hint: local_psk_identity_hint.clone(),
694                             elliptic_curve_type: EllipticCurveType::Unsupported,
695                             named_curve: NamedCurve::Unsupported,
696                             public_key: vec![],
697                             algorithm: SignatureHashAlgorithm {
698                                 hash: HashAlgorithm::Unsupported,
699                                 signature: SignatureAlgorithm::Unsupported,
700                             },
701                             signature: vec![],
702                         },
703                     ))),
704                 ),
705                 should_encrypt: false,
706                 reset_local_sequence_number: false,
707             });
708         }
709 
710         pkts.push(Packet {
711             record: RecordLayer::new(
712                 PROTOCOL_VERSION1_2,
713                 0,
714                 Content::Handshake(Handshake::new(HandshakeMessage::ServerHelloDone(
715                     HandshakeMessageServerHelloDone {},
716                 ))),
717             ),
718             should_encrypt: false,
719             reset_local_sequence_number: false,
720         });
721 
722         Ok(pkts)
723     }
724 }
725 
726 #[cfg(test)]
727 mod tests {
728     use super::*;
729     use crate::error::Result;
730     use std::sync::Arc;
731     use tokio::sync::Mutex;
732 
733     struct MockCipherSuite {}
734 
735     impl CipherSuite for MockCipherSuite {
to_string(&self) -> String736         fn to_string(&self) -> String {
737             "MockCipherSuite".into()
738         }
id(&self) -> CipherSuiteId739         fn id(&self) -> CipherSuiteId {
740             unimplemented!();
741         }
certificate_type(&self) -> ClientCertificateType742         fn certificate_type(&self) -> ClientCertificateType {
743             unimplemented!();
744         }
hash_func(&self) -> CipherSuiteHash745         fn hash_func(&self) -> CipherSuiteHash {
746             unimplemented!();
747         }
is_psk(&self) -> bool748         fn is_psk(&self) -> bool {
749             false
750         }
is_initialized(&self) -> bool751         fn is_initialized(&self) -> bool {
752             panic!("is_initialized called with Certificate but not CertificateVerify");
753         }
754 
755         // Generate the internal encryption state
init( &mut self, _master_secret: &[u8], _client_random: &[u8], _server_random: &[u8], _is_client: bool, ) -> Result<()>756         fn init(
757             &mut self,
758             _master_secret: &[u8],
759             _client_random: &[u8],
760             _server_random: &[u8],
761             _is_client: bool,
762         ) -> Result<()> {
763             unimplemented!();
764         }
765 
encrypt(&self, _pkt_rlh: &RecordLayerHeader, _raw: &[u8]) -> Result<Vec<u8>>766         fn encrypt(&self, _pkt_rlh: &RecordLayerHeader, _raw: &[u8]) -> Result<Vec<u8>> {
767             unimplemented!();
768         }
decrypt(&self, _input: &[u8]) -> Result<Vec<u8>>769         fn decrypt(&self, _input: &[u8]) -> Result<Vec<u8>> {
770             unimplemented!();
771         }
772     }
773 
774     // Assert that if a client sends a certificate they must also send a `CertificateVerify`
775     // message. The `Flight4` must not interact with the `cipher_suite` if the `CertificateVerify`
776     // is missing.
777     #[tokio::test]
test_flight4_process_certificateverify()778     async fn test_flight4_process_certificateverify() {
779         let mut state = State {
780             cipher_suite: Arc::new(Mutex::new(Some(Box::new(MockCipherSuite {})))),
781             ..Default::default()
782         };
783 
784         let raw_certificate = vec![
785             0x0b, 0x00, 0x01, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9b, 0x00, 0x01,
786             0x98, 0x00, 0x01, 0x95, 0x30, 0x82, 0x01, 0x91, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03,
787             0x02, 0x01, 0x02, 0x02, 0x11, 0x01, 0x65, 0x03, 0x3f, 0x4d, 0x0b, 0x9a, 0x62, 0x91,
788             0xdb, 0x4d, 0x28, 0x2c, 0x1f, 0xd6, 0x73, 0x32, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86,
789             0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x00, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32,
790             0x30, 0x35, 0x31, 0x35, 0x31, 0x38, 0x34, 0x33, 0x35, 0x35, 0x5a, 0x17, 0x0d, 0x32,
791             0x32, 0x30, 0x36, 0x31, 0x35, 0x31, 0x38, 0x34, 0x33, 0x35, 0x35, 0x5a, 0x30, 0x00,
792             0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06,
793             0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc3,
794             0xb7, 0x13, 0x1a, 0x0a, 0xfc, 0xd0, 0x82, 0xf8, 0x94, 0x5e, 0xc0, 0x77, 0x07, 0x81,
795             0x28, 0xc9, 0xcb, 0x08, 0x84, 0x50, 0x6b, 0xf0, 0x22, 0xe8, 0x79, 0xb9, 0x15, 0x33,
796             0xc4, 0x56, 0xa1, 0xd3, 0x1b, 0x24, 0xe3, 0x61, 0xbd, 0x4d, 0x65, 0x80, 0x6b, 0x5d,
797             0x96, 0x48, 0xa2, 0x44, 0x9e, 0xce, 0xe8, 0x65, 0xd6, 0x3c, 0xe0, 0x9b, 0x6b, 0xa1,
798             0x36, 0x34, 0xb2, 0x39, 0xe2, 0x03, 0x00, 0xa3, 0x81, 0x92, 0x30, 0x81, 0x8f, 0x30,
799             0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x02,
800             0xa4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08,
801             0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
802             0x05, 0x07, 0x03, 0x01, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
803             0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
804             0x04, 0x16, 0x04, 0x14, 0xb1, 0x1a, 0xe3, 0xeb, 0x6f, 0x7c, 0xc3, 0x8f, 0xba, 0x6f,
805             0x1c, 0xe8, 0xf0, 0x23, 0x08, 0x50, 0x8d, 0x3c, 0xea, 0x31, 0x30, 0x2e, 0x06, 0x03,
806             0x55, 0x1d, 0x11, 0x01, 0x01, 0xff, 0x04, 0x24, 0x30, 0x22, 0x82, 0x20, 0x30, 0x30,
807             0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
808             0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
809             0x30, 0x30, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
810             0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x06, 0x31, 0x43, 0xac, 0x03, 0x45, 0x79,
811             0x3c, 0xd7, 0x5f, 0x6e, 0x6a, 0xf8, 0x0e, 0xfd, 0x35, 0x49, 0xee, 0x1b, 0xbc, 0x47,
812             0xce, 0xe3, 0x39, 0xec, 0xe4, 0x62, 0xe1, 0x30, 0x1a, 0xa1, 0x89, 0x02, 0x20, 0x35,
813             0xcd, 0x7a, 0x15, 0x68, 0x09, 0x50, 0x49, 0x9e, 0x3e, 0x05, 0xd7, 0xc2, 0x69, 0x3f,
814             0x9c, 0x0c, 0x98, 0x92, 0x65, 0xec, 0xae, 0x44, 0xfe, 0xe5, 0x68, 0xb8, 0x09, 0x78,
815             0x7f, 0x6b, 0x77,
816         ];
817 
818         let raw_client_key_exchange = vec![
819             0x10, 0x00, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x20, 0x96,
820             0xed, 0x0c, 0xee, 0xf3, 0x11, 0xb1, 0x9d, 0x8b, 0x1c, 0x02, 0x7f, 0x06, 0x7c, 0x57,
821             0x7a, 0x14, 0xa6, 0x41, 0xde, 0x63, 0x57, 0x9e, 0xcd, 0x34, 0x54, 0xba, 0x37, 0x4d,
822             0x34, 0x15, 0x18,
823         ];
824 
825         let mut cache = HandshakeCache::new();
826         cache
827             .push(raw_certificate, 0, 0, HandshakeType::Certificate, true)
828             .await;
829         cache
830             .push(
831                 raw_client_key_exchange,
832                 0,
833                 1,
834                 HandshakeType::ClientKeyExchange,
835                 true,
836             )
837             .await;
838 
839         let cfg = HandshakeConfig::default();
840 
841         let (mut tx, _rx) = mpsc::channel::<mpsc::Sender<()>>(1);
842 
843         let f = Flight4 {};
844         let res = f.parse(&mut tx, &mut state, &cache, &cfg).await;
845         assert!(res.is_err());
846     }
847 }
848