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