fec712cfd425894269d94f16f0330536428a8e6a
[feed/packages.git] / net / haproxy / patches / 0016-BUG-MEDIUM-ssl-for-a-handshake-when-server-side-SNI-.patch
1 From 5fbcf1a914507b4c73d83387fdc5e8f612d83558 Mon Sep 17 00:00:00 2001
2 From: Willy Tarreau <w@1wt.eu>
3 Date: Thu, 22 Dec 2016 21:58:38 +0100
4 Subject: [PATCH 16/19] BUG/MEDIUM: ssl: for a handshake when server-side SNI
5 changes
6
7 Calling SSL_set_tlsext_host_name() on the current SSL ctx has no effect
8 if the session is being resumed because the hostname is already stored
9 in the session and is not advertised again in subsequent connections.
10 It's visible when enabling SNI and health checks at the same time because
11 checks do not send an SNI and regular traffic reuses the same connection,
12 resulting in no SNI being sent.
13
14 The only short-term solution is to reset the reused session when the
15 SNI changes compared to the previous one. It can make the server-side
16 performance suffer when SNIs are interleaved but it will work. A better
17 long-term solution would be to keep a small cache of a few contexts for
18 a few SNIs.
19
20 Now with SSL_set_session(ctx, NULL) it works. This needs to be double-
21 checked though. The man says that SSL_set_session() frees any previously
22 existing context. Some people report a bit of breakage when calling
23 SSL_set_session(NULL) on openssl 1.1.0a (freed session not reusable at
24 all though it's not an issue for now).
25
26 This needs to be backported to 1.7 and 1.6.
27 (cherry picked from commit 119a4084bf88418bce74d8af686576e371700c20)
28 ---
29 src/ssl_sock.c | 15 +++++++++++++++
30 1 file changed, 15 insertions(+)
31
32 diff --git a/src/ssl_sock.c b/src/ssl_sock.c
33 index 55eaa28..77fb4b3 100644
34 --- a/src/ssl_sock.c
35 +++ b/src/ssl_sock.c
36 @@ -4143,12 +4143,27 @@ char *ssl_sock_get_version(struct connection *conn)
37 return (char *)SSL_get_version(conn->xprt_ctx);
38 }
39
40 +/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
41 + * to disable SNI.
42 + */
43 void ssl_sock_set_servername(struct connection *conn, const char *hostname)
44 {
45 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
46 + char *prev_name;
47 +
48 if (!ssl_sock_is_ssl(conn))
49 return;
50
51 + /* if the SNI changes, we must destroy the reusable context so that a
52 + * new connection will present a new SNI. As an optimization we could
53 + * later imagine having a small cache of ssl_ctx to hold a few SNI per
54 + * server.
55 + */
56 + prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
57 + if ((!prev_name && hostname) ||
58 + (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
59 + SSL_set_session(conn->xprt_ctx, NULL);
60 +
61 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
62 #endif
63 }
64 --
65 2.10.2
66