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