From: Wouter Wijngaards Date: Wed, 23 Jan 2019 10:19:04 +0000 (+0000) Subject: More fixes, statistic counter at end of struct for backwards compatibility, man page... X-Git-Tag: release-1.9.0rc1~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d3f397c686059f117dac669eff6e89773eeedebb;p=thirdparty%2Funbound.git More fixes, statistic counter at end of struct for backwards compatibility, man page, free at exit, indent. git-svn-id: file:///svn/unbound/trunk@5062 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/daemon.c b/daemon/daemon.c index 4c3d5f1c1..e14edb99d 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -749,6 +749,7 @@ daemon_delete(struct daemon* daemon) free(daemon->pidfile); free(daemon->env); #ifdef HAVE_SSL + listen_sslctx_delete_ticket_keys(); SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx); SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx); #endif diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index f5944a75f..6ea40009c 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -538,6 +538,10 @@ other servers. Number of queries that were made using TLS towards the unbound server. These are also counted in num.query.tcp, because TLS uses TCP. .TP +.I num.query.tls.resume +Number of TLS session resumptions, these are queries over TLS towards +the unbound server where the client negotiated a TLS session resumption key. +.TP .I num.query.ipv6 Number of queries that were made using IPv6 towards the unbound server. .TP diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index d23292725..9723141b9 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -504,6 +504,16 @@ List portnumbers as tls\-additional\-port, and when interfaces are defined, eg. with the @port suffix, as this port number, they provide dns over TLS service. Can list multiple, each on a new statement. .TP +.B tls-session-ticket-keys: \fI +If not "", lists files with 80 bytes of random contents that are used to +perform TLS session resumption for clients using the unbound server. +These files contain the secret key for the TLS session tickets. +First key use to encrypt and decrypt TLS session tickets. +Other keys use to decrypt only. With this you can roll over to new keys, +by generating a new first file and allowing decrypt of the old file by +listing it after the first file for some time, after the wait clients are not +using the old key any more and the old key can be removed. +.TP .B tls\-ciphers: \fI Set the list of ciphers to allow when serving TLS. Use "" for defaults, and that is the default. diff --git a/libunbound/unbound.h b/libunbound/unbound.h index 3681340f8..a290e3e6c 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -682,8 +682,6 @@ struct ub_server_stats { long long qtcp_outgoing; /** number of queries over (DNS over) TLS */ long long qtls; - /** number of TLS connection resume */ - long long qtls_resume; /** number of queries over IPv6 */ long long qipv6; /** number of queries with QR bit */ @@ -774,6 +772,8 @@ struct ub_server_stats { long long num_query_subnet_cache; /** number of bytes in the stream wait buffers */ long long mem_stream_wait; + /** number of TLS connection resume */ + long long qtls_resume; }; /** diff --git a/util/net_help.c b/util/net_help.c index 01c82cc0a..63841becb 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -74,9 +74,9 @@ int RRSET_ROUNDROBIN = 0; int LOG_TAG_QUERYREPLY = 0; static struct tls_session_ticket_key { - unsigned char *key_name; - unsigned char *aes_key; - unsigned char *hmac_key; + unsigned char *key_name; + unsigned char *aes_key; + unsigned char *hmac_key; } *ticket_keys; /* returns true is string addr is an ip6 specced address */ @@ -1108,7 +1108,7 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses s++; } keys = calloc(s, sizeof(struct tls_session_ticket_key)); - memset(keys, 0, sizeof(*keys)); + memset(keys, 0, s*sizeof(*keys)); ticket_keys = keys; for(p = tls_session_ticket_keys; p; p = p->next) { @@ -1133,50 +1133,51 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses keys->hmac_key = data + 48; keys++; } + /* terminate array with NULL key name entry */ keys->key_name = NULL; - if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { + if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { log_err("no support for TLS session ticket"); return 0; - } - return 1; + } + return 1; #else return 0; #endif } -int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name,unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc) +int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc) { #ifdef HAVE_SSL - const EVP_MD *digest; - const EVP_CIPHER *cipher; - int evp_chiper_length; + const EVP_MD *digest; + const EVP_CIPHER *cipher; + int evp_cipher_length; digest = EVP_sha256(); cipher = EVP_aes_256_cbc(); - evp_chiper_length = EVP_CIPHER_iv_length(cipher); + evp_cipher_length = EVP_CIPHER_iv_length(cipher); if( enc == 1 ) { /* encrypt */ verbose(VERB_CLIENT, "start session encrypt"); memcpy(key_name, ticket_keys->key_name, 16); - if (RAND_bytes(iv, evp_chiper_length) != 1) { + if (RAND_bytes(iv, evp_cipher_length) != 1) { verbose(VERB_CLIENT, "RAND_bytes failed"); - return -1; + return -1; } - if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) { + if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) { verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed"); - return -1; + return -1; } - if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) { + if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); - return -1; - } - return 1; - } else if (enc == 0) { + return -1; + } + return 1; + } else if (enc == 0) { /* decrypt */ struct tls_session_ticket_key *key; verbose(VERB_CLIENT, "start session decrypt"); for(key = ticket_keys; key->key_name != NULL; key++) { - if (!memcmp(key_name, key->key_name, 16)) { + if (!memcmp(key_name, key->key_name, 16)) { verbose(VERB_CLIENT, "Found session_key"); break; } @@ -1186,20 +1187,31 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name return 0; } - if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) { + if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); - return -1; - } - if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) { + return -1; + } + if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) { log_err("EVP_DecryptInit_ex failed"); - return -1; - } + return -1; + } return (key == ticket_keys) ? 1 : 2; } - return -1; + return -1; #else return 0; #endif +} +void +listen_sslctx_delete_ticket_keys(void) +{ + struct tls_session_ticket_key *key; + if(!ticket_keys) return; + for(key = ticket_keys; key->key_name != NULL; key++) { + free(key->key_name); + } + free(ticket_keys); + ticket_keys = NULL; } diff --git a/util/net_help.h b/util/net_help.h index 6c6707677..0b197fbdd 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -444,18 +444,24 @@ void ub_openssl_lock_delete(void); * @param tls_session_ticket_keys: TLS ticket secret filenames * @return false on failure (alloc failure). */ -int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys); +int listen_sslctx_setup_ticket_keys(void* sslctx, + struct config_strlist* tls_session_ticket_keys); /** * callback TLS session ticket encrypt and decrypt + * For use with SSL_CTX_set_tlsext_ticket_key_cb * @param s: the SSL_CTX to use (from connect_sslctx_create()) - * @param key_name: secret name - * @param iv: - * @param evp_ctx: - * @param hmac_ctx: + * @param key_name: secret name, 16 bytes + * @param iv: up to EVP_MAX_IV_LENGTH. + * @param evp_ctx: the evp cipher context, function sets this. + * @param hmac_ctx: the hmax context, function sets this. * @param enc: 1 is encrypt, 0 is decrypt - * @return false on failure (alloc failure). + * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket + * (the ticket is decrypt only). and <0 for failures. */ - int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv, void *evp_ctx, void *hmac_ctx, int enc); + +/** Free memory used for TLS session ticket keys */ +void listen_sslctx_delete_ticket_keys(void); + #endif /* NET_HELP_H */