tlsn_core/
connection.rs

1//! TLS connection types.
2
3use std::fmt;
4
5use rustls_pki_types as webpki_types;
6use serde::{Deserialize, Serialize};
7use tls_core::msgs::{codec::Codec, enums::NamedGroup, handshake::ServerECDHParams};
8
9use crate::webpki::{CertificateDer, ServerCertVerifier, ServerCertVerifierError};
10
11/// TLS version.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[serde(rename_all = "snake_case")]
14pub enum TlsVersion {
15    /// TLS 1.2.
16    V1_2,
17    /// TLS 1.3.
18    V1_3,
19}
20
21impl TryFrom<tls_core::msgs::enums::ProtocolVersion> for TlsVersion {
22    type Error = &'static str;
23
24    fn try_from(value: tls_core::msgs::enums::ProtocolVersion) -> Result<Self, Self::Error> {
25        Ok(match value {
26            tls_core::msgs::enums::ProtocolVersion::TLSv1_2 => TlsVersion::V1_2,
27            tls_core::msgs::enums::ProtocolVersion::TLSv1_3 => TlsVersion::V1_3,
28            _ => return Err("unsupported TLS version"),
29        })
30    }
31}
32
33/// Server's name.
34#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35pub enum ServerName {
36    /// DNS name.
37    Dns(DnsName),
38}
39
40impl ServerName {
41    pub(crate) fn to_webpki(&self) -> webpki_types::ServerName<'static> {
42        match self {
43            ServerName::Dns(name) => webpki_types::ServerName::DnsName(
44                webpki_types::DnsName::try_from(name.0.as_str())
45                    .expect("name was validated")
46                    .to_owned(),
47            ),
48        }
49    }
50}
51
52impl fmt::Display for ServerName {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            ServerName::Dns(name) => write!(f, "{name}"),
56        }
57    }
58}
59
60/// DNS name.
61#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
62#[serde(try_from = "String")]
63pub struct DnsName(String);
64
65impl DnsName {
66    /// Returns the DNS name as a string.
67    pub fn as_str(&self) -> &str {
68        self.0.as_str()
69    }
70}
71
72impl fmt::Display for DnsName {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "{}", self.0)
75    }
76}
77
78impl AsRef<str> for DnsName {
79    fn as_ref(&self) -> &str {
80        &self.0
81    }
82}
83
84/// Error returned when a DNS name is invalid.
85#[derive(Debug, thiserror::Error)]
86#[error("invalid DNS name")]
87pub struct InvalidDnsNameError {}
88
89impl TryFrom<&str> for DnsName {
90    type Error = InvalidDnsNameError;
91
92    fn try_from(value: &str) -> Result<Self, Self::Error> {
93        // Borrow validation from rustls
94        match webpki_types::DnsName::try_from_str(value) {
95            Ok(_) => Ok(DnsName(value.to_string())),
96            Err(_) => Err(InvalidDnsNameError {}),
97        }
98    }
99}
100
101impl TryFrom<String> for DnsName {
102    type Error = InvalidDnsNameError;
103
104    fn try_from(value: String) -> Result<Self, Self::Error> {
105        Self::try_from(value.as_str())
106    }
107}
108
109/// Type of a public key.
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
111#[serde(rename_all = "lowercase")]
112#[non_exhaustive]
113#[allow(non_camel_case_types)]
114pub enum KeyType {
115    /// secp256r1.
116    SECP256R1 = 0x0017,
117}
118
119/// Signature algorithm used on the key exchange parameters.
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
121#[serde(rename_all = "lowercase")]
122#[allow(non_camel_case_types, missing_docs)]
123pub enum SignatureAlgorithm {
124    ECDSA_NISTP256_SHA256,
125    ECDSA_NISTP256_SHA384,
126    ECDSA_NISTP384_SHA256,
127    ECDSA_NISTP384_SHA384,
128    ED25519,
129    RSA_PKCS1_2048_8192_SHA256,
130    RSA_PKCS1_2048_8192_SHA384,
131    RSA_PKCS1_2048_8192_SHA512,
132    RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
133    RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
134    RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
135}
136
137impl fmt::Display for SignatureAlgorithm {
138    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139        match self {
140            SignatureAlgorithm::ECDSA_NISTP256_SHA256 => write!(f, "ECDSA_NISTP256_SHA256"),
141            SignatureAlgorithm::ECDSA_NISTP256_SHA384 => write!(f, "ECDSA_NISTP256_SHA384"),
142            SignatureAlgorithm::ECDSA_NISTP384_SHA256 => write!(f, "ECDSA_NISTP384_SHA256"),
143            SignatureAlgorithm::ECDSA_NISTP384_SHA384 => write!(f, "ECDSA_NISTP384_SHA384"),
144            SignatureAlgorithm::ED25519 => write!(f, "ED25519"),
145            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA256 => {
146                write!(f, "RSA_PKCS1_2048_8192_SHA256")
147            }
148            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA384 => {
149                write!(f, "RSA_PKCS1_2048_8192_SHA384")
150            }
151            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA512 => {
152                write!(f, "RSA_PKCS1_2048_8192_SHA512")
153            }
154            SignatureAlgorithm::RSA_PSS_2048_8192_SHA256_LEGACY_KEY => {
155                write!(f, "RSA_PSS_2048_8192_SHA256_LEGACY_KEY")
156            }
157            SignatureAlgorithm::RSA_PSS_2048_8192_SHA384_LEGACY_KEY => {
158                write!(f, "RSA_PSS_2048_8192_SHA384_LEGACY_KEY")
159            }
160            SignatureAlgorithm::RSA_PSS_2048_8192_SHA512_LEGACY_KEY => {
161                write!(f, "RSA_PSS_2048_8192_SHA512_LEGACY_KEY")
162            }
163        }
164    }
165}
166
167impl From<tls_core::verify::SignatureAlgorithm> for SignatureAlgorithm {
168    fn from(value: tls_core::verify::SignatureAlgorithm) -> Self {
169        use tls_core::verify::SignatureAlgorithm as Core;
170        match value {
171            Core::ECDSA_NISTP256_SHA256 => SignatureAlgorithm::ECDSA_NISTP256_SHA256,
172            Core::ECDSA_NISTP256_SHA384 => SignatureAlgorithm::ECDSA_NISTP256_SHA384,
173            Core::ECDSA_NISTP384_SHA256 => SignatureAlgorithm::ECDSA_NISTP384_SHA256,
174            Core::ECDSA_NISTP384_SHA384 => SignatureAlgorithm::ECDSA_NISTP384_SHA384,
175            Core::ED25519 => SignatureAlgorithm::ED25519,
176            Core::RSA_PKCS1_2048_8192_SHA256 => SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA256,
177            Core::RSA_PKCS1_2048_8192_SHA384 => SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA384,
178            Core::RSA_PKCS1_2048_8192_SHA512 => SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA512,
179            Core::RSA_PSS_2048_8192_SHA256_LEGACY_KEY => {
180                SignatureAlgorithm::RSA_PSS_2048_8192_SHA256_LEGACY_KEY
181            }
182            Core::RSA_PSS_2048_8192_SHA384_LEGACY_KEY => {
183                SignatureAlgorithm::RSA_PSS_2048_8192_SHA384_LEGACY_KEY
184            }
185            Core::RSA_PSS_2048_8192_SHA512_LEGACY_KEY => {
186                SignatureAlgorithm::RSA_PSS_2048_8192_SHA512_LEGACY_KEY
187            }
188        }
189    }
190}
191
192/// Server's signature of the key exchange parameters.
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct ServerSignature {
195    /// Signature algorithm.
196    pub alg: SignatureAlgorithm,
197    /// Signature data.
198    pub sig: Vec<u8>,
199}
200
201/// Server's ephemeral public key.
202#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
203pub struct ServerEphemKey {
204    /// Type of the public key.
205    #[serde(rename = "type")]
206    pub typ: KeyType,
207    /// Public key data.
208    pub key: Vec<u8>,
209}
210
211impl ServerEphemKey {
212    /// Encodes the key exchange parameters as in TLS.
213    pub(crate) fn kx_params(&self) -> Vec<u8> {
214        let group = match self.typ {
215            KeyType::SECP256R1 => NamedGroup::secp256r1,
216        };
217
218        let mut kx_params = Vec::new();
219        ServerECDHParams::new(group, &self.key).encode(&mut kx_params);
220
221        kx_params
222    }
223}
224
225impl TryFrom<tls_core::key::PublicKey> for ServerEphemKey {
226    type Error = &'static str;
227
228    fn try_from(value: tls_core::key::PublicKey) -> Result<Self, Self::Error> {
229        let tls_core::msgs::enums::NamedGroup::secp256r1 = value.group else {
230            return Err("unsupported key type");
231        };
232
233        Ok(ServerEphemKey {
234            typ: KeyType::SECP256R1,
235            key: value.key,
236        })
237    }
238}
239
240/// TLS session information.
241#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
242pub struct ConnectionInfo {
243    /// UNIX time when the TLS connection started.
244    pub time: u64,
245    /// TLS version used in the connection.
246    pub version: TlsVersion,
247    /// Transcript length.
248    pub transcript_length: TranscriptLength,
249}
250
251/// Transcript length information.
252#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
253pub struct TranscriptLength {
254    /// Number of bytes sent by the Prover to the Server.
255    pub sent: u32,
256    /// Number of bytes received by the Prover from the Server.
257    pub received: u32,
258}
259
260/// TLS 1.2 certificate binding.
261#[derive(Debug, Clone, Serialize, Deserialize)]
262pub struct CertBindingV1_2 {
263    /// Client random.
264    pub client_random: [u8; 32],
265    /// Server random.
266    pub server_random: [u8; 32],
267    /// Server's ephemeral public key.
268    pub server_ephemeral_key: ServerEphemKey,
269}
270
271/// TLS certificate binding.
272///
273/// This is the data that the server signs using its public key in the
274/// certificate it presents during the TLS handshake. This provides a binding
275/// between the server's identity and the ephemeral keys used to authenticate
276/// the TLS session.
277#[derive(Debug, Clone, Serialize, Deserialize)]
278#[serde(rename_all = "snake_case")]
279#[non_exhaustive]
280pub enum CertBinding {
281    /// TLS 1.2 certificate binding.
282    V1_2(CertBindingV1_2),
283}
284
285/// Verify data from the TLS handshake finished messages.
286#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct VerifyData {
288    /// Client finished verify data.
289    pub client_finished: Vec<u8>,
290    /// Server finished verify data.
291    pub server_finished: Vec<u8>,
292}
293
294/// TLS handshake data.
295#[derive(Debug, Clone, Serialize, Deserialize)]
296pub struct HandshakeData {
297    /// Server certificate chain.
298    pub certs: Vec<CertificateDer>,
299    /// Server certificate signature over the binding message.
300    pub sig: ServerSignature,
301    /// Certificate binding.
302    pub binding: CertBinding,
303}
304
305impl HandshakeData {
306    /// Verifies the handshake data.
307    ///
308    /// # Arguments
309    ///
310    /// * `verifier` - Cerificate verifier.
311    /// * `time` - The time of the connection.
312    /// * `server_ephemeral_key` - The server's ephemeral key.
313    /// * `server_name` - The server name.
314    pub fn verify(
315        &self,
316        verifier: &ServerCertVerifier,
317        time: u64,
318        server_ephemeral_key: &ServerEphemKey,
319        server_name: &ServerName,
320    ) -> Result<(), HandshakeVerificationError> {
321        #[allow(irrefutable_let_patterns)]
322        let CertBinding::V1_2(CertBindingV1_2 {
323            client_random,
324            server_random,
325            server_ephemeral_key: expected_server_ephemeral_key,
326        }) = &self.binding
327        else {
328            unreachable!("only TLS 1.2 is implemented")
329        };
330
331        if server_ephemeral_key != expected_server_ephemeral_key {
332            return Err(HandshakeVerificationError::InvalidServerEphemeralKey);
333        }
334
335        let (end_entity, intermediates) = self
336            .certs
337            .split_first()
338            .ok_or(HandshakeVerificationError::MissingCerts)?;
339
340        // Verify the end entity cert is valid for the provided server name
341        // and that it chains to at least one of the roots we trust.
342        verifier
343            .verify_server_cert(end_entity, intermediates, server_name, time)
344            .map_err(HandshakeVerificationError::ServerCert)?;
345
346        // Verify the signature matches the certificate and key exchange parameters.
347        let mut message = Vec::new();
348        message.extend_from_slice(client_random);
349        message.extend_from_slice(server_random);
350        message.extend_from_slice(&server_ephemeral_key.kx_params());
351
352        use webpki::ring as alg;
353        let sig_alg = match self.sig.alg {
354            SignatureAlgorithm::ECDSA_NISTP256_SHA256 => alg::ECDSA_P256_SHA256,
355            SignatureAlgorithm::ECDSA_NISTP256_SHA384 => alg::ECDSA_P256_SHA384,
356            SignatureAlgorithm::ECDSA_NISTP384_SHA256 => alg::ECDSA_P384_SHA256,
357            SignatureAlgorithm::ECDSA_NISTP384_SHA384 => alg::ECDSA_P384_SHA384,
358            SignatureAlgorithm::ED25519 => alg::ED25519,
359            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA256 => alg::RSA_PKCS1_2048_8192_SHA256,
360            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA384 => alg::RSA_PKCS1_2048_8192_SHA384,
361            SignatureAlgorithm::RSA_PKCS1_2048_8192_SHA512 => alg::RSA_PKCS1_2048_8192_SHA512,
362            SignatureAlgorithm::RSA_PSS_2048_8192_SHA256_LEGACY_KEY => {
363                alg::RSA_PSS_2048_8192_SHA256_LEGACY_KEY
364            }
365            SignatureAlgorithm::RSA_PSS_2048_8192_SHA384_LEGACY_KEY => {
366                alg::RSA_PSS_2048_8192_SHA384_LEGACY_KEY
367            }
368            SignatureAlgorithm::RSA_PSS_2048_8192_SHA512_LEGACY_KEY => {
369                alg::RSA_PSS_2048_8192_SHA512_LEGACY_KEY
370            }
371        };
372
373        let end_entity = webpki_types::CertificateDer::from(end_entity.0.as_slice());
374        let end_entity = webpki::EndEntityCert::try_from(&end_entity)
375            .map_err(|_| HandshakeVerificationError::InvalidEndEntityCertificate)?;
376
377        end_entity
378            .verify_signature(sig_alg, &message, &self.sig.sig)
379            .map_err(|_| HandshakeVerificationError::InvalidServerSignature)?;
380
381        Ok(())
382    }
383}
384
385/// Errors that can occur when verifying a certificate chain or signature.
386#[derive(Debug, thiserror::Error)]
387#[allow(missing_docs)]
388pub enum HandshakeVerificationError {
389    #[error("invalid end entity certificate")]
390    InvalidEndEntityCertificate,
391    #[error("missing server certificates")]
392    MissingCerts,
393    #[error("invalid server signature")]
394    InvalidServerSignature,
395    #[error("invalid server ephemeral key")]
396    InvalidServerEphemeralKey,
397    #[error("server certificate verification failed: {0}")]
398    ServerCert(ServerCertVerifierError),
399}
400
401#[cfg(test)]
402mod tests {
403    use super::*;
404    use crate::{fixtures::ConnectionFixture, transcript::Transcript, webpki::RootCertStore};
405
406    use hex::FromHex;
407    use rstest::*;
408    use tlsn_data_fixtures::http::{request::GET_WITH_HEADER, response::OK_JSON};
409
410    #[fixture]
411    #[once]
412    fn verifier() -> ServerCertVerifier {
413        let mut root_store = RootCertStore {
414            roots: webpki_root_certs::TLS_SERVER_ROOT_CERTS
415                .iter()
416                .map(|c| CertificateDer(c.to_vec()))
417                .collect(),
418        };
419
420        // Add a cert which is no longer included in the Mozilla root store.
421        root_store.roots.push(
422            appliedzkp()
423                .server_cert_data
424                .certs
425                .last()
426                .expect("chain is valid")
427                .clone(),
428        );
429
430        ServerCertVerifier::new(&root_store).unwrap()
431    }
432
433    fn tlsnotary() -> ConnectionFixture {
434        ConnectionFixture::tlsnotary(Transcript::new(GET_WITH_HEADER, OK_JSON).length())
435    }
436
437    fn appliedzkp() -> ConnectionFixture {
438        ConnectionFixture::appliedzkp(Transcript::new(GET_WITH_HEADER, OK_JSON).length())
439    }
440
441    /// Expect chain verification to succeed.
442    #[rstest]
443    #[case::tlsnotary(tlsnotary())]
444    #[case::appliedzkp(appliedzkp())]
445    fn test_verify_cert_chain_sucess_ca_implicit(
446        verifier: &ServerCertVerifier,
447        #[case] mut data: ConnectionFixture,
448    ) {
449        // Remove the CA cert
450        data.server_cert_data.certs.pop();
451
452        assert!(data
453            .server_cert_data
454            .verify(
455                verifier,
456                data.connection_info.time,
457                data.server_ephemeral_key(),
458                &data.server_name,
459            )
460            .is_ok());
461    }
462
463    /// Expect chain verification to succeed even when a trusted CA is provided
464    /// among the intermediate certs. webpki handles such cases properly.
465    #[rstest]
466    #[case::tlsnotary(tlsnotary())]
467    #[case::appliedzkp(appliedzkp())]
468    fn test_verify_cert_chain_success_ca_explicit(
469        verifier: &ServerCertVerifier,
470        #[case] data: ConnectionFixture,
471    ) {
472        assert!(data
473            .server_cert_data
474            .verify(
475                verifier,
476                data.connection_info.time,
477                data.server_ephemeral_key(),
478                &data.server_name,
479            )
480            .is_ok());
481    }
482
483    /// Expect to fail since the end entity cert was not valid at the time.
484    #[rstest]
485    #[case::tlsnotary(tlsnotary())]
486    #[case::appliedzkp(appliedzkp())]
487    fn test_verify_cert_chain_fail_bad_time(
488        verifier: &ServerCertVerifier,
489        #[case] data: ConnectionFixture,
490    ) {
491        // unix time when the cert chain was NOT valid
492        let bad_time: u64 = 1571465711;
493
494        let err = data.server_cert_data.verify(
495            verifier,
496            bad_time,
497            data.server_ephemeral_key(),
498            &data.server_name,
499        );
500
501        assert!(matches!(
502            err.unwrap_err(),
503            HandshakeVerificationError::ServerCert(_)
504        ));
505    }
506
507    /// Expect to fail when no intermediate cert provided.
508    #[rstest]
509    #[case::tlsnotary(tlsnotary())]
510    #[case::appliedzkp(appliedzkp())]
511    fn test_verify_cert_chain_fail_no_interm_cert(
512        verifier: &ServerCertVerifier,
513        #[case] mut data: ConnectionFixture,
514    ) {
515        // Remove the CA cert
516        data.server_cert_data.certs.pop();
517        // Remove the intermediate cert
518        data.server_cert_data.certs.pop();
519
520        let err = data.server_cert_data.verify(
521            verifier,
522            data.connection_info.time,
523            data.server_ephemeral_key(),
524            &data.server_name,
525        );
526
527        assert!(matches!(
528            err.unwrap_err(),
529            HandshakeVerificationError::ServerCert(_)
530        ));
531    }
532
533    /// Expect to fail when no intermediate cert provided even if a trusted CA
534    /// cert is provided.
535    #[rstest]
536    #[case::tlsnotary(tlsnotary())]
537    #[case::appliedzkp(appliedzkp())]
538    fn test_verify_cert_chain_fail_no_interm_cert_with_ca_cert(
539        verifier: &ServerCertVerifier,
540        #[case] mut data: ConnectionFixture,
541    ) {
542        // Remove the intermediate cert
543        data.server_cert_data.certs.remove(1);
544
545        let err = data.server_cert_data.verify(
546            verifier,
547            data.connection_info.time,
548            data.server_ephemeral_key(),
549            &data.server_name,
550        );
551
552        assert!(matches!(
553            err.unwrap_err(),
554            HandshakeVerificationError::ServerCert(_)
555        ));
556    }
557
558    /// Expect to fail because end-entity cert is wrong.
559    #[rstest]
560    #[case::tlsnotary(tlsnotary())]
561    #[case::appliedzkp(appliedzkp())]
562    fn test_verify_cert_chain_fail_bad_ee_cert(
563        verifier: &ServerCertVerifier,
564        #[case] mut data: ConnectionFixture,
565    ) {
566        let ee: &[u8] = include_bytes!("./fixtures/data/unknown/ee.der");
567
568        // Change the end entity cert
569        data.server_cert_data.certs[0] = CertificateDer(ee.to_vec());
570
571        let err = data.server_cert_data.verify(
572            verifier,
573            data.connection_info.time,
574            data.server_ephemeral_key(),
575            &data.server_name,
576        );
577
578        assert!(matches!(
579            err.unwrap_err(),
580            HandshakeVerificationError::ServerCert(_)
581        ));
582    }
583
584    /// Expect sig verification to fail because client_random is wrong.
585    #[rstest]
586    #[case::tlsnotary(tlsnotary())]
587    #[case::appliedzkp(appliedzkp())]
588    fn test_verify_sig_ke_params_fail_bad_client_random(
589        verifier: &ServerCertVerifier,
590        #[case] mut data: ConnectionFixture,
591    ) {
592        let CertBinding::V1_2(CertBindingV1_2 { client_random, .. }) =
593            &mut data.server_cert_data.binding;
594        client_random[31] = client_random[31].wrapping_add(1);
595
596        let err = data.server_cert_data.verify(
597            verifier,
598            data.connection_info.time,
599            data.server_ephemeral_key(),
600            &data.server_name,
601        );
602
603        assert!(matches!(
604            err.unwrap_err(),
605            HandshakeVerificationError::InvalidServerSignature
606        ));
607    }
608
609    /// Expect sig verification to fail because the sig is wrong.
610    #[rstest]
611    #[case::tlsnotary(tlsnotary())]
612    #[case::appliedzkp(appliedzkp())]
613    fn test_verify_sig_ke_params_fail_bad_sig(
614        verifier: &ServerCertVerifier,
615        #[case] mut data: ConnectionFixture,
616    ) {
617        data.server_cert_data.sig.sig[31] = data.server_cert_data.sig.sig[31].wrapping_add(1);
618
619        let err = data.server_cert_data.verify(
620            verifier,
621            data.connection_info.time,
622            data.server_ephemeral_key(),
623            &data.server_name,
624        );
625
626        assert!(matches!(
627            err.unwrap_err(),
628            HandshakeVerificationError::InvalidServerSignature
629        ));
630    }
631
632    /// Expect to fail because the dns name is not in the cert.
633    #[rstest]
634    #[case::tlsnotary(tlsnotary())]
635    #[case::appliedzkp(appliedzkp())]
636    fn test_check_dns_name_present_in_cert_fail_bad_host(
637        verifier: &ServerCertVerifier,
638        #[case] data: ConnectionFixture,
639    ) {
640        let bad_name = ServerName::Dns(DnsName::try_from("badhost.com").unwrap());
641
642        let err = data.server_cert_data.verify(
643            verifier,
644            data.connection_info.time,
645            data.server_ephemeral_key(),
646            &bad_name,
647        );
648
649        assert!(matches!(
650            err.unwrap_err(),
651            HandshakeVerificationError::ServerCert(_)
652        ));
653    }
654
655    /// Expect to fail because the ephemeral key provided is wrong.
656    #[rstest]
657    #[case::tlsnotary(tlsnotary())]
658    #[case::appliedzkp(appliedzkp())]
659    fn test_invalid_ephemeral_key(verifier: &ServerCertVerifier, #[case] data: ConnectionFixture) {
660        let wrong_ephemeral_key = ServerEphemKey {
661            typ: KeyType::SECP256R1,
662            key: Vec::<u8>::from_hex(include_bytes!("./fixtures/data/unknown/pubkey")).unwrap(),
663        };
664
665        let err = data.server_cert_data.verify(
666            verifier,
667            data.connection_info.time,
668            &wrong_ephemeral_key,
669            &data.server_name,
670        );
671
672        assert!(matches!(
673            err.unwrap_err(),
674            HandshakeVerificationError::InvalidServerEphemeralKey
675        ));
676    }
677
678    /// Expect to fail when no cert provided.
679    #[rstest]
680    #[case::tlsnotary(tlsnotary())]
681    #[case::appliedzkp(appliedzkp())]
682    fn test_verify_cert_chain_fail_no_cert(
683        verifier: &ServerCertVerifier,
684        #[case] mut data: ConnectionFixture,
685    ) {
686        // Empty certs
687        data.server_cert_data.certs = Vec::new();
688
689        let err = data.server_cert_data.verify(
690            verifier,
691            data.connection_info.time,
692            data.server_ephemeral_key(),
693            &data.server_name,
694        );
695
696        assert!(matches!(
697            err.unwrap_err(),
698            HandshakeVerificationError::MissingCerts
699        ));
700    }
701}