]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add "session-tickets" options to the "tls" clause
authorArtem Boldariev <artem@boldariev.com>
Tue, 21 Sep 2021 11:09:56 +0000 (14:09 +0300)
committerArtem Boldariev <artem@boldariev.com>
Fri, 1 Oct 2021 12:50:43 +0000 (15:50 +0300)
This commit adds the ability to enable or disable stateless TLS
session resumption tickets (see RFC5077). Having this ability is
twofold.

Firstly, these tickets are encrypted by the server, and the algorithm
might be weaker than the algorithm negotiated during the TLS session
establishment (it is in general the case for TLSv1.2, but the generic
principle applies to TLSv1.3 as well, despite it having better ciphers
for session tickets). Thus, they might compromise Perfect Forward
Secrecy.

Secondly, disabling it might be necessary if the same TLS key/cert
pair is supposed to be used by multiple servers to achieve, e.g., load
balancing because the session ticket by default gets generated in
runtime, while to achieve successful session resumption ability, in
this case, would have required using a shared key.

The proper alternative to having the ability to disable stateless TLS
session resumption tickets is to implement a proper session tickets
key rollover mechanism so that key rotation might be performed
often (e.g. once an hour) to not compromise forward secrecy while
retaining the associated performance benefits. That is much more work,
though. On the other hand, having the ability to disable session
tickets allows having a deployable configuration right now in the
cases when either forward secrecy is wanted or sharing the TLS
key/cert pair between multiple servers is needed (or both).

14 files changed:
bin/named/named.conf.rst
bin/named/server.c
bin/tests/system/checkconf/good-doh-tlsopts.conf
bin/tests/system/checkconf/good-dot-tlsopts.conf
doc/arm/reference.rst
doc/man/named.conf.5in
doc/misc/options
doc/misc/options.active
doc/misc/tls.grammar.rst
lib/isc/include/isc/tls.h
lib/isc/tls.c
lib/isccfg/namedconf.c
lib/ns/include/ns/listenlist.h
lib/ns/listenlist.c

index ff9e7de0f88b029e07adb702fdfb0f87cd01e6f7..7274c2044abf6a53b98b1c26892dc5e5a1f8da36 100644 (file)
@@ -569,6 +569,7 @@ TLS
        key-file quoted_string;
        prefer-server-ciphers boolean;
        protocols { string; ... };
+       session-tickets boolean;
   };
 
 TRUST-ANCHORS
index 3c3ebd7b4830f45b8f2d07cdc299d5a742698466..e9d3bdc59e7d4d68cb299bdf73a3e7d39a3d9ffe 100644 (file)
@@ -11027,6 +11027,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                   *ciphers = NULL;
        bool tls_prefer_server_ciphers = false,
             tls_prefer_server_ciphers_set = false;
+       bool tls_session_tickets = false, tls_session_tickets_set = false;
        bool do_tls = false, no_tls = false, http = false;
        ns_listenelt_t *delt = NULL;
        uint32_t tls_protos = 0;
@@ -11052,6 +11053,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                        const cfg_obj_t *tls_proto_list = NULL;
                        const cfg_obj_t *ciphers_obj = NULL;
                        const cfg_obj_t *prefer_server_ciphers_obj = NULL;
+                       const cfg_obj_t *session_tickets_obj = NULL;
 
                        do_tls = true;
 
@@ -11109,6 +11111,14 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                                        prefer_server_ciphers_obj);
                                tls_prefer_server_ciphers_set = true;
                        }
+
+                       if (cfg_map_get(tlsmap, "session-tickets",
+                                       &session_tickets_obj) == ISC_R_SUCCESS)
+                       {
+                               tls_session_tickets =
+                                       cfg_obj_asboolean(session_tickets_obj);
+                               tls_session_tickets_set = true;
+                       }
                }
        }
 
@@ -11120,6 +11130,8 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                .ciphers = ciphers,
                .prefer_server_ciphers = tls_prefer_server_ciphers,
                .prefer_server_ciphers_set = tls_prefer_server_ciphers_set,
+               .session_tickets = tls_session_tickets,
+               .session_tickets_set = tls_session_tickets_set
        };
 
        httpobj = cfg_tuple_get(ltup, "http");
