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