TLS: increase resumption ticket lifetime to 2 hours
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 6 May 2019 12:34:18 +0000 (13:34 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 7 May 2019 21:45:51 +0000 (22:45 +0100)
doc/doc-txt/experimental-spec.txt
src/src/tls-gnu.c
src/src/tls-openssl.c
test/scripts/5891-Resume-OpenSSL/5891

index f304cf455127cef1e58afd1510e3fdc6182d0243..0f749c6cf72e23ecb8392e2ee191062d60dac517 100644 (file)
@@ -984,7 +984,10 @@ Security aspects:
  vulnarability surface.  An attacker able to decrypt it would have access
  all connections using the resumed session.
  The session ticket encryption key is not committed to storage by the server
- and is rotated regularly.  Tickets have limited lifetime.
+ and is rotated regularly (OpenSSL: 1hr, and one previous key is used for
+ overlap; GnuTLS 6hr but does not specify any overlap).
+ Tickets have limited lifetime (2hr, and new ones issued after 1hr under
+ OpenSSL.  GnuTLS 2hr, appears to not do overlap).
 
  There is a question-mark over the security of the Diffie-Helman parameters
  used for session negotiation. TBD.  q-value; cf bug 1895
index 085f6b8404aa0e9d7dd2accd993fdf5d0b7b294d..df07c536c7373b31d54a047ec9edecff5aecda74 100644 (file)
@@ -215,7 +215,7 @@ don't want to repeat this. */
 
 static gnutls_dh_params_t dh_server_params = NULL;
 
-static int ssl_session_timeout = 3600; /* One hour */
+static int ssl_session_timeout = 7200; /* Two hours */
 
 static const uschar * const exim_default_gnutls_priority = US"NORMAL";
 
@@ -2457,7 +2457,9 @@ if (verify_check_given_host(CUSS &ob->tls_resumption_hosts, host) == OK)
   tlsp->resumption |= RESUME_CLIENT_REQUESTED;
   if ((dbm_file = dbfn_open(US"tls", O_RDONLY, &dbblock, FALSE, FALSE)))
     {
-    /* key for the db is the IP */
+    /* Key for the db is the IP.  We'd like to filter the retrieved session
+    for ticket advisory expiry, but 3.6.1 seems to give no access to that */
+
     if ((dt = dbfn_read_with_length(dbm_file, host->address, &len)))
       if (!(rc = gnutls_session_set_data(session,
                    CUS dt->session, (size_t)len - sizeof(dbdata_tls_session))))
index df884355ea14bc71432e9fe9623130ddc462fdf3..3092dce2ed9d66c7af8cad36a52030914fa2e4ca 100644 (file)
@@ -315,7 +315,7 @@ static SSL_CTX *server_sni = NULL;
 
 static char ssl_errstring[256];
 
-static int  ssl_session_timeout = 3600;
+static int  ssl_session_timeout = 7200;                /* Two hours */
 static BOOL client_verify_optional = FALSE;
 static BOOL server_verify_optional = FALSE;
 
@@ -943,6 +943,12 @@ else
   EVP_DecryptInit_ex(ctx, key->aes_cipher, NULL, key->aes_key, iv);
 
   DEBUG(D_tls) debug_printf("ticket usable, STEK expire %ld\n", key->expire - now);
+
+  /* The ticket lifetime and renewal are the same as the STEK lifetime and
+  renewal, which is overenthusiastic.  A factor of, say, 3x longer STEK would
+  be better.  To do that we'd have to encode ticket lifetime in the name as
+  we don't yet see the restored session.  Could check posthandshake for TLS1.3
+  and trigger a new ticket then, but cannot do that for TLS1.2 */
   return key->renew < now ? 2 : 1;
   }
 }
index 116f5cfe91baadbf62a9398eb172263084a18b7c..58631f55e300fe079d2ec35ca17100fd99982b5f 100644 (file)
@@ -26,7 +26,7 @@ Test message, not requesting resumption.
 ****
 killdaemon
 sleep 1
-sudo rm DIR/spool/db/tls
+sudo rm -f DIR/spool/db/tls
 #
 #
 ### TLS1.3