Skip to content

Commit 0129f67

Browse files
committed
SNI: added restriction for TLSv1.3 cross-SNI session resumption
Signed-off-by: Nic <[email protected]>
1 parent 463fab6 commit 0129f67

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
From 823e886851263a8ce84fd22aeead4c3aa819bce1 Mon Sep 17 00:00:00 2001
2+
From: Sergey Kandaurov <[email protected]>
3+
Date: Wed, 22 Jan 2025 18:55:44 +0400
4+
Subject: [PATCH] SNI: added restriction for TLSv1.3 cross-SNI session
5+
resumption.
6+
7+
In OpenSSL, session resumption always happens in the default SSL context,
8+
prior to invoking the SNI callback. Further, unlike in TLSv1.2 and older
9+
protocols, SSL_get_servername() returns values received in the resumption
10+
handshake, which may be different from the value in the initial handshake.
11+
Notably, this makes the restriction added in b720f650b insufficient for
12+
sessions resumed with different SNI server name.
13+
14+
Considering the example from b720f650b, previously, a client was able to
15+
request example.org by presenting a certificate for example.org, then to
16+
resume and request example.com.
17+
18+
The fix is to reject handshakes resumed with a different server name, if
19+
verification of client certificates is enabled in a corresponding server
20+
configuration.
21+
---
22+
src/http/ngx_http_request.c | 27 +++++++++++++++++++++++++--
23+
1 file changed, 25 insertions(+), 2 deletions(-)
24+
25+
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
26+
index 013b7158e..d5ac3d415 100644
27+
--- a/src/http/ngx_http_request.c
28+
+++ b/src/http/ngx_http_request.c
29+
@@ -909,6 +909,31 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
30+
goto done;
31+
}
32+
33+
+ sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
34+
+
35+
+#if (defined TLS1_3_VERSION \
36+
+ && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL)
37+
+
38+
+ /*
39+
+ * SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+,
40+
+ * but servername being negotiated in every TLSv1.3 handshake
41+
+ * is only returned in OpenSSL 1.1.1+ as well
42+
+ */
43+
+
44+
+ if (sscf->verify) {
45+
+ const char *hostname;
46+
+
47+
+ hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn));
48+
+
49+
+ if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) {
50+
+ c->ssl->handshake_rejected = 1;
51+
+ *ad = SSL_AD_ACCESS_DENIED;
52+
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
53+
+ }
54+
+ }
55+
+
56+
+#endif
57+
+
58+
hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
59+
if (hc->ssl_servername == NULL) {
60+
goto error;
61+
@@ -922,8 +947,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
62+
63+
ngx_set_connection_log(c, clcf->error_log);
64+
65+
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
66+
-
67+
c->ssl->buffer_size = sscf->buffer_size;
68+
69+
if (sscf->ssl.ctx) {
70+
--
71+
2.43.0
72+

0 commit comments

Comments
 (0)