dnscrypt.c revision 1.1.1.3 1 1.1 christos
2 1.1 christos #include "config.h"
3 1.1 christos #include <stdlib.h>
4 1.1 christos #include <fcntl.h>
5 1.1 christos #ifdef HAVE_TIME_H
6 1.1 christos #include <time.h>
7 1.1 christos #endif
8 1.1.1.2 christos #include <inttypes.h>
9 1.1 christos #include <sys/time.h>
10 1.1 christos #include <sys/types.h>
11 1.1 christos #include "sldns/sbuffer.h"
12 1.1 christos #include "util/config_file.h"
13 1.1 christos #include "util/net_help.h"
14 1.1 christos #include "util/netevent.h"
15 1.1 christos #include "util/log.h"
16 1.1 christos #include "util/storage/slabhash.h"
17 1.1 christos #include "util/storage/lookup3.h"
18 1.1 christos
19 1.1 christos #include "dnscrypt/cert.h"
20 1.1 christos #include "dnscrypt/dnscrypt.h"
21 1.1 christos #include "dnscrypt/dnscrypt_config.h"
22 1.1 christos
23 1.1 christos #include <ctype.h>
24 1.1 christos
25 1.1 christos
26 1.1 christos /**
27 1.1 christos * \file
28 1.1 christos * dnscrypt functions for encrypting DNS packets.
29 1.1 christos */
30 1.1 christos
31 1.1 christos #define DNSCRYPT_QUERY_BOX_OFFSET \
32 1.1 christos (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + \
33 1.1 christos crypto_box_HALF_NONCEBYTES)
34 1.1 christos
35 1.1 christos // 8 bytes: magic header (CERT_MAGIC_HEADER)
36 1.1 christos // 12 bytes: the client's nonce
37 1.1 christos // 12 bytes: server nonce extension
38 1.1 christos // 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39 1.1 christos
40 1.1 christos #define DNSCRYPT_REPLY_BOX_OFFSET \
41 1.1 christos (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES + \
42 1.1 christos crypto_box_HALF_NONCEBYTES)
43 1.1 christos
44 1.1 christos
45 1.1 christos /**
46 1.1 christos * Shared secret cache key length.
47 1.1 christos * secret key.
48 1.1 christos * 1 byte: ES_VERSION[1]
49 1.1 christos * 32 bytes: client crypto_box_PUBLICKEYBYTES
50 1.1 christos * 32 bytes: server crypto_box_SECRETKEYBYTES
51 1.1 christos */
52 1.1 christos #define DNSCRYPT_SHARED_SECRET_KEY_LENGTH \
53 1.1 christos (1 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES)
54 1.1 christos
55 1.1 christos
56 1.1 christos struct shared_secret_cache_key {
57 1.1 christos /** the hash table key */
58 1.1 christos uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH];
59 1.1 christos /** the hash table entry, data is uint8_t pointer of size crypto_box_BEFORENMBYTES which contains the shared secret. */
60 1.1 christos struct lruhash_entry entry;
61 1.1 christos };
62 1.1 christos
63 1.1 christos
64 1.1 christos struct nonce_cache_key {
65 1.1 christos /** the nonce used by the client */
66 1.1 christos uint8_t nonce[crypto_box_HALF_NONCEBYTES];
67 1.1 christos /** the client_magic used by the client, this is associated to 1 cert only */
68 1.1 christos uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
69 1.1 christos /** the client public key */
70 1.1 christos uint8_t client_publickey[crypto_box_PUBLICKEYBYTES];
71 1.1 christos /** the hash table entry, data is uint8_t */
72 1.1 christos struct lruhash_entry entry;
73 1.1 christos };
74 1.1 christos
75 1.1 christos /**
76 1.1 christos * Generate a key suitable to find shared secret in slabhash.
77 1.1 christos * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
78 1.1 christos * \param[in] esversion: The es version least significant byte.
79 1.1 christos * \param[in] pk: The public key of the client. uint8_t pointer of size
80 1.1 christos * crypto_box_PUBLICKEYBYTES.
81 1.1 christos * \param[in] sk: The secret key of the server matching the magic query number.
82 1.1 christos * uint8_t pointer of size crypto_box_SECRETKEYBYTES.
83 1.1 christos * \return the hash of the key.
84 1.1 christos */
85 1.1 christos static uint32_t
86 1.1 christos dnsc_shared_secrets_cache_key(uint8_t* key,
87 1.1 christos uint8_t esversion,
88 1.1 christos uint8_t* pk,
89 1.1 christos uint8_t* sk)
90 1.1 christos {
91 1.1 christos key[0] = esversion;
92 1.1 christos memcpy(key + 1, pk, crypto_box_PUBLICKEYBYTES);
93 1.1 christos memcpy(key + 1 + crypto_box_PUBLICKEYBYTES, sk, crypto_box_SECRETKEYBYTES);
94 1.1 christos return hashlittle(key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH, 0);
95 1.1 christos }
96 1.1 christos
97 1.1 christos /**
98 1.1 christos * Inserts a shared secret into the shared_secrets_cache slabhash.
99 1.1 christos * The shared secret is copied so the caller can use it freely without caring
100 1.1 christos * about the cache entry being evicted or not.
101 1.1 christos * \param[in] cache: the slabhash in which to look for the key.
102 1.1 christos * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
103 1.1 christos * which contains the key of the shared secret.
104 1.1 christos * \param[in] hash: the hash of the key.
105 1.1 christos * \param[in] nmkey: a uint8_t pointer of size crypto_box_BEFORENMBYTES which
106 1.1 christos * contains the shared secret.
107 1.1 christos */
108 1.1 christos static void
109 1.1 christos dnsc_shared_secret_cache_insert(struct slabhash *cache,
110 1.1 christos uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH],
111 1.1 christos uint32_t hash,
112 1.1 christos uint8_t nmkey[crypto_box_BEFORENMBYTES])
113 1.1 christos {
114 1.1 christos struct shared_secret_cache_key* k =
115 1.1 christos (struct shared_secret_cache_key*)calloc(1, sizeof(*k));
116 1.1 christos uint8_t* d = malloc(crypto_box_BEFORENMBYTES);
117 1.1 christos if(!k || !d) {
118 1.1 christos free(k);
119 1.1 christos free(d);
120 1.1 christos return;
121 1.1 christos }
122 1.1 christos memcpy(d, nmkey, crypto_box_BEFORENMBYTES);
123 1.1 christos lock_rw_init(&k->entry.lock);
124 1.1 christos memcpy(k->key, key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
125 1.1 christos k->entry.hash = hash;
126 1.1 christos k->entry.key = k;
127 1.1 christos k->entry.data = d;
128 1.1 christos slabhash_insert(cache,
129 1.1 christos hash, &k->entry,
130 1.1 christos d,
131 1.1 christos NULL);
132 1.1 christos }
133 1.1 christos
134 1.1 christos /**
135 1.1 christos * Lookup a record in shared_secrets_cache.
136 1.1 christos * \param[in] cache: a pointer to shared_secrets_cache slabhash.
137 1.1 christos * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
138 1.1 christos * containing the key to look for.
139 1.1 christos * \param[in] hash: a hash of the key.
140 1.1 christos * \return a pointer to the locked cache entry or NULL on failure.
141 1.1 christos */
142 1.1 christos static struct lruhash_entry*
143 1.1 christos dnsc_shared_secrets_lookup(struct slabhash* cache,
144 1.1 christos uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH],
145 1.1 christos uint32_t hash)
146 1.1 christos {
147 1.1 christos return slabhash_lookup(cache, hash, key, 0);
148 1.1 christos }
149 1.1 christos
150 1.1 christos /**
151 1.1 christos * Generate a key hash suitable to find a nonce in slabhash.
152 1.1 christos * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
153 1.1 christos * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
154 1.1 christos * \param[in] pk: The public key of the client. uint8_t pointer of size
155 1.1 christos * crypto_box_PUBLICKEYBYTES.
156 1.1 christos * \return the hash of the key.
157 1.1 christos */
158 1.1 christos static uint32_t
159 1.1 christos dnsc_nonce_cache_key_hash(const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
160 1.1 christos const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
161 1.1 christos const uint8_t pk[crypto_box_PUBLICKEYBYTES])
162 1.1 christos {
163 1.1 christos uint32_t h = 0;
164 1.1 christos h = hashlittle(nonce, crypto_box_HALF_NONCEBYTES, h);
165 1.1 christos h = hashlittle(magic_query, DNSCRYPT_MAGIC_HEADER_LEN, h);
166 1.1 christos return hashlittle(pk, crypto_box_PUBLICKEYBYTES, h);
167 1.1 christos }
168 1.1 christos
169 1.1 christos /**
170 1.1 christos * Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash.
171 1.1 christos * \param[in] cache: the slabhash in which to look for the key.
172 1.1 christos * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
173 1.1 christos * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
174 1.1 christos * \param[in] pk: The public key of the client. uint8_t pointer of size
175 1.1 christos * crypto_box_PUBLICKEYBYTES.
176 1.1 christos * \param[in] hash: the hash of the key.
177 1.1 christos */
178 1.1 christos static void
179 1.1 christos dnsc_nonce_cache_insert(struct slabhash *cache,
180 1.1 christos const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
181 1.1 christos const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
182 1.1 christos const uint8_t pk[crypto_box_PUBLICKEYBYTES],
183 1.1 christos uint32_t hash)
184 1.1 christos {
185 1.1 christos struct nonce_cache_key* k =
186 1.1 christos (struct nonce_cache_key*)calloc(1, sizeof(*k));
187 1.1 christos if(!k) {
188 1.1 christos free(k);
189 1.1 christos return;
190 1.1 christos }
191 1.1 christos lock_rw_init(&k->entry.lock);
192 1.1 christos memcpy(k->nonce, nonce, crypto_box_HALF_NONCEBYTES);
193 1.1 christos memcpy(k->magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
194 1.1 christos memcpy(k->client_publickey, pk, crypto_box_PUBLICKEYBYTES);
195 1.1 christos k->entry.hash = hash;
196 1.1 christos k->entry.key = k;
197 1.1 christos k->entry.data = NULL;
198 1.1 christos slabhash_insert(cache,
199 1.1 christos hash, &k->entry,
200 1.1 christos NULL,
201 1.1 christos NULL);
202 1.1 christos }
203 1.1 christos
204 1.1 christos /**
205 1.1 christos * Lookup a record in nonces_cache.
206 1.1 christos * \param[in] cache: the slabhash in which to look for the key.
207 1.1 christos * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
208 1.1 christos * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
209 1.1 christos * \param[in] pk: The public key of the client. uint8_t pointer of size
210 1.1 christos * crypto_box_PUBLICKEYBYTES.
211 1.1 christos * \param[in] hash: the hash of the key.
212 1.1 christos * \return a pointer to the locked cache entry or NULL on failure.
213 1.1 christos */
214 1.1 christos static struct lruhash_entry*
215 1.1 christos dnsc_nonces_lookup(struct slabhash* cache,
216 1.1 christos const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
217 1.1 christos const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
218 1.1 christos const uint8_t pk[crypto_box_PUBLICKEYBYTES],
219 1.1 christos uint32_t hash)
220 1.1 christos {
221 1.1 christos struct nonce_cache_key k;
222 1.1 christos memset(&k, 0, sizeof(k));
223 1.1 christos k.entry.hash = hash;
224 1.1 christos memcpy(k.nonce, nonce, crypto_box_HALF_NONCEBYTES);
225 1.1 christos memcpy(k.magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
226 1.1 christos memcpy(k.client_publickey, pk, crypto_box_PUBLICKEYBYTES);
227 1.1 christos
228 1.1 christos return slabhash_lookup(cache, hash, &k, 0);
229 1.1 christos }
230 1.1 christos
231 1.1 christos /**
232 1.1 christos * Decrypt a query using the dnsccert that was found using dnsc_find_cert.
233 1.1 christos * The client nonce will be extracted from the encrypted query and stored in
234 1.1 christos * client_nonce, a shared secret will be computed and stored in nmkey and the
235 1.1 christos * buffer will be decrypted inplace.
236 1.1 christos * \param[in] env the dnscrypt environment.
237 1.1 christos * \param[in] cert the cert that matches this encrypted query.
238 1.1 christos * \param[in] client_nonce where the client nonce will be stored.
239 1.1 christos * \param[in] nmkey where the shared secret key will be written.
240 1.1 christos * \param[in] buffer the encrypted buffer.
241 1.1 christos * \return 0 on success.
242 1.1 christos */
243 1.1 christos static int
244 1.1 christos dnscrypt_server_uncurve(struct dnsc_env* env,
245 1.1 christos const dnsccert *cert,
246 1.1 christos uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
247 1.1 christos uint8_t nmkey[crypto_box_BEFORENMBYTES],
248 1.1 christos struct sldns_buffer* buffer)
249 1.1 christos {
250 1.1 christos size_t len = sldns_buffer_limit(buffer);
251 1.1 christos uint8_t *const buf = sldns_buffer_begin(buffer);
252 1.1 christos uint8_t nonce[crypto_box_NONCEBYTES];
253 1.1 christos struct dnscrypt_query_header *query_header;
254 1.1 christos // shared secret cache
255 1.1 christos uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH];
256 1.1 christos struct lruhash_entry* entry;
257 1.1 christos uint32_t hash;
258 1.1 christos
259 1.1 christos uint32_t nonce_hash;
260 1.1 christos
261 1.1 christos if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
262 1.1 christos return -1;
263 1.1 christos }
264 1.1 christos
265 1.1 christos query_header = (struct dnscrypt_query_header *)buf;
266 1.1 christos
267 1.1 christos /* Detect replay attacks */
268 1.1 christos nonce_hash = dnsc_nonce_cache_key_hash(
269 1.1 christos query_header->nonce,
270 1.1 christos cert->magic_query,
271 1.1 christos query_header->publickey);
272 1.1 christos
273 1.1 christos lock_basic_lock(&env->nonces_cache_lock);
274 1.1 christos entry = dnsc_nonces_lookup(
275 1.1 christos env->nonces_cache,
276 1.1 christos query_header->nonce,
277 1.1 christos cert->magic_query,
278 1.1 christos query_header->publickey,
279 1.1 christos nonce_hash);
280 1.1 christos
281 1.1 christos if(entry) {
282 1.1 christos lock_rw_unlock(&entry->lock);
283 1.1 christos env->num_query_dnscrypt_replay++;
284 1.1 christos lock_basic_unlock(&env->nonces_cache_lock);
285 1.1 christos return -1;
286 1.1 christos }
287 1.1 christos
288 1.1 christos dnsc_nonce_cache_insert(
289 1.1 christos env->nonces_cache,
290 1.1 christos query_header->nonce,
291 1.1 christos cert->magic_query,
292 1.1 christos query_header->publickey,
293 1.1 christos nonce_hash);
294 1.1 christos lock_basic_unlock(&env->nonces_cache_lock);
295 1.1 christos
296 1.1 christos /* Find existing shared secret */
297 1.1 christos hash = dnsc_shared_secrets_cache_key(key,
298 1.1 christos cert->es_version[1],
299 1.1 christos query_header->publickey,
300 1.1 christos cert->keypair->crypt_secretkey);
301 1.1 christos entry = dnsc_shared_secrets_lookup(env->shared_secrets_cache,
302 1.1 christos key,
303 1.1 christos hash);
304 1.1 christos
305 1.1 christos if(!entry) {
306 1.1 christos lock_basic_lock(&env->shared_secrets_cache_lock);
307 1.1 christos env->num_query_dnscrypt_secret_missed_cache++;
308 1.1 christos lock_basic_unlock(&env->shared_secrets_cache_lock);
309 1.1 christos if(cert->es_version[1] == 2) {
310 1.1 christos #ifdef USE_DNSCRYPT_XCHACHA20
311 1.1 christos if (crypto_box_curve25519xchacha20poly1305_beforenm(
312 1.1 christos nmkey, query_header->publickey,
313 1.1 christos cert->keypair->crypt_secretkey) != 0) {
314 1.1 christos return -1;
315 1.1 christos }
316 1.1 christos #else
317 1.1 christos return -1;
318 1.1 christos #endif
319 1.1 christos } else {
320 1.1 christos if (crypto_box_beforenm(nmkey,
321 1.1 christos query_header->publickey,
322 1.1 christos cert->keypair->crypt_secretkey) != 0) {
323 1.1 christos return -1;
324 1.1 christos }
325 1.1 christos }
326 1.1 christos // Cache the shared secret we just computed.
327 1.1 christos dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
328 1.1 christos key,
329 1.1 christos hash,
330 1.1 christos nmkey);
331 1.1 christos } else {
332 1.1 christos /* copy shared secret and unlock entry */
333 1.1 christos memcpy(nmkey, entry->data, crypto_box_BEFORENMBYTES);
334 1.1 christos lock_rw_unlock(&entry->lock);
335 1.1 christos }
336 1.1 christos
337 1.1 christos memcpy(nonce, query_header->nonce, crypto_box_HALF_NONCEBYTES);
338 1.1 christos memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
339 1.1 christos
340 1.1 christos if(cert->es_version[1] == 2) {
341 1.1 christos #ifdef USE_DNSCRYPT_XCHACHA20
342 1.1 christos if (crypto_box_curve25519xchacha20poly1305_open_easy_afternm
343 1.1 christos (buf,
344 1.1 christos buf + DNSCRYPT_QUERY_BOX_OFFSET,
345 1.1 christos len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
346 1.1 christos nmkey) != 0) {
347 1.1 christos return -1;
348 1.1 christos }
349 1.1 christos #else
350 1.1 christos return -1;
351 1.1 christos #endif
352 1.1 christos } else {
353 1.1 christos if (crypto_box_open_easy_afternm
354 1.1 christos (buf,
355 1.1 christos buf + DNSCRYPT_QUERY_BOX_OFFSET,
356 1.1 christos len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
357 1.1 christos nmkey) != 0) {
358 1.1 christos return -1;
359 1.1 christos }
360 1.1 christos }
361 1.1 christos
362 1.1 christos len -= DNSCRYPT_QUERY_HEADER_SIZE;
363 1.1 christos
364 1.1 christos while (*sldns_buffer_at(buffer, --len) == 0)
365 1.1 christos ;
366 1.1 christos
367 1.1 christos if (*sldns_buffer_at(buffer, len) != 0x80) {
368 1.1 christos return -1;
369 1.1 christos }
370 1.1 christos
371 1.1 christos memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
372 1.1 christos
373 1.1 christos sldns_buffer_set_position(buffer, 0);
374 1.1 christos sldns_buffer_set_limit(buffer, len);
375 1.1 christos
376 1.1 christos return 0;
377 1.1 christos }
378 1.1 christos
379 1.1 christos
380 1.1 christos /**
381 1.1 christos * Add random padding to a buffer, according to a client nonce.
382 1.1 christos * The length has to depend on the query in order to avoid reply attacks.
383 1.1 christos *
384 1.1 christos * @param buf a buffer
385 1.1 christos * @param len the initial size of the buffer
386 1.1 christos * @param max_len the maximum size
387 1.1 christos * @param nonce a nonce, made of the client nonce repeated twice
388 1.1 christos * @param secretkey
389 1.1 christos * @return the new size, after padding
390 1.1 christos */
391 1.1 christos size_t
392 1.1 christos dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len,
393 1.1 christos const uint8_t *nonce, const uint8_t *secretkey)
394 1.1 christos {
395 1.1 christos uint8_t *buf_padding_area = buf + len;
396 1.1 christos size_t padded_len;
397 1.1 christos uint32_t rnd;
398 1.1 christos
399 1.1 christos // no padding
400 1.1 christos if (max_len < len + DNSCRYPT_MIN_PAD_LEN)
401 1.1 christos return len;
402 1.1 christos
403 1.1 christos assert(nonce[crypto_box_HALF_NONCEBYTES] == nonce[0]);
404 1.1 christos
405 1.1 christos crypto_stream((unsigned char *)&rnd, (unsigned long long)sizeof(rnd), nonce,
406 1.1 christos secretkey);
407 1.1 christos padded_len =
408 1.1 christos len + DNSCRYPT_MIN_PAD_LEN + rnd % (max_len - len -
409 1.1 christos DNSCRYPT_MIN_PAD_LEN + 1);
410 1.1 christos padded_len += DNSCRYPT_BLOCK_SIZE - padded_len % DNSCRYPT_BLOCK_SIZE;
411 1.1 christos if (padded_len > max_len)
412 1.1 christos padded_len = max_len;
413 1.1 christos
414 1.1 christos memset(buf_padding_area, 0, padded_len - len);
415 1.1 christos *buf_padding_area = 0x80;
416 1.1 christos
417 1.1 christos return padded_len;
418 1.1 christos }
419 1.1 christos
420 1.1 christos uint64_t
421 1.1 christos dnscrypt_hrtime(void)
422 1.1 christos {
423 1.1 christos struct timeval tv;
424 1.1 christos uint64_t ts = (uint64_t)0U;
425 1.1 christos int ret;
426 1.1 christos
427 1.1 christos ret = gettimeofday(&tv, NULL);
428 1.1 christos if (ret == 0) {
429 1.1 christos ts = (uint64_t)tv.tv_sec * 1000000U + (uint64_t)tv.tv_usec;
430 1.1 christos } else {
431 1.1 christos log_err("gettimeofday: %s", strerror(errno));
432 1.1 christos }
433 1.1 christos return ts;
434 1.1 christos }
435 1.1 christos
436 1.1 christos /**
437 1.1 christos * Add the server nonce part to once.
438 1.1 christos * The nonce is made half of client nonce and the seconf half of the server
439 1.1 christos * nonce, both of them of size crypto_box_HALF_NONCEBYTES.
440 1.1 christos * \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES
441 1.1 christos */
442 1.1 christos static void
443 1.1 christos add_server_nonce(uint8_t *nonce)
444 1.1 christos {
445 1.1 christos uint64_t ts;
446 1.1 christos uint64_t tsn;
447 1.1 christos uint32_t suffix;
448 1.1 christos ts = dnscrypt_hrtime();
449 1.1 christos // TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
450 1.1 christos // unclear if we really need it, so skipping it for now.
451 1.1 christos tsn = (ts << 10) | (randombytes_random() & 0x3ff);
452 1.1 christos #if (BYTE_ORDER == LITTLE_ENDIAN)
453 1.1 christos tsn =
454 1.1 christos (((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
455 1.1 christos #endif
456 1.1 christos memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
457 1.1 christos suffix = randombytes_random();
458 1.1 christos memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
459 1.1 christos }
460 1.1 christos
461 1.1 christos /**
462 1.1 christos * Encrypt a reply using the dnsccert that was used with the query.
463 1.1 christos * The client nonce will be extracted from the encrypted query and stored in
464 1.1 christos * The buffer will be encrypted inplace.
465 1.1 christos * \param[in] cert the dnsccert that matches this encrypted query.
466 1.1 christos * \param[in] client_nonce client nonce used during the query
467 1.1 christos * \param[in] nmkey shared secret key used during the query.
468 1.1 christos * \param[in] buffer the buffer where to encrypt the reply.
469 1.1 christos * \param[in] udp if whether or not it is a UDP query.
470 1.1 christos * \param[in] max_udp_size configured max udp size.
471 1.1 christos * \return 0 on success.
472 1.1 christos */
473 1.1 christos static int
474 1.1 christos dnscrypt_server_curve(const dnsccert *cert,
475 1.1 christos uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
476 1.1 christos uint8_t nmkey[crypto_box_BEFORENMBYTES],
477 1.1 christos struct sldns_buffer* buffer,
478 1.1 christos uint8_t udp,
479 1.1 christos size_t max_udp_size)
480 1.1 christos {
481 1.1 christos size_t dns_reply_len = sldns_buffer_limit(buffer);
482 1.1 christos size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING \
483 1.1 christos + DNSCRYPT_REPLY_HEADER_SIZE;
484 1.1 christos size_t max_reply_size = max_udp_size - 20U - 8U;
485 1.1 christos uint8_t nonce[crypto_box_NONCEBYTES];
486 1.1 christos uint8_t *boxed;
487 1.1 christos uint8_t *const buf = sldns_buffer_begin(buffer);
488 1.1 christos size_t len = sldns_buffer_limit(buffer);
489 1.1 christos
490 1.1 christos if(udp){
491 1.1 christos if (max_len > max_reply_size)
492 1.1 christos max_len = max_reply_size;
493 1.1 christos }
494 1.1 christos
495 1.1 christos
496 1.1 christos memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
497 1.1 christos memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce,
498 1.1 christos crypto_box_HALF_NONCEBYTES);
499 1.1 christos
500 1.1 christos boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET;
501 1.1 christos memmove(boxed + crypto_box_MACBYTES, buf, len);
502 1.1 christos len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
503 1.1 christos max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce,
504 1.1 christos cert->keypair->crypt_secretkey);
505 1.1 christos sldns_buffer_set_at(buffer,
506 1.1 christos DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
507 1.1 christos 0, crypto_box_ZEROBYTES);
508 1.1 christos
509 1.1 christos // add server nonce extension
510 1.1 christos add_server_nonce(nonce);
511 1.1 christos
512 1.1 christos if(cert->es_version[1] == 2) {
513 1.1 christos #ifdef USE_DNSCRYPT_XCHACHA20
514 1.1 christos if (crypto_box_curve25519xchacha20poly1305_easy_afternm
515 1.1 christos (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
516 1.1 christos return -1;
517 1.1 christos }
518 1.1 christos #else
519 1.1 christos return -1;
520 1.1 christos #endif
521 1.1 christos } else {
522 1.1 christos if (crypto_box_easy_afternm
523 1.1 christos (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
524 1.1 christos return -1;
525 1.1 christos }
526 1.1 christos }
527 1.1 christos
528 1.1 christos sldns_buffer_write_at(buffer,
529 1.1 christos 0,
530 1.1 christos DNSCRYPT_MAGIC_RESPONSE,
531 1.1 christos DNSCRYPT_MAGIC_HEADER_LEN);
532 1.1 christos sldns_buffer_write_at(buffer,
533 1.1 christos DNSCRYPT_MAGIC_HEADER_LEN,
534 1.1 christos nonce,
535 1.1 christos crypto_box_NONCEBYTES);
536 1.1 christos sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
537 1.1 christos return 0;
538 1.1 christos }
539 1.1 christos
540 1.1 christos /**
541 1.1 christos * Read the content of fname into buf.
542 1.1 christos * \param[in] fname name of the file to read.
543 1.1 christos * \param[in] buf the buffer in which to read the content of the file.
544 1.1 christos * \param[in] count number of bytes to read.
545 1.1 christos * \return 0 on success.
546 1.1 christos */
547 1.1 christos static int
548 1.1 christos dnsc_read_from_file(char *fname, char *buf, size_t count)
549 1.1 christos {
550 1.1 christos int fd;
551 1.1 christos fd = open(fname, O_RDONLY);
552 1.1 christos if (fd == -1) {
553 1.1 christos return -1;
554 1.1 christos }
555 1.1 christos if (read(fd, buf, count) != (ssize_t)count) {
556 1.1 christos close(fd);
557 1.1 christos return -2;
558 1.1 christos }
559 1.1 christos close(fd);
560 1.1 christos return 0;
561 1.1 christos }
562 1.1 christos
563 1.1 christos /**
564 1.1 christos * Given an absolute path on the original root, returns the absolute path
565 1.1 christos * within the chroot. If chroot is disabled, the path is not modified.
566 1.1 christos * No char * is malloced so there is no need to free this.
567 1.1 christos * \param[in] cfg the configuration.
568 1.1 christos * \param[in] path the path from the original root.
569 1.1 christos * \return the path from inside the chroot.
570 1.1 christos */
571 1.1 christos static char *
572 1.1 christos dnsc_chroot_path(struct config_file *cfg, char *path)
573 1.1 christos {
574 1.1 christos char *nm;
575 1.1 christos nm = path;
576 1.1 christos if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
577 1.1 christos cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
578 1.1 christos nm += strlen(cfg->chrootdir);
579 1.1 christos return nm;
580 1.1 christos }
581 1.1 christos
582 1.1 christos /**
583 1.1 christos * Parse certificates files provided by the configuration and load them into
584 1.1 christos * dnsc_env.
585 1.1 christos * \param[in] env the dnsc_env structure to load the certs into.
586 1.1 christos * \param[in] cfg the configuration.
587 1.1 christos * \return the number of certificates loaded.
588 1.1 christos */
589 1.1 christos static int
590 1.1 christos dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
591 1.1 christos {
592 1.1.1.2 christos struct config_strlist *head, *head2;
593 1.1 christos size_t signed_cert_id;
594 1.1.1.2 christos size_t rotated_cert_id;
595 1.1 christos char *nm;
596 1.1 christos
597 1.1 christos env->signed_certs_count = 0U;
598 1.1.1.2 christos env->rotated_certs_count = 0U;
599 1.1 christos for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
600 1.1 christos env->signed_certs_count++;
601 1.1 christos }
602 1.1.1.2 christos for (head = cfg->dnscrypt_provider_cert_rotated; head; head = head->next) {
603 1.1.1.2 christos env->rotated_certs_count++;
604 1.1.1.2 christos }
605 1.1 christos env->signed_certs = sodium_allocarray(env->signed_certs_count,
606 1.1 christos sizeof *env->signed_certs);
607 1.1 christos
608 1.1.1.2 christos env->rotated_certs = sodium_allocarray(env->rotated_certs_count,
609 1.1.1.2 christos sizeof env->signed_certs);
610 1.1 christos signed_cert_id = 0U;
611 1.1.1.2 christos rotated_cert_id = 0U;
612 1.1 christos for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
613 1.1 christos nm = dnsc_chroot_path(cfg, head->str);
614 1.1 christos if(dnsc_read_from_file(
615 1.1 christos nm,
616 1.1 christos (char *)(env->signed_certs + signed_cert_id),
617 1.1 christos sizeof(struct SignedCert)) != 0) {
618 1.1 christos fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
619 1.1 christos }
620 1.1.1.2 christos for(head2 = cfg->dnscrypt_provider_cert_rotated; head2; head2 = head2->next) {
621 1.1.1.2 christos if(strcmp(head->str, head2->str) == 0) {
622 1.1.1.2 christos *(env->rotated_certs + rotated_cert_id) = env->signed_certs + signed_cert_id;
623 1.1.1.2 christos rotated_cert_id++;
624 1.1.1.2 christos verbose(VERB_OPS, "Cert %s is rotated and will not be distributed via DNS", head->str);
625 1.1.1.2 christos break;
626 1.1.1.2 christos }
627 1.1.1.2 christos }
628 1.1 christos verbose(VERB_OPS, "Loaded cert %s", head->str);
629 1.1 christos }
630 1.1 christos return signed_cert_id;
631 1.1 christos }
632 1.1 christos
633 1.1 christos /**
634 1.1 christos * Helper function to convert a binary key into a printable fingerprint.
635 1.1 christos * \param[in] fingerprint the buffer in which to write the printable key.
636 1.1 christos * \param[in] key the key to convert.
637 1.1 christos */
638 1.1 christos void
639 1.1 christos dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
640 1.1 christos {
641 1.1 christos const size_t fingerprint_size = 80U;
642 1.1 christos size_t fingerprint_pos = (size_t) 0U;
643 1.1 christos size_t key_pos = (size_t) 0U;
644 1.1 christos
645 1.1 christos for (;;) {
646 1.1 christos assert(fingerprint_size > fingerprint_pos);
647 1.1 christos snprintf(&fingerprint[fingerprint_pos],
648 1.1 christos fingerprint_size - fingerprint_pos, "%02X%02X",
649 1.1 christos key[key_pos], key[key_pos + 1U]);
650 1.1 christos key_pos += 2U;
651 1.1 christos if (key_pos >= crypto_box_PUBLICKEYBYTES) {
652 1.1 christos break;
653 1.1 christos }
654 1.1 christos fingerprint[fingerprint_pos + 4U] = ':';
655 1.1 christos fingerprint_pos += 5U;
656 1.1 christos }
657 1.1 christos }
658 1.1 christos
659 1.1 christos /**
660 1.1 christos * Find the cert matching a DNSCrypt query.
661 1.1 christos * \param[in] dnscenv The DNSCrypt environment, which contains the list of certs
662 1.1 christos * supported by the server.
663 1.1 christos * \param[in] buffer The encrypted DNS query.
664 1.1 christos * \return a dnsccert * if we found a cert matching the magic_number of the
665 1.1 christos * query, NULL otherwise.
666 1.1 christos */
667 1.1 christos static const dnsccert *
668 1.1 christos dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
669 1.1 christos {
670 1.1 christos const dnsccert *certs = dnscenv->certs;
671 1.1 christos struct dnscrypt_query_header *dnscrypt_header;
672 1.1 christos size_t i;
673 1.1 christos
674 1.1 christos if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) {
675 1.1 christos return NULL;
676 1.1 christos }
677 1.1 christos dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
678 1.1 christos for (i = 0U; i < dnscenv->signed_certs_count; i++) {
679 1.1 christos if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
680 1.1 christos DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
681 1.1 christos return &certs[i];
682 1.1 christos }
683 1.1 christos }
684 1.1 christos return NULL;
685 1.1 christos }
686 1.1 christos
687 1.1 christos /**
688 1.1 christos * Insert local-zone and local-data into configuration.
689 1.1 christos * In order to be able to serve certs over TXT, we can reuse the local-zone and
690 1.1 christos * local-data config option. The zone and qname are infered from the
691 1.1 christos * provider_name and the content of the TXT record from the certificate content.
692 1.1 christos * returns the number of certificate TXT record that were loaded.
693 1.1 christos * < 0 in case of error.
694 1.1 christos */
695 1.1 christos static int
696 1.1 christos dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
697 1.1 christos {
698 1.1 christos size_t i, j;
699 1.1 christos // Insert 'local-zone: "2.dnscrypt-cert.example.com" deny'
700 1.1 christos if(!cfg_str2list_insert(&cfg->local_zones,
701 1.1 christos strdup(dnscenv->provider_name),
702 1.1 christos strdup("deny"))) {
703 1.1 christos log_err("Could not load dnscrypt local-zone: %s deny",
704 1.1 christos dnscenv->provider_name);
705 1.1 christos return -1;
706 1.1 christos }
707 1.1 christos
708 1.1 christos // Add local data entry of type:
709 1.1 christos // 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
710 1.1 christos for(i=0; i<dnscenv->signed_certs_count; i++) {
711 1.1 christos const char *ttl_class_type = " 86400 IN TXT \"";
712 1.1.1.2 christos int rotated_cert = 0;
713 1.1.1.2 christos uint32_t serial;
714 1.1.1.2 christos uint16_t rrlen;
715 1.1.1.2 christos char* rr;
716 1.1 christos struct SignedCert *cert = dnscenv->signed_certs + i;
717 1.1.1.2 christos // Check if the certificate is being rotated and should not be published
718 1.1.1.2 christos for(j=0; j<dnscenv->rotated_certs_count; j++){
719 1.1.1.2 christos if(cert == dnscenv->rotated_certs[j]) {
720 1.1.1.2 christos rotated_cert = 1;
721 1.1.1.2 christos break;
722 1.1.1.2 christos }
723 1.1.1.2 christos }
724 1.1.1.2 christos memcpy(&serial, cert->serial, sizeof serial);
725 1.1.1.2 christos serial = htonl(serial);
726 1.1.1.2 christos if(rotated_cert) {
727 1.1.1.2 christos verbose(VERB_OPS,
728 1.1.1.2 christos "DNSCrypt: not adding cert with serial #%"
729 1.1.1.2 christos PRIu32
730 1.1.1.2 christos " to local-data as it is rotated",
731 1.1.1.2 christos serial
732 1.1.1.2 christos );
733 1.1.1.2 christos continue;
734 1.1.1.2 christos }
735 1.1.1.2 christos rrlen = strlen(dnscenv->provider_name) +
736 1.1 christos strlen(ttl_class_type) +
737 1.1 christos 4 * sizeof(struct SignedCert) + // worst case scenario
738 1.1 christos 1 + // trailing double quote
739 1.1 christos 1;
740 1.1.1.2 christos rr = malloc(rrlen);
741 1.1 christos if(!rr) {
742 1.1 christos log_err("Could not allocate memory");
743 1.1 christos return -2;
744 1.1 christos }
745 1.1 christos snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
746 1.1 christos for(j=0; j<sizeof(struct SignedCert); j++) {
747 1.1.1.2 christos int c = (int)*((const uint8_t *) cert + j);
748 1.1 christos if (isprint(c) && c != '"' && c != '\\') {
749 1.1 christos snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
750 1.1 christos } else {
751 1.1 christos snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
752 1.1 christos }
753 1.1 christos }
754 1.1.1.2 christos verbose(VERB_OPS,
755 1.1.1.2 christos "DNSCrypt: adding cert with serial #%"
756 1.1.1.2 christos PRIu32
757 1.1.1.2 christos " to local-data to config: %s",
758 1.1.1.2 christos serial, rr
759 1.1.1.2 christos );
760 1.1 christos snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
761 1.1 christos cfg_strlist_insert(&cfg->local_data, strdup(rr));
762 1.1 christos free(rr);
763 1.1 christos }
764 1.1 christos return dnscenv->signed_certs_count;
765 1.1 christos }
766 1.1 christos
767 1.1 christos static const char *
768 1.1 christos key_get_es_version(uint8_t version[2])
769 1.1 christos {
770 1.1 christos struct es_version {
771 1.1 christos uint8_t es_version[2];
772 1.1 christos const char *name;
773 1.1 christos };
774 1.1 christos
775 1.1.1.3 christos const int num_versions = 2;
776 1.1 christos struct es_version es_versions[] = {
777 1.1 christos {{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
778 1.1 christos {{0x00, 0x02}, "X25519-XChacha20Poly1305"},
779 1.1 christos };
780 1.1 christos int i;
781 1.1.1.3 christos for(i=0; i < num_versions; i++){
782 1.1 christos if(es_versions[i].es_version[0] == version[0] &&
783 1.1 christos es_versions[i].es_version[1] == version[1]){
784 1.1 christos return es_versions[i].name;
785 1.1 christos }
786 1.1 christos }
787 1.1 christos return NULL;
788 1.1 christos }
789 1.1 christos
790 1.1 christos
791 1.1 christos /**
792 1.1 christos * Parse the secret key files from `dnscrypt-secret-key` config and populates
793 1.1 christos * a list of dnsccert with es_version, magic number and secret/public keys
794 1.1 christos * supported by dnscrypt listener.
795 1.1 christos * \param[in] env The dnsc_env structure which will hold the keypairs.
796 1.1 christos * \param[in] cfg The config with the secret key file paths.
797 1.1 christos */
798 1.1 christos static int
799 1.1 christos dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
800 1.1 christos {
801 1.1 christos struct config_strlist *head;
802 1.1 christos size_t cert_id, keypair_id;
803 1.1 christos size_t c;
804 1.1 christos char *nm;
805 1.1 christos
806 1.1 christos env->keypairs_count = 0U;
807 1.1 christos for (head = cfg->dnscrypt_secret_key; head; head = head->next) {
808 1.1 christos env->keypairs_count++;
809 1.1 christos }
810 1.1 christos
811 1.1 christos env->keypairs = sodium_allocarray(env->keypairs_count,
812 1.1 christos sizeof *env->keypairs);
813 1.1 christos env->certs = sodium_allocarray(env->signed_certs_count,
814 1.1 christos sizeof *env->certs);
815 1.1 christos
816 1.1 christos cert_id = 0U;
817 1.1 christos keypair_id = 0U;
818 1.1 christos for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
819 1.1 christos char fingerprint[80];
820 1.1 christos int found_cert = 0;
821 1.1 christos KeyPair *current_keypair = &env->keypairs[keypair_id];
822 1.1 christos nm = dnsc_chroot_path(cfg, head->str);
823 1.1 christos if(dnsc_read_from_file(
824 1.1 christos nm,
825 1.1 christos (char *)(current_keypair->crypt_secretkey),
826 1.1 christos crypto_box_SECRETKEYBYTES) != 0) {
827 1.1 christos fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno));
828 1.1 christos }
829 1.1 christos verbose(VERB_OPS, "Loaded key %s", head->str);
830 1.1 christos if (crypto_scalarmult_base(current_keypair->crypt_publickey,
831 1.1 christos current_keypair->crypt_secretkey) != 0) {
832 1.1 christos fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
833 1.1 christos }
834 1.1 christos dnsc_key_to_fingerprint(fingerprint, current_keypair->crypt_publickey);
835 1.1 christos verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
836 1.1 christos // find the cert matching this key
837 1.1 christos for(c = 0; c < env->signed_certs_count; c++) {
838 1.1 christos if(memcmp(current_keypair->crypt_publickey,
839 1.1 christos env->signed_certs[c].server_publickey,
840 1.1 christos crypto_box_PUBLICKEYBYTES) == 0) {
841 1.1 christos dnsccert *current_cert = &env->certs[cert_id++];
842 1.1 christos found_cert = 1;
843 1.1 christos current_cert->keypair = current_keypair;
844 1.1 christos memcpy(current_cert->magic_query,
845 1.1 christos env->signed_certs[c].magic_query,
846 1.1 christos sizeof env->signed_certs[c].magic_query);
847 1.1 christos memcpy(current_cert->es_version,
848 1.1 christos env->signed_certs[c].version_major,
849 1.1 christos sizeof env->signed_certs[c].version_major
850 1.1 christos );
851 1.1 christos dnsc_key_to_fingerprint(fingerprint,
852 1.1 christos current_cert->keypair->crypt_publickey);
853 1.1 christos verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s",
854 1.1 christos head->str, fingerprint);
855 1.1 christos verbose(VERB_OPS, "Using %s",
856 1.1 christos key_get_es_version(current_cert->es_version));
857 1.1 christos #ifndef USE_DNSCRYPT_XCHACHA20
858 1.1 christos if (current_cert->es_version[1] == 0x02) {
859 1.1 christos fatal_exit("Certificate for XChacha20 but libsodium does not support it.");
860 1.1 christos }
861 1.1 christos #endif
862 1.1 christos
863 1.1 christos }
864 1.1 christos }
865 1.1 christos if (!found_cert) {
866 1.1 christos fatal_exit("dnsc_parse_keys: could not match certificate for key "
867 1.1 christos "%s. Unable to determine ES version.",
868 1.1 christos head->str);
869 1.1 christos }
870 1.1 christos }
871 1.1 christos return cert_id;
872 1.1 christos }
873 1.1 christos
874 1.1.1.2 christos static void
875 1.1.1.2 christos sodium_misuse_handler(void)
876 1.1.1.2 christos {
877 1.1.1.2 christos fatal_exit(
878 1.1.1.2 christos "dnscrypt: libsodium could not be initialized, this typically"
879 1.1.1.2 christos " happens when no good source of entropy is found. If you run"
880 1.1.1.2 christos " unbound in a chroot, make sure /dev/random is available. See"
881 1.1.1.2 christos " https://www.unbound.net/documentation/unbound.conf.html");
882 1.1.1.2 christos }
883 1.1.1.2 christos
884 1.1 christos
885 1.1 christos /**
886 1.1 christos * #########################################################
887 1.1 christos * ############# Publicly accessible functions #############
888 1.1 christos * #########################################################
889 1.1 christos */
890 1.1 christos
891 1.1 christos int
892 1.1 christos dnsc_handle_curved_request(struct dnsc_env* dnscenv,
893 1.1 christos struct comm_reply* repinfo)
894 1.1 christos {
895 1.1 christos struct comm_point* c = repinfo->c;
896 1.1 christos
897 1.1 christos repinfo->is_dnscrypted = 0;
898 1.1 christos if( !c->dnscrypt ) {
899 1.1 christos return 1;
900 1.1 christos }
901 1.1 christos // Attempt to decrypt the query. If it is not crypted, we may still need
902 1.1 christos // to serve the certificate.
903 1.1 christos verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
904 1.1 christos if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) {
905 1.1 christos if(dnscrypt_server_uncurve(dnscenv,
906 1.1 christos repinfo->dnsc_cert,
907 1.1 christos repinfo->client_nonce,
908 1.1 christos repinfo->nmkey,
909 1.1 christos c->buffer) != 0){
910 1.1 christos verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
911 1.1 christos comm_point_drop_reply(repinfo);
912 1.1 christos return 0;
913 1.1 christos }
914 1.1 christos repinfo->is_dnscrypted = 1;
915 1.1 christos sldns_buffer_rewind(c->buffer);
916 1.1 christos }
917 1.1 christos return 1;
918 1.1 christos }
919 1.1 christos
920 1.1 christos int
921 1.1 christos dnsc_handle_uncurved_request(struct comm_reply *repinfo)
922 1.1 christos {
923 1.1 christos if(!repinfo->c->dnscrypt) {
924 1.1 christos return 1;
925 1.1 christos }
926 1.1 christos sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
927 1.1 christos if(!repinfo->is_dnscrypted) {
928 1.1 christos return 1;
929 1.1 christos }
930 1.1 christos if(dnscrypt_server_curve(repinfo->dnsc_cert,
931 1.1 christos repinfo->client_nonce,
932 1.1 christos repinfo->nmkey,
933 1.1 christos repinfo->c->dnscrypt_buffer,
934 1.1 christos repinfo->c->type == comm_udp,
935 1.1 christos repinfo->max_udp_size) != 0){
936 1.1 christos verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
937 1.1 christos comm_point_drop_reply(repinfo);
938 1.1 christos return 0;
939 1.1 christos }
940 1.1 christos return 1;
941 1.1 christos }
942 1.1 christos
943 1.1 christos struct dnsc_env *
944 1.1 christos dnsc_create(void)
945 1.1 christos {
946 1.1 christos struct dnsc_env *env;
947 1.1.1.2 christos #ifdef SODIUM_MISUSE_HANDLER
948 1.1.1.2 christos sodium_set_misuse_handler(sodium_misuse_handler);
949 1.1.1.2 christos #endif
950 1.1 christos if (sodium_init() == -1) {
951 1.1 christos fatal_exit("dnsc_create: could not initialize libsodium.");
952 1.1 christos }
953 1.1 christos env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
954 1.1 christos lock_basic_init(&env->shared_secrets_cache_lock);
955 1.1 christos lock_protect(&env->shared_secrets_cache_lock,
956 1.1 christos &env->num_query_dnscrypt_secret_missed_cache,
957 1.1 christos sizeof(env->num_query_dnscrypt_secret_missed_cache));
958 1.1 christos lock_basic_init(&env->nonces_cache_lock);
959 1.1 christos lock_protect(&env->nonces_cache_lock,
960 1.1 christos &env->nonces_cache,
961 1.1 christos sizeof(env->nonces_cache));
962 1.1 christos lock_protect(&env->nonces_cache_lock,
963 1.1 christos &env->num_query_dnscrypt_replay,
964 1.1 christos sizeof(env->num_query_dnscrypt_replay));
965 1.1 christos
966 1.1 christos return env;
967 1.1 christos }
968 1.1 christos
969 1.1 christos int
970 1.1 christos dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
971 1.1 christos {
972 1.1 christos if(dnsc_parse_certs(env, cfg) <= 0) {
973 1.1 christos fatal_exit("dnsc_apply_cfg: no cert file loaded");
974 1.1 christos }
975 1.1 christos if(dnsc_parse_keys(env, cfg) <= 0) {
976 1.1 christos fatal_exit("dnsc_apply_cfg: no key file loaded");
977 1.1 christos }
978 1.1 christos randombytes_buf(env->hash_key, sizeof env->hash_key);
979 1.1 christos env->provider_name = cfg->dnscrypt_provider;
980 1.1 christos
981 1.1 christos if(dnsc_load_local_data(env, cfg) <= 0) {
982 1.1 christos fatal_exit("dnsc_apply_cfg: could not load local data");
983 1.1 christos }
984 1.1.1.2 christos lock_basic_lock(&env->shared_secrets_cache_lock);
985 1.1 christos env->shared_secrets_cache = slabhash_create(
986 1.1 christos cfg->dnscrypt_shared_secret_cache_slabs,
987 1.1 christos HASH_DEFAULT_STARTARRAY,
988 1.1 christos cfg->dnscrypt_shared_secret_cache_size,
989 1.1 christos dnsc_shared_secrets_sizefunc,
990 1.1 christos dnsc_shared_secrets_compfunc,
991 1.1 christos dnsc_shared_secrets_delkeyfunc,
992 1.1 christos dnsc_shared_secrets_deldatafunc,
993 1.1 christos NULL
994 1.1 christos );
995 1.1.1.2 christos lock_basic_unlock(&env->shared_secrets_cache_lock);
996 1.1 christos if(!env->shared_secrets_cache){
997 1.1 christos fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
998 1.1 christos }
999 1.1.1.2 christos lock_basic_lock(&env->nonces_cache_lock);
1000 1.1 christos env->nonces_cache = slabhash_create(
1001 1.1 christos cfg->dnscrypt_nonce_cache_slabs,
1002 1.1 christos HASH_DEFAULT_STARTARRAY,
1003 1.1 christos cfg->dnscrypt_nonce_cache_size,
1004 1.1 christos dnsc_nonces_sizefunc,
1005 1.1 christos dnsc_nonces_compfunc,
1006 1.1 christos dnsc_nonces_delkeyfunc,
1007 1.1 christos dnsc_nonces_deldatafunc,
1008 1.1 christos NULL
1009 1.1 christos );
1010 1.1.1.2 christos lock_basic_unlock(&env->nonces_cache_lock);
1011 1.1 christos return 0;
1012 1.1 christos }
1013 1.1 christos
1014 1.1 christos void
1015 1.1 christos dnsc_delete(struct dnsc_env *env)
1016 1.1 christos {
1017 1.1 christos if(!env) {
1018 1.1 christos return;
1019 1.1 christos }
1020 1.1 christos verbose(VERB_OPS, "DNSCrypt: Freeing environment.");
1021 1.1 christos sodium_free(env->signed_certs);
1022 1.1.1.2 christos sodium_free(env->rotated_certs);
1023 1.1 christos sodium_free(env->certs);
1024 1.1 christos sodium_free(env->keypairs);
1025 1.1 christos lock_basic_destroy(&env->shared_secrets_cache_lock);
1026 1.1 christos lock_basic_destroy(&env->nonces_cache_lock);
1027 1.1.1.2 christos slabhash_delete(env->shared_secrets_cache);
1028 1.1.1.2 christos slabhash_delete(env->nonces_cache);
1029 1.1 christos free(env);
1030 1.1 christos }
1031 1.1 christos
1032 1.1 christos /**
1033 1.1 christos * #########################################################
1034 1.1 christos * ############# Shared secrets cache functions ############
1035 1.1 christos * #########################################################
1036 1.1 christos */
1037 1.1 christos
1038 1.1 christos size_t
1039 1.1 christos dnsc_shared_secrets_sizefunc(void *k, void* ATTR_UNUSED(d))
1040 1.1 christos {
1041 1.1 christos struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1042 1.1 christos size_t key_size = sizeof(struct shared_secret_cache_key)
1043 1.1 christos + lock_get_mem(&ssk->entry.lock);
1044 1.1 christos size_t data_size = crypto_box_BEFORENMBYTES;
1045 1.1 christos (void)ssk; /* otherwise ssk is unused if no threading, or fixed locksize */
1046 1.1 christos return key_size + data_size;
1047 1.1 christos }
1048 1.1 christos
1049 1.1 christos int
1050 1.1 christos dnsc_shared_secrets_compfunc(void *m1, void *m2)
1051 1.1 christos {
1052 1.1 christos return sodium_memcmp(m1, m2, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
1053 1.1 christos }
1054 1.1 christos
1055 1.1 christos void
1056 1.1 christos dnsc_shared_secrets_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1057 1.1 christos {
1058 1.1 christos struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1059 1.1 christos lock_rw_destroy(&ssk->entry.lock);
1060 1.1 christos free(ssk);
1061 1.1 christos }
1062 1.1 christos
1063 1.1 christos void
1064 1.1 christos dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg))
1065 1.1 christos {
1066 1.1 christos uint8_t* data = (uint8_t*)d;
1067 1.1 christos free(data);
1068 1.1 christos }
1069 1.1 christos
1070 1.1 christos /**
1071 1.1 christos * #########################################################
1072 1.1 christos * ############### Nonces cache functions ##################
1073 1.1 christos * #########################################################
1074 1.1 christos */
1075 1.1 christos
1076 1.1 christos size_t
1077 1.1 christos dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
1078 1.1 christos {
1079 1.1 christos struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1080 1.1 christos size_t key_size = sizeof(struct nonce_cache_key)
1081 1.1 christos + lock_get_mem(&nk->entry.lock);
1082 1.1 christos (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
1083 1.1 christos return key_size;
1084 1.1 christos }
1085 1.1 christos
1086 1.1 christos int
1087 1.1 christos dnsc_nonces_compfunc(void *m1, void *m2)
1088 1.1 christos {
1089 1.1 christos struct nonce_cache_key *k1 = m1, *k2 = m2;
1090 1.1 christos return
1091 1.1 christos sodium_memcmp(
1092 1.1 christos k1->nonce,
1093 1.1 christos k2->nonce,
1094 1.1 christos crypto_box_HALF_NONCEBYTES) != 0 ||
1095 1.1 christos sodium_memcmp(
1096 1.1 christos k1->magic_query,
1097 1.1 christos k2->magic_query,
1098 1.1 christos DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
1099 1.1 christos sodium_memcmp(
1100 1.1 christos k1->client_publickey, k2->client_publickey,
1101 1.1 christos crypto_box_PUBLICKEYBYTES) != 0;
1102 1.1 christos }
1103 1.1 christos
1104 1.1 christos void
1105 1.1 christos dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1106 1.1 christos {
1107 1.1 christos struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1108 1.1 christos lock_rw_destroy(&nk->entry.lock);
1109 1.1 christos free(nk);
1110 1.1 christos }
1111 1.1 christos
1112 1.1 christos void
1113 1.1 christos dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))
1114 1.1 christos {
1115 1.1 christos return;
1116 1.1 christos }
1117