1 use crate::anonymized_dns::*;
2 use crate::config::*;
3 use crate::crypto::*;
4 use crate::dnscrypt::*;
5 use crate::globals::*;
6 
7 use byteorder::{BigEndian, ByteOrder};
8 use clockpro_cache::ClockProCache;
9 use parking_lot::Mutex;
10 use rand::prelude::*;
11 use std::mem;
12 use std::slice;
13 use std::sync::Arc;
14 use std::time::SystemTime;
15 
16 pub const DNSCRYPT_CERTS_TTL: u32 = 86400;
17 pub const DNSCRYPT_CERTS_RENEWAL: u32 = 28800;
18 
now() -> u3219 fn now() -> u32 {
20     SystemTime::now()
21         .duration_since(SystemTime::UNIX_EPOCH)
22         .expect("The clock is completely off")
23         .as_secs() as _
24 }
25 
26 #[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
27 #[repr(C, packed)]
28 pub struct DNSCryptCertInner {
29     resolver_pk: [u8; 32],
30     client_magic: [u8; 8],
31     serial: [u8; 4],
32     ts_start: [u8; 4],
33     ts_end: [u8; 4],
34 }
35 
36 impl DNSCryptCertInner {
as_bytes(&self) -> &[u8]37     pub fn as_bytes(&self) -> &[u8] {
38         unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of_val(self)) }
39     }
40 }
41 
42 big_array! { BigArray; 64 }
43 
44 #[derive(Derivative, Serialize, Deserialize)]
45 #[derivative(Debug, Default, Clone)]
46 #[repr(C, packed)]
47 pub struct DNSCryptCert {
48     cert_magic: [u8; 4],
49     es_version: [u8; 2],
50     minor_version: [u8; 2],
51     #[derivative(Debug = "ignore", Default(value = "[0u8; 64]"))]
52     #[serde(with = "BigArray")]
53     signature: [u8; 64],
54     inner: DNSCryptCertInner,
55 }
56 
57 impl DNSCryptCert {
new(provider_kp: &SignKeyPair, resolver_kp: &CryptKeyPair, ts_start: u32) -> Self58     pub fn new(provider_kp: &SignKeyPair, resolver_kp: &CryptKeyPair, ts_start: u32) -> Self {
59         let ts_end = ts_start + DNSCRYPT_CERTS_TTL;
60 
61         let mut dnscrypt_cert = DNSCryptCert::default();
62 
63         let dnscrypt_cert_inner = &mut dnscrypt_cert.inner;
64         dnscrypt_cert_inner
65             .resolver_pk
66             .copy_from_slice(resolver_kp.pk.as_bytes());
67         dnscrypt_cert_inner
68             .client_magic
69             .copy_from_slice(&dnscrypt_cert_inner.resolver_pk[..8]);
70         BigEndian::write_u32(&mut dnscrypt_cert_inner.serial, 1);
71         BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_start, ts_start);
72         BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_end, ts_end);
73 
74         BigEndian::write_u32(&mut dnscrypt_cert.cert_magic, 0x44_4e_53_43);
75         BigEndian::write_u16(&mut dnscrypt_cert.es_version, 2);
76         BigEndian::write_u16(&mut dnscrypt_cert.minor_version, 0);
77 
78         dnscrypt_cert.signature.copy_from_slice(
79             provider_kp
80                 .sk
81                 .sign(dnscrypt_cert_inner.as_bytes())
82                 .as_bytes(),
83         );
84         dnscrypt_cert
85     }
86 
as_bytes(&self) -> &[u8]87     pub fn as_bytes(&self) -> &[u8] {
88         unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of_val(self)) }
89     }
90 
client_magic(&self) -> &[u8]91     pub fn client_magic(&self) -> &[u8] {
92         &self.inner.client_magic
93     }
94 
ts_start(&self) -> u3295     pub fn ts_start(&self) -> u32 {
96         BigEndian::read_u32(&self.inner.ts_start)
97     }
98 
ts_end(&self) -> u3299     pub fn ts_end(&self) -> u32 {
100         BigEndian::read_u32(&self.inner.ts_end)
101     }
102 }
103 
104 #[derive(Serialize, Deserialize, Clone, Derivative)]
105 #[derivative(Debug)]
106 pub struct DNSCryptEncryptionParams {
107     dnscrypt_cert: DNSCryptCert,
108     resolver_kp: CryptKeyPair,
109     #[serde(skip)]
110     #[derivative(Debug = "ignore")]
111     pub cache: Option<Arc<Mutex<ClockProCache<[u8; DNSCRYPT_QUERY_PK_SIZE], SharedKey>>>>,
112 }
113 
114 impl DNSCryptEncryptionParams {
new( provider_kp: &SignKeyPair, cache_capacity: usize, previous_params: Option<Arc<DNSCryptEncryptionParams>>, ) -> Vec<Self>115     pub fn new(
116         provider_kp: &SignKeyPair,
117         cache_capacity: usize,
118         previous_params: Option<Arc<DNSCryptEncryptionParams>>,
119     ) -> Vec<Self> {
120         let now = now();
121         let (mut ts_start, mut seed) = match &previous_params {
122             None => (now, rand::thread_rng().gen()),
123             Some(p) => (
124                 p.dnscrypt_cert().ts_start() + DNSCRYPT_CERTS_RENEWAL,
125                 *p.resolver_kp().sk.as_bytes(),
126             ),
127         };
128         let mut active_params = vec![];
129         loop {
130             if ts_start > now + DNSCRYPT_CERTS_RENEWAL {
131                 break;
132             }
133             let resolver_kp = CryptKeyPair::from_seed(seed);
134             seed = *resolver_kp.sk.as_bytes();
135             if resolver_kp.pk.as_bytes()
136                 == &ANONYMIZED_DNSCRYPT_QUERY_MAGIC[..DNSCRYPT_QUERY_MAGIC_SIZE]
137             {
138                 ts_start += DNSCRYPT_CERTS_RENEWAL;
139                 continue;
140             }
141             if now >= ts_start {
142                 let dnscrypt_cert = DNSCryptCert::new(provider_kp, &resolver_kp, ts_start);
143                 let cache = ClockProCache::new(cache_capacity).unwrap();
144                 active_params.push(DNSCryptEncryptionParams {
145                     dnscrypt_cert,
146                     resolver_kp,
147                     cache: Some(Arc::new(Mutex::new(cache))),
148                 });
149             }
150             ts_start += DNSCRYPT_CERTS_RENEWAL;
151         }
152         if active_params.is_empty() && previous_params.is_none() {
153             warn!("Unable to recover a seed; creating an emergency certificate");
154             let ts_start = now - (now % DNSCRYPT_CERTS_RENEWAL);
155             let resolver_kp = CryptKeyPair::from_seed(seed);
156             let dnscrypt_cert = DNSCryptCert::new(provider_kp, &resolver_kp, ts_start);
157             let cache = ClockProCache::new(cache_capacity).unwrap();
158             active_params.push(DNSCryptEncryptionParams {
159                 dnscrypt_cert,
160                 resolver_kp,
161                 cache: Some(Arc::new(Mutex::new(cache))),
162             });
163         }
164         active_params
165     }
166 
add_key_cache(&mut self, cache_capacity: usize)167     pub fn add_key_cache(&mut self, cache_capacity: usize) {
168         let cache = ClockProCache::new(cache_capacity).unwrap();
169         self.cache = Some(Arc::new(Mutex::new(cache)));
170     }
171 
client_magic(&self) -> &[u8]172     pub fn client_magic(&self) -> &[u8] {
173         self.dnscrypt_cert.client_magic()
174     }
175 
dnscrypt_cert(&self) -> &DNSCryptCert176     pub fn dnscrypt_cert(&self) -> &DNSCryptCert {
177         &self.dnscrypt_cert
178     }
179 
resolver_kp(&self) -> &CryptKeyPair180     pub fn resolver_kp(&self) -> &CryptKeyPair {
181         &self.resolver_kp
182     }
183 }
184 
185 pub struct DNSCryptEncryptionParamsUpdater {
186     globals: Arc<Globals>,
187 }
188 
189 impl DNSCryptEncryptionParamsUpdater {
new(globals: Arc<Globals>) -> Self190     pub fn new(globals: Arc<Globals>) -> Self {
191         DNSCryptEncryptionParamsUpdater { globals }
192     }
193 
update(&self)194     pub fn update(&self) {
195         let now = now();
196         let mut new_params_set = vec![];
197         let previous_params = {
198             let params_set = self.globals.dnscrypt_encryption_params_set.read();
199             for params in &**params_set {
200                 if params.dnscrypt_cert().ts_end() >= now {
201                     new_params_set.push(params.clone());
202                 }
203             }
204             params_set.last().cloned()
205         };
206         let active_params = DNSCryptEncryptionParams::new(
207             &self.globals.provider_kp,
208             self.globals.key_cache_capacity,
209             previous_params,
210         );
211         for params in active_params {
212             new_params_set.push(Arc::new(params));
213         }
214         let state = State {
215             provider_kp: self.globals.provider_kp.clone(),
216             dnscrypt_encryption_params_set: new_params_set.iter().map(|x| (**x).clone()).collect(),
217         };
218         let state_file = self.globals.state_file.to_path_buf();
219         self.globals.runtime_handle.spawn(async move {
220             let _ = state.async_save(state_file).await;
221         });
222         *self.globals.dnscrypt_encryption_params_set.write() = Arc::new(new_params_set);
223         debug!("New certificate issued");
224     }
225 
run(self)226     pub async fn run(self) {
227         let mut fut_interval = tokio::time::interval(std::time::Duration::from_secs(u64::from(
228             DNSCRYPT_CERTS_RENEWAL,
229         )));
230         let fut = async move {
231             loop {
232                 fut_interval.tick().await;
233                 self.update();
234                 debug!("New cert issued");
235             }
236         };
237         fut.await
238     }
239 }
240