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