1 use crate::crypto::*;
2 use crate::dns::*;
3 use crate::dnscrypt_certs::*;
4 use crate::errors::*;
5 
6 use libsodium_sys::*;
7 use rand::prelude::*;
8 use std::sync::Arc;
9 
10 pub const DNSCRYPT_FULL_NONCE_SIZE: usize =
11     crypto_box_curve25519xchacha20poly1305_NONCEBYTES as usize;
12 pub const DNSCRYPT_MAC_SIZE: usize = crypto_box_curve25519xchacha20poly1305_MACBYTES as usize;
13 
14 pub const DNSCRYPT_QUERY_MAGIC_SIZE: usize = 8;
15 pub const DNSCRYPT_QUERY_PK_SIZE: usize = 32;
16 pub const DNSCRYPT_QUERY_NONCE_SIZE: usize = DNSCRYPT_FULL_NONCE_SIZE / 2;
17 pub const DNSCRYPT_QUERY_HEADER_SIZE: usize =
18     DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE + DNSCRYPT_QUERY_NONCE_SIZE;
19 pub const DNSCRYPT_QUERY_MIN_PADDING_SIZE: usize = 1;
20 pub const DNSCRYPT_QUERY_MIN_OVERHEAD: usize =
21     DNSCRYPT_QUERY_HEADER_SIZE + DNSCRYPT_MAC_SIZE + DNSCRYPT_QUERY_MIN_PADDING_SIZE;
22 
23 pub const DNSCRYPT_RESPONSE_MAGIC_SIZE: usize = 8;
24 pub const DNSCRYPT_RESPONSE_MAGIC: [u8; DNSCRYPT_RESPONSE_MAGIC_SIZE] =
25     [0x72, 0x36, 0x66, 0x6e, 0x76, 0x57, 0x6a, 0x38];
26 pub const DNSCRYPT_RESPONSE_CERT_PREFIX_OFFSET: usize = 4;
27 pub const DNSCRYPT_RESPONSE_NONCE_SIZE: usize = DNSCRYPT_FULL_NONCE_SIZE;
28 pub const DNSCRYPT_RESPONSE_HEADER_SIZE: usize =
29     DNSCRYPT_RESPONSE_MAGIC_SIZE + DNSCRYPT_RESPONSE_NONCE_SIZE;
30 pub const DNSCRYPT_RESPONSE_MIN_PADDING_SIZE: usize = 1;
31 pub const DNSCRYPT_RESPONSE_MIN_OVERHEAD: usize =
32     DNSCRYPT_RESPONSE_HEADER_SIZE + DNSCRYPT_MAC_SIZE + DNSCRYPT_RESPONSE_MIN_PADDING_SIZE;
33 
34 pub const DNSCRYPT_UDP_QUERY_MIN_SIZE: usize = DNSCRYPT_QUERY_MIN_OVERHEAD + DNS_HEADER_SIZE;
35 pub const DNSCRYPT_UDP_QUERY_MAX_SIZE: usize = DNS_MAX_PACKET_SIZE;
36 pub const DNSCRYPT_TCP_QUERY_MIN_SIZE: usize = DNSCRYPT_QUERY_MIN_OVERHEAD + DNS_HEADER_SIZE;
37 pub const DNSCRYPT_TCP_QUERY_MAX_SIZE: usize = DNSCRYPT_QUERY_MIN_OVERHEAD + DNS_MAX_PACKET_SIZE;
38 
39 pub const DNSCRYPT_UDP_RESPONSE_MIN_SIZE: usize = DNSCRYPT_RESPONSE_MIN_OVERHEAD + DNS_HEADER_SIZE;
40 pub const DNSCRYPT_UDP_RESPONSE_MAX_SIZE: usize = DNS_MAX_PACKET_SIZE;
41 pub const DNSCRYPT_TCP_RESPONSE_MIN_SIZE: usize = DNSCRYPT_RESPONSE_MIN_OVERHEAD + DNS_HEADER_SIZE;
42 pub const DNSCRYPT_TCP_RESPONSE_MAX_SIZE: usize =
43     DNSCRYPT_RESPONSE_MIN_OVERHEAD + DNS_MAX_PACKET_SIZE;
44 
decrypt( wrapped_packet: &[u8], dnscrypt_encryption_params_set: &[Arc<DNSCryptEncryptionParams>], ) -> Result<(SharedKey, [u8; DNSCRYPT_FULL_NONCE_SIZE as usize], Vec<u8>), Error>45 pub fn decrypt(
46     wrapped_packet: &[u8],
47     dnscrypt_encryption_params_set: &[Arc<DNSCryptEncryptionParams>],
48 ) -> Result<(SharedKey, [u8; DNSCRYPT_FULL_NONCE_SIZE as usize], Vec<u8>), Error> {
49     ensure!(
50         wrapped_packet.len()
51             >= DNSCRYPT_QUERY_MAGIC_SIZE
52                 + DNSCRYPT_QUERY_PK_SIZE
53                 + DNSCRYPT_QUERY_NONCE_SIZE
54                 + DNS_HEADER_SIZE,
55         "Short packet"
56     );
57     let client_magic = &wrapped_packet[..DNSCRYPT_QUERY_MAGIC_SIZE];
58     let client_pk = &wrapped_packet
59         [DNSCRYPT_QUERY_MAGIC_SIZE..DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE];
60     let client_nonce = &wrapped_packet[DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE
61         ..DNSCRYPT_QUERY_MAGIC_SIZE + DNSCRYPT_QUERY_PK_SIZE + DNSCRYPT_QUERY_NONCE_SIZE];
62     let encrypted_packet = &wrapped_packet[DNSCRYPT_QUERY_HEADER_SIZE..];
63 
64     let dnscrypt_encryption_params = dnscrypt_encryption_params_set
65         .iter()
66         .find(|p| p.client_magic() == client_magic)
67         .ok_or_else(|| anyhow!("Client magic not found"))?;
68 
69     let mut nonce = [0u8; DNSCRYPT_FULL_NONCE_SIZE as usize];
70     nonce[..DNSCRYPT_QUERY_NONCE_SIZE].copy_from_slice(client_nonce);
71 
72     let cached_shared_key = {
73         let mut cache = dnscrypt_encryption_params.cache.as_ref().unwrap().lock();
74         cache
75             .get(client_pk)
76             .map(|cached_shared_key| (*cached_shared_key).clone())
77     };
78     let shared_key = match cached_shared_key {
79         Some(cached_shared_key) => cached_shared_key,
80         None => {
81             let shared_key = dnscrypt_encryption_params
82                 .resolver_kp()
83                 .compute_shared_key(client_pk)?;
84             let mut client_pk_ = [0u8; DNSCRYPT_QUERY_PK_SIZE];
85             client_pk_.copy_from_slice(client_pk);
86             dnscrypt_encryption_params
87                 .cache
88                 .as_ref()
89                 .unwrap()
90                 .lock()
91                 .insert(client_pk_, shared_key.clone());
92             shared_key
93         }
94     };
95     let packet = shared_key.decrypt(&nonce, encrypted_packet)?;
96     rand::thread_rng().fill_bytes(&mut nonce[DNSCRYPT_QUERY_NONCE_SIZE..]);
97 
98     Ok((shared_key, nonce, packet))
99 }
100 
encrypt( packet: Vec<u8>, shared_key: &SharedKey, nonce: &[u8; DNSCRYPT_FULL_NONCE_SIZE as usize], max_packet_size: usize, ) -> Result<Vec<u8>, Error>101 pub fn encrypt(
102     packet: Vec<u8>,
103     shared_key: &SharedKey,
104     nonce: &[u8; DNSCRYPT_FULL_NONCE_SIZE as usize],
105     max_packet_size: usize,
106 ) -> Result<Vec<u8>, Error> {
107     let mut wrapped_packet = Vec::with_capacity(DNS_MAX_PACKET_SIZE);
108     wrapped_packet.extend_from_slice(&DNSCRYPT_RESPONSE_MAGIC);
109     wrapped_packet.extend_from_slice(nonce);
110     ensure!(
111         max_packet_size >= wrapped_packet.len(),
112         "Max packet size too short"
113     );
114     let max_encrypted_size = max_packet_size - wrapped_packet.len();
115     shared_key.encrypt_into(
116         &mut wrapped_packet,
117         nonce,
118         &nonce[..DNSCRYPT_QUERY_NONCE_SIZE],
119         packet,
120         max_encrypted_size,
121     )?;
122     Ok(wrapped_packet)
123 }
124