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}