xref: /freebsd/contrib/unbound/dnscrypt/dnscrypt.c (revision e86b9096)
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
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
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*
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
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
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*
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
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
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
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 seconf 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
443 add_server_nonce(uint8_t *nonce)
444 {
445     uint64_t ts;
446     uint64_t tsn;
447     uint32_t suffix;
448     ts = dnscrypt_hrtime();
449     // TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
450     // unclear if we really need it, so skipping it for now.
451     tsn = (ts << 10) | (randombytes_random() & 0x3ff);
452 #if (BYTE_ORDER == LITTLE_ENDIAN)
453     tsn =
454         (((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
455 #endif
456     memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
457     suffix = randombytes_random();
458     memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
459 }
460 
461 /**
462  * Encrypt a reply using the dnsccert that was used with the query.
463  * The client nonce will be extracted from the encrypted query and stored in
464  * The buffer will be encrypted inplace.
465  * \param[in] cert the dnsccert that matches this encrypted query.
466  * \param[in] client_nonce client nonce used during the query
467  * \param[in] nmkey shared secret key used during the query.
468  * \param[in] buffer the buffer where to encrypt the reply.
469  * \param[in] udp if whether or not it is a UDP query.
470  * \param[in] max_udp_size configured max udp size.
471  * \return 0 on success.
472  */
473 static int
474 dnscrypt_server_curve(const dnsccert *cert,
475                       uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
476                       uint8_t nmkey[crypto_box_BEFORENMBYTES],
477                       struct sldns_buffer* buffer,
478                       uint8_t udp,
479                       size_t max_udp_size)
480 {
481     size_t dns_reply_len = sldns_buffer_limit(buffer);
482     size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING \
483         + DNSCRYPT_REPLY_HEADER_SIZE;
484     size_t max_reply_size = max_udp_size - 20U - 8U;
485     uint8_t nonce[crypto_box_NONCEBYTES];
486     uint8_t *boxed;
487     uint8_t *const buf = sldns_buffer_begin(buffer);
488     size_t len = sldns_buffer_limit(buffer);
489 
490     if(udp){
491         if (max_len > max_reply_size)
492             max_len = max_reply_size;
493     }
494 
495 
496     memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
497     memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce,
498            crypto_box_HALF_NONCEBYTES);
499 
500     boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET;
501     memmove(boxed + crypto_box_MACBYTES, buf, len);
502     len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
503                        max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce,
504                        cert->keypair->crypt_secretkey);
505     sldns_buffer_set_at(buffer,
506                         DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
507                         0, crypto_box_ZEROBYTES);
508 
509     // add server nonce extension
510     add_server_nonce(nonce);
511 
512     if(cert->es_version[1] == 2) {
513 #ifdef USE_DNSCRYPT_XCHACHA20
514         if (crypto_box_curve25519xchacha20poly1305_easy_afternm
515             (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
516             return -1;
517         }
518 #else
519         return -1;
520 #endif
521     } else {
522         if (crypto_box_easy_afternm
523             (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
524             return -1;
525         }
526     }
527 
528     sldns_buffer_write_at(buffer,
529                           0,
530                           DNSCRYPT_MAGIC_RESPONSE,
531                           DNSCRYPT_MAGIC_HEADER_LEN);
532     sldns_buffer_write_at(buffer,
533                           DNSCRYPT_MAGIC_HEADER_LEN,
534                           nonce,
535                           crypto_box_NONCEBYTES);
536     sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
537     return 0;
538 }
539 
540 /**
541  * Read the content of fname into buf.
542  * \param[in] fname name of the file to read.
543  * \param[in] buf the buffer in which to read the content of the file.
544  * \param[in] count number of bytes to read.
545  * \return 0 on success.
546  */
547 static int
548 dnsc_read_from_file(char *fname, char *buf, size_t count)
549 {
550     int fd;
551     fd = open(fname, O_RDONLY);
552     if (fd == -1) {
553         return -1;
554     }
555     if (read(fd, buf, count) != (ssize_t)count) {
556         close(fd);
557         return -2;
558     }
559     close(fd);
560     return 0;
561 }
562 
563 /**
564  * Given an absolute path on the original root, returns the absolute path
565  * within the chroot. If chroot is disabled, the path is not modified.
566  * No char * is malloced so there is no need to free this.
567  * \param[in] cfg the configuration.
568  * \param[in] path the path from the original root.
569  * \return the path from inside the chroot.
570  */
571 static char *
572 dnsc_chroot_path(struct config_file *cfg, char *path)
573 {
574     char *nm;
575     nm = path;
576     if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
577         cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
578         nm += strlen(cfg->chrootdir);
579     return nm;
580 }
581 
582 /**
583  * Parse certificates files provided by the configuration and load them into
584  * dnsc_env.
585  * \param[in] env the dnsc_env structure to load the certs into.
586  * \param[in] cfg the configuration.
587  * \return the number of certificates loaded.
588  */
589 static int
590 dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
591 {
592 	struct config_strlist *head, *head2;
593 	size_t signed_cert_id;
594 	size_t rotated_cert_id;
595 	char *nm;
596 
597 	env->signed_certs_count = 0U;
598 	env->rotated_certs_count = 0U;
599 	for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
600 		env->signed_certs_count++;
601 	}
602 	for (head = cfg->dnscrypt_provider_cert_rotated; head; head = head->next) {
603 		env->rotated_certs_count++;
604 	}
605 	env->signed_certs = sodium_allocarray(env->signed_certs_count,
606 										  sizeof *env->signed_certs);
607 
608 	env->rotated_certs = sodium_allocarray(env->rotated_certs_count,
609 										  sizeof env->signed_certs);
610 	signed_cert_id = 0U;
611 	rotated_cert_id = 0U;
612 	for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
613 		nm = dnsc_chroot_path(cfg, head->str);
614 		if(dnsc_read_from_file(
615 				nm,
616 				(char *)(env->signed_certs + signed_cert_id),
617 				sizeof(struct SignedCert)) != 0) {
618 			fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
619 		}
620 		for(head2 = cfg->dnscrypt_provider_cert_rotated; head2; head2 = head2->next) {
621 			if(strcmp(head->str, head2->str) == 0) {
622 				*(env->rotated_certs + rotated_cert_id) = env->signed_certs + signed_cert_id;
623 				rotated_cert_id++;
624 				verbose(VERB_OPS, "Cert %s is rotated and will not be distributed via DNS", head->str);
625 				break;
626 			}
627 		}
628 		verbose(VERB_OPS, "Loaded cert %s", head->str);
629 	}
630 	return signed_cert_id;
631 }
632 
633 /**
634  * Helper function to convert a binary key into a printable fingerprint.
635  * \param[in] fingerprint the buffer in which to write the printable key.
636  * \param[in] key the key to convert.
637  */
638 void
639 dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
640 {
641     const size_t fingerprint_size = 80U;
642     size_t       fingerprint_pos = (size_t) 0U;
643     size_t       key_pos = (size_t) 0U;
644 
645     for (;;) {
646         assert(fingerprint_size > fingerprint_pos);
647         snprintf(&fingerprint[fingerprint_pos],
648                         fingerprint_size - fingerprint_pos, "%02X%02X",
649                         key[key_pos], key[key_pos + 1U]);
650         key_pos += 2U;
651         if (key_pos >= crypto_box_PUBLICKEYBYTES) {
652             break;
653         }
654         fingerprint[fingerprint_pos + 4U] = ':';
655         fingerprint_pos += 5U;
656     }
657 }
658 
659 /**
660  * Find the cert matching a DNSCrypt query.
661  * \param[in] dnscenv The DNSCrypt environment, which contains the list of certs
662  * supported by the server.
663  * \param[in] buffer The encrypted DNS query.
664  * \return a dnsccert * if we found a cert matching the magic_number of the
665  * query, NULL otherwise.
666  */
667 static const dnsccert *
668 dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
669 {
670 	const dnsccert *certs = dnscenv->certs;
671 	struct dnscrypt_query_header *dnscrypt_header;
672 	size_t i;
673 
674 	if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) {
675 		return NULL;
676 	}
677 	dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
678 	for (i = 0U; i < dnscenv->signed_certs_count; i++) {
679 		if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
680                    DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
681 			return &certs[i];
682 		}
683 	}
684 	return NULL;
685 }
686 
687 /**
688  * Insert local-zone and local-data into configuration.
689  * In order to be able to serve certs over TXT, we can reuse the local-zone and
690  * local-data config option. The zone and qname are infered from the
691  * provider_name and the content of the TXT record from the certificate content.
692  * returns the number of certificate TXT record that were loaded.
693  * < 0 in case of error.
694  */
695 static int
696 dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
697 {
698     size_t i, j;
699 	// Insert 'local-zone: "2.dnscrypt-cert.example.com" deny'
700     if(!cfg_str2list_insert(&cfg->local_zones,
701                             strdup(dnscenv->provider_name),
702                             strdup("deny"))) {
703         log_err("Could not load dnscrypt local-zone: %s deny",
704                 dnscenv->provider_name);
705         return -1;
706     }
707 
708     // Add local data entry of type:
709     // 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
710     for(i=0; i<dnscenv->signed_certs_count; i++) {
711         const char *ttl_class_type = " 86400 IN TXT \"";
712         int rotated_cert = 0;
713 	uint32_t serial;
714 	uint16_t rrlen;
715 	char* rr;
716         struct SignedCert *cert = dnscenv->signed_certs + i;
717 		// Check if the certificate is being rotated and should not be published
718         for(j=0; j<dnscenv->rotated_certs_count; j++){
719             if(cert == dnscenv->rotated_certs[j]) {
720                 rotated_cert = 1;
721                 break;
722             }
723         }
724 		memcpy(&serial, cert->serial, sizeof serial);
725 		serial = htonl(serial);
726         if(rotated_cert) {
727             verbose(VERB_OPS,
728                 "DNSCrypt: not adding cert with serial #%"
729                 PRIu32
730                 " to local-data as it is rotated",
731                 serial
732             );
733             continue;
734         }
735         rrlen = strlen(dnscenv->provider_name) +
736                          strlen(ttl_class_type) +
737                          4 * sizeof(struct SignedCert) + // worst case scenario
738                          1 + // trailing double quote
739                          1;
740         rr = malloc(rrlen);
741         if(!rr) {
742             log_err("Could not allocate memory");
743             return -2;
744         }
745         snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
746         for(j=0; j<sizeof(struct SignedCert); j++) {
747 			int c = (int)*((const uint8_t *) cert + j);
748             if (isprint(c) && c != '"' && c != '\\') {
749                 snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
750             } else {
751                 snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
752             }
753         }
754         verbose(VERB_OPS,
755 			"DNSCrypt: adding cert with serial #%"
756 			PRIu32
757 			" to local-data to config: %s",
758 			serial, rr
759 		);
760         snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
761         cfg_strlist_insert(&cfg->local_data, strdup(rr));
762         free(rr);
763     }
764     return dnscenv->signed_certs_count;
765 }
766 
767 static const char *
768 key_get_es_version(uint8_t version[2])
769 {
770     struct es_version {
771         uint8_t es_version[2];
772         const char *name;
773     };
774 
775     const int num_versions = 2;
776     struct es_version es_versions[] = {
777         {{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
778         {{0x00, 0x02}, "X25519-XChacha20Poly1305"},
779     };
780     int i;
781     for(i=0; i < num_versions; i++){
782         if(es_versions[i].es_version[0] == version[0] &&
783            es_versions[i].es_version[1] == version[1]){
784             return es_versions[i].name;
785         }
786     }
787     return NULL;
788 }
789 
790 
791 /**
792  * Parse the secret key files from `dnscrypt-secret-key` config and populates
793  * a list of dnsccert with es_version, magic number and secret/public keys
794  * supported by dnscrypt listener.
795  * \param[in] env The dnsc_env structure which will hold the keypairs.
796  * \param[in] cfg The config with the secret key file paths.
797  */
798 static int
799 dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
800 {
801 	struct config_strlist *head;
802 	size_t cert_id, keypair_id;
803 	size_t c;
804 	char *nm;
805 
806 	env->keypairs_count = 0U;
807 	for (head = cfg->dnscrypt_secret_key; head; head = head->next) {
808 		env->keypairs_count++;
809 	}
810 
811 	env->keypairs = sodium_allocarray(env->keypairs_count,
812 		sizeof *env->keypairs);
813 	env->certs = sodium_allocarray(env->signed_certs_count,
814 		sizeof *env->certs);
815 
816 	cert_id = 0U;
817 	keypair_id = 0U;
818 	for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
819 		char fingerprint[80];
820 		int found_cert = 0;
821 		KeyPair *current_keypair = &env->keypairs[keypair_id];
822 		nm = dnsc_chroot_path(cfg, head->str);
823 		if(dnsc_read_from_file(
824 				nm,
825 				(char *)(current_keypair->crypt_secretkey),
826 				crypto_box_SECRETKEYBYTES) != 0) {
827 			fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno));
828 		}
829 		verbose(VERB_OPS, "Loaded key %s", head->str);
830 		if (crypto_scalarmult_base(current_keypair->crypt_publickey,
831 			current_keypair->crypt_secretkey) != 0) {
832 			fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
833 		}
834 		dnsc_key_to_fingerprint(fingerprint, current_keypair->crypt_publickey);
835 		verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
836 		// find the cert matching this key
837 		for(c = 0; c < env->signed_certs_count; c++) {
838 			if(memcmp(current_keypair->crypt_publickey,
839 				env->signed_certs[c].server_publickey,
840 				crypto_box_PUBLICKEYBYTES) == 0) {
841 				dnsccert *current_cert = &env->certs[cert_id++];
842 				found_cert = 1;
843 				current_cert->keypair = current_keypair;
844 				memcpy(current_cert->magic_query,
845 				       env->signed_certs[c].magic_query,
846 					sizeof env->signed_certs[c].magic_query);
847 				memcpy(current_cert->es_version,
848 				       env->signed_certs[c].version_major,
849 				       sizeof env->signed_certs[c].version_major
850 				);
851 				dnsc_key_to_fingerprint(fingerprint,
852 							current_cert->keypair->crypt_publickey);
853 				verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s",
854 					head->str, fingerprint);
855 				verbose(VERB_OPS, "Using %s",
856 					key_get_es_version(current_cert->es_version));
857 #ifndef USE_DNSCRYPT_XCHACHA20
858 				if (current_cert->es_version[1] == 0x02) {
859 				    fatal_exit("Certificate for XChacha20 but libsodium does not support it.");
860 				}
861 #endif
862 
863             		}
864         	}
865 		if (!found_cert) {
866 		    fatal_exit("dnsc_parse_keys: could not match certificate for key "
867 			       "%s. Unable to determine ES version.",
868 			       head->str);
869 		}
870 	}
871 	return cert_id;
872 }
873 
874 static void
875 sodium_misuse_handler(void)
876 {
877 	fatal_exit(
878 		"dnscrypt: libsodium could not be initialized, this typically"
879 		" happens when no good source of entropy is found. If you run"
880 		" unbound in a chroot, make sure /dev/random is available. See"
881 		" https://www.unbound.net/documentation/unbound.conf.html");
882 }
883 
884 
885 /**
886  * #########################################################
887  * ############# Publicly accessible functions #############
888  * #########################################################
889  */
890 
891 int
892 dnsc_handle_curved_request(struct dnsc_env* dnscenv,
893                            struct comm_reply* repinfo)
894 {
895     struct comm_point* c = repinfo->c;
896 
897     repinfo->is_dnscrypted = 0;
898     if( !c->dnscrypt ) {
899         return 1;
900     }
901     // Attempt to decrypt the query. If it is not crypted, we may still need
902     // to serve the certificate.
903     verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
904     if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) {
905         if(dnscrypt_server_uncurve(dnscenv,
906                                    repinfo->dnsc_cert,
907                                    repinfo->client_nonce,
908                                    repinfo->nmkey,
909                                    c->buffer) != 0){
910             verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
911             comm_point_drop_reply(repinfo);
912             return 0;
913         }
914         repinfo->is_dnscrypted = 1;
915         sldns_buffer_rewind(c->buffer);
916     }
917     return 1;
918 }
919 
920 int
921 dnsc_handle_uncurved_request(struct comm_reply *repinfo)
922 {
923     if(!repinfo->c->dnscrypt) {
924         return 1;
925     }
926     sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
927     if(!repinfo->is_dnscrypted) {
928         return 1;
929     }
930 	if(dnscrypt_server_curve(repinfo->dnsc_cert,
931                              repinfo->client_nonce,
932                              repinfo->nmkey,
933                              repinfo->c->dnscrypt_buffer,
934                              repinfo->c->type == comm_udp,
935                              repinfo->max_udp_size) != 0){
936 		verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
937 		comm_point_drop_reply(repinfo);
938 		return 0;
939 	}
940     return 1;
941 }
942 
943 struct dnsc_env *
944 dnsc_create(void)
945 {
946 	struct dnsc_env *env;
947 #ifdef SODIUM_MISUSE_HANDLER
948 	sodium_set_misuse_handler(sodium_misuse_handler);
949 #endif
950 	if (sodium_init() == -1) {
951 		fatal_exit("dnsc_create: could not initialize libsodium.");
952 	}
953 	env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
954 	lock_basic_init(&env->shared_secrets_cache_lock);
955 	lock_protect(&env->shared_secrets_cache_lock,
956                  &env->num_query_dnscrypt_secret_missed_cache,
957                  sizeof(env->num_query_dnscrypt_secret_missed_cache));
958 	lock_basic_init(&env->nonces_cache_lock);
959 	lock_protect(&env->nonces_cache_lock,
960                  &env->nonces_cache,
961                  sizeof(env->nonces_cache));
962 	lock_protect(&env->nonces_cache_lock,
963                  &env->num_query_dnscrypt_replay,
964                  sizeof(env->num_query_dnscrypt_replay));
965 
966 	return env;
967 }
968 
969 int
970 dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
971 {
972     if(dnsc_parse_certs(env, cfg) <= 0) {
973         fatal_exit("dnsc_apply_cfg: no cert file loaded");
974     }
975     if(dnsc_parse_keys(env, cfg) <= 0) {
976         fatal_exit("dnsc_apply_cfg: no key file loaded");
977     }
978     randombytes_buf(env->hash_key, sizeof env->hash_key);
979     env->provider_name = cfg->dnscrypt_provider;
980 
981     if(dnsc_load_local_data(env, cfg) <= 0) {
982         fatal_exit("dnsc_apply_cfg: could not load local data");
983     }
984     lock_basic_lock(&env->shared_secrets_cache_lock);
985     env->shared_secrets_cache = slabhash_create(
986         cfg->dnscrypt_shared_secret_cache_slabs,
987         HASH_DEFAULT_STARTARRAY,
988         cfg->dnscrypt_shared_secret_cache_size,
989         dnsc_shared_secrets_sizefunc,
990         dnsc_shared_secrets_compfunc,
991         dnsc_shared_secrets_delkeyfunc,
992         dnsc_shared_secrets_deldatafunc,
993         NULL
994     );
995     lock_basic_unlock(&env->shared_secrets_cache_lock);
996     if(!env->shared_secrets_cache){
997         fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
998     }
999     lock_basic_lock(&env->nonces_cache_lock);
1000     env->nonces_cache = slabhash_create(
1001         cfg->dnscrypt_nonce_cache_slabs,
1002         HASH_DEFAULT_STARTARRAY,
1003         cfg->dnscrypt_nonce_cache_size,
1004         dnsc_nonces_sizefunc,
1005         dnsc_nonces_compfunc,
1006         dnsc_nonces_delkeyfunc,
1007         dnsc_nonces_deldatafunc,
1008         NULL
1009     );
1010     lock_basic_unlock(&env->nonces_cache_lock);
1011     return 0;
1012 }
1013 
1014 void
1015 dnsc_delete(struct dnsc_env *env)
1016 {
1017 	if(!env) {
1018 		return;
1019 	}
1020 	verbose(VERB_OPS, "DNSCrypt: Freeing environment.");
1021 	sodium_free(env->signed_certs);
1022 	sodium_free(env->rotated_certs);
1023 	sodium_free(env->certs);
1024 	sodium_free(env->keypairs);
1025 	lock_basic_destroy(&env->shared_secrets_cache_lock);
1026 	lock_basic_destroy(&env->nonces_cache_lock);
1027 	slabhash_delete(env->shared_secrets_cache);
1028 	slabhash_delete(env->nonces_cache);
1029 	free(env);
1030 }
1031 
1032 /**
1033  * #########################################################
1034  * ############# Shared secrets cache functions ############
1035  * #########################################################
1036  */
1037 
1038 size_t
1039 dnsc_shared_secrets_sizefunc(void *k, void* ATTR_UNUSED(d))
1040 {
1041     struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1042     size_t key_size = sizeof(struct shared_secret_cache_key)
1043         + lock_get_mem(&ssk->entry.lock);
1044     size_t data_size = crypto_box_BEFORENMBYTES;
1045     (void)ssk; /* otherwise ssk is unused if no threading, or fixed locksize */
1046     return key_size + data_size;
1047 }
1048 
1049 int
1050 dnsc_shared_secrets_compfunc(void *m1, void *m2)
1051 {
1052     return sodium_memcmp(m1, m2, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
1053 }
1054 
1055 void
1056 dnsc_shared_secrets_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1057 {
1058     struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1059     lock_rw_destroy(&ssk->entry.lock);
1060     free(ssk);
1061 }
1062 
1063 void
1064 dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg))
1065 {
1066     uint8_t* data = (uint8_t*)d;
1067     free(data);
1068 }
1069 
1070 /**
1071  * #########################################################
1072  * ############### Nonces cache functions ##################
1073  * #########################################################
1074  */
1075 
1076 size_t
1077 dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
1078 {
1079     struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1080     size_t key_size = sizeof(struct nonce_cache_key)
1081         + lock_get_mem(&nk->entry.lock);
1082     (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
1083     return key_size;
1084 }
1085 
1086 int
1087 dnsc_nonces_compfunc(void *m1, void *m2)
1088 {
1089     struct nonce_cache_key *k1 = m1, *k2 = m2;
1090     return
1091         sodium_memcmp(
1092             k1->nonce,
1093             k2->nonce,
1094             crypto_box_HALF_NONCEBYTES) != 0 ||
1095         sodium_memcmp(
1096             k1->magic_query,
1097             k2->magic_query,
1098             DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
1099         sodium_memcmp(
1100             k1->client_publickey, k2->client_publickey,
1101             crypto_box_PUBLICKEYBYTES) != 0;
1102 }
1103 
1104 void
1105 dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1106 {
1107     struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1108     lock_rw_destroy(&nk->entry.lock);
1109     free(nk);
1110 }
1111 
1112 void
1113 dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))
1114 {
1115     return;
1116 }
1117