aranya_internal_rustls/client/
handy.rs1use alloc::vec::Vec;
2
3use pki_types::ServerName;
4
5use crate::crypto::PresharedKey;
6use crate::enums::SignatureScheme;
7use crate::msgs::persist;
8use crate::sync::Arc;
9use crate::{NamedGroup, client, sign};
10
11#[derive(Debug)]
13pub(super) struct NoClientSessionStorage;
14
15impl client::ClientSessionStore for NoClientSessionStorage {
16 fn set_kx_hint(&self, _: ServerName<'static>, _: NamedGroup) {}
17
18 fn kx_hint(&self, _: &ServerName<'_>) -> Option<NamedGroup> {
19 None
20 }
21
22 fn set_tls12_session(&self, _: ServerName<'static>, _: persist::Tls12ClientSessionValue) {}
23
24 fn tls12_session(&self, _: &ServerName<'_>) -> Option<persist::Tls12ClientSessionValue> {
25 None
26 }
27
28 fn remove_tls12_session(&self, _: &ServerName<'_>) {}
29
30 fn insert_tls13_ticket(&self, _: ServerName<'static>, _: persist::Tls13ClientSessionValue) {}
31
32 fn take_tls13_ticket(&self, _: &ServerName<'_>) -> Option<persist::Tls13ClientSessionValue> {
33 None
34 }
35}
36
37#[derive(Debug)]
39pub(super) struct NoPresharedKeys;
40
41impl client::PresharedKeyStore for NoPresharedKeys {
42 fn psks(&self, _server_name: &ServerName<'_>) -> Vec<Arc<PresharedKey>> {
43 Vec::new()
44 }
45}
46
47#[cfg(any(feature = "std", feature = "hashbrown"))]
48mod cache {
49 use alloc::collections::VecDeque;
50 use core::fmt;
51
52 use pki_types::ServerName;
53
54 use crate::lock::Mutex;
55 use crate::msgs::persist;
56 use crate::{NamedGroup, limited_cache};
57
58 const MAX_TLS13_TICKETS_PER_SERVER: usize = 8;
59
60 struct ServerData {
61 kx_hint: Option<NamedGroup>,
62
63 #[cfg(feature = "tls12")]
65 tls12: Option<persist::Tls12ClientSessionValue>,
66
67 tls13: VecDeque<persist::Tls13ClientSessionValue>,
69 }
70
71 impl Default for ServerData {
72 fn default() -> Self {
73 Self {
74 kx_hint: None,
75 #[cfg(feature = "tls12")]
76 tls12: None,
77 tls13: VecDeque::with_capacity(MAX_TLS13_TICKETS_PER_SERVER),
78 }
79 }
80 }
81
82 pub struct ClientSessionMemoryCache {
87 servers: Mutex<limited_cache::LimitedCache<ServerName<'static>, ServerData>>,
88 }
89
90 impl ClientSessionMemoryCache {
91 #[cfg(feature = "std")]
94 pub fn new(size: usize) -> Self {
95 let max_servers = size.saturating_add(MAX_TLS13_TICKETS_PER_SERVER - 1)
96 / MAX_TLS13_TICKETS_PER_SERVER;
97 Self {
98 servers: Mutex::new(limited_cache::LimitedCache::new(max_servers)),
99 }
100 }
101
102 #[cfg(not(feature = "std"))]
105 pub fn new<M: crate::lock::MakeMutex>(size: usize) -> Self {
106 let max_servers = size.saturating_add(MAX_TLS13_TICKETS_PER_SERVER - 1)
107 / MAX_TLS13_TICKETS_PER_SERVER;
108 Self {
109 servers: Mutex::new::<M>(limited_cache::LimitedCache::new(max_servers)),
110 }
111 }
112 }
113
114 impl super::client::ClientSessionStore for ClientSessionMemoryCache {
115 fn set_kx_hint(&self, server_name: ServerName<'static>, group: NamedGroup) {
116 self.servers
117 .lock()
118 .unwrap()
119 .get_or_insert_default_and_edit(server_name, |data| data.kx_hint = Some(group));
120 }
121
122 fn kx_hint(&self, server_name: &ServerName<'_>) -> Option<NamedGroup> {
123 self.servers
124 .lock()
125 .unwrap()
126 .get(server_name)
127 .and_then(|sd| sd.kx_hint)
128 }
129
130 fn set_tls12_session(
131 &self,
132 _server_name: ServerName<'static>,
133 _value: persist::Tls12ClientSessionValue,
134 ) {
135 #[cfg(feature = "tls12")]
136 self.servers
137 .lock()
138 .unwrap()
139 .get_or_insert_default_and_edit(_server_name.clone(), |data| {
140 data.tls12 = Some(_value)
141 });
142 }
143
144 fn tls12_session(
145 &self,
146 _server_name: &ServerName<'_>,
147 ) -> Option<persist::Tls12ClientSessionValue> {
148 #[cfg(not(feature = "tls12"))]
149 return None;
150
151 #[cfg(feature = "tls12")]
152 self.servers
153 .lock()
154 .unwrap()
155 .get(_server_name)
156 .and_then(|sd| sd.tls12.as_ref().cloned())
157 }
158
159 fn remove_tls12_session(&self, _server_name: &ServerName<'static>) {
160 #[cfg(feature = "tls12")]
161 self.servers
162 .lock()
163 .unwrap()
164 .get_mut(_server_name)
165 .and_then(|data| data.tls12.take());
166 }
167
168 fn insert_tls13_ticket(
169 &self,
170 server_name: ServerName<'static>,
171 value: persist::Tls13ClientSessionValue,
172 ) {
173 self.servers
174 .lock()
175 .unwrap()
176 .get_or_insert_default_and_edit(server_name.clone(), |data| {
177 if data.tls13.len() == data.tls13.capacity() {
178 data.tls13.pop_front();
179 }
180 data.tls13.push_back(value);
181 });
182 }
183
184 fn take_tls13_ticket(
185 &self,
186 server_name: &ServerName<'static>,
187 ) -> Option<persist::Tls13ClientSessionValue> {
188 self.servers
189 .lock()
190 .unwrap()
191 .get_mut(server_name)
192 .and_then(|data| data.tls13.pop_back())
193 }
194 }
195
196 impl fmt::Debug for ClientSessionMemoryCache {
197 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 f.debug_struct("ClientSessionMemoryCache")
200 .finish()
201 }
202 }
203}
204
205#[cfg(any(feature = "std", feature = "hashbrown"))]
206pub use cache::ClientSessionMemoryCache;
207
208#[derive(Debug)]
209pub(super) struct FailResolveClientCert {}
210
211impl client::ResolvesClientCert for FailResolveClientCert {
212 fn resolve(
213 &self,
214 _root_hint_subjects: &[&[u8]],
215 _sigschemes: &[SignatureScheme],
216 ) -> Option<Arc<sign::CertifiedKey>> {
217 None
218 }
219
220 fn has_certs(&self) -> bool {
221 false
222 }
223}
224
225#[derive(Clone, Debug)]
230pub struct AlwaysResolvesClientRawPublicKeys(Arc<sign::CertifiedKey>);
231impl AlwaysResolvesClientRawPublicKeys {
232 pub fn new(certified_key: Arc<sign::CertifiedKey>) -> Self {
234 Self(certified_key)
235 }
236}
237
238impl client::ResolvesClientCert for AlwaysResolvesClientRawPublicKeys {
239 fn resolve(
240 &self,
241 _root_hint_subjects: &[&[u8]],
242 _sigschemes: &[SignatureScheme],
243 ) -> Option<Arc<sign::CertifiedKey>> {
244 Some(Arc::clone(&self.0))
245 }
246
247 fn only_raw_public_keys(&self) -> bool {
248 true
249 }
250
251 fn has_certs(&self) -> bool {
256 true
257 }
258}
259
260#[cfg(test)]
261#[macro_rules_attribute::apply(test_for_each_provider)]
262mod tests {
263 use std::prelude::v1::*;
264
265 use pki_types::{ServerName, UnixTime};
266
267 use super::NoClientSessionStorage;
268 use super::provider::cipher_suite;
269 use crate::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
270 use crate::client::{ClientSessionStore, ResolvesClientCert};
271 use crate::msgs::base::PayloadU16;
272 use crate::msgs::enums::NamedGroup;
273 use crate::msgs::handshake::CertificateChain;
274 #[cfg(feature = "tls12")]
275 use crate::msgs::handshake::SessionId;
276 use crate::msgs::persist::Tls13ClientSessionValue;
277 use crate::pki_types::CertificateDer;
278 use crate::suites::SupportedCipherSuite;
279 use crate::sync::Arc;
280 use crate::{DigitallySignedStruct, Error, SignatureScheme, sign};
281
282 #[test]
283 fn test_noclientsessionstorage_does_nothing() {
284 let c = NoClientSessionStorage {};
285 let name = ServerName::try_from("example.com").unwrap();
286 let now = UnixTime::now();
287 let server_cert_verifier: Arc<dyn ServerCertVerifier> = Arc::new(DummyServerCertVerifier);
288 let resolves_client_cert: Arc<dyn ResolvesClientCert> = Arc::new(DummyResolvesClientCert);
289
290 c.set_kx_hint(name.clone(), NamedGroup::X25519);
291 assert_eq!(None, c.kx_hint(&name));
292
293 #[cfg(feature = "tls12")]
294 {
295 use crate::msgs::persist::Tls12ClientSessionValue;
296 let SupportedCipherSuite::Tls12(tls12_suite) =
297 cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
298 else {
299 unreachable!()
300 };
301
302 c.set_tls12_session(
303 name.clone(),
304 Tls12ClientSessionValue::new(
305 tls12_suite,
306 SessionId::empty(),
307 Arc::new(PayloadU16::empty()),
308 &[],
309 CertificateChain::default(),
310 &server_cert_verifier,
311 &resolves_client_cert,
312 now,
313 0,
314 true,
315 ),
316 );
317 assert!(c.tls12_session(&name).is_none());
318 c.remove_tls12_session(&name);
319 }
320
321 let SupportedCipherSuite::Tls13(tls13_suite) = cipher_suite::TLS13_AES_256_GCM_SHA384
322 else {
323 unreachable!();
324 };
325 c.insert_tls13_ticket(
326 name.clone(),
327 Tls13ClientSessionValue::new(
328 tls13_suite,
329 Arc::new(PayloadU16::empty()),
330 &[],
331 CertificateChain::default(),
332 &server_cert_verifier,
333 &resolves_client_cert,
334 now,
335 0,
336 0,
337 0,
338 ),
339 );
340 assert!(c.take_tls13_ticket(&name).is_none());
341 }
342
343 #[derive(Debug)]
344 struct DummyServerCertVerifier;
345
346 impl ServerCertVerifier for DummyServerCertVerifier {
347 #[cfg_attr(coverage_nightly, coverage(off))]
348 fn verify_server_cert(
349 &self,
350 _end_entity: &CertificateDer<'_>,
351 _intermediates: &[CertificateDer<'_>],
352 _server_name: &ServerName<'_>,
353 _ocsp_response: &[u8],
354 _now: UnixTime,
355 ) -> Result<ServerCertVerified, Error> {
356 unreachable!()
357 }
358
359 #[cfg_attr(coverage_nightly, coverage(off))]
360 fn verify_tls12_signature(
361 &self,
362 _message: &[u8],
363 _cert: &CertificateDer<'_>,
364 _dss: &DigitallySignedStruct,
365 ) -> Result<HandshakeSignatureValid, Error> {
366 unreachable!()
367 }
368
369 #[cfg_attr(coverage_nightly, coverage(off))]
370 fn verify_tls13_signature(
371 &self,
372 _message: &[u8],
373 _cert: &CertificateDer<'_>,
374 _dss: &DigitallySignedStruct,
375 ) -> Result<HandshakeSignatureValid, Error> {
376 unreachable!()
377 }
378
379 #[cfg_attr(coverage_nightly, coverage(off))]
380 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
381 unreachable!()
382 }
383 }
384
385 #[derive(Debug)]
386 struct DummyResolvesClientCert;
387
388 impl ResolvesClientCert for DummyResolvesClientCert {
389 #[cfg_attr(coverage_nightly, coverage(off))]
390 fn resolve(
391 &self,
392 _root_hint_subjects: &[&[u8]],
393 _sigschemes: &[SignatureScheme],
394 ) -> Option<Arc<sign::CertifiedKey>> {
395 unreachable!()
396 }
397
398 #[cfg_attr(coverage_nightly, coverage(off))]
399 fn has_certs(&self) -> bool {
400 unreachable!()
401 }
402 }
403}