summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2019-05-05 20:24:03 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2019-05-06 01:13:58 -0400
commit1a325a196cf2cb54fdb3874cd96f5d57043a86f8 (patch)
tree0d16bd40ea664277ed3e9d60f53cb2f3d4450159
parent52c489837f511771a00be91ecf1b15d390d2980c (diff)
downloadlighttpd1.4-1a325a196cf2cb54fdb3874cd96f5d57043a86f8.tar.gz
lighttpd1.4-1a325a196cf2cb54fdb3874cd96f5d57043a86f8.zip
[mod_openssl] use SSL_CTX_set_client_hello_cb()
use SSL_CTX_set_client_hello_cb() when available (obsoletes SSL_CTX_set_tlsext_servername_callback() and SSL_CTX_set_tlsext_servername_arg())
-rw-r--r--src/mod_openssl.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/src/mod_openssl.c b/src/mod_openssl.c
index 68b889a7..f9a4fe82 100644
--- a/src/mod_openssl.c
+++ b/src/mod_openssl.c
@@ -328,32 +328,16 @@ verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
static int mod_openssl_patch_connection (server *srv, connection *con, handler_ctx *hctx);
static int
-network_ssl_servername_callback (SSL *ssl, int *al, server *srv)
+mod_openssl_SNI (SSL *ssl, server *srv, handler_ctx *hctx, const char *servername, size_t len)
{
- const char *servername;
- handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
- connection *con = hctx->con;
- size_t len;
- UNUSED(al);
-
- buffer_copy_string(con->uri.scheme, "https");
-
- servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
- if (NULL == servername) {
-#if 0
- /* this "error" just means the client didn't support it */
- log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:",
- "failed to get TLS server name");
-#endif
- return SSL_TLSEXT_ERR_NOACK;
- }
- len = strlen(servername);
- if (len >= 1024) { /*(expecting < 256)*/
- log_error_write(srv, __FILE__, __LINE__, "sss", "SSL:",
- "SNI name too long", servername);
+ if (len >= 1024) { /*(expecting < 256; TLSEXT_MAXLEN_host_name is 255)*/
+ log_error(srv->errh, __FILE__, __LINE__,
+ "SSL: SNI name too long %.*s", (int)len, servername);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
+
/* use SNI to patch mod_openssl config and then reset COMP_HTTP_HOST */
+ connection * const con = hctx->con;
buffer_copy_string_len(con->uri.authority, servername, len);
buffer_to_lower(con->uri.authority);
#if 0
@@ -426,6 +410,47 @@ network_ssl_servername_callback (SSL *ssl, int *al, server *srv)
return SSL_TLSEXT_ERR_OK;
}
+
+#ifdef SSL_CLIENT_HELLO_SUCCESS
+static int
+mod_openssl_client_hello_cb (SSL *ssl, int *al, void *srv)
+{
+ handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
+ buffer_copy_string(hctx->con->uri.scheme, "https");
+
+ const unsigned char *name;
+ size_t len, slen;
+ if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &name, &len)) {
+ return SSL_CLIENT_HELLO_SUCCESS; /* client did not provide SNI */
+ }
+
+ /* expecting single element in the server_name extension; parse first one */
+ if (len > 5
+ && (size_t)((name[0] << 8) + name[1]) == len-2
+ && name[2] == TLSEXT_TYPE_server_name
+ && (slen = (name[3] << 8) + name[4]) <= len-5) { /*(first)*/
+ int rc = mod_openssl_SNI(ssl, srv, hctx, (const char *)name+5, slen);
+ if (rc == SSL_TLSEXT_ERR_OK)
+ return SSL_CLIENT_HELLO_SUCCESS;
+ }
+
+ *al = TLS1_AD_UNRECOGNIZED_NAME;
+ return SSL_CLIENT_HELLO_ERROR;
+}
+#else
+static int
+network_ssl_servername_callback (SSL *ssl, int *al, server *srv)
+{
+ handler_ctx *hctx = (handler_ctx *) SSL_get_app_data(ssl);
+ buffer_copy_string(hctx->con->uri.scheme, "https");
+ UNUSED(al);
+
+ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ return (NULL != servername)
+ ? mod_openssl_SNI(ssl, srv, hctx, servername, strlen(servername))
+ : SSL_TLSEXT_ERR_NOACK; /* client did not provide SNI */
+}
+#endif
#endif
@@ -1152,6 +1177,9 @@ network_init_ssl (server *srv, void *p_d)
| SSL_MODE_RELEASE_BUFFERS);
#ifndef OPENSSL_NO_TLSEXT
+ #ifdef SSL_CLIENT_HELLO_SUCCESS
+ SSL_CTX_set_client_hello_cb(s->ssl_ctx,mod_openssl_client_hello_cb,srv);
+ #else
if (!SSL_CTX_set_tlsext_servername_callback(
s->ssl_ctx, network_ssl_servername_callback) ||
!SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) {
@@ -1161,6 +1189,7 @@ network_init_ssl (server *srv, void *p_d)
"extension");
return -1;
}
+ #endif
#if OPENSSL_VERSION_NUMBER >= 0x10002000
SSL_CTX_set_alpn_select_cb(s->ssl_ctx,mod_openssl_alpn_select_cb,NULL);