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