mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
mod_ssl: negotiate the TLS protocol version per name based vhost configuration.
By using the new ClientHello callback provided by OpenSSL 1.1.1, which runs at the earliest connection stage, we can switch the SSL_CTX of the SSL connection early enough for OpenSSL to take into account the protocol configuration of the vhost. In other words: SSL_set_SSL_CTX(c->SSL, s->SSL_CTX) followed by: SSL_set_{min,max}_proto_version(SSL_CTX_get_{min,max}_proto_version(s->SSL_CTX)) works as expected at this stage (while the same from the SNI callback is ignored by/due to OpenSSL's state machine). Extracting the SNI (to select the relevant vhost) in the ClientHello callback is not as easy as calling SSL_get_servername() though, we have to work with the raw TLS extensions helpers provided by OpenSSL. I stole this code from a test in the OpenSSL source code (i.e. client_hello_select_server_ctx() in test/handshake_helper.c). We can then call init_vhost() as with the SNI callback (in use only for OpenSSL versions earlier than 1.1.1 now), and pass it the extracted SNI. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1868645 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -500,8 +500,11 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
|
||||
"Configuring TLS extension handling");
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
|
||||
/*
|
||||
* Server name indication (SNI)
|
||||
* The Server Name Indication (SNI) provided by the ClientHello can be
|
||||
* used to select the right (name-based-)vhost and its SSL configuration
|
||||
* before the handshake takes place.
|
||||
*/
|
||||
if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
|
||||
ssl_callback_ServerNameIndication) ||
|
||||
@@ -512,6 +515,15 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
|
||||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
return ssl_die(s);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* The ClientHello callback also allows to retrieve the SNI, but since it
|
||||
* runs at the earliest possible connection stage we can even set the TLS
|
||||
* protocol version(s) according to the selected (name-based-)vhost, which
|
||||
* is not possible at the SNI callback stage (due to OpenSSL internals).
|
||||
*/
|
||||
SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OCSP_STAPLING
|
||||
/*
|
||||
@@ -706,7 +718,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||||
/* We first determine the maximum protocol version we should provide */
|
||||
#if SSL_HAVE_PROTOCOL_TLSV1_3
|
||||
if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
|
||||
if (protocol & SSL_PROTOCOL_TLSV1_3) {
|
||||
prot = TLS1_3_VERSION;
|
||||
} else
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user