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