2019-10-13 20:34:46 +00:00
|
|
|
use crate::anonymized_dns::*;
|
2019-09-19 18:47:44 +00:00
|
|
|
use crate::config::*;
|
2019-09-02 21:02:23 +00:00
|
|
|
use crate::crypto::*;
|
2019-09-20 08:39:42 +00:00
|
|
|
use crate::dnscrypt::*;
|
2019-09-19 13:51:27 +00:00
|
|
|
use crate::globals::*;
|
2019-09-02 21:02:23 +00:00
|
|
|
|
|
|
|
use byteorder::{BigEndian, ByteOrder};
|
2021-01-31 11:24:02 +00:00
|
|
|
use cart_cache::CartCache;
|
2019-09-20 08:39:42 +00:00
|
|
|
use parking_lot::Mutex;
|
2019-09-02 21:02:23 +00:00
|
|
|
use std::mem;
|
|
|
|
use std::slice;
|
2019-09-19 13:51:27 +00:00
|
|
|
use std::sync::Arc;
|
2019-11-05 10:38:45 +00:00
|
|
|
use std::time::SystemTime;
|
2019-09-02 21:02:23 +00:00
|
|
|
|
2019-09-19 13:51:27 +00:00
|
|
|
pub const DNSCRYPT_CERTS_TTL: u32 = 86400;
|
|
|
|
pub const DNSCRYPT_CERTS_RENEWAL: u32 = 28800;
|
|
|
|
|
2019-09-02 21:02:23 +00:00
|
|
|
fn now() -> u32 {
|
2019-11-05 10:38:45 +00:00
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.expect("The clock is completely off")
|
|
|
|
.as_secs() as _
|
2019-09-02 21:02:23 +00:00
|
|
|
}
|
|
|
|
|
2020-06-24 11:46:28 +00:00
|
|
|
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
|
2019-09-02 21:02:23 +00:00
|
|
|
#[repr(C, packed)]
|
|
|
|
pub struct DNSCryptCertInner {
|
|
|
|
resolver_pk: [u8; 32],
|
|
|
|
client_magic: [u8; 8],
|
2019-09-02 23:10:35 +00:00
|
|
|
serial: [u8; 4],
|
2019-09-02 21:02:23 +00:00
|
|
|
ts_start: [u8; 4],
|
|
|
|
ts_end: [u8; 4],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DNSCryptCertInner {
|
|
|
|
pub fn as_bytes(&self) -> &[u8] {
|
|
|
|
unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of_val(self)) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-04 06:54:08 +00:00
|
|
|
big_array! { BigArray; 64 }
|
2019-09-19 18:47:44 +00:00
|
|
|
|
|
|
|
#[derive(Derivative, Serialize, Deserialize)]
|
2019-09-19 13:51:27 +00:00
|
|
|
#[derivative(Debug, Default, Clone)]
|
2019-09-02 21:02:23 +00:00
|
|
|
#[repr(C, packed)]
|
|
|
|
pub struct DNSCryptCert {
|
|
|
|
cert_magic: [u8; 4],
|
|
|
|
es_version: [u8; 2],
|
|
|
|
minor_version: [u8; 2],
|
|
|
|
#[derivative(Debug = "ignore", Default(value = "[0u8; 64]"))]
|
2019-09-19 18:47:44 +00:00
|
|
|
#[serde(with = "BigArray")]
|
2019-09-02 21:02:23 +00:00
|
|
|
signature: [u8; 64],
|
|
|
|
inner: DNSCryptCertInner,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DNSCryptCert {
|
2019-09-17 20:33:15 +00:00
|
|
|
pub fn new(provider_kp: &SignKeyPair, resolver_kp: &CryptKeyPair) -> Self {
|
2019-09-02 21:02:23 +00:00
|
|
|
let ts_start = now();
|
2019-09-19 13:51:27 +00:00
|
|
|
let ts_end = ts_start + DNSCRYPT_CERTS_TTL;
|
2019-09-02 21:02:23 +00:00
|
|
|
|
|
|
|
let mut dnscrypt_cert = DNSCryptCert::default();
|
|
|
|
|
|
|
|
let dnscrypt_cert_inner = &mut dnscrypt_cert.inner;
|
|
|
|
dnscrypt_cert_inner
|
|
|
|
.resolver_pk
|
|
|
|
.copy_from_slice(resolver_kp.pk.as_bytes());
|
|
|
|
dnscrypt_cert_inner
|
|
|
|
.client_magic
|
|
|
|
.copy_from_slice(&dnscrypt_cert_inner.resolver_pk[..8]);
|
2019-09-02 23:10:35 +00:00
|
|
|
BigEndian::write_u32(&mut dnscrypt_cert_inner.serial, 1);
|
2019-09-02 21:02:23 +00:00
|
|
|
BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_start, ts_start);
|
|
|
|
BigEndian::write_u32(&mut dnscrypt_cert_inner.ts_end, ts_end);
|
|
|
|
|
|
|
|
BigEndian::write_u32(&mut dnscrypt_cert.cert_magic, 0x44_4e_53_43);
|
|
|
|
BigEndian::write_u16(&mut dnscrypt_cert.es_version, 2);
|
|
|
|
BigEndian::write_u16(&mut dnscrypt_cert.minor_version, 0);
|
|
|
|
|
|
|
|
dnscrypt_cert.signature.copy_from_slice(
|
2019-09-17 20:33:15 +00:00
|
|
|
provider_kp
|
2019-09-02 21:02:23 +00:00
|
|
|
.sk
|
|
|
|
.sign(dnscrypt_cert_inner.as_bytes())
|
|
|
|
.as_bytes(),
|
|
|
|
);
|
|
|
|
dnscrypt_cert
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_bytes(&self) -> &[u8] {
|
|
|
|
unsafe { slice::from_raw_parts(self as *const _ as *const u8, mem::size_of_val(self)) }
|
|
|
|
}
|
2019-09-17 20:33:15 +00:00
|
|
|
|
|
|
|
pub fn client_magic(&self) -> &[u8] {
|
|
|
|
&self.inner.client_magic
|
|
|
|
}
|
2019-09-18 11:40:05 +00:00
|
|
|
|
2019-09-19 14:23:04 +00:00
|
|
|
pub fn ts_end(&self) -> u32 {
|
|
|
|
BigEndian::read_u32(&self.inner.ts_end)
|
2019-09-18 11:40:05 +00:00
|
|
|
}
|
2019-09-17 20:33:15 +00:00
|
|
|
}
|
|
|
|
|
2019-09-20 08:39:42 +00:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Derivative)]
|
|
|
|
#[derivative(Debug)]
|
2019-09-17 20:33:15 +00:00
|
|
|
pub struct DNSCryptEncryptionParams {
|
|
|
|
dnscrypt_cert: DNSCryptCert,
|
|
|
|
resolver_kp: CryptKeyPair,
|
2019-09-20 08:39:42 +00:00
|
|
|
#[serde(skip)]
|
|
|
|
#[derivative(Debug = "ignore")]
|
2021-01-31 11:24:02 +00:00
|
|
|
pub cache: Option<Arc<Mutex<CartCache<[u8; DNSCRYPT_QUERY_PK_SIZE], SharedKey>>>>,
|
2019-09-17 20:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DNSCryptEncryptionParams {
|
2019-09-20 08:39:42 +00:00
|
|
|
pub fn new(provider_kp: &SignKeyPair, cache_capacity: usize) -> Self {
|
2019-10-09 15:55:49 +00:00
|
|
|
let mut resolver_kp;
|
|
|
|
while {
|
|
|
|
resolver_kp = CryptKeyPair::new();
|
|
|
|
resolver_kp.pk.as_bytes()
|
|
|
|
== &ANONYMIZED_DNSCRYPT_QUERY_MAGIC[..DNSCRYPT_QUERY_MAGIC_SIZE]
|
|
|
|
} {}
|
2019-09-17 20:33:15 +00:00
|
|
|
let dnscrypt_cert = DNSCryptCert::new(&provider_kp, &resolver_kp);
|
2021-01-31 11:24:02 +00:00
|
|
|
let cache = CartCache::new(cache_capacity).unwrap();
|
2019-09-17 20:33:15 +00:00
|
|
|
DNSCryptEncryptionParams {
|
|
|
|
dnscrypt_cert,
|
|
|
|
resolver_kp,
|
2019-09-20 08:39:42 +00:00
|
|
|
cache: Some(Arc::new(Mutex::new(cache))),
|
2019-09-17 20:33:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-20 08:39:42 +00:00
|
|
|
pub fn add_key_cache(&mut self, cache_capacity: usize) {
|
2021-01-31 11:24:02 +00:00
|
|
|
let cache = CartCache::new(cache_capacity).unwrap();
|
2019-09-20 08:39:42 +00:00
|
|
|
self.cache = Some(Arc::new(Mutex::new(cache)));
|
|
|
|
}
|
|
|
|
|
2019-09-17 20:33:15 +00:00
|
|
|
pub fn client_magic(&self) -> &[u8] {
|
|
|
|
self.dnscrypt_cert.client_magic()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dnscrypt_cert(&self) -> &DNSCryptCert {
|
|
|
|
&self.dnscrypt_cert
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn resolver_kp(&self) -> &CryptKeyPair {
|
|
|
|
&self.resolver_kp
|
|
|
|
}
|
2019-09-02 21:02:23 +00:00
|
|
|
}
|
2019-09-19 13:51:27 +00:00
|
|
|
|
|
|
|
pub struct DNSCryptEncryptionParamsUpdater {
|
|
|
|
globals: Arc<Globals>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DNSCryptEncryptionParamsUpdater {
|
|
|
|
pub fn new(globals: Arc<Globals>) -> Self {
|
|
|
|
DNSCryptEncryptionParamsUpdater { globals }
|
|
|
|
}
|
|
|
|
|
2019-09-21 09:53:40 +00:00
|
|
|
pub fn update(&self) {
|
2019-09-19 14:23:04 +00:00
|
|
|
let now = now();
|
|
|
|
let mut new_params_set = vec![];
|
|
|
|
{
|
|
|
|
let params_set = self.globals.dnscrypt_encryption_params_set.read();
|
|
|
|
for params in &**params_set {
|
|
|
|
if params.dnscrypt_cert().ts_end() >= now {
|
|
|
|
new_params_set.push(params.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-20 08:39:42 +00:00
|
|
|
let new_params = DNSCryptEncryptionParams::new(
|
|
|
|
&self.globals.provider_kp,
|
|
|
|
self.globals.key_cache_capacity,
|
|
|
|
);
|
2019-09-19 14:23:04 +00:00
|
|
|
new_params_set.push(Arc::new(new_params));
|
2019-09-19 18:47:44 +00:00
|
|
|
let state = State {
|
|
|
|
provider_kp: self.globals.provider_kp.clone(),
|
2019-09-19 19:08:49 +00:00
|
|
|
dnscrypt_encryption_params_set: new_params_set.iter().map(|x| (**x).clone()).collect(),
|
2019-09-19 18:47:44 +00:00
|
|
|
};
|
2019-09-20 00:31:31 +00:00
|
|
|
let state_file = self.globals.state_file.to_path_buf();
|
2019-12-04 16:14:11 +00:00
|
|
|
self.globals.runtime_handle.spawn(async move {
|
2019-09-20 00:31:31 +00:00
|
|
|
let _ = state.async_save(state_file).await;
|
|
|
|
});
|
2019-09-19 14:23:04 +00:00
|
|
|
*self.globals.dnscrypt_encryption_params_set.write() = Arc::new(new_params_set);
|
2019-09-20 08:39:42 +00:00
|
|
|
debug!("New certificate issued");
|
2019-09-19 14:23:04 +00:00
|
|
|
}
|
|
|
|
|
2019-09-19 13:51:27 +00:00
|
|
|
pub async fn run(self) {
|
2019-12-04 16:14:11 +00:00
|
|
|
let mut fut_interval = tokio::time::interval(std::time::Duration::from_secs(u64::from(
|
|
|
|
DNSCRYPT_CERTS_RENEWAL,
|
|
|
|
)));
|
2019-09-19 14:23:04 +00:00
|
|
|
let fut = async move {
|
2019-12-04 16:14:11 +00:00
|
|
|
loop {
|
|
|
|
fut_interval.tick().await;
|
2019-09-19 14:23:04 +00:00
|
|
|
self.update();
|
2019-09-19 13:51:27 +00:00
|
|
|
debug!("New cert issued");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
fut.await
|
|
|
|
}
|
|
|
|
}
|