From: Stefan Eissing Date: Fri, 25 Jan 2019 13:33:07 +0000 (+0000) Subject: mod_ssl: give mod_md the chance to override certificate after ALPN protocol negotiation. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0b256026827f46a835b35e487810e22420ab27b;p=apache mod_ssl: give mod_md the chance to override certificate after ALPN protocol negotiation. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1852128 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 5a3824b978..c12376fc58 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) mod_ssl: give mod_md the chance to override certificate after ALPN protocol + negotiation. [Stefan Eissing] + *) mod_http2: enable re-use of slave connections again. Fixed slave connection keepalives counter. [Stefan Eissing] diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 1570d8da64..49c46d7e3c 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -2308,6 +2308,37 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) } #ifdef HAVE_TLSEXT + +static apr_status_t set_challenge_creds(conn_rec *c, const char *servername, + SSL *ssl, X509 *cert, EVP_PKEY *key) +{ + SSLConnRec *sslcon = myConnConfig(c); + + sslcon->service_unavailable = 1; + if ((SSL_use_certificate(ssl, cert) < 1)) { + ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086) + "Failed to configure challenge certificate %s", + servername); + return APR_EGENERAL; + } + + if (!SSL_use_PrivateKey(ssl, key)) { + ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087) + "error '%s' using Challenge key: %s", + ERR_error_string(ERR_peek_last_error(), NULL), + servername); + return APR_EGENERAL; + } + + if (SSL_check_private_key(ssl) < 1) { + ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088) + "Challenge certificate and private key %s " + "do not match", servername); + return APR_EGENERAL; + } + return APR_SUCCESS; +} + /* * This function sets the virtual host from an extended * client hello with a server name indication extension ("SNI", cf. RFC 6066). @@ -2337,30 +2368,12 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl) return APR_SUCCESS; } else if (ssl_is_challenge(c, servername, &cert, &key)) { - - sslcon->service_unavailable = 1; - if ((SSL_use_certificate(ssl, cert) < 1)) { - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086) - "Failed to configure challenge certificate %s", - servername); + /* With ACMEv1 we can have challenge connections to a unknown domains + * that need to be answered with a special certificate and will + * otherwise not answer any requests. */ + if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) { return APR_EGENERAL; } - - if (!SSL_use_PrivateKey(ssl, key)) { - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087) - "error '%s' using Challenge key: %s", - ERR_error_string(ERR_peek_last_error(), NULL), - servername); - return APR_EGENERAL; - } - - if (SSL_check_private_key(ssl) < 1) { - ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088) - "Challenge certificate and private key %s " - "do not match", servername); - return APR_EGENERAL; - } - } else { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044) @@ -2653,6 +2666,23 @@ int ssl_callback_alpn_select(SSL *ssl, proposed); return SSL_TLSEXT_ERR_ALERT_FATAL; } + + /* protocol was switched, this could be a challenge protocol such as "acme-tls/1". + * For that to work, we need to allow overrides to our ssl certificate. + * However, exclude challenge checks on our best known traffic protocol. + * (http/1.1 is the default, we never switch to it anyway.) + */ + if (strcmp("h2", proposed)) { + const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + X509 *cert; + EVP_PKEY *key; + + if (ssl_is_challenge(c, servername, &cert, &key)) { + if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) { + return SSL_TLSEXT_ERR_ALERT_FATAL; + } + } + } } return SSL_TLSEXT_ERR_OK;