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]
128 fn test_serversessionmemorycache_drops_to_maintain_size_invariant() {
129 let c = ServerSessionMemoryCache::new(2);
130 assert!(c.put(vec![0x01], vec![0x02]));
131 assert!(c.put(vec![0x03], vec![0x04]));
132 assert!(c.put(vec![0x05], vec![0x06]));
133 assert!(c.put(vec![0x07], vec![0x08]));
134 assert!(c.put(vec![0x09], vec![0x0a]));
135
136 let count = c.get(&[0x01]).iter().count()
137 + c.get(&[0x03]).iter().count()
138 + c.get(&[0x05]).iter().count()
139 + c.get(&[0x07]).iter().count()
140 + c.get(&[0x09]).iter().count();
141
142 assert!(count < 5);
143 }
144 }
145}
146
147#[cfg(any(feature = "std", feature = "hashbrown"))]
148pub use cache::ServerSessionMemoryCache;
149
150#[derive(Debug)]
152pub(super) struct NeverProducesTickets {}
153
154impl server::ProducesTickets for NeverProducesTickets {
155 fn enabled(&self) -> bool {
156 false
157 }
158 fn lifetime(&self) -> u32 {
159 0
160 }
161 fn encrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
162 None
163 }
164 fn decrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
165 None
166 }
167}
168
169#[derive(Clone, Debug)]
174pub struct AlwaysResolvesServerRawPublicKeys(Arc<sign::CertifiedKey>);
175
176impl AlwaysResolvesServerRawPublicKeys {
177 pub fn new(certified_key: Arc<sign::CertifiedKey>) -> Self {
179 Self(certified_key)
180 }
181}
182
183impl server::ResolvesServerCert for AlwaysResolvesServerRawPublicKeys {
184 fn resolve(&self, _client_hello: ClientHello<'_>) -> Option<Arc<sign::CertifiedKey>> {
185 Some(Arc::clone(&self.0))
186 }
187
188 fn only_raw_public_keys(&self) -> bool {
189 true
190 }
191}
192
193#[cfg(any(feature = "std", feature = "hashbrown"))]
194mod sni_resolver {
195 use alloc::string::{String, ToString};
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<String, 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: &str, ck: sign::CertifiedKey) -> Result<(), Error> {
228 let server_name = {
229 let checked_name = DnsName::try_from(name)
230 .map_err(|_| Error::General("Bad DNS name".into()))
231 .map(|name| name.to_lowercase_owned())?;
232 ServerName::DnsName(checked_name)
233 };
234
235 ck.end_entity_cert()
245 .and_then(ParsedCertificate::try_from)
246 .and_then(|cert| verify_server_name(&cert, &server_name))?;
247
248 if let ServerName::DnsName(name) = server_name {
249 self.by_name
250 .insert(name.as_ref().to_string(), Arc::new(ck));
251 }
252 Ok(())
253 }
254 }
255
256 impl server::ResolvesServerCert for ResolvesServerCertUsingSni {
257 fn resolve(&self, client_hello: ClientHello<'_>) -> Option<Arc<sign::CertifiedKey>> {
258 if let Some(name) = client_hello.server_name() {
259 self.by_name.get(name).cloned()
260 } else {
261 None
263 }
264 }
265 }
266
267 #[cfg(test)]
268 mod tests {
269 use super::*;
270 use crate::server::ResolvesServerCert;
271
272 #[test]
273 fn test_resolvesservercertusingsni_requires_sni() {
274 let rscsni = ResolvesServerCertUsingSni::new();
275 assert!(
276 rscsni
277 .resolve(ClientHello {
278 server_name: &None,
279 signature_schemes: &[],
280 alpn: None,
281 server_cert_types: None,
282 client_cert_types: None,
283 cipher_suites: &[],
284 certificate_authorities: None,
285 })
286 .is_none()
287 );
288 }
289
290 #[test]
291 fn test_resolvesservercertusingsni_handles_unknown_name() {
292 let rscsni = ResolvesServerCertUsingSni::new();
293 let name = DnsName::try_from("hello.com")
294 .unwrap()
295 .to_owned();
296 assert!(
297 rscsni
298 .resolve(ClientHello {
299 server_name: &Some(name),
300 signature_schemes: &[],
301 alpn: None,
302 server_cert_types: None,
303 client_cert_types: None,
304 cipher_suites: &[],
305 certificate_authorities: None,
306 })
307 .is_none()
308 );
309 }
310 }
311}
312
313#[cfg(any(feature = "std", feature = "hashbrown"))]
314pub use sni_resolver::ResolvesServerCertUsingSni;
315
316#[cfg(test)]
317mod tests {
318 use std::vec;
319
320 use super::*;
321 use crate::server::{ProducesTickets, StoresServerSessions};
322
323 #[test]
324 fn test_noserversessionstorage_drops_put() {
325 let c = NoServerSessionStorage {};
326 assert!(!c.put(vec![0x01], vec![0x02]));
327 }
328
329 #[test]
330 fn test_noserversessionstorage_denies_gets() {
331 let c = NoServerSessionStorage {};
332 c.put(vec![0x01], vec![0x02]);
333 assert_eq!(c.get(&[]), None);
334 assert_eq!(c.get(&[0x01]), None);
335 assert_eq!(c.get(&[0x02]), None);
336 }
337
338 #[test]
339 fn test_noserversessionstorage_denies_takes() {
340 let c = NoServerSessionStorage {};
341 assert_eq!(c.take(&[]), None);
342 assert_eq!(c.take(&[0x01]), None);
343 assert_eq!(c.take(&[0x02]), None);
344 }
345
346 #[test]
347 fn test_neverproducestickets_does_nothing() {
348 let npt = NeverProducesTickets {};
349 assert!(!npt.enabled());
350 assert_eq!(0, npt.lifetime());
351 assert_eq!(None, npt.encrypt(&[]));
352 assert_eq!(None, npt.decrypt(&[]));
353 }
354}