10 #include <sys/types.h>
11 #include "sldns/sbuffer.h"
12 #include "util/config_file.h"
13 #include "util/net_help.h"
14 #include "util/netevent.h"
16 #include "util/storage/slabhash.h"
17 #include "util/storage/lookup3.h"
19 #include "dnscrypt/cert.h"
20 #include "dnscrypt/dnscrypt.h"
21 #include "dnscrypt/dnscrypt_config.h"
28 * dnscrypt functions for encrypting DNS packets.
31 #define DNSCRYPT_QUERY_BOX_OFFSET \
32 (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + \
33 crypto_box_HALF_NONCEBYTES)
35 // 8 bytes: magic header (CERT_MAGIC_HEADER)
36 // 12 bytes: the client's nonce
37 // 12 bytes: server nonce extension
38 // 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
40 #define DNSCRYPT_REPLY_BOX_OFFSET \
41 (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES + \
42 crypto_box_HALF_NONCEBYTES)
46 * Shared secret cache key length.
48 * 1 byte: ES_VERSION[1]
49 * 32 bytes: client crypto_box_PUBLICKEYBYTES
50 * 32 bytes: server crypto_box_SECRETKEYBYTES
52 #define DNSCRYPT_SHARED_SECRET_KEY_LENGTH \
53 (1 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES)
56 struct shared_secret_cache_key {
57 /** the hash table key */
58 uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH];
59 /** the hash table entry, data is uint8_t pointer of size crypto_box_BEFORENMBYTES which contains the shared secret. */
60 struct lruhash_entry entry;
64 struct nonce_cache_key {
65 /** the nonce used by the client */
66 uint8_t nonce[crypto_box_HALF_NONCEBYTES];
67 /** the client_magic used by the client, this is associated to 1 cert only */
68 uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
69 /** the client public key */
70 uint8_t client_publickey[crypto_box_PUBLICKEYBYTES];
71 /** the hash table entry, data is uint8_t */
72 struct lruhash_entry entry;
76 * Generate a key suitable to find shared secret in slabhash.
77 * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
78 * \param[in] esversion: The es version least significant byte.
79 * \param[in] pk: The public key of the client. uint8_t pointer of size
80 * crypto_box_PUBLICKEYBYTES.
81 * \param[in] sk: The secret key of the server matching the magic query number.
82 * uint8_t pointer of size crypto_box_SECRETKEYBYTES.
83 * \return the hash of the key.
86 dnsc_shared_secrets_cache_key(uint8_t* key,
92 memcpy(key + 1, pk, crypto_box_PUBLICKEYBYTES);
93 memcpy(key + 1 + crypto_box_PUBLICKEYBYTES, sk, crypto_box_SECRETKEYBYTES);
94 return hashlittle(key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH, 0);
98 * Inserts a shared secret into the shared_secrets_cache slabhash.
99 * The shared secret is copied so the caller can use it freely without caring
100 * about the cache entry being evicted or not.
101 * \param[in] cache: the slabhash in which to look for the key.
102 * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
103 * which contains the key of the shared secret.
104 * \param[in] hash: the hash of the key.
105 * \param[in] nmkey: a uint8_t pointer of size crypto_box_BEFORENMBYTES which
106 * contains the shared secret.
109 dnsc_shared_secret_cache_insert(struct slabhash *cache,
110 uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH],
112 uint8_t nmkey[crypto_box_BEFORENMBYTES])
114 struct shared_secret_cache_key* k =
115 (struct shared_secret_cache_key*)calloc(1, sizeof(*k));
116 uint8_t* d = malloc(crypto_box_BEFORENMBYTES);
122 memcpy(d, nmkey, crypto_box_BEFORENMBYTES);
123 lock_rw_init(&k->entry.lock);
124 memcpy(k->key, key, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
125 k->entry.hash = hash;
128 slabhash_insert(cache,
135 * Lookup a record in shared_secrets_cache.
136 * \param[in] cache: a pointer to shared_secrets_cache slabhash.
137 * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
138 * containing the key to look for.
139 * \param[in] hash: a hash of the key.
140 * \return a pointer to the locked cache entry or NULL on failure.
142 static struct lruhash_entry*
143 dnsc_shared_secrets_lookup(struct slabhash* cache,
144 uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH],
147 return slabhash_lookup(cache, hash, key, 0);
151 * Generate a key hash suitable to find a nonce in slabhash.
152 * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
153 * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
154 * \param[in] pk: The public key of the client. uint8_t pointer of size
155 * crypto_box_PUBLICKEYBYTES.
156 * \return the hash of the key.
159 dnsc_nonce_cache_key_hash(const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
160 const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
161 const uint8_t pk[crypto_box_PUBLICKEYBYTES])
164 h = hashlittle(nonce, crypto_box_HALF_NONCEBYTES, h);
165 h = hashlittle(magic_query, DNSCRYPT_MAGIC_HEADER_LEN, h);
166 return hashlittle(pk, crypto_box_PUBLICKEYBYTES, h);
170 * Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash.
171 * \param[in] cache: the slabhash in which to look for the key.
172 * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
173 * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
174 * \param[in] pk: The public key of the client. uint8_t pointer of size
175 * crypto_box_PUBLICKEYBYTES.
176 * \param[in] hash: the hash of the key.
179 dnsc_nonce_cache_insert(struct slabhash *cache,
180 const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
181 const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
182 const uint8_t pk[crypto_box_PUBLICKEYBYTES],
185 struct nonce_cache_key* k =
186 (struct nonce_cache_key*)calloc(1, sizeof(*k));
191 lock_rw_init(&k->entry.lock);
192 memcpy(k->nonce, nonce, crypto_box_HALF_NONCEBYTES);
193 memcpy(k->magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
194 memcpy(k->client_publickey, pk, crypto_box_PUBLICKEYBYTES);
195 k->entry.hash = hash;
197 k->entry.data = NULL;
198 slabhash_insert(cache,
205 * Lookup a record in nonces_cache.
206 * \param[in] cache: the slabhash in which to look for the key.
207 * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
208 * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
209 * \param[in] pk: The public key of the client. uint8_t pointer of size
210 * crypto_box_PUBLICKEYBYTES.
211 * \param[in] hash: the hash of the key.
212 * \return a pointer to the locked cache entry or NULL on failure.
214 static struct lruhash_entry*
215 dnsc_nonces_lookup(struct slabhash* cache,
216 const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
217 const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
218 const uint8_t pk[crypto_box_PUBLICKEYBYTES],
221 struct nonce_cache_key k;
222 memset(&k, 0, sizeof(k));
224 memcpy(k.nonce, nonce, crypto_box_HALF_NONCEBYTES);
225 memcpy(k.magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
226 memcpy(k.client_publickey, pk, crypto_box_PUBLICKEYBYTES);
228 return slabhash_lookup(cache, hash, &k, 0);
232 * Decrypt a query using the dnsccert that was found using dnsc_find_cert.
233 * The client nonce will be extracted from the encrypted query and stored in
234 * client_nonce, a shared secret will be computed and stored in nmkey and the
235 * buffer will be decrypted inplace.
236 * \param[in] env the dnscrypt environment.
237 * \param[in] cert the cert that matches this encrypted query.
238 * \param[in] client_nonce where the client nonce will be stored.
239 * \param[in] nmkey where the shared secret key will be written.
240 * \param[in] buffer the encrypted buffer.
241 * \return 0 on success.
244 dnscrypt_server_uncurve(struct dnsc_env* env,
245 const dnsccert *cert,
246 uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
247 uint8_t nmkey[crypto_box_BEFORENMBYTES],
248 struct sldns_buffer* buffer)
250 size_t len = sldns_buffer_limit(buffer);
251 uint8_t *const buf = sldns_buffer_begin(buffer);
252 uint8_t nonce[crypto_box_NONCEBYTES];
253 struct dnscrypt_query_header *query_header;
254 // shared secret cache
255 uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH];
256 struct lruhash_entry* entry;
261 if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
265 query_header = (struct dnscrypt_query_header *)buf;
267 /* Detect replay attacks */
268 nonce_hash = dnsc_nonce_cache_key_hash(
271 query_header->publickey);
273 lock_basic_lock(&env->nonces_cache_lock);
274 entry = dnsc_nonces_lookup(
278 query_header->publickey,
282 lock_rw_unlock(&entry->lock);
283 env->num_query_dnscrypt_replay++;
284 lock_basic_unlock(&env->nonces_cache_lock);
288 dnsc_nonce_cache_insert(
292 query_header->publickey,
294 lock_basic_unlock(&env->nonces_cache_lock);
296 /* Find existing shared secret */
297 hash = dnsc_shared_secrets_cache_key(key,
299 query_header->publickey,
300 cert->keypair->crypt_secretkey);
301 entry = dnsc_shared_secrets_lookup(env->shared_secrets_cache,
306 lock_basic_lock(&env->shared_secrets_cache_lock);
307 env->num_query_dnscrypt_secret_missed_cache++;
308 lock_basic_unlock(&env->shared_secrets_cache_lock);
309 if(cert->es_version[1] == 2) {
310 #ifdef USE_DNSCRYPT_XCHACHA20
311 if (crypto_box_curve25519xchacha20poly1305_beforenm(
312 nmkey, query_header->publickey,
313 cert->keypair->crypt_secretkey) != 0) {
320 if (crypto_box_beforenm(nmkey,
321 query_header->publickey,
322 cert->keypair->crypt_secretkey) != 0) {
326 // Cache the shared secret we just computed.
327 dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
332 /* copy shared secret and unlock entry */
333 memcpy(nmkey, entry->data, crypto_box_BEFORENMBYTES);
334 lock_rw_unlock(&entry->lock);
337 memcpy(nonce, query_header->nonce, crypto_box_HALF_NONCEBYTES);
338 memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
340 if(cert->es_version[1] == 2) {
341 #ifdef USE_DNSCRYPT_XCHACHA20
342 if (crypto_box_curve25519xchacha20poly1305_open_easy_afternm
344 buf + DNSCRYPT_QUERY_BOX_OFFSET,
345 len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
353 if (crypto_box_open_easy_afternm
355 buf + DNSCRYPT_QUERY_BOX_OFFSET,
356 len - DNSCRYPT_QUERY_BOX_OFFSET, nonce,
362 len -= DNSCRYPT_QUERY_HEADER_SIZE;
364 while (*sldns_buffer_at(buffer, --len) == 0)
367 if (*sldns_buffer_at(buffer, len) != 0x80) {
371 memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
373 sldns_buffer_set_position(buffer, 0);
374 sldns_buffer_set_limit(buffer, len);
381 * Add random padding to a buffer, according to a client nonce.
382 * The length has to depend on the query in order to avoid reply attacks.
384 * @param buf a buffer
385 * @param len the initial size of the buffer
386 * @param max_len the maximum size
387 * @param nonce a nonce, made of the client nonce repeated twice
389 * @return the new size, after padding
392 dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len,
393 const uint8_t *nonce, const uint8_t *secretkey)
395 uint8_t *buf_padding_area = buf + len;
400 if (max_len < len + DNSCRYPT_MIN_PAD_LEN)
403 assert(nonce[crypto_box_HALF_NONCEBYTES] == nonce[0]);
405 crypto_stream((unsigned char *)&rnd, (unsigned long long)sizeof(rnd), nonce,
408 len + DNSCRYPT_MIN_PAD_LEN + rnd % (max_len - len -
409 DNSCRYPT_MIN_PAD_LEN + 1);
410 padded_len += DNSCRYPT_BLOCK_SIZE - padded_len % DNSCRYPT_BLOCK_SIZE;
411 if (padded_len > max_len)
412 padded_len = max_len;
414 memset(buf_padding_area, 0, padded_len - len);
415 *buf_padding_area = 0x80;
421 dnscrypt_hrtime(void)
424 uint64_t ts = (uint64_t)0U;
427 ret = gettimeofday(&tv, NULL);
429 ts = (uint64_t)tv.tv_sec * 1000000U + (uint64_t)tv.tv_usec;
431 log_err("gettimeofday: %s", strerror(errno));
437 * Add the server nonce part to once.
438 * The nonce is made half of client nonce and the seconf half of the server
439 * nonce, both of them of size crypto_box_HALF_NONCEBYTES.
440 * \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES
443 add_server_nonce(uint8_t *nonce)
448 ts = dnscrypt_hrtime();
449 // TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
450 // unclear if we really need it, so skipping it for now.
451 tsn = (ts << 10) | (randombytes_random() & 0x3ff);
452 #if (BYTE_ORDER == LITTLE_ENDIAN)
454 (((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
456 memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
457 suffix = randombytes_random();
458 memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
462 * Encrypt a reply using the dnsccert that was used with the query.
463 * The client nonce will be extracted from the encrypted query and stored in
464 * The buffer will be encrypted inplace.
465 * \param[in] cert the dnsccert that matches this encrypted query.
466 * \param[in] client_nonce client nonce used during the query
467 * \param[in] nmkey shared secret key used during the query.
468 * \param[in] buffer the buffer where to encrypt the reply.
469 * \param[in] udp if whether or not it is a UDP query.
470 * \param[in] max_udp_size configured max udp size.
471 * \return 0 on success.
474 dnscrypt_server_curve(const dnsccert *cert,
475 uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
476 uint8_t nmkey[crypto_box_BEFORENMBYTES],
477 struct sldns_buffer* buffer,
481 size_t dns_reply_len = sldns_buffer_limit(buffer);
482 size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING \
483 + DNSCRYPT_REPLY_HEADER_SIZE;
484 size_t max_reply_size = max_udp_size - 20U - 8U;
485 uint8_t nonce[crypto_box_NONCEBYTES];
487 uint8_t *const buf = sldns_buffer_begin(buffer);
488 size_t len = sldns_buffer_limit(buffer);
491 if (max_len > max_reply_size)
492 max_len = max_reply_size;
496 memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
497 memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce,
498 crypto_box_HALF_NONCEBYTES);
500 boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET;
501 memmove(boxed + crypto_box_MACBYTES, buf, len);
502 len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
503 max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce,
504 cert->keypair->crypt_secretkey);
505 sldns_buffer_set_at(buffer,
506 DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
507 0, crypto_box_ZEROBYTES);
509 // add server nonce extension
510 add_server_nonce(nonce);
512 if(cert->es_version[1] == 2) {
513 #ifdef USE_DNSCRYPT_XCHACHA20
514 if (crypto_box_curve25519xchacha20poly1305_easy_afternm
515 (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
522 if (crypto_box_easy_afternm
523 (boxed, boxed + crypto_box_MACBYTES, len, nonce, nmkey) != 0) {
528 sldns_buffer_write_at(buffer,
530 DNSCRYPT_MAGIC_RESPONSE,
531 DNSCRYPT_MAGIC_HEADER_LEN);
532 sldns_buffer_write_at(buffer,
533 DNSCRYPT_MAGIC_HEADER_LEN,
535 crypto_box_NONCEBYTES);
536 sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
541 * Read the content of fname into buf.
542 * \param[in] fname name of the file to read.
543 * \param[in] buf the buffer in which to read the content of the file.
544 * \param[in] count number of bytes to read.
545 * \return 0 on success.
548 dnsc_read_from_file(char *fname, char *buf, size_t count)
551 fd = open(fname, O_RDONLY);
555 if (read(fd, buf, count) != (ssize_t)count) {
564 * Given an absolute path on the original root, returns the absolute path
565 * within the chroot. If chroot is disabled, the path is not modified.
566 * No char * is malloced so there is no need to free this.
567 * \param[in] cfg the configuration.
568 * \param[in] path the path from the original root.
569 * \return the path from inside the chroot.
572 dnsc_chroot_path(struct config_file *cfg, char *path)
576 if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
577 cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
578 nm += strlen(cfg->chrootdir);
583 * Parse certificates files provided by the configuration and load them into
585 * \param[in] env the dnsc_env structure to load the certs into.
586 * \param[in] cfg the configuration.
587 * \return the number of certificates loaded.
590 dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
592 struct config_strlist *head, *head2;
593 size_t signed_cert_id;
594 size_t rotated_cert_id;
597 env->signed_certs_count = 0U;
598 env->rotated_certs_count = 0U;
599 for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
600 env->signed_certs_count++;
602 for (head = cfg->dnscrypt_provider_cert_rotated; head; head = head->next) {
603 env->rotated_certs_count++;
605 env->signed_certs = sodium_allocarray(env->signed_certs_count,
606 sizeof *env->signed_certs);
608 env->rotated_certs = sodium_allocarray(env->rotated_certs_count,
609 sizeof env->signed_certs);
611 rotated_cert_id = 0U;
612 for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
613 nm = dnsc_chroot_path(cfg, head->str);
614 if(dnsc_read_from_file(
616 (char *)(env->signed_certs + signed_cert_id),
617 sizeof(struct SignedCert)) != 0) {
618 fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
620 for(head2 = cfg->dnscrypt_provider_cert_rotated; head2; head2 = head2->next) {
621 if(strcmp(head->str, head2->str) == 0) {
622 *(env->rotated_certs + rotated_cert_id) = env->signed_certs + signed_cert_id;
624 verbose(VERB_OPS, "Cert %s is rotated and will not be distributed via DNS", head->str);
628 verbose(VERB_OPS, "Loaded cert %s", head->str);
630 return signed_cert_id;
634 * Helper function to convert a binary key into a printable fingerprint.
635 * \param[in] fingerprint the buffer in which to write the printable key.
636 * \param[in] key the key to convert.
639 dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
641 const size_t fingerprint_size = 80U;
642 size_t fingerprint_pos = (size_t) 0U;
643 size_t key_pos = (size_t) 0U;
646 assert(fingerprint_size > fingerprint_pos);
647 snprintf(&fingerprint[fingerprint_pos],
648 fingerprint_size - fingerprint_pos, "%02X%02X",
649 key[key_pos], key[key_pos + 1U]);
651 if (key_pos >= crypto_box_PUBLICKEYBYTES) {
654 fingerprint[fingerprint_pos + 4U] = ':';
655 fingerprint_pos += 5U;
660 * Find the cert matching a DNSCrypt query.
661 * \param[in] dnscenv The DNSCrypt environment, which contains the list of certs
662 * supported by the server.
663 * \param[in] buffer The encrypted DNS query.
664 * \return a dnsccert * if we found a cert matching the magic_number of the
665 * query, NULL otherwise.
667 static const dnsccert *
668 dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
670 const dnsccert *certs = dnscenv->certs;
671 struct dnscrypt_query_header *dnscrypt_header;
674 if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) {
677 dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
678 for (i = 0U; i < dnscenv->signed_certs_count; i++) {
679 if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
680 DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
688 * Insert local-zone and local-data into configuration.
689 * In order to be able to serve certs over TXT, we can reuse the local-zone and
690 * local-data config option. The zone and qname are infered from the
691 * provider_name and the content of the TXT record from the certificate content.
692 * returns the number of certificate TXT record that were loaded.
693 * < 0 in case of error.
696 dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
699 // Insert 'local-zone: "2.dnscrypt-cert.example.com" deny'
700 if(!cfg_str2list_insert(&cfg->local_zones,
701 strdup(dnscenv->provider_name),
703 log_err("Could not load dnscrypt local-zone: %s deny",
704 dnscenv->provider_name);
708 // Add local data entry of type:
709 // 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
710 for(i=0; i<dnscenv->signed_certs_count; i++) {
711 const char *ttl_class_type = " 86400 IN TXT \"";
712 int rotated_cert = 0;
716 struct SignedCert *cert = dnscenv->signed_certs + i;
717 // Check if the certificate is being rotated and should not be published
718 for(j=0; j<dnscenv->rotated_certs_count; j++){
719 if(cert == dnscenv->rotated_certs[j]) {
724 memcpy(&serial, cert->serial, sizeof serial);
725 serial = htonl(serial);
728 "DNSCrypt: not adding cert with serial #%"
730 " to local-data as it is rotated",
735 rrlen = strlen(dnscenv->provider_name) +
736 strlen(ttl_class_type) +
737 4 * sizeof(struct SignedCert) + // worst case scenario
738 1 + // trailing double quote
742 log_err("Could not allocate memory");
745 snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
746 for(j=0; j<sizeof(struct SignedCert); j++) {
747 int c = (int)*((const uint8_t *) cert + j);
748 if (isprint(c) && c != '"' && c != '\\') {
749 snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
751 snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
755 "DNSCrypt: adding cert with serial #%"
757 " to local-data to config: %s",
760 snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
761 cfg_strlist_insert(&cfg->local_data, strdup(rr));
764 return dnscenv->signed_certs_count;
768 key_get_es_version(uint8_t version[2])
771 uint8_t es_version[2];
775 const int num_versions = 2;
776 struct es_version es_versions[] = {
777 {{0x00, 0x01}, "X25519-XSalsa20Poly1305"},
778 {{0x00, 0x02}, "X25519-XChacha20Poly1305"},
781 for(i=0; i < num_versions; i++){
782 if(es_versions[i].es_version[0] == version[0] &&
783 es_versions[i].es_version[1] == version[1]){
784 return es_versions[i].name;
792 * Parse the secret key files from `dnscrypt-secret-key` config and populates
793 * a list of dnsccert with es_version, magic number and secret/public keys
794 * supported by dnscrypt listener.
795 * \param[in] env The dnsc_env structure which will hold the keypairs.
796 * \param[in] cfg The config with the secret key file paths.
799 dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
801 struct config_strlist *head;
802 size_t cert_id, keypair_id;
806 env->keypairs_count = 0U;
807 for (head = cfg->dnscrypt_secret_key; head; head = head->next) {
808 env->keypairs_count++;
811 env->keypairs = sodium_allocarray(env->keypairs_count,
812 sizeof *env->keypairs);
813 env->certs = sodium_allocarray(env->signed_certs_count,
818 for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
819 char fingerprint[80];
821 KeyPair *current_keypair = &env->keypairs[keypair_id];
822 nm = dnsc_chroot_path(cfg, head->str);
823 if(dnsc_read_from_file(
825 (char *)(current_keypair->crypt_secretkey),
826 crypto_box_SECRETKEYBYTES) != 0) {
827 fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno));
829 verbose(VERB_OPS, "Loaded key %s", head->str);
830 if (crypto_scalarmult_base(current_keypair->crypt_publickey,
831 current_keypair->crypt_secretkey) != 0) {
832 fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
834 dnsc_key_to_fingerprint(fingerprint, current_keypair->crypt_publickey);
835 verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
836 // find the cert matching this key
837 for(c = 0; c < env->signed_certs_count; c++) {
838 if(memcmp(current_keypair->crypt_publickey,
839 env->signed_certs[c].server_publickey,
840 crypto_box_PUBLICKEYBYTES) == 0) {
841 dnsccert *current_cert = &env->certs[cert_id++];
843 current_cert->keypair = current_keypair;
844 memcpy(current_cert->magic_query,
845 env->signed_certs[c].magic_query,
846 sizeof env->signed_certs[c].magic_query);
847 memcpy(current_cert->es_version,
848 env->signed_certs[c].version_major,
849 sizeof env->signed_certs[c].version_major
851 dnsc_key_to_fingerprint(fingerprint,
852 current_cert->keypair->crypt_publickey);
853 verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s",
854 head->str, fingerprint);
855 verbose(VERB_OPS, "Using %s",
856 key_get_es_version(current_cert->es_version));
857 #ifndef USE_DNSCRYPT_XCHACHA20
858 if (current_cert->es_version[1] == 0x02) {
859 fatal_exit("Certificate for XChacha20 but libsodium does not support it.");
866 fatal_exit("dnsc_parse_keys: could not match certificate for key "
867 "%s. Unable to determine ES version.",
875 sodium_misuse_handler(void)
878 "dnscrypt: libsodium could not be initialized, this typically"
879 " happens when no good source of entropy is found. If you run"
880 " unbound in a chroot, make sure /dev/random is available. See"
881 " https://www.unbound.net/documentation/unbound.conf.html");
886 * #########################################################
887 * ############# Publicly accessible functions #############
888 * #########################################################
892 dnsc_handle_curved_request(struct dnsc_env* dnscenv,
893 struct comm_reply* repinfo)
895 struct comm_point* c = repinfo->c;
897 repinfo->is_dnscrypted = 0;
901 // Attempt to decrypt the query. If it is not crypted, we may still need
902 // to serve the certificate.
903 verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
904 if ((repinfo->dnsc_cert = dnsc_find_cert(dnscenv, c->buffer)) != NULL) {
905 if(dnscrypt_server_uncurve(dnscenv,
907 repinfo->client_nonce,
910 verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
911 comm_point_drop_reply(repinfo);
914 repinfo->is_dnscrypted = 1;
915 sldns_buffer_rewind(c->buffer);
921 dnsc_handle_uncurved_request(struct comm_reply *repinfo)
923 if(!repinfo->c->dnscrypt) {
926 sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
927 if(!repinfo->is_dnscrypted) {
930 if(dnscrypt_server_curve(repinfo->dnsc_cert,
931 repinfo->client_nonce,
933 repinfo->c->dnscrypt_buffer,
934 repinfo->c->type == comm_udp,
935 repinfo->max_udp_size) != 0){
936 verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
937 comm_point_drop_reply(repinfo);
946 struct dnsc_env *env;
947 #ifdef SODIUM_MISUSE_HANDLER
948 sodium_set_misuse_handler(sodium_misuse_handler);
950 if (sodium_init() == -1) {
951 fatal_exit("dnsc_create: could not initialize libsodium.");
953 env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
954 lock_basic_init(&env->shared_secrets_cache_lock);
955 lock_protect(&env->shared_secrets_cache_lock,
956 &env->num_query_dnscrypt_secret_missed_cache,
957 sizeof(env->num_query_dnscrypt_secret_missed_cache));
958 lock_basic_init(&env->nonces_cache_lock);
959 lock_protect(&env->nonces_cache_lock,
961 sizeof(env->nonces_cache));
962 lock_protect(&env->nonces_cache_lock,
963 &env->num_query_dnscrypt_replay,
964 sizeof(env->num_query_dnscrypt_replay));
970 dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
972 if(dnsc_parse_certs(env, cfg) <= 0) {
973 fatal_exit("dnsc_apply_cfg: no cert file loaded");
975 if(dnsc_parse_keys(env, cfg) <= 0) {
976 fatal_exit("dnsc_apply_cfg: no key file loaded");
978 randombytes_buf(env->hash_key, sizeof env->hash_key);
979 env->provider_name = cfg->dnscrypt_provider;
981 if(dnsc_load_local_data(env, cfg) <= 0) {
982 fatal_exit("dnsc_apply_cfg: could not load local data");
984 lock_basic_lock(&env->shared_secrets_cache_lock);
985 env->shared_secrets_cache = slabhash_create(
986 cfg->dnscrypt_shared_secret_cache_slabs,
987 HASH_DEFAULT_STARTARRAY,
988 cfg->dnscrypt_shared_secret_cache_size,
989 dnsc_shared_secrets_sizefunc,
990 dnsc_shared_secrets_compfunc,
991 dnsc_shared_secrets_delkeyfunc,
992 dnsc_shared_secrets_deldatafunc,
995 lock_basic_unlock(&env->shared_secrets_cache_lock);
996 if(!env->shared_secrets_cache){
997 fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
999 lock_basic_lock(&env->nonces_cache_lock);
1000 env->nonces_cache = slabhash_create(
1001 cfg->dnscrypt_nonce_cache_slabs,
1002 HASH_DEFAULT_STARTARRAY,
1003 cfg->dnscrypt_nonce_cache_size,
1004 dnsc_nonces_sizefunc,
1005 dnsc_nonces_compfunc,
1006 dnsc_nonces_delkeyfunc,
1007 dnsc_nonces_deldatafunc,
1010 lock_basic_unlock(&env->nonces_cache_lock);
1015 dnsc_delete(struct dnsc_env *env)
1020 verbose(VERB_OPS, "DNSCrypt: Freeing environment.");
1021 sodium_free(env->signed_certs);
1022 sodium_free(env->rotated_certs);
1023 sodium_free(env->certs);
1024 sodium_free(env->keypairs);
1025 lock_basic_destroy(&env->shared_secrets_cache_lock);
1026 lock_basic_destroy(&env->nonces_cache_lock);
1027 slabhash_delete(env->shared_secrets_cache);
1028 slabhash_delete(env->nonces_cache);
1033 * #########################################################
1034 * ############# Shared secrets cache functions ############
1035 * #########################################################
1039 dnsc_shared_secrets_sizefunc(void *k, void* ATTR_UNUSED(d))
1041 struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1042 size_t key_size = sizeof(struct shared_secret_cache_key)
1043 + lock_get_mem(&ssk->entry.lock);
1044 size_t data_size = crypto_box_BEFORENMBYTES;
1045 (void)ssk; /* otherwise ssk is unused if no threading, or fixed locksize */
1046 return key_size + data_size;
1050 dnsc_shared_secrets_compfunc(void *m1, void *m2)
1052 return sodium_memcmp(m1, m2, DNSCRYPT_SHARED_SECRET_KEY_LENGTH);
1056 dnsc_shared_secrets_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1058 struct shared_secret_cache_key* ssk = (struct shared_secret_cache_key*)k;
1059 lock_rw_destroy(&ssk->entry.lock);
1064 dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg))
1066 uint8_t* data = (uint8_t*)d;
1071 * #########################################################
1072 * ############### Nonces cache functions ##################
1073 * #########################################################
1077 dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
1079 struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1080 size_t key_size = sizeof(struct nonce_cache_key)
1081 + lock_get_mem(&nk->entry.lock);
1082 (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
1087 dnsc_nonces_compfunc(void *m1, void *m2)
1089 struct nonce_cache_key *k1 = m1, *k2 = m2;
1094 crypto_box_HALF_NONCEBYTES) != 0 ||
1098 DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
1100 k1->client_publickey, k2->client_publickey,
1101 crypto_box_PUBLICKEYBYTES) != 0;
1105 dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
1107 struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
1108 lock_rw_destroy(&nk->entry.lock);
1113 dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))