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