rustls/server/
handy.rs
1use crate::dns_name::DnsNameRef;
2use crate::error::Error;
3use crate::key;
4use crate::limited_cache;
5use crate::server;
6use crate::server::ClientHello;
7use crate::sign;
8
9use std::collections;
10use std::sync::{Arc, Mutex};
11
12pub struct NoServerSessionStorage {}
14
15impl server::StoresServerSessions for NoServerSessionStorage {
16 fn put(&self, _id: Vec<u8>, _sec: Vec<u8>) -> bool {
17 false
18 }
19 fn get(&self, _id: &[u8]) -> Option<Vec<u8>> {
20 None
21 }
22 fn take(&self, _id: &[u8]) -> Option<Vec<u8>> {
23 None
24 }
25 fn can_cache(&self) -> bool {
26 false
27 }
28}
29
30pub struct ServerSessionMemoryCache {
34 cache: Mutex<limited_cache::LimitedCache<Vec<u8>, Vec<u8>>>,
35}
36
37impl ServerSessionMemoryCache {
38 pub fn new(size: usize) -> Arc<Self> {
42 Arc::new(Self {
43 cache: Mutex::new(limited_cache::LimitedCache::new(size)),
44 })
45 }
46}
47
48impl server::StoresServerSessions for ServerSessionMemoryCache {
49 fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool {
50 self.cache
51 .lock()
52 .unwrap()
53 .insert(key, value);
54 true
55 }
56
57 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
58 self.cache
59 .lock()
60 .unwrap()
61 .get(key)
62 .cloned()
63 }
64
65 fn take(&self, key: &[u8]) -> Option<Vec<u8>> {
66 self.cache.lock().unwrap().remove(key)
67 }
68
69 fn can_cache(&self) -> bool {
70 true
71 }
72}
73
74pub(super) struct NeverProducesTickets {}
76
77impl server::ProducesTickets for NeverProducesTickets {
78 fn enabled(&self) -> bool {
79 false
80 }
81 fn lifetime(&self) -> u32 {
82 0
83 }
84 fn encrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
85 None
86 }
87 fn decrypt(&self, _bytes: &[u8]) -> Option<Vec<u8>> {
88 None
89 }
90}
91
92pub(super) struct AlwaysResolvesChain(Arc<sign::CertifiedKey>);
94
95impl AlwaysResolvesChain {
96 pub(super) fn new(
99 chain: Vec<key::Certificate>,
100 priv_key: &key::PrivateKey,
101 ) -> Result<Self, Error> {
102 let key = sign::any_supported_type(priv_key)
103 .map_err(|_| Error::General("invalid private key".into()))?;
104 Ok(Self(Arc::new(sign::CertifiedKey::new(chain, key))))
105 }
106
107 pub(super) fn new_with_extras(
112 chain: Vec<key::Certificate>,
113 priv_key: &key::PrivateKey,
114 ocsp: Vec<u8>,
115 scts: Vec<u8>,
116 ) -> Result<Self, Error> {
117 let mut r = Self::new(chain, priv_key)?;
118
119 {
120 let cert = Arc::make_mut(&mut r.0);
121 if !ocsp.is_empty() {
122 cert.ocsp = Some(ocsp);
123 }
124 if !scts.is_empty() {
125 cert.sct_list = Some(scts);
126 }
127 }
128
129 Ok(r)
130 }
131}
132
133impl server::ResolvesServerCert for AlwaysResolvesChain {
134 fn resolve(&self, _client_hello: ClientHello) -> Option<Arc<sign::CertifiedKey>> {
135 Some(Arc::clone(&self.0))
136 }
137}
138
139pub struct ResolvesServerCertUsingSni {
142 by_name: collections::HashMap<String, Arc<sign::CertifiedKey>>,
143}
144
145impl ResolvesServerCertUsingSni {
146 pub fn new() -> Self {
148 Self {
149 by_name: collections::HashMap::new(),
150 }
151 }
152
153 pub fn add(&mut self, name: &str, ck: sign::CertifiedKey) -> Result<(), Error> {
159 let checked_name = DnsNameRef::try_from(name)
160 .map_err(|_| Error::General("Bad DNS name".into()))
161 .map(|dns| dns.to_lowercase_owned())?;
162
163 let end_entity_cert = ck.end_entity_cert().map_err(|_| {
174 Error::General("No end-entity certificate in certificate chain".to_string())
175 })?;
176
177 let end_entity_cert =
179 webpki::EndEntityCert::try_from(end_entity_cert.as_ref()).map_err(|_| {
180 Error::General(
181 "End-entity certificate in certificate chain is syntactically invalid"
182 .to_string(),
183 )
184 })?;
185
186 let general_error =
190 || Error::General("The server certificate is not valid for the given name".to_string());
191
192 let name = webpki::DnsNameRef::try_from_ascii(checked_name.as_ref().as_bytes())
193 .map_err(|_| general_error())?;
194
195 end_entity_cert
196 .verify_is_valid_for_subject_name(webpki::SubjectNameRef::DnsName(name))
197 .map_err(|_| general_error())?;
198
199 let as_str: &str = checked_name.as_ref();
200 self.by_name
201 .insert(as_str.to_string(), Arc::new(ck));
202 Ok(())
203 }
204}
205
206impl server::ResolvesServerCert for ResolvesServerCertUsingSni {
207 fn resolve(&self, client_hello: ClientHello) -> Option<Arc<sign::CertifiedKey>> {
208 if let Some(name) = client_hello.server_name() {
209 self.by_name.get(name).cloned()
210 } else {
211 None
213 }
214 }
215}
216
217#[cfg(test)]
218mod test {
219 use super::*;
220 use crate::server::ProducesTickets;
221 use crate::server::ResolvesServerCert;
222 use crate::server::StoresServerSessions;
223
224 #[test]
225 fn test_noserversessionstorage_drops_put() {
226 let c = NoServerSessionStorage {};
227 assert!(!c.put(vec![0x01], vec![0x02]));
228 }
229
230 #[test]
231 fn test_noserversessionstorage_denies_gets() {
232 let c = NoServerSessionStorage {};
233 c.put(vec![0x01], vec![0x02]);
234 assert_eq!(c.get(&[]), None);
235 assert_eq!(c.get(&[0x01]), None);
236 assert_eq!(c.get(&[0x02]), None);
237 }
238
239 #[test]
240 fn test_noserversessionstorage_denies_takes() {
241 let c = NoServerSessionStorage {};
242 assert_eq!(c.take(&[]), None);
243 assert_eq!(c.take(&[0x01]), None);
244 assert_eq!(c.take(&[0x02]), None);
245 }
246
247 #[test]
248 fn test_serversessionmemorycache_accepts_put() {
249 let c = ServerSessionMemoryCache::new(4);
250 assert!(c.put(vec![0x01], vec![0x02]));
251 }
252
253 #[test]
254 fn test_serversessionmemorycache_persists_put() {
255 let c = ServerSessionMemoryCache::new(4);
256 assert!(c.put(vec![0x01], vec![0x02]));
257 assert_eq!(c.get(&[0x01]), Some(vec![0x02]));
258 assert_eq!(c.get(&[0x01]), Some(vec![0x02]));
259 }
260
261 #[test]
262 fn test_serversessionmemorycache_overwrites_put() {
263 let c = ServerSessionMemoryCache::new(4);
264 assert!(c.put(vec![0x01], vec![0x02]));
265 assert!(c.put(vec![0x01], vec![0x04]));
266 assert_eq!(c.get(&[0x01]), Some(vec![0x04]));
267 }
268
269 #[test]
270 fn test_serversessionmemorycache_drops_to_maintain_size_invariant() {
271 let c = ServerSessionMemoryCache::new(2);
272 assert!(c.put(vec![0x01], vec![0x02]));
273 assert!(c.put(vec![0x03], vec![0x04]));
274 assert!(c.put(vec![0x05], vec![0x06]));
275 assert!(c.put(vec![0x07], vec![0x08]));
276 assert!(c.put(vec![0x09], vec![0x0a]));
277
278 let count = c.get(&[0x01]).iter().count()
279 + c.get(&[0x03]).iter().count()
280 + c.get(&[0x05]).iter().count()
281 + c.get(&[0x07]).iter().count()
282 + c.get(&[0x09]).iter().count();
283
284 assert!(count < 5);
285 }
286
287 #[test]
288 fn test_neverproducestickets_does_nothing() {
289 let npt = NeverProducesTickets {};
290 assert!(!npt.enabled());
291 assert_eq!(0, npt.lifetime());
292 assert_eq!(None, npt.encrypt(&[]));
293 assert_eq!(None, npt.decrypt(&[]));
294 }
295
296 #[test]
297 fn test_resolvesservercertusingsni_requires_sni() {
298 let rscsni = ResolvesServerCertUsingSni::new();
299 assert!(rscsni
300 .resolve(ClientHello::new(&None, &[], None, &[]))
301 .is_none());
302 }
303
304 #[test]
305 fn test_resolvesservercertusingsni_handles_unknown_name() {
306 let rscsni = ResolvesServerCertUsingSni::new();
307 let name = DnsNameRef::try_from("hello.com")
308 .unwrap()
309 .to_owned();
310 assert!(rscsni
311 .resolve(ClientHello::new(&Some(name), &[], None, &[]))
312 .is_none());
313 }
314}