index f6cafa342f7ad317b304a09d15c0a06c5687daf9..0de934bfe4217ebfaf98b5584473b47b419f3537 100644 (file)
@@ -16,6 +16,7 @@ tls local-tls {
        dhparam-file "dhparam.pem";
        ciphers "HIGH:!aNULL:!MD5:!RC4";
        prefer-server-ciphers yes;
+       session-tickets no;
 };
 
 http local-http-server {
index 8912646f65a098ad263d025f55b2312e71dda168..e68e6211e388912f27df56998f09789ad6be38f3 100644 (file)
@@ -16,6 +16,7 @@ tls local-tls {
        dhparam-file "dhparam.pem";
        ciphers "HIGH:!aNULL:!MD5:!RC4";
        prefer-server-ciphers yes;
+       session-tickets no;
 };
 
 options {
index b6a7c14e273126242eabdbdf68e8f7f12f9799ff..bed3ed0140b5b3076756c21ce79752e36b4fa19c 100644 (file)
@@ -293,7 +293,7 @@ The following statements are supported:
         Declares communication channels to get access to ``named`` statistics.
 
     ``tls``
-        Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``dhparam-file``, ``hostname``, ``ciphers``, ``protocols``, and ``prefer-server-ciphers``.
+        Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``dhparam-file``, ``hostname``, ``ciphers``, ``protocols``, ``prefer-server-ciphers``, and ``session-tickets``.
 
     ``http``
         Specifies configuration information for an HTTP connection, including ``endponts``, ``listener-clients`` and ``streams-per-connection``.
@@ -4795,6 +4795,13 @@ The following options can be specified in a ``tls`` statement:
   ``prefer-server-ciphers``
     Specifies that server ciphers should be preferred over client ones.
 
+  ``session-tickets``
+    Enables or disables session resumption through TLS session tickets,
+    as defined in RFC5077. Disabling the stateless session tickets
+    might be required in the cases when forward secrecy is needed,
+    or the TLS certificate and key pair is planned to be used across
+    multiple BIND instances.
+
 There are two built-in TLS connection configurations: ``ephemeral``,
 uses a temporary key and certificate created for the current ``named``
 session only, and ``none``, which can be used when setting up an HTTP
index 036d5899495d5a06d72b94b9f8afb6c6c20be60e..30d73bab2f80dd0ddb2b3374f7b5b062413478a9 100644 (file)
@@ -660,6 +660,7 @@ tls string {
       key\-file quoted_string;
       prefer\-server\-ciphers boolean;
       protocols { string; ... };
+      session\-tickets boolean;
 };
 .ft P
 .fi
index da7fcceb311636993a642bec30981eea1f646c32..06fec355affcb9c391267eb62a9f52d2cbaf8b67 100644 (file)
@@ -465,6 +465,7 @@ tls <string> {
         key-file <quoted_string>;
         prefer-server-ciphers <boolean>;
         protocols { <string>; ... };
+        session-tickets <boolean>;
 }; // may occur multiple times
 
 trust-anchors { <string> ( static-key |
index f579cc2835e408b95f8885c00950e738abffe8cb..226e77da17fabb75ff135115e5ccb731269216c5 100644 (file)
@@ -462,6 +462,7 @@ tls <string> {
         key-file <quoted_string>;
         prefer-server-ciphers <boolean>;
         protocols { <string>; ... };
+        session-tickets <boolean>;
 }; // may occur multiple times
 
 trust-anchors { <string> ( static-key |
index 4cb078da9478b64a1370371a0b3078ca8929b3c6..98f724a6d8f517e3003476a7864eedd5d2dd4902 100644 (file)
@@ -9,4 +9,5 @@
        key-file <quoted_string>;
        prefer-server-ciphers <boolean>;
        protocols { <string>; ... };
+       session-tickets <boolean>;
   };
index 5c32053df32c60795ddf8c55154fe47c104f6528..addc27ba5ca3c26ff58f9e2ce40994e9804248d5 100644 (file)
@@ -124,6 +124,16 @@ isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer);
  * \li 'ctx' != NULL.
  */
 
+void
+isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use);
+/*%<
+ * Enable/Disable stateless session resumptions tickets on the given
+ * TLS context 'ctx' (see RFC5077).
+ *
+ * Requires:
+ * \li 'ctx' != NULL.
+ */
+
 isc_tls_t *
 isc_tls_create(isc_tlsctx_t *ctx);
 /*%<
index f2dcbf187bc355bd23dc749e86e0d26ab56bfb01..94d42b7e17491d2f293c42af5b538761cc86b444 100644 (file)
@@ -574,6 +574,17 @@ isc_tlsctx_prefer_server_ciphers(isc_tlsctx_t *ctx, const bool prefer) {
        }
 }
 
+void
+isc_tlsctx_session_tickets(isc_tlsctx_t *ctx, const bool use) {
+       REQUIRE(ctx != NULL);
+
+       if (!use) {
+               (void)SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
+       } else {
+               (void)SSL_CTX_clear_options(ctx, SSL_OP_NO_TICKET);
+       }
+}
+
 isc_tls_t *
 isc_tls_create(isc_tlsctx_t *ctx) {
        isc_tls_t *newctx = NULL;
index 0f8329f26ad60d282b941184d5c5de74a1117622..7bff17d184bd5344c9d11d3dac0492bce4755c32 100644 (file)
@@ -3891,6 +3891,7 @@ static cfg_clausedef_t tls_clauses[] = {
        { "protocols", &cfg_type_tlsprotos, 0 },
        { "ciphers", &cfg_type_astring, 0 },
        { "prefer-server-ciphers", &cfg_type_boolean, 0 },
+       { "session-tickets", &cfg_type_boolean, 0 },
        { NULL, NULL, 0 }
 };
 
index 207c1f6ab384d6b60ab5752dd35a8115378d1c59..8119821b5b8fe78966f8616fc6d001c6be9981a5 100644 (file)
@@ -67,6 +67,8 @@ typedef struct ns_listen_tls_params {
        const char *ciphers;
        bool        prefer_server_ciphers;
        bool        prefer_server_ciphers_set;
+       bool        session_tickets;
+       bool        session_tickets_set;
 } ns_listen_tls_params_t;
 
 /***
index 600ee64ceb7e159671e9e0724e86977ca7587d34..6aa67dbd2bc1bbfaecdad6a7b6318006a83220a8 100644 (file)
@@ -64,6 +64,11 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
                        isc_tlsctx_prefer_server_ciphers(
                                sslctx, tls_params->prefer_server_ciphers);
                }
+
+               if (tls_params->session_tickets_set) {
+                       isc_tlsctx_session_tickets(sslctx,
+                                                  tls_params->session_tickets);
+               }
        }
 
        elt = isc_mem_get(mctx, sizeof(*elt));