2
0
mirror of https://github.com/jedisct1/encrypted-dns-server synced 2024-11-12 13:10:44 +00:00
encrypted-dns-server/src/dnscrypt_certs.rs

151 lines
4.2 KiB
Rust
Raw Normal View History

2019-09-02 21:02:23 +00:00
use crate::crypto::*;
2019-09-19 13:51:27 +00:00
use crate::globals::*;
2019-09-02 21:02:23 +00:00
use byteorder::{BigEndian, ByteOrder};
2019-09-18 11:40:05 +00:00
use coarsetime::{Clock, Duration};
2019-09-19 13:51:27 +00:00
use parking_lot::RwLock;
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-09-02 21:02:23 +00:00
use std::time::SystemTime;
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 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs() as u32
}
2019-09-19 13:51:27 +00:00
#[derive(Debug, Default, Clone)]
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)) }
}
}
#[derive(Derivative)]
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]"))]
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
pub fn ts_end(&self) -> Duration {
Duration::from_secs(u64::from(BigEndian::read_u32(&self.inner.ts_end)))
}
2019-09-17 20:33:15 +00:00
}
#[derive(Debug)]
pub struct DNSCryptEncryptionParams {
dnscrypt_cert: DNSCryptCert,
resolver_kp: CryptKeyPair,
}
impl DNSCryptEncryptionParams {
pub fn new(provider_kp: &SignKeyPair) -> Self {
let resolver_kp = CryptKeyPair::new();
let dnscrypt_cert = DNSCryptCert::new(&provider_kp, &resolver_kp);
DNSCryptEncryptionParams {
dnscrypt_cert,
resolver_kp,
}
}
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 }
}
pub async fn run(self) {
let mut fut_interval = tokio::timer::Interval::new_interval(
std::time::Duration::from_secs(u64::from(DNSCRYPT_CERTS_RENEWAL)),
);
let fut = async {
loop {
fut_interval.next().await;
let new_params = DNSCryptEncryptionParams::new(&self.globals.provider_kp);
debug!("New cert issued");
let mut params_set = self.globals.dnscrypt_encryption_params_set.write();
if params_set.len() >= (DNSCRYPT_CERTS_TTL / DNSCRYPT_CERTS_RENEWAL) as usize {
params_set.swap_remove(0);
}
params_set.push(Arc::new(new_params));
}
};
fut.await
}
}