rustls/client/
common.rs

1use crate::hash_hs;
2#[cfg(feature = "logging")]
3use crate::log::trace;
4use crate::msgs::enums::ExtensionType;
5use crate::msgs::enums::NamedGroup;
6use crate::msgs::handshake::CertificatePayload;
7use crate::msgs::handshake::ClientExtension;
8use crate::msgs::handshake::DigitallySignedStruct;
9use crate::msgs::handshake::SCTList;
10use crate::msgs::handshake::ServerExtension;
11use crate::msgs::handshake::SessionID;
12use crate::msgs::persist;
13use crate::session::SessionRandoms;
14use crate::sign;
15use crate::suites;
16use webpki;
17
18use std::mem;
19
20pub struct ServerCertDetails {
21    pub cert_chain: CertificatePayload,
22    pub ocsp_response: Vec<u8>,
23    pub scts: Option<SCTList>,
24}
25
26impl ServerCertDetails {
27    pub fn new() -> ServerCertDetails {
28        ServerCertDetails {
29            cert_chain: Vec::new(),
30            ocsp_response: Vec::new(),
31            scts: None,
32        }
33    }
34
35    pub fn take_chain(&mut self) -> CertificatePayload {
36        mem::replace(&mut self.cert_chain, Vec::new())
37    }
38}
39
40pub struct ServerKXDetails {
41    pub kx_params: Vec<u8>,
42    pub kx_sig: DigitallySignedStruct,
43}
44
45impl ServerKXDetails {
46    pub fn new(params: Vec<u8>, sig: DigitallySignedStruct) -> ServerKXDetails {
47        ServerKXDetails {
48            kx_params: params,
49            kx_sig: sig,
50        }
51    }
52}
53
54pub struct HandshakeDetails {
55    pub resuming_session: Option<persist::ClientSessionValue>,
56    pub transcript: hash_hs::HandshakeHash,
57    pub hash_at_client_recvd_server_hello: Vec<u8>,
58    pub randoms: SessionRandoms,
59    pub using_ems: bool,
60    pub session_id: SessionID,
61    pub sent_tls13_fake_ccs: bool,
62    pub dns_name: webpki::DNSName,
63    pub extra_exts: Vec<ClientExtension>,
64}
65
66impl HandshakeDetails {
67    pub fn new(host_name: webpki::DNSName, extra_exts: Vec<ClientExtension>) -> HandshakeDetails {
68        HandshakeDetails {
69            resuming_session: None,
70            transcript: hash_hs::HandshakeHash::new(),
71            hash_at_client_recvd_server_hello: Vec::new(),
72            randoms: SessionRandoms::for_client(),
73            using_ems: false,
74            session_id: SessionID::empty(),
75            sent_tls13_fake_ccs: false,
76            dns_name: host_name,
77            extra_exts,
78        }
79    }
80}
81
82pub struct ClientHelloDetails {
83    pub sent_extensions: Vec<ExtensionType>,
84    pub offered_key_shares: Vec<suites::KeyExchange>,
85}
86
87impl ClientHelloDetails {
88    pub fn new() -> ClientHelloDetails {
89        ClientHelloDetails {
90            sent_extensions: Vec::new(),
91            offered_key_shares: Vec::new(),
92        }
93    }
94
95    pub fn has_key_share(&self, group: NamedGroup) -> bool {
96        self.offered_key_shares
97            .iter()
98            .any(|share| share.group == group)
99    }
100
101    pub fn find_key_share(&mut self, group: NamedGroup) -> Option<suites::KeyExchange> {
102        self.offered_key_shares
103            .iter()
104            .position(|s| s.group == group)
105            .map(|idx| self.offered_key_shares.remove(idx))
106    }
107
108    pub fn find_key_share_and_discard_others(
109        &mut self,
110        group: NamedGroup,
111    ) -> Option<suites::KeyExchange> {
112        match self.find_key_share(group) {
113            Some(group) => {
114                self.offered_key_shares.clear();
115                Some(group)
116            }
117            None => None,
118        }
119    }
120
121    pub fn server_sent_unsolicited_extensions(
122        &self,
123        received_exts: &[ServerExtension],
124        allowed_unsolicited: &[ExtensionType],
125    ) -> bool {
126        for ext in received_exts {
127            let ext_type = ext.get_type();
128            if !self.sent_extensions.contains(&ext_type) && !allowed_unsolicited.contains(&ext_type)
129            {
130                trace!("Unsolicited extension {:?}", ext_type);
131                return true;
132            }
133        }
134
135        false
136    }
137}
138
139pub struct ReceivedTicketDetails {
140    pub new_ticket: Vec<u8>,
141    pub new_ticket_lifetime: u32,
142}
143
144impl ReceivedTicketDetails {
145    pub fn new() -> ReceivedTicketDetails {
146        ReceivedTicketDetails::from(Vec::new(), 0)
147    }
148
149    pub fn from(ticket: Vec<u8>, lifetime: u32) -> ReceivedTicketDetails {
150        ReceivedTicketDetails {
151            new_ticket: ticket,
152            new_ticket_lifetime: lifetime,
153        }
154    }
155}
156
157pub struct ClientAuthDetails {
158    pub cert: Option<CertificatePayload>,
159    pub signer: Option<Box<dyn sign::Signer>>,
160    pub auth_context: Option<Vec<u8>>,
161}
162
163impl ClientAuthDetails {
164    pub fn new() -> ClientAuthDetails {
165        ClientAuthDetails {
166            cert: None,
167            signer: None,
168            auth_context: None,
169        }
170    }
171}