On 08/22/16 08:17, Claudio Jeker wrote:
On Sun, Aug 21, 2016 at 02:25:15PM -0400, Ted Unangst wrote:
Andreas Bartelt wrote:
Since the use of TLS session tickets potentially interferes with forward
secrecy on a per-session basis, I'd personally prefer an opt-in in
libtls as well as in httpd with regard to its usage. However, such a
semantic change would not be transparent. Any opinions on this?

Defaulting to off makes sense to me. It's the marginally safer option and at
small scale probably not a performance concern. But if the default results in
900 "tutorials" telling people to turn it back on because web scale, then all
we've done is make things difficult.


While I agree it is important to turn them on for HTTP servers or any
other protocol that does a lot of reconnects. This should also include
the magic to make them work accross multiple processes (see my relayd diff
for that -- which uses the libssl callback madness though).
Without tickets the full TLS handshake will be made for every reconnect
which is a common mode of operation for HTTP. Also I think tickets are a
bit saver than the session cache (which AFAIK is also default on for
servers) and probably the fallback mode.
Client side tickets should be enabled since they are just pass along to
the next connect without processing them.


here's another diff which also adds enable/disable functions with regard to TLS session resumption. Although this mechanism is technically not a TLS extension, it is also optional and basically provides the same functionality as the TLS session ticket extension.

This diff is transparent to the current behaviour of libtls, i.e., it enables session tickets as well as session resumption by default. As I already said, I personally don't like the current default. In particular, I don't like the lack of key management for TLS tickets which always has to be done manually (see Claudio's relayd patch on tech@). If things go wrong, the corresponding damage might be pretty high on long-running TLS servers.

I suppose further API functions should be added for explicitly configuring session resumption and session ticket parameters.

During testing, I've also noticed that the session resumption mechanism currently doesn't work reliably. It always seems to fail at the first session resumption attempt, and it works with unpredictable reliability afterwards. I didn't look at the corresponding code in libssl yet.

OK?
Index: src/lib/libtls/tls.h
===================================================================
RCS file: /cvs/src/lib/libtls/tls.h,v
retrieving revision 1.35
diff -u -p -u -r1.35 tls.h
--- src/lib/libtls/tls.h	22 Aug 2016 14:58:26 -0000	1.35
+++ src/lib/libtls/tls.h	28 Aug 2016 10:35:31 -0000
@@ -41,6 +41,10 @@ extern "C" {
 #define TLS_WANT_POLLIN		-2
 #define TLS_WANT_POLLOUT	-3
 
+/* TLS extensions and other optional mechanisms */
+#define TLS_SESSION_RESUMPTION		0x00000001L
+#define TLS_SESSION_TICKETS		0x00000002L
+
 struct tls;
 struct tls_config;
 
@@ -78,6 +82,12 @@ int tls_config_set_keypair_mem(struct tl
     size_t _cert_len, const uint8_t *_key, size_t _key_len);
 void tls_config_set_protocols(struct tls_config *_config, uint32_t _protocols);
 void tls_config_set_verify_depth(struct tls_config *_config, int _verify_depth);
+
+void tls_config_enable_session_resumption(struct tls_config *_config);
+void tls_config_enable_session_tickets(struct tls_config *_config);
+
+void tls_config_disable_session_resumption(struct tls_config *_config);
+void tls_config_disable_session_tickets(struct tls_config *_config);
 
 void tls_config_prefer_ciphers_client(struct tls_config *_config);
 void tls_config_prefer_ciphers_server(struct tls_config *_config);
Index: src/lib/libtls/tls_config.c
===================================================================
RCS file: /cvs/src/lib/libtls/tls_config.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 tls_config.c
--- src/lib/libtls/tls_config.c	22 Aug 2016 14:55:59 -0000	1.28
+++ src/lib/libtls/tls_config.c	28 Aug 2016 10:35:32 -0000
@@ -193,6 +193,9 @@ tls_config_new(void)
 	tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT);
 	tls_config_set_verify_depth(config, 6);
 
+	tls_config_enable_session_resumption(config);
+	tls_config_enable_session_tickets(config);
+
 	tls_config_prefer_ciphers_server(config);
 
 	tls_config_verify(config);
@@ -580,6 +583,30 @@ void
 tls_config_set_verify_depth(struct tls_config *config, int verify_depth)
 {
 	config->verify_depth = verify_depth;
+}
+
+void
+tls_config_enable_session_resumption(struct tls_config *config)
+{
+	config->tls_extensions |= TLS_SESSION_RESUMPTION;
+}
+
+void
+tls_config_enable_session_tickets(struct tls_config *config)
+{
+	config->tls_extensions |= TLS_SESSION_TICKETS;
+}
+
+void
+tls_config_disable_session_resumption(struct tls_config *config)
+{
+	config->tls_extensions &= ~TLS_SESSION_RESUMPTION;
+}
+
+void
+tls_config_disable_session_tickets(struct tls_config *config)
+{
+	config->tls_extensions &= ~TLS_SESSION_TICKETS;
 }
 
 void
Index: src/lib/libtls/tls_init.3
===================================================================
RCS file: /cvs/src/lib/libtls/tls_init.3,v
retrieving revision 1.67
diff -u -p -u -r1.67 tls_init.3
--- src/lib/libtls/tls_init.3	22 Aug 2016 14:55:59 -0000	1.67
+++ src/lib/libtls/tls_init.3	28 Aug 2016 10:35:32 -0000
@@ -41,6 +41,10 @@
 .Nm tls_config_set_keypair_mem ,
 .Nm tls_config_set_protocols ,
 .Nm tls_config_set_verify_depth ,
+.Nm tls_config_enable_session_resumption ,
+.Nm tls_config_enable_session_tickets ,
+.Nm tls_config_disable_session_resumption ,
+.Nm tls_config_disable_session_tickets ,
 .Nm tls_config_prefer_ciphers_client ,
 .Nm tls_config_prefer_ciphers_server ,
 .Nm tls_config_clear_keys ,
@@ -126,6 +130,14 @@
 .Fn tls_config_set_protocols "struct tls_config *config" "uint32_t protocols"
 .Ft "void"
 .Fn tls_config_set_verify_depth "struct tls_config *config" "int verify_depth"
+.Ft "void"
+.Fn tls_config_enable_session_resumption "struct tls_config *config"
+.Ft "void"
+.Fn tls_config_enable_session_tickets "struct tls_config *config"
+.Ft "void"
+.Fn tls_config_disable_session_resumption "struct tls_config *config"
+.Ft "void"
+.Fn tls_config_disable_session_tickets "struct tls_config *config"
 .Ft "void"
 .Fn tls_config_prefer_ciphers_client "struct tls_config *config"
 .Ft "void"
Index: src/lib/libtls/tls_internal.h
===================================================================
RCS file: /cvs/src/lib/libtls/tls_internal.h,v
retrieving revision 1.42
diff -u -p -u -r1.42 tls_internal.h
--- src/lib/libtls/tls_internal.h	22 Aug 2016 17:12:35 -0000	1.42
+++ src/lib/libtls/tls_internal.h	28 Aug 2016 10:35:32 -0000
@@ -64,6 +64,7 @@ struct tls_config {
 	int ecdhecurve;
 	struct tls_keypair *keypair;
 	uint32_t protocols;
+	uint32_t tls_extensions;
 	int verify_cert;
 	int verify_client;
 	int verify_depth;
Index: src/lib/libtls/tls_server.c
===================================================================
RCS file: /cvs/src/lib/libtls/tls_server.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 tls_server.c
--- src/lib/libtls/tls_server.c	22 Aug 2016 14:51:37 -0000	1.25
+++ src/lib/libtls/tls_server.c	28 Aug 2016 10:35:32 -0000
@@ -213,6 +213,25 @@ tls_configure_server_ssl(struct tls *ctx
 	if (ctx->config->ciphers_server == 1)
 		SSL_CTX_set_options(*ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
 
+	if (ctx->config->tls_extensions & TLS_SESSION_RESUMPTION) {
+		/* sets the defaults from libssl */
+		SSL_CTX_set_session_cache_mode(*ssl_ctx, SSL_SESS_CACHE_SERVER);
+		SSL_CTX_sess_set_cache_size(*ssl_ctx, SSL_SESSION_CACHE_MAX_SIZE_DEFAULT);
+
+	} else {
+		SSL_CTX_set_session_cache_mode(*ssl_ctx,
+		    SSL_SESS_CACHE_SERVER
+		    |SSL_SESS_CACHE_NO_AUTO_CLEAR
+		    |SSL_SESS_CACHE_NO_INTERNAL_STORE);
+
+		SSL_CTX_sess_set_cache_size(*ssl_ctx, 1);
+	}
+
+	if (ctx->config->tls_extensions & TLS_SESSION_TICKETS)
+		SSL_CTX_clear_options(*ssl_ctx, SSL_OP_NO_TICKET);
+	else
+		SSL_CTX_set_options(*ssl_ctx, SSL_OP_NO_TICKET);
+
 	/*
 	 * Set session ID context to a random value.  We don't support
 	 * persistent caching of sessions so it is OK to set a temporary

Reply via email to