Skip to main content

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!(
453            data.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
464    /// Expect chain verification to succeed even when a trusted CA is provided
465    /// among the intermediate certs. webpki handles such cases properly.
466    #[rstest]
467    #[case::tlsnotary(tlsnotary())]
468    #[case::appliedzkp(appliedzkp())]
469    fn test_verify_cert_chain_success_ca_explicit(
470        verifier: &ServerCertVerifier,
471        #[case] data: ConnectionFixture,
472    ) {
473        assert!(
474            data.server_cert_data
475                .verify(
476                    verifier,
477                    data.connection_info.time,
478                    data.server_ephemeral_key(),
479                    &data.server_name,
480                )
481                .is_ok()
482        );
483    }
484
485    /// Expect to fail since the end entity cert was not valid at the time.
486    #[rstest]
487    #[case::tlsnotary(tlsnotary())]
488    #[case::appliedzkp(appliedzkp())]
489    fn test_verify_cert_chain_fail_bad_time(
490        verifier: &ServerCertVerifier,
491        #[case] data: ConnectionFixture,
492    ) {
493        // unix time when the cert chain was NOT valid
494        let bad_time: u64 = 1571465711;
495
496        let err = data.server_cert_data.verify(
497            verifier,
498            bad_time,
499            data.server_ephemeral_key(),
500            &data.server_name,
501        );
502
503        assert!(matches!(
504            err.unwrap_err(),
505            HandshakeVerificationError::ServerCert(_)
506        ));
507    }
508
509    /// Expect to fail when no intermediate cert provided.
510    #[rstest]
511    #[case::tlsnotary(tlsnotary())]
512    #[case::appliedzkp(appliedzkp())]
513    fn test_verify_cert_chain_fail_no_interm_cert(
514        verifier: &ServerCertVerifier,
515        #[case] mut data: ConnectionFixture,
516    ) {
517        // Remove the CA cert
518        data.server_cert_data.certs.pop();
519        // Remove the intermediate cert
520        data.server_cert_data.certs.pop();
521
522        let err = data.server_cert_data.verify(
523            verifier,
524            data.connection_info.time,
525            data.server_ephemeral_key(),
526            &data.server_name,
527        );
528
529        assert!(matches!(
530            err.unwrap_err(),
531            HandshakeVerificationError::ServerCert(_)
532        ));
533    }
534
535    /// Expect to fail when no intermediate cert provided even if a trusted CA
536    /// cert is provided.
537    #[rstest]
538    #[case::tlsnotary(tlsnotary())]
539    #[case::appliedzkp(appliedzkp())]
540    fn test_verify_cert_chain_fail_no_interm_cert_with_ca_cert(
541        verifier: &ServerCertVerifier,
542        #[case] mut data: ConnectionFixture,
543    ) {
544        // Remove the intermediate cert
545        data.server_cert_data.certs.remove(1);
546
547        let err = data.server_cert_data.verify(
548            verifier,
549            data.connection_info.time,
550            data.server_ephemeral_key(),
551            &data.server_name,
552        );
553
554        assert!(matches!(
555            err.unwrap_err(),
556            HandshakeVerificationError::ServerCert(_)
557        ));
558    }
559
560    /// Expect to fail because end-entity cert is wrong.
561    #[rstest]
562    #[case::tlsnotary(tlsnotary())]
563    #[case::appliedzkp(appliedzkp())]
564    fn test_verify_cert_chain_fail_bad_ee_cert(
565        verifier: &ServerCertVerifier,
566        #[case] mut data: ConnectionFixture,
567    ) {
568        let ee: &[u8] = include_bytes!("./fixtures/data/unknown/ee.der");
569
570        // Change the end entity cert
571        data.server_cert_data.certs[0] = CertificateDer(ee.to_vec());
572
573        let err = data.server_cert_data.verify(
574            verifier,
575            data.connection_info.time,
576            data.server_ephemeral_key(),
577            &data.server_name,
578        );
579
580        assert!(matches!(
581            err.unwrap_err(),
582            HandshakeVerificationError::ServerCert(_)
583        ));
584    }
585
586    /// Expect sig verification to fail because client_random is wrong.
587    #[rstest]
588    #[case::tlsnotary(tlsnotary())]
589    #[case::appliedzkp(appliedzkp())]
590    fn test_verify_sig_ke_params_fail_bad_client_random(
591        verifier: &ServerCertVerifier,
592        #[case] mut data: ConnectionFixture,
593    ) {
594        let CertBinding::V1_2(CertBindingV1_2 { client_random, .. }) =
595            &mut data.server_cert_data.binding;
596        client_random[31] = client_random[31].wrapping_add(1);
597
598        let err = data.server_cert_data.verify(
599            verifier,
600            data.connection_info.time,
601            data.server_ephemeral_key(),
602            &data.server_name,
603        );
604
605        assert!(matches!(
606            err.unwrap_err(),
607            HandshakeVerificationError::InvalidServerSignature
608        ));
609    }
610
611    /// Expect sig verification to fail because the sig is wrong.
612    #[rstest]
613    #[case::tlsnotary(tlsnotary())]
614    #[case::appliedzkp(appliedzkp())]
615    fn test_verify_sig_ke_params_fail_bad_sig(
616        verifier: &ServerCertVerifier,
617        #[case] mut data: ConnectionFixture,
618    ) {
619        data.server_cert_data.sig.sig[31] = data.server_cert_data.sig.sig[31].wrapping_add(1);
620
621        let err = data.server_cert_data.verify(
622            verifier,
623            data.connection_info.time,
624            data.server_ephemeral_key(),
625            &data.server_name,
626        );
627
628        assert!(matches!(
629            err.unwrap_err(),
630            HandshakeVerificationError::InvalidServerSignature
631        ));
632    }
633
634    /// Expect to fail because the dns name is not in the cert.
635    #[rstest]
636    #[case::tlsnotary(tlsnotary())]
637    #[case::appliedzkp(appliedzkp())]
638    fn test_check_dns_name_present_in_cert_fail_bad_host(
639        verifier: &ServerCertVerifier,
640        #[case] data: ConnectionFixture,
641    ) {
642        let bad_name = ServerName::Dns(DnsName::try_from("badhost.com").unwrap());
643
644        let err = data.server_cert_data.verify(
645            verifier,
646            data.connection_info.time,
647            data.server_ephemeral_key(),
648            &bad_name,
649        );
650
651        assert!(matches!(
652            err.unwrap_err(),
653            HandshakeVerificationError::ServerCert(_)
654        ));
655    }
656
657    /// Expect to fail because the ephemeral key provided is wrong.
658    #[rstest]
659    #[case::tlsnotary(tlsnotary())]
660    #[case::appliedzkp(appliedzkp())]
661    fn test_invalid_ephemeral_key(verifier: &ServerCertVerifier, #[case] data: ConnectionFixture) {
662        let wrong_ephemeral_key = ServerEphemKey {
663            typ: KeyType::SECP256R1,
664            key: Vec::<u8>::from_hex(include_bytes!("./fixtures/data/unknown/pubkey")).unwrap(),
665        };
666
667        let err = data.server_cert_data.verify(
668            verifier,
669            data.connection_info.time,
670            &wrong_ephemeral_key,
671            &data.server_name,
672        );
673
674        assert!(matches!(
675            err.unwrap_err(),
676            HandshakeVerificationError::InvalidServerEphemeralKey
677        ));
678    }
679
680    /// Expect to fail when no cert provided.
681    #[rstest]
682    #[case::tlsnotary(tlsnotary())]
683    #[case::appliedzkp(appliedzkp())]
684    fn test_verify_cert_chain_fail_no_cert(
685        verifier: &ServerCertVerifier,
686        #[case] mut data: ConnectionFixture,
687    ) {
688        // Empty certs
689        data.server_cert_data.certs = Vec::new();
690
691        let err = data.server_cert_data.verify(
692            verifier,
693            data.connection_info.time,
694            data.server_ephemeral_key(),
695            &data.server_name,
696        );
697
698        assert!(matches!(
699            err.unwrap_err(),
700            HandshakeVerificationError::MissingCerts
701        ));
702    }
703}