gnutls backend doesn't reuse sessions #1109

Closed
kroeckx opened this Issue Nov 5, 2016 · 2 comments

Projects

None yet

3 participants

@kroeckx
kroeckx commented Nov 5, 2016

Hi,

It seems that curl has support for session IDs but not for session tickets. When linked with gnutls client hello indicates support for TLS tickets so the server sends a TLS ticket back and does not send a session id back. But curl doesn't seem to handle the TLS tickets.

In case of OpenSSL it doesn't send a TLS ticket extension in the client hello and so gets a session id back, and then it properly reuses the session.

@bagder bagder added the SSL/TLS label Nov 5, 2016
@bagder
Member
bagder commented Nov 9, 2016

We'll welcome help and patches to fix this. This seems to be the GnuTLS docs for how it works: https://www.gnutls.org/manual/html_node/Session-resumption.html

@mkauf
Contributor
mkauf commented Jan 22, 2017

Probably TLS session tickets don't work because curl does not use the same SSL context for multiple requests. See TODO: Cache/share OpenSSL contexts

I have tested this: After disabling TLS session tickets, reusing the SSL sessions works properly. TLS session tickets are already disabled for OpenSSL.

For GnuTLS 3.5.6 and newer versions, this can be fixed with this patch:

diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index a992f99..faa70ac 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -380,6 +380,7 @@ gtls_connect_step1(struct connectdata *conn,
                    int sockindex)
 {
   struct Curl_easy *data = conn->data;
+  unsigned int init_flags;
   gnutls_session_t session;
   int rc;
   bool sni = TRUE; /* default is SNI enabled */
@@ -526,7 +527,14 @@ gtls_connect_step1(struct connectdata *conn,
   }

   /* Initialize TLS session as a client */
-  rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT);
+  init_flags = GNUTLS_CLIENT;
+
+#if defined(GNUTLS_NO_TICKETS)
+  /* Disable TLS session tickets */
+  init_flags |= GNUTLS_NO_TICKETS;
+#endif
+
+  rc = gnutls_init(&conn->ssl[sockindex].session, init_flags);
   if(rc != GNUTLS_E_SUCCESS) {
     failf(data, "gnutls_init() failed: %d", rc);
     return CURLE_SSL_CONNECT_ERROR;

The same problem also exists for mbed TLS. Patch:

diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c
index 8bcaddd..213a58f 100644
--- a/lib/vtls/mbedtls.c
+++ b/lib/vtls/mbedtls.c
@@ -373,6 +373,11 @@ mbed_connect_step1(struct connectdata *conn,
   mbedtls_ssl_conf_ciphersuites(&connssl->config,
                                 mbedtls_ssl_list_ciphersuites());

+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+  mbedtls_ssl_conf_session_tickets(&connssl->config,
+                                   MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
+#endif
+
   /* Check if there's a cached ID we can/should use here! */
   if(data->set.general_ssl.sessionid) {
     void *old_session = NULL;

What do you think?

@mkauf mkauf added a commit to mkauf/curl that referenced this issue Jan 28, 2017
@mkauf mkauf gnutls: disable TLS session tickets
SSL session reuse with TLS session tickets is not supported yet.
Use SSL session IDs instead.

Fixes curl#1109
511674a
@mkauf mkauf added a commit that closed this issue Jan 28, 2017
@mkauf mkauf gnutls: disable TLS session tickets
SSL session reuse with TLS session tickets is not supported yet.
Use SSL session IDs instead.

Fixes #1109
511674a
@mkauf mkauf closed this in 511674a Jan 28, 2017
@mkauf mkauf added a commit that referenced this issue Jan 28, 2017
@mkauf mkauf mbedtls: disable TLS session tickets
SSL session reuse with TLS session tickets is not supported yet.
Use SSL session IDs instead.

See #1109
ab08d82
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment