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