Coverage Report

Created: 2026-01-15 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/src/client/common.rs
Line
Count
Source
1
use alloc::boxed::Box;
2
use alloc::vec::Vec;
3
4
use super::ResolvesClientCert;
5
use crate::log::{debug, trace};
6
use crate::msgs::enums::ExtensionType;
7
use crate::msgs::handshake::{CertificateChain, DistinguishedName, ProtocolName, ServerExtensions};
8
use crate::sync::Arc;
9
use crate::{SignatureScheme, compress, sign};
10
11
#[derive(Debug)]
12
pub(super) struct ServerCertDetails<'a> {
13
    pub(super) cert_chain: CertificateChain<'a>,
14
    pub(super) ocsp_response: Vec<u8>,
15
}
16
17
impl<'a> ServerCertDetails<'a> {
18
0
    pub(super) fn new(cert_chain: CertificateChain<'a>, ocsp_response: Vec<u8>) -> Self {
19
0
        Self {
20
0
            cert_chain,
21
0
            ocsp_response,
22
0
        }
23
0
    }
24
25
0
    pub(super) fn into_owned(self) -> ServerCertDetails<'static> {
26
0
        let Self {
27
0
            cert_chain,
28
0
            ocsp_response,
29
0
        } = self;
30
0
        ServerCertDetails {
31
0
            cert_chain: cert_chain.into_owned(),
32
0
            ocsp_response,
33
0
        }
34
0
    }
35
}
36
37
pub(super) struct ClientHelloDetails {
38
    pub(super) alpn_protocols: Vec<ProtocolName>,
39
    pub(super) sent_extensions: Vec<ExtensionType>,
40
    pub(super) extension_order_seed: u16,
41
    pub(super) offered_cert_compression: bool,
42
}
43
44
impl ClientHelloDetails {
45
0
    pub(super) fn new(alpn_protocols: Vec<ProtocolName>, extension_order_seed: u16) -> Self {
46
0
        Self {
47
0
            alpn_protocols,
48
0
            sent_extensions: Vec::new(),
49
0
            extension_order_seed,
50
0
            offered_cert_compression: false,
51
0
        }
52
0
    }
53
54
0
    pub(super) fn server_sent_unsolicited_extensions(
55
0
        &self,
56
0
        received_exts: &ServerExtensions<'_>,
57
0
        allowed_unsolicited: &[ExtensionType],
58
0
    ) -> bool {
59
0
        let mut extensions = received_exts.collect_used();
60
0
        extensions.extend(
61
0
            received_exts
62
0
                .unknown_extensions
63
0
                .iter()
64
0
                .map(|ext| ExtensionType::from(*ext)),
65
        );
66
0
        for ext_type in extensions {
67
0
            if !self.sent_extensions.contains(&ext_type) && !allowed_unsolicited.contains(&ext_type)
68
            {
69
0
                trace!("Unsolicited extension {ext_type:?}");
70
0
                return true;
71
0
            }
72
        }
73
74
0
        false
75
0
    }
76
}
77
78
pub(super) enum ClientAuthDetails {
79
    /// Send an empty `Certificate` and no `CertificateVerify`.
80
    Empty { auth_context_tls13: Option<Vec<u8>> },
81
    /// Send a non-empty `Certificate` and a `CertificateVerify`.
82
    Verify {
83
        certkey: Arc<sign::CertifiedKey>,
84
        signer: Box<dyn sign::Signer>,
85
        auth_context_tls13: Option<Vec<u8>>,
86
        compressor: Option<&'static dyn compress::CertCompressor>,
87
    },
88
}
89
90
impl ClientAuthDetails {
91
0
    pub(super) fn resolve(
92
0
        resolver: &dyn ResolvesClientCert,
93
0
        canames: Option<&[DistinguishedName]>,
94
0
        sigschemes: &[SignatureScheme],
95
0
        auth_context_tls13: Option<Vec<u8>>,
96
0
        compressor: Option<&'static dyn compress::CertCompressor>,
97
0
    ) -> Self {
98
0
        let acceptable_issuers = canames
99
0
            .unwrap_or_default()
100
0
            .iter()
101
0
            .map(|p| p.as_ref())
102
0
            .collect::<Vec<&[u8]>>();
103
104
0
        if let Some(certkey) = resolver.resolve(&acceptable_issuers, sigschemes) {
105
0
            if let Some(signer) = certkey.key.choose_scheme(sigschemes) {
106
0
                debug!("Attempting client auth");
107
0
                return Self::Verify {
108
0
                    certkey,
109
0
                    signer,
110
0
                    auth_context_tls13,
111
0
                    compressor,
112
0
                };
113
0
            }
114
0
        }
115
116
0
        debug!("Client auth requested but no cert/sigscheme available");
117
0
        Self::Empty { auth_context_tls13 }
118
0
    }
119
}