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