|
unbound 0.1
|
dnscrypt functions for encrypting DNS packets. More...
#include "config.h"#include <stdlib.h>#include <fcntl.h>#include <inttypes.h>#include <sys/time.h>#include <sys/types.h>#include "sldns/sbuffer.h"#include "util/config_file.h"#include "util/net_help.h"#include "util/netevent.h"#include "util/log.h"#include "util/storage/slabhash.h"#include "util/storage/lookup3.h"#include "dnscrypt/cert.h"#include "dnscrypt/dnscrypt.h"#include "dnscrypt/dnscrypt_config.h"#include <ctype.h>Data Structures | |
| struct | shared_secret_cache_key |
| struct | nonce_cache_key |
Macros | |
| #define | DNSCRYPT_QUERY_BOX_OFFSET |
| #define | DNSCRYPT_REPLY_BOX_OFFSET |
| #define | DNSCRYPT_SHARED_SECRET_KEY_LENGTH (1 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES) |
| Shared secret cache key length. | |
Functions | |
| static uint32_t | dnsc_shared_secrets_cache_key (uint8_t *key, uint8_t esversion, uint8_t *pk, uint8_t *sk) |
| Generate a key suitable to find shared secret in slabhash. | |
| static void | dnsc_shared_secret_cache_insert (struct slabhash *cache, uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH], uint32_t hash, uint8_t nmkey[crypto_box_BEFORENMBYTES]) |
| Inserts a shared secret into the shared_secrets_cache slabhash. | |
| static struct lruhash_entry * | dnsc_shared_secrets_lookup (struct slabhash *cache, uint8_t key[DNSCRYPT_SHARED_SECRET_KEY_LENGTH], uint32_t hash) |
| Lookup a record in shared_secrets_cache. | |
| static uint32_t | dnsc_nonce_cache_key_hash (const uint8_t nonce[crypto_box_HALF_NONCEBYTES], const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], const uint8_t pk[crypto_box_PUBLICKEYBYTES]) |
| Generate a key hash suitable to find a nonce in slabhash. | |
| static void | dnsc_nonce_cache_insert (struct slabhash *cache, const uint8_t nonce[crypto_box_HALF_NONCEBYTES], const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], const uint8_t pk[crypto_box_PUBLICKEYBYTES], uint32_t hash) |
| Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash. | |
| static struct lruhash_entry * | dnsc_nonces_lookup (struct slabhash *cache, const uint8_t nonce[crypto_box_HALF_NONCEBYTES], const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN], const uint8_t pk[crypto_box_PUBLICKEYBYTES], uint32_t hash) |
| Lookup a record in nonces_cache. | |
| static int | dnscrypt_server_uncurve (struct dnsc_env *env, const dnsccert *cert, uint8_t client_nonce[crypto_box_HALF_NONCEBYTES], uint8_t nmkey[crypto_box_BEFORENMBYTES], struct sldns_buffer *buffer) |
| Decrypt a query using the dnsccert that was found using dnsc_find_cert. | |
| size_t | dnscrypt_pad (uint8_t *buf, const size_t len, const size_t max_len, const uint8_t *nonce, const uint8_t *secretkey) |
| Add random padding to a buffer, according to a client nonce. | |
| uint64_t | dnscrypt_hrtime (void) |
| static void | add_server_nonce (uint8_t *nonce) |
| Add the server nonce part to once. | |
| static int | dnscrypt_server_curve (const dnsccert *cert, uint8_t client_nonce[crypto_box_HALF_NONCEBYTES], uint8_t nmkey[crypto_box_BEFORENMBYTES], struct sldns_buffer *buffer, uint8_t udp, size_t max_udp_size) |
| Encrypt a reply using the dnsccert that was used with the query. | |
| static int | dnsc_read_from_file (char *fname, char *buf, size_t count) |
| Read the content of fname into buf. | |
| static char * | dnsc_chroot_path (struct config_file *cfg, char *path) |
| Given an absolute path on the original root, returns the absolute path within the chroot. | |
| static int | dnsc_parse_certs (struct dnsc_env *env, struct config_file *cfg) |
| Parse certificates files provided by the configuration and load them into dnsc_env. | |
| void | dnsc_key_to_fingerprint (char fingerprint[80U], const uint8_t *const key) |
| Helper function to convert a binary key into a printable fingerprint. | |
| static const dnsccert * | dnsc_find_cert (struct dnsc_env *dnscenv, struct sldns_buffer *buffer) |
| Find the cert matching a DNSCrypt query. | |
| static int | dnsc_load_local_data (struct dnsc_env *dnscenv, struct config_file *cfg) |
| Insert local-zone and local-data into configuration. | |
| static const char * | key_get_es_version (uint8_t version[2]) |
| static int | dnsc_parse_keys (struct dnsc_env *env, struct config_file *cfg) |
Parse the secret key files from dnscrypt-secret-key config and populates a list of dnsccert with es_version, magic number and secret/public keys supported by dnscrypt listener. | |
| int | dnsc_handle_curved_request (struct dnsc_env *dnscenv, struct comm_reply *repinfo) |
| ######################################################### ############# Publicly accessible functions ############# ######################################################### | |
| int | dnsc_handle_uncurved_request (struct comm_reply *repinfo) |
| struct dnsc_env * | dnsc_create (void) |
| int | dnsc_apply_cfg (struct dnsc_env *env, struct config_file *cfg) |
| void | dnsc_delete (struct dnsc_env *env) |
| size_t | dnsc_shared_secrets_sizefunc (void *k, void *ATTR_UNUSED(d)) |
| ######################################################### ############# Shared secrets cache functions ############ ######################################################### | |
| int | dnsc_shared_secrets_compfunc (void *m1, void *m2) |
| void | dnsc_shared_secrets_delkeyfunc (void *k, void *ATTR_UNUSED(arg)) |
| void | dnsc_shared_secrets_deldatafunc (void *d, void *ATTR_UNUSED(arg)) |
| size_t | dnsc_nonces_sizefunc (void *k, void *ATTR_UNUSED(d)) |
| ######################################################### ############### Nonces cache functions ################## ######################################################### | |
| int | dnsc_nonces_compfunc (void *m1, void *m2) |
| void | dnsc_nonces_delkeyfunc (void *k, void *ATTR_UNUSED(arg)) |
| void | dnsc_nonces_deldatafunc (void *ATTR_UNUSED(d), void *ATTR_UNUSED(arg)) |
dnscrypt functions for encrypting DNS packets.
| #define DNSCRYPT_QUERY_BOX_OFFSET |
| #define DNSCRYPT_REPLY_BOX_OFFSET |
| #define DNSCRYPT_SHARED_SECRET_KEY_LENGTH (1 + crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES) |
Shared secret cache key length.
secret key. 1 byte: ES_VERSION[1] 32 bytes: client crypto_box_PUBLICKEYBYTES 32 bytes: server crypto_box_SECRETKEYBYTES
Referenced by dnsc_shared_secret_cache_insert(), dnsc_shared_secrets_cache_key(), and dnscrypt_server_uncurve().
|
static |
Generate a key suitable to find shared secret in slabhash.
| [in] | key | a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH |
| [in] | esversion | The es version least significant byte. |
| [in] | pk | The public key of the client. uint8_t pointer of size crypto_box_PUBLICKEYBYTES. |
| [in] | sk | The secret key of the server matching the magic query number. uint8_t pointer of size crypto_box_SECRETKEYBYTES. |
References DNSCRYPT_SHARED_SECRET_KEY_LENGTH, and lruhash_entry::key.
Referenced by dnscrypt_server_uncurve().
|
static |
Inserts a shared secret into the shared_secrets_cache slabhash.
The shared secret is copied so the caller can use it freely without caring about the cache entry being evicted or not.
| [in] | cache | the slabhash in which to look for the key. |
| [in] | key | a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH which contains the key of the shared secret. |
| [in] | hash | the hash of the key. |
| [in] | nmkey | a uint8_t pointer of size crypto_box_BEFORENMBYTES which contains the shared secret. |
References lruhash_entry::data, DNSCRYPT_SHARED_SECRET_KEY_LENGTH, shared_secret_cache_key::entry, lruhash_entry::hash, lruhash_entry::key, shared_secret_cache_key::key, lruhash_entry::lock, and slabhash_insert().
Referenced by dnscrypt_server_uncurve().
|
static |
Lookup a record in shared_secrets_cache.
| [in] | cache | a pointer to shared_secrets_cache slabhash. |
| [in] | key | a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH containing the key to look for. |
| [in] | hash | a hash of the key. |
References lruhash_entry::hash, lruhash_entry::key, and slabhash_lookup().
Referenced by dnscrypt_server_uncurve().
|
static |
Generate a key hash suitable to find a nonce in slabhash.
| [in] | nonce | a uint8_t pointer of size crypto_box_HALF_NONCEBYTES |
| [in] | magic_query | a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN |
| [in] | pk | The public key of the client. uint8_t pointer of size crypto_box_PUBLICKEYBYTES. |
Referenced by dnscrypt_server_uncurve().
|
static |
Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash.
| [in] | cache | the slabhash in which to look for the key. |
| [in] | nonce | a uint8_t pointer of size crypto_box_HALF_NONCEBYTES |
| [in] | magic_query | a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN |
| [in] | pk | The public key of the client. uint8_t pointer of size crypto_box_PUBLICKEYBYTES. |
| [in] | hash | the hash of the key. |
References nonce_cache_key::client_publickey, lruhash_entry::data, nonce_cache_key::entry, lruhash_entry::hash, lruhash_entry::key, lruhash_entry::lock, nonce_cache_key::magic_query, nonce_cache_key::nonce, and slabhash_insert().
Referenced by dnscrypt_server_uncurve().
|
static |
Lookup a record in nonces_cache.
| [in] | cache | the slabhash in which to look for the key. |
| [in] | nonce | a uint8_t pointer of size crypto_box_HALF_NONCEBYTES |
| [in] | magic_query | a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN |
| [in] | pk | The public key of the client. uint8_t pointer of size crypto_box_PUBLICKEYBYTES. |
| [in] | hash | the hash of the key. |
References nonce_cache_key::client_publickey, nonce_cache_key::entry, lruhash_entry::hash, nonce_cache_key::magic_query, nonce_cache_key::nonce, and slabhash_lookup().
Referenced by dnscrypt_server_uncurve().
|
static |
Decrypt a query using the dnsccert that was found using dnsc_find_cert.
The client nonce will be extracted from the encrypted query and stored in client_nonce, a shared secret will be computed and stored in nmkey and the buffer will be decrypted inplace.
| [in] | env | the dnscrypt environment. |
| [in] | cert | the cert that matches this encrypted query. |
| [in] | client_nonce | where the client nonce will be stored. |
| [in] | nmkey | where the shared secret key will be written. |
| [in] | buffer | the encrypted buffer. |
References dnsc_nonce_cache_insert(), dnsc_nonce_cache_key_hash(), dnsc_nonces_lookup(), dnsc_shared_secret_cache_insert(), dnsc_shared_secrets_cache_key(), dnsc_shared_secrets_lookup(), DNSCRYPT_SHARED_SECRET_KEY_LENGTH, lruhash_entry::hash, nonce_cache_key::nonce, sldns_buffer_at(), sldns_buffer_begin(), sldns_buffer_limit(), sldns_buffer_set_limit(), and sldns_buffer_set_position().
Referenced by dnsc_handle_curved_request().
| size_t dnscrypt_pad | ( | uint8_t * | buf, |
| const size_t | len, | ||
| const size_t | max_len, | ||
| const uint8_t * | nonce, | ||
| const uint8_t * | secretkey ) |
Add random padding to a buffer, according to a client nonce.
The length has to depend on the query in order to avoid reply attacks.
| buf | a buffer |
| len | the initial size of the buffer |
| max_len | the maximum size |
| nonce | a nonce, made of the client nonce repeated twice |
| secretkey |
Referenced by dnscrypt_server_curve().
|
static |
Add the server nonce part to once.
The nonce is made half of client nonce and the second half of the server nonce, both of them of size crypto_box_HALF_NONCEBYTES.
| [in] | nonce | a uint8_t* of size crypto_box_NONCEBYTES |
Referenced by dnscrypt_server_curve().
|
static |
Encrypt a reply using the dnsccert that was used with the query.
The client nonce will be extracted from the encrypted query and stored in The buffer will be encrypted inplace.
| [in] | cert | the dnsccert that matches this encrypted query. |
| [in] | client_nonce | client nonce used during the query |
| [in] | nmkey | shared secret key used during the query. |
| [in] | buffer | the buffer where to encrypt the reply. |
| [in] | udp | if whether or not it is a UDP query. |
| [in] | max_udp_size | configured max udp size. |
References add_server_nonce(), dnscrypt_pad(), sldns_buffer_begin(), sldns_buffer_limit(), sldns_buffer_set_at(), sldns_buffer_set_limit(), and sldns_buffer_write_at().
|
static |
Read the content of fname into buf.
| [in] | fname | name of the file to read. |
| [in] | buf | the buffer in which to read the content of the file. |
| [in] | count | number of bytes to read. |
Referenced by dnsc_parse_certs(), and dnsc_parse_keys().
|
static |
Given an absolute path on the original root, returns the absolute path within the chroot.
If chroot is disabled, the path is not modified. No char * is malloced so there is no need to free this.
| [in] | cfg | the configuration. |
| [in] | path | the path from the original root. |
References config_file::chrootdir.
Referenced by dnsc_parse_certs(), and dnsc_parse_keys().
|
static |
Parse certificates files provided by the configuration and load them into dnsc_env.
| [in] | env | the dnsc_env structure to load the certs into. |
| [in] | cfg | the configuration. |
References dnsc_chroot_path(), dnsc_read_from_file(), config_file::dnscrypt_provider_cert, config_file::dnscrypt_provider_cert_rotated, fatal_exit(), config_strlist::next, config_strlist::str, VERB_OPS, and verbose().
| void dnsc_key_to_fingerprint | ( | char | fingerprint[80U], |
| const uint8_t *const | key ) |
Helper function to convert a binary key into a printable fingerprint.
| [in] | fingerprint | the buffer in which to write the printable key. |
| [in] | key | the key to convert. |
Referenced by dnsc_parse_keys().
|
static |
Find the cert matching a DNSCrypt query.
| [in] | dnscenv | The DNSCrypt environment, which contains the list of certs supported by the server. |
| [in] | buffer | The encrypted DNS query. |
References sldns_buffer_begin(), and sldns_buffer_limit().
Referenced by dnsc_handle_curved_request().
|
static |
Insert local-zone and local-data into configuration.
In order to be able to serve certs over TXT, we can reuse the local-zone and local-data config option. The zone and qname are inferred from the provider_name and the content of the TXT record from the certificate content. returns the number of certificate TXT record that were loaded. < 0 in case of error.
References cfg_str2list_insert(), cfg_strlist_insert(), config_file::local_data, config_file::local_zones, log_err(), VERB_OPS, and verbose().
|
static |
Parse the secret key files from dnscrypt-secret-key config and populates a list of dnsccert with es_version, magic number and secret/public keys supported by dnscrypt listener.
| [in] | env | The dnsc_env structure which will hold the keypairs. |
| [in] | cfg | The config with the secret key file paths. |
References dnsc_chroot_path(), dnsc_key_to_fingerprint(), dnsc_read_from_file(), config_file::dnscrypt_secret_key, fatal_exit(), config_strlist::next, config_strlist::str, VERB_OPS, and verbose().