s4:lib:tls: Don't negotiate session resumption with session tickets
authorNoel Power <noel.power@suse.com>
Fri, 4 Nov 2022 16:56:49 +0000 (16:56 +0000)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 16 Nov 2022 09:58:44 +0000 (09:58 +0000)
tls_tstream can't properly handle 'New Session Ticket' messages
sent 'after' the client sends the 'Finished' message.

This is needed because some servers (at least elasticsearch) wait till
they get 'Finished' messgage from the client before sending the
"New Ticket" message.

Without this patch what typcially happens is when the application code
sends data it then tries to read the response, but, instead of the
response to the request it actually recieves the "New Session Ticket"
instead. The "New Session Ticket" message gets processed by the upper layer
logic e.g.
   tstream_tls_readv_send
       ->tstream_tls_readv_crypt_next
           ->tstream_tls_retry_read
               ->gnutls_record_recv

instead of the core gnutls routines.

This results in the response processing failing due to the
currently 'unexpected' New Ticket message.

In order to avoid this scenario we can ensure the client doesn't
negotiate resumption with session tickets.

Signed-off-by: Noel Power <noel.power@suse.com>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Wed Nov 16 09:58:45 UTC 2022 on sn-devel-184

source4/lib/tls/tls_tstream.c

index d984addeec5f139336612225170c256cbea1417e..f1bfe474d6ed528a1f338e54ac85e888990b5641 100644 (file)
@@ -995,6 +995,7 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
        const char *error_pos;
        struct tstream_tls *tlss;
        int ret;
+       unsigned int flags = GNUTLS_CLIENT;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct tstream_tls_connect_state);
@@ -1028,7 +1029,18 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       ret = gnutls_init(&tlss->tls_session, GNUTLS_CLIENT);
+#ifdef GNUTLS_NO_TICKETS
+       /*
+        * tls_tstream can't properly handle 'New Session Ticket' messages
+        * sent 'after' the client sends the 'Finished' message.
+        * GNUTLS_NO_TICKETS was introduced in GnuTLS 3.5.6.  This flag is to
+        * indicate the session Flag session should not use resumption with
+        * session tickets.
+        */
+       flags |= GNUTLS_NO_TICKETS;
+#endif
+
+       ret = gnutls_init(&tlss->tls_session, flags);
        if (ret != GNUTLS_E_SUCCESS) {
                DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
                tevent_req_error(req, EINVAL);