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