1use alloc::vec::Vec;
2use core::fmt::Debug;
3
4use crate::server::ClientHello;
5use crate::sync::Arc;
6use crate::{server, sign};
7
8#[derive(Debug)]
10pub struct NoServerSessionStorage {}
11
12impl server::StoresServerSessions for NoServerSessionStorage {
13 fn put(&self, _id: Vec<u8>, _sec: Vec<u8>) -> bool {
14 false
15 }
16 fn get(&self, _id: &[u8]) -> Option<Vec<u8>> {
17 None
18 }
19 fn take(&self, _id: &[u8]) -> Option<Vec<u8>> {
20 None
21 }
22 fn can_cache(&self) -> bool {
23 false
24 }
25}
26
27#[cfg(any(feature = "std", feature = "hashbrown"))]
28mod cache {
29 use alloc::vec::Vec;
30 use core::fmt::{Debug, Formatter};
31
32 use crate::lock::Mutex;
33 use crate::sync::Arc;
34 use crate::{limited_cache, server};
35
36 pub struct ServerSessionMemoryCache {
40 cache: Mutex<limited_cache::LimitedCache<Vec<u8>, Vec<u8>>>,
41 }
42
43 impl ServerSessionMemoryCache {
44 #[cfg(feature = "std")]
48 pub fn new(size: usize) -> Arc<Self> {
49 Arc::new(Self {
50 cache: Mutex::new(limited_cache::LimitedCache::new(size)),
51 })
52 }
53
54 #[cfg(not(feature = "std"))]
58 pub fn new<M: crate::lock::MakeMutex>(size: usize) -> Arc<Self> {
59 Arc::new(Self {
60 cache: Mutex::new::<M>(limited_cache::LimitedCache::new(size)),
61 })
62 }
63 }
64
65 impl server::StoresServerSessions for ServerSessionMemoryCache {
66 fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool {
67 self.cache
68 .lock()
69 .unwrap()
70 .insert(key, value);
71 true
72 }
73
74 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
75 self.cache
76 .lock()
77 .unwrap()
78 .get(key)
79 .cloned()
80 }
81
82 fn take(&self, key: &[u8]) -> Option<Vec<u8>> {
83 self.cache.lock().unwrap().remove(key)
84 }
85
86 fn can_cache(&self) -> bool {
87 true
88 }
89 }
90
91 impl Debug for ServerSessionMemoryCache {
92 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
93 f.debug_struct("ServerSessionMemoryCache")
94 .finish()
95 }
96 }
97
98 #[cfg(test)]
99 mod tests {
100 use std::vec;
101
102 use super::*;
103 use crate::server::StoresServerSessions;
104
105 #[test]
106 fn test_serversessionmemorycache_accepts_put() {
107 let c = ServerSessionMemoryCache::new(4);
108 assert!(c.put(vec![0x01], vec![0x02]));
109 }
110
111 #[test]
112 fn test_serversessionmemorycache_persists_put() {
113 let c = ServerSessionMemoryCache::new(4);
114 assert!(c.put(vec![0x01], vec![0x02]));
115 assert_eq!(c.get(&[0x01]), Some(vec![0x02]));
116 assert_eq!(c.get(&[0x01]), Some(vec![0x02]));
117 }
118
119 #[test]
120 fn test_serversessionmemorycache_overwrites_put() {
121 let c = ServerSessionMemoryCache::new(4);
122 assert!(c.put(vec![0x01], vec![0x02]));
123 assert!(c.put(vec![0x01], vec![0x04]));
124 assert_eq!(c.get(&[0x01]), Some(vec![0x04]));
125 }
126
127 #[test]
130 fn test_serversessionmemorycache_drops_to_maintain_size_invariant() {
131 let c = ServerSessionMemoryCache::new(2);
132 assert!(c.put(vec![0x01], vec![0x02]));
133 assert!(c.put(vec![0x03], vec![0x04]));
134 assert!(c.put(vec![0x05], vec![0x06]));
135 assert!(c.put(vec![0x07], vec![0x08]));
136 assert!(c.put(vec![0x09], vec![0x0a]));
137
138 assert_eq!(c.get(&[0x01]), None);
139 assert_eq!(c.get(&[0x03]), None);
140 assert_eq!(c.get(&[0x05]), None);
141 assert_eq!(c.get(&[0x07]), Some(vec![0x08]));
142 assert_eq!(c.get(&[0x09]), Some(vec![0x0a]));
143 }
144
145 #[test]
148 fn test_serversessionmemorycache_size_one_retains_session() {
149 let c = ServerSessionMemoryCache::new(1);
150 assert!(c.put(vec![0x01], vec![0x02]));
151 assert_eq!(c.get(&[0x01]), Some(vec![0x02]));
152
153 assert!(c.put(vec![0x03], vec![0x04]));
154 assert_eq!(c.get(&[0x01]), None);
155 assert_eq!(c.get(&[0x03]), Some(vec![0x04]));
156 }
157 }
158}
159
160#[cfg(any(feature = "std", feature = "hashbrown"))]
161pub use cache::ServerSessionMemoryCache;
162
163#[derive(Debug)]
165pub(super) struct NeverProducesTickets {}
166
167impl server::ProducesTickets for NeverProducesTickets {
168 fn enabled(&self) -> bool {
169 false
170 }
171 fn lifetime(&self) -> u32 {
172 0
173 }
174 fn encrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
175 None
176 }
177 fn decrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
178 None
179 }
180}
181
182#[derive(Clone, Debug)]
187pub struct AlwaysResolvesServerRawPublicKeys(Arc<sign::CertifiedKey>);
188
189impl AlwaysResolvesServerRawPublicKeys {
190 pub fn new(certified_key: Arc<sign::CertifiedKey>) -> Self {
192 Self(certified_key)
193 }
194}
195
196impl server::ResolvesServerCert for AlwaysResolvesServerRawPublicKeys {
197 fn resolve(&self, _client_hello: ClientHello<'_>) -> Option<Arc<sign::CertifiedKey>> {
198 Some(self.0.clone())
199 }
200
201 fn only_raw_public_keys(&self) -> bool {
202 true
203 }
204}
205
206#[cfg(any(feature = "std", feature = "hashbrown"))]
207mod sni_resolver {
208 use alloc::string::{String, ToString};
209 use core::fmt::Debug;
210
211 use pki_types::{DnsName, ServerName};
212
213 use crate::error::Error;
214 use crate::hash_map::HashMap;
215 use crate::server::ClientHello;
216 use crate::sync::Arc;
217 use crate::webpki::{ParsedCertificate, verify_server_name};
218 use crate::{server, sign};
219
220 #[derive(Debug)]
223 pub struct ResolvesServerCertUsingSni {
224 by_name: HashMap<String, Arc<sign::CertifiedKey>>,
225 }
226
227 impl ResolvesServerCertUsingSni {
228 pub fn new() -> Self {
230 Self {
231 by_name: HashMap::new(),
232 }
233 }
234
235 pub fn add(&mut self, name: &str, ck: sign::CertifiedKey) -> Result<(), Error> {
241 let server_name = {
242 let checked_name = DnsName::try_from(name)
243 .map_err(|_| Error::General("Bad DNS name".into()))
244 .map(|name| name.to_lowercase_owned())?;
245 ServerName::DnsName(checked_name)
246 };
247
248 ck.end_entity_cert()
258 .and_then(ParsedCertificate::try_from)
259 .and_then(|cert| verify_server_name(&cert, &server_name))?;
260
261 if let ServerName::DnsName(name) = server_name {
262 self.by_name
263 .insert(name.as_ref().to_string(), Arc::new(ck));
264 }
265 Ok(())
266 }
267 }
268
269 impl server::ResolvesServerCert for ResolvesServerCertUsingSni {
270 fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<sign::CertifiedKey>> {
271 if let Some(name) = client_hello.server_name() {
272 self.by_name.get(name).cloned()
273 } else {
274 None
276 }
277 }
278 }
279
280 #[cfg(test)]
281 mod tests {
282 use super::*;
283 use crate::server::ResolvesServerCert;
284
285 #[test]
286 fn test_resolvesservercertusingsni_requires_sni() {
287 let rscsni = ResolvesServerCertUsingSni::new();
288 assert!(
289 rscsni
290 .resolve(ClientHello {
291 server_name: &None,
292 signature_schemes: &[],
293 alpn: None,
294 server_cert_types: None,
295 client_cert_types: None,
296 cipher_suites: &[],
297 certificate_authorities: None,
298 named_groups: None,
299 })
300 .is_none()
301 );
302 }
303
304 #[test]
305 fn test_resolvesservercertusingsni_handles_unknown_name() {
306 let rscsni = ResolvesServerCertUsingSni::new();
307 let name = DnsName::try_from("hello.com")
308 .unwrap()
309 .to_owned();
310 assert!(
311 rscsni
312 .resolve(ClientHello {
313 server_name: &Some(name),
314 signature_schemes: &[],
315 alpn: None,
316 server_cert_types: None,
317 client_cert_types: None,
318 cipher_suites: &[],
319 certificate_authorities: None,
320 named_groups: None,
321 })
322 .is_none()
323 );
324 }
325 }
326}
327
328#[cfg(any(feature = "std", feature = "hashbrown"))]
329pub use sni_resolver::ResolvesServerCertUsingSni;
330
331#[cfg(test)]
332mod tests {
333 use std::vec;
334
335 use super::*;
336 use crate::server::{ProducesTickets, StoresServerSessions};
337
338 #[test]
339 fn test_noserversessionstorage_drops_put() {
340 let c = NoServerSessionStorage {};
341 assert!(!c.put(vec![0x01], vec![0x02]));
342 }
343
344 #[test]
345 fn test_noserversessionstorage_denies_gets() {
346 let c = NoServerSessionStorage {};
347 c.put(vec![0x01], vec![0x02]);
348 assert_eq!(c.get(&[]), None);
349 assert_eq!(c.get(&[0x01]), None);
350 assert_eq!(c.get(&[0x02]), None);
351 }
352
353 #[test]
354 fn test_noserversessionstorage_denies_takes() {
355 let c = NoServerSessionStorage {};
356 assert_eq!(c.take(&[]), None);
357 assert_eq!(c.take(&[0x01]), None);
358 assert_eq!(c.take(&[0x02]), None);
359 }
360
361 #[test]
362 fn test_neverproducestickets_does_nothing() {
363 let npt = NeverProducesTickets {};
364 assert!(!npt.enabled());
365 assert_eq!(0, npt.lifetime());
366 assert_eq!(None, npt.encrypt(&[]));
367 assert_eq!(None, npt.decrypt(&[]));
368 }
369}