dnscrypt.c revision 356345
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
56struct 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
64struct 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 */
85static uint32_t
86dnsc_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 */
108static void
109dnsc_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 */
142static struct lruhash_entry*
143dnsc_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 */
158static uint32_t
159dnsc_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 */
178static void
179dnsc_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 */
214static struct lruhash_entry*
215dnsc_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 */
243static int
244dnscrypt_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 */
391size_t
392dnscrypt_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
420uint64_t
421dnscrypt_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 */
442static void
443add_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 */
460static int
461dnscrypt_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 */
534static int
535dnsc_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 */
558static char *
559dnsc_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 */
576static int
577dnsc_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 */
625void
626dnsc_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 */
654static const dnsccert *
655dnsc_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 infered 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 */
682static int
683dnsc_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
759static const char *
760key_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 */
790static int
791dnsc_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
866static void
867sodium_misuse_handler(void)
868{
869	fatal_exit(
870		"dnscrypt: libsodium could not be initialized, this typically"
871		" happens when no good source of entropy is found. If you run"
872		" unbound in a chroot, make sure /dev/urandom is available. See"
873		" https://www.unbound.net/documentation/unbound.conf.html");
874}
875
876
877/**
878 * #########################################################
879 * ############# Publicly accessible functions #############
880 * #########################################################
881 */
882
883int
884dnsc_handle_curved_request(struct dnsc_env* dnscenv,
885                           struct comm_reply* repinfo)
886{
887    struct comm_point* c = repinfo->c;
888
889    repinfo->is_dnscrypted = 0;
890    if( !c->dnscrypt ) {
891        return 1;
892    }
893    // Attempt to decrypt the query. If it is not crypted, we may still need
894    // to serve the certificate.
895    verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
896    if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) {
897        if(dnscrypt_server_uncurve(dnscenv,
898                                   repinfo->dnsc_cert,
899                                   repinfo->client_nonce,
900                                   repinfo->nmkey,
901                                   c->buffer) != 0){
902            verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
903            comm_point_drop_reply(repinfo);
904            return 0;
905        }
906        repinfo->is_dnscrypted = 1;
907        sldns_buffer_rewind(c->buffer);
908    }
909    return 1;
910}
911
912int
913dnsc_handle_uncurved_request(struct comm_reply *repinfo)
914{
915    if(!repinfo->c->dnscrypt) {
916        return 1;
917    }
918    sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
919    if(!repinfo->is_dnscrypted) {
920        return 1;
921    }
922	if(dnscrypt_server_curve(repinfo->dnsc_cert,
923                             repinfo->client_nonce,
924                             repinfo->nmkey,
925                             repinfo->c->dnscrypt_buffer,
926                             repinfo->c->type == comm_udp,
927                             repinfo->max_udp_size) != 0){
928		verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
929		comm_point_drop_reply(repinfo);
930		return 0;
931	}
932    return 1;
933}
934
935struct dnsc_env *
936dnsc_create(void)
937{
938	struct dnsc_env *env;
939#ifdef SODIUM_MISUSE_HANDLER
940	sodium_set_misuse_handler(sodium_misuse_handler);
941#endif
942	if (sodium_init() == -1) {
943		fatal_exit("dnsc_create: could not initialize libsodium.");
944	}
945	env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
946	lock_basic_init(&env->shared_secrets_cache_lock);
947	lock_protect(&env->shared_secrets_cache_lock,
948                 &env->num_query_dnscrypt_secret_missed_cache,
949                 sizeof(env->num_query_dnscrypt_secret_missed_cache));
950	lock_basic_init(&env->nonces_cache_lock);
951	lock_protect(&env->nonces_cache_lock,
952                 &env->nonces_cache,
953                 sizeof(env->nonces_cache));
954	lock_protect(&env->nonces_cache_lock,
955                 &env->num_query_dnscrypt_replay,
956                 sizeof(env->num_query_dnscrypt_replay));
957
958	return env;
959}
960
961int
962dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
963{
964    if(dnsc_parse_certs(env, cfg) <= 0) {
965        fatal_exit("dnsc_apply_cfg: no cert file loaded");
966    }
967    if(dnsc_parse_keys(env, cfg) <= 0) {
968        fatal_exit("dnsc_apply_cfg: no key file loaded");
969    }
970    randombytes_buf(env->hash_key, sizeof env->hash_key);
971    env->provider_name = cfg->dnscrypt_provider;
972
973    if(dnsc_load_local_data(env, cfg) <= 0) {
974        fatal_exit("dnsc_apply_cfg: could not load local data");
975    }
976    lock_basic_lock(&env->shared_secrets_cache_lock);
977    env->shared_secrets_cache = slabhash_create(
978        cfg->dnscrypt_shared_secret_cache_slabs,
979        HASH_DEFAULT_STARTARRAY,
980        cfg->dnscrypt_shared_secret_cache_size,
981        dnsc_shared_secrets_sizefunc,
982        dnsc_shared_secrets_compfunc,
983        dnsc_shared_secrets_delkeyfunc,
984        dnsc_shared_secrets_deldatafunc,
985        NULL
986    );
987    lock_basic_unlock(&env->shared_secrets_cache_lock);
988    if(!env->shared_secrets_cache){
989        fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
990    }
991    lock_basic_lock(&env->nonces_cache_lock);
992    env->nonces_cache = slabhash_create(
993        cfg->dnscrypt_nonce_cache_slabs,
994        HASH_DEFAULT_STARTARRAY,
995        cfg->dnscrypt_nonce_cache_size,
996        dnsc_nonces_sizefunc,
997        dnsc_nonces_compfunc,
998        dnsc_nonces_delkeyfunc,
999        dnsc_nonces_deldatafunc,
1000        NULL
1001    );
1002    lock_basic_unlock(&env->nonces_cache_lock);
1003    return 0;
1004}
1005
1006void
1007dnsc_delete(struct dnsc_env *env)
1008{
1009	if(!env) {
1010		return;
1011	}
1012	verbose(VERB_OPS, "DNSCrypt: Freeing environment.");
1013	sodium_free(env->signed_certs);
1014	sodium_free(env->rotated_certs);
1015	sodium_free(env->certs);
1016	sodium_free(env->keypairs);
1017	lock_basic_destroy(&env->shared_secrets_cache_lock);
1018	lock_basic_destroy(&env->nonces_cache_lock);
1019	slabhash_delete(env->shared_secrets_cache);
1020	slabhash_delete(env->nonces_cache);
1021	free(env);
1022}
1023
1024/**
1025 * #########################################################
1026 * ############# Shared secrets cache functions ############
1027 * #########################################################
1028 */
1029
1030size_t
1031dnsc_shared_secrets_sizefunc(void *k, void* ATTR_UNUSED(d))
1032{
1033    struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1034    size_t key_size = sizeof(struct shared_secret_cache_key)
1035        + lock_get_mem(&ssk->entry.lock);
1036    size_t data_size = crypto_box_BEFORENMBYTES;
1037    (void)ssk; /* otherwise ssk is unused if no threading, or fixed locksize */
1038    return key_size + data_size;
1039}
1040
1041int
1042dnsc_shared_secrets_compfunc(void *m1, void *m2)
1043{
1044    return sodium_memcmp(m1, m2, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
1045}
1046
1047void
1048dnsc_shared_secrets_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1049{
1050    struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1051    lock_rw_destroy(&ssk->entry.lock);
1052    free(ssk);
1053}
1054
1055void
1056dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg))
1057{
1058    uint8_t* data = (uint8_t*)d;
1059    free(data);
1060}
1061
1062/**
1063 * #########################################################
1064 * ############### Nonces cache functions ##################
1065 * #########################################################
1066 */
1067
1068size_t
1069dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
1070{
1071    struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1072    size_t key_size = sizeof(struct nonce_cache_key)
1073        + lock_get_mem(&nk->entry.lock);
1074    (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
1075    return key_size;
1076}
1077
1078int
1079dnsc_nonces_compfunc(void *m1, void *m2)
1080{
1081    struct nonce_cache_key *k1 = m1, *k2 = m2;
1082    return
1083        sodium_memcmp(
1084            k1->nonce,
1085            k2->nonce,
1086            crypto_box_HALF_NONCEBYTES) != 0 ||
1087        sodium_memcmp(
1088            k1->magic_query,
1089            k2->magic_query,
1090            DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
1091        sodium_memcmp(
1092            k1->client_publickey, k2->client_publickey,
1093            crypto_box_PUBLICKEYBYTES) != 0;
1094}
1095
1096void
1097dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1098{
1099    struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1100    lock_rw_destroy(&nk->entry.lock);
1101    free(nk);
1102}
1103
1104void
1105dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))
1106{
1107    return;
1108}
1109