]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
More fixes, statistic counter at end of struct for backwards compatibility, man page...
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Jan 2019 10:19:04 +0000 (10:19 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 Jan 2019 10:19:04 +0000 (10:19 +0000)
git-svn-id: file:///svn/unbound/trunk@5062 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/daemon.c
doc/unbound-control.8.in
doc/unbound.conf.5.in
libunbound/unbound.h
util/net_help.c
util/net_help.h

index 4c3d5f1c1a174f0c34e9eea88f8890bf1c7576c1..e14edb99df05ae8f73491aa19cad59956ba87974 100644 (file)
@@ -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
index f5944a75f0c5c25809272915d4ce52acd0ba906d..6ea40009cfb14b162363966dc89048b9f0bbd91d 100644 (file)
@@ -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
index d23292725a6524a226a8b0e647b736f4b0df30f1..9723141b994783910112070dce0058779fa757f2 100644 (file)
@@ -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<file>
+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<string with cipher list>
 Set the list of ciphers to allow when serving TLS.  Use "" for defaults,
 and that is the default.
index 3681340f860d6f90f143aa499d870c27d5af71a5..a290e3e6ccb6de34fe64c39e0cfd8d18c2d0eb56 100644 (file)
@@ -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;
 };
 
 /** 
index 01c82cc0afa6d00d4774abe3309589c1ed415e57..63841becb76b1b225e894432d74930a0f1348878 100644 (file)
@@ -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;
 }
index 6c6707677c61087c16fd896161c0f59293609e13..0b197fbdd6e73e411ae11c0579d7be60ef31ef15 100644 (file)
@@ -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 */