mod_ssl: backport TLSv1.3 support changes from upstream (#1615059)

Resolves: rhbz#1615059
This commit is contained in:
Joe Orton 2018-08-13 14:43:07 +01:00
parent 16e8d75233
commit 2f9bc4598d
3 changed files with 769 additions and 1 deletions

24
httpd-2.4.34-layfix.patch Normal file
View File

@ -0,0 +1,24 @@
--- httpd-2.4.34/config.layout.layfix
+++ httpd-2.4.34/config.layout
@@ -133,6 +133,7 @@
# Layout used in Fedora httpd packaging.
<Layout Fedora>
prefix: /usr
+ localstatedir: /var
exec_prefix: ${prefix}
bindir: ${prefix}/bin
sbindir: ${prefix}/sbin
@@ -144,11 +145,10 @@
installbuilddir: ${libdir}/httpd/build
errordir: ${datadir}/error
iconsdir: ${datadir}/icons
- htdocsdir: /var/www/html
+ htdocsdir: ${localstatedir}/www/html
manualdir: ${datadir}/manual
- cgidir: /var/www/cgi-bin
+ cgidir: ${localstatedir}/www/cgi-bin
includedir: ${prefix}/include/httpd
- localstatedir: /var
runtimedir: /run/httpd
logfiledir: ${localstatedir}/log/httpd
proxycachedir: ${localstatedir}/cache/httpd/proxy

View File

@ -0,0 +1,737 @@
# ./pullrev.sh 1827912 1827924 1827992 1828220 1828222 1828720 1828723 1828790 1828791 1828792
http://svn.apache.org/viewvc?view=revision&revision=1827912
http://svn.apache.org/viewvc?view=revision&revision=1827924
http://svn.apache.org/viewvc?view=revision&revision=1827992
http://svn.apache.org/viewvc?view=revision&revision=1828220
http://svn.apache.org/viewvc?view=revision&revision=1828222
http://svn.apache.org/viewvc?view=revision&revision=1828720
http://svn.apache.org/viewvc?view=revision&revision=1828723
http://svn.apache.org/viewvc?view=revision&revision=1828790
http://svn.apache.org/viewvc?view=revision&revision=1828791
http://svn.apache.org/viewvc?view=revision&revision=1828792
--- httpd-2.4.34/modules/ssl/mod_ssl.c.r1827912+
+++ httpd-2.4.34/modules/ssl/mod_ssl.c
@@ -93,9 +93,9 @@
SSL_CMD_SRV(FIPS, FLAG,
"Enable FIPS-140 mode "
"(`on', `off')")
- SSL_CMD_ALL(CipherSuite, TAKE1,
- "Colon-delimited list of permitted SSL Ciphers "
- "('XXX:...:XXX' - see manual)")
+ SSL_CMD_ALL(CipherSuite, TAKE12,
+ "Colon-delimited list of permitted SSL Ciphers, optional preceeded "
+ "by protocol identifier ('XXX:...:XXX' - see manual)")
SSL_CMD_SRV(CertificateFile, TAKE1,
"SSL Server Certificate file "
"('/path/to/file' - PEM or DER encoded)")
@@ -185,9 +185,9 @@
SSL_CMD_PXY(ProxyProtocol, RAW_ARGS,
"SSL Proxy: enable or disable SSL protocol flavors "
"('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
- SSL_CMD_PXY(ProxyCipherSuite, TAKE1,
+ SSL_CMD_PXY(ProxyCipherSuite, TAKE12,
"SSL Proxy: colon-delimited list of permitted SSL ciphers "
- "('XXX:...:XXX' - see manual)")
+ ", optionally preceeded by protocol specifier ('XXX:...:XXX' - see manual)")
SSL_CMD_PXY(ProxyVerify, TAKE1,
"SSL Proxy: whether to verify the remote certificate "
"('on' or 'off')")
@@ -398,7 +398,7 @@
/* We must register the library in full, to ensure our configuration
* code can successfully test the SSL environment.
*/
-#if MODSSL_USE_OPENSSL_PRE_1_1_API
+#if MODSSL_USE_OPENSSL_PRE_1_1_API || defined(LIBRESSL_VERSION_NUMBER)
(void)CRYPTO_malloc_init();
#else
OPENSSL_malloc_init();
--- httpd-2.4.34/modules/ssl/ssl_engine_config.c.r1827912+
+++ httpd-2.4.34/modules/ssl/ssl_engine_config.c
@@ -136,6 +136,7 @@
mctx->auth.cipher_suite = NULL;
mctx->auth.verify_depth = UNSET;
mctx->auth.verify_mode = SSL_CVERIFY_UNSET;
+ mctx->auth.tls13_ciphers = NULL;
mctx->ocsp_mask = UNSET;
mctx->ocsp_force_default = UNSET;
@@ -280,6 +281,7 @@
cfgMergeString(auth.cipher_suite);
cfgMergeInt(auth.verify_depth);
cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
+ cfgMergeString(auth.tls13_ciphers);
cfgMergeInt(ocsp_mask);
cfgMergeBool(ocsp_force_default);
@@ -761,24 +763,39 @@
const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
void *dcfg,
- const char *arg)
+ const char *arg1, const char *arg2)
{
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- /* Disable null and export ciphers by default, except for PROFILE=
- * configs where the parser doesn't cope. */
- if (strncmp(arg, "PROFILE=", 8) != 0)
- arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
-
- if (cmd->path) {
- dc->szCipherSuite = arg;
- }
- else {
- sc->server->auth.cipher_suite = arg;
+ if (arg2 == NULL) {
+ arg2 = arg1;
+ arg1 = "SSL";
}
-
- return NULL;
+
+ if (!strcmp("SSL", arg1)) {
+ /* Disable null and export ciphers by default, except for PROFILE=
+ * configs where the parser doesn't cope. */
+ if (strncmp(arg2, "PROFILE=", 8) != 0)
+ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
+ if (cmd->path) {
+ dc->szCipherSuite = arg2;
+ }
+ else {
+ sc->server->auth.cipher_suite = arg2;
+ }
+ return NULL;
+ }
+#ifdef SSL_OP_NO_TLSv1_3
+ else if (!strcmp("TLSv1.3", arg1)) {
+ if (cmd->path) {
+ return "TLSv1.3 ciphers cannot be set inside a directory context";
+ }
+ sc->server->auth.tls13_ciphers = arg2;
+ return NULL;
+ }
+#endif
+ return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
}
#define SSL_FLAGS_CHECK_FILE \
@@ -1451,6 +1468,9 @@
else if (strcEQ(w, "TLSv1.2")) {
thisopt = SSL_PROTOCOL_TLSV1_2;
}
+ else if (SSL_HAVE_PROTOCOL_TLSV1_3 && strcEQ(w, "TLSv1.3")) {
+ thisopt = SSL_PROTOCOL_TLSV1_3;
+ }
#endif
else if (strcEQ(w, "all")) {
thisopt = SSL_PROTOCOL_ALL;
@@ -1512,18 +1532,30 @@
const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
void *dcfg,
- const char *arg)
+ const char *arg1, const char *arg2)
{
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
-
- /* Disable null and export ciphers by default, except for PROFILE=
- * configs where the parser doesn't cope. */
- if (strncmp(arg, "PROFILE=", 8) != 0)
- arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
-
- dc->proxy->auth.cipher_suite = arg;
-
- return NULL;
+
+ if (arg2 == NULL) {
+ arg2 = arg1;
+ arg1 = "SSL";
+ }
+
+ if (!strcmp("SSL", arg1)) {
+ /* Disable null and export ciphers by default, except for PROFILE=
+ * configs where the parser doesn't cope. */
+ if (strncmp(arg2, "PROFILE=", 8) != 0)
+ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
+ dc->proxy->auth.cipher_suite = arg2;
+ return NULL;
+ }
+#ifdef SSL_OP_NO_TLSv1_3
+ else if (!strcmp("TLSv1.3", arg1)) {
+ dc->proxy->auth.tls13_ciphers = arg2;
+ return NULL;
+ }
+#endif
+ return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
}
const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
--- httpd-2.4.34/modules/ssl/ssl_engine_init.c.r1827912+
+++ httpd-2.4.34/modules/ssl/ssl_engine_init.c
@@ -568,6 +568,9 @@
#ifdef HAVE_TLSV1_X
(protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
(protocol & SSL_PROTOCOL_TLSV1_2 ? "TLSv1.2, " : ""),
+#if SSL_HAVE_PROTOCOL_TLSV1_3
+ (protocol & SSL_PROTOCOL_TLSV1_3 ? "TLSv1.3, " : ""),
+#endif
#endif
NULL);
cp[strlen(cp)-2] = NUL;
@@ -600,6 +603,13 @@
TLSv1_2_client_method() : /* proxy */
TLSv1_2_server_method(); /* server */
}
+#ifdef SSL_OP_NO_TLSv1_3
+ else if (protocol == SSL_PROTOCOL_TLSV1_3) {
+ method = mctx->pkp ?
+ TLSv1_3_client_method() : /* proxy */
+ TLSv1_3_server_method(); /* server */
+ }
+#endif
#endif
else { /* For multiple protocols, we need a flexible method */
method = mctx->pkp ?
@@ -617,7 +627,8 @@
SSL_CTX_set_options(ctx, SSL_OP_ALL);
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
/* always disable SSLv2, as per RFC 6176 */
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
@@ -640,9 +651,19 @@
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
}
#endif
+#ifdef SSL_OP_NO_TLSv1_3
+ if (!(protocol & SSL_PROTOCOL_TLSV1_3)) {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
+ }
+#endif
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
/* We first determine the maximum protocol version we should provide */
+#ifdef SSL_OP_NO_TLSv1_3
+ if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
+ prot = TLS1_3_VERSION;
+ } else
+#endif
if (protocol & SSL_PROTOCOL_TLSV1_2) {
prot = TLS1_2_VERSION;
} else if (protocol & SSL_PROTOCOL_TLSV1_1) {
@@ -664,6 +685,11 @@
/* Next we scan for the minimal protocol version we should provide,
* but we do not allow holes between max and min */
+#ifdef SSL_OP_NO_TLSv1_3
+ if (prot == TLS1_3_VERSION && protocol & SSL_PROTOCOL_TLSV1_2) {
+ prot = TLS1_2_VERSION;
+ }
+#endif
if (prot == TLS1_2_VERSION && protocol & SSL_PROTOCOL_TLSV1_1) {
prot = TLS1_1_VERSION;
}
@@ -888,7 +914,15 @@
ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
return ssl_die(s);
}
-
+#ifdef SSL_OP_NO_TLSv1_3
+ if (mctx->auth.tls13_ciphers
+ && !SSL_CTX_set_ciphersuites(ctx, mctx->auth.tls13_ciphers)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
+ "Unable to configure permitted TLSv1.3 ciphers");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+ return ssl_die(s);
+ }
+#endif
return APR_SUCCESS;
}
--- httpd-2.4.34/modules/ssl/ssl_engine_kernel.c.r1827912+
+++ httpd-2.4.34/modules/ssl/ssl_engine_kernel.c
@@ -188,6 +188,12 @@
|| strcmp(a1->cipher_suite, a2->cipher_suite))) {
return 0;
}
+ /* both have the same ca cipher suite string */
+ if ((a1->tls13_ciphers != a2->tls13_ciphers)
+ && (!a1->tls13_ciphers || !a2->tls13_ciphers
+ || strcmp(a1->tls13_ciphers, a2->tls13_ciphers))) {
+ return 0;
+ }
return 1;
}
@@ -424,21 +430,55 @@
}
}
+static int ssl_check_post_client_verify(request_rec *r, SSLSrvConfigRec *sc,
+ SSLDirConfigRec *dc, SSL *ssl)
+{
+ /*
+ * Finally check for acceptable renegotiation results
+ */
+ if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
+ (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
+ BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
+
+ if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
+ "Re-negotiation handshake failed: "
+ "Client verification failed");
+
+ return HTTP_FORBIDDEN;
+ }
+
+ if (do_verify) {
+ X509 *peercert;
+
+ if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
+ "Re-negotiation handshake failed: "
+ "Client certificate missing");
+
+ return HTTP_FORBIDDEN;
+ }
+
+ X509_free(peercert);
+ }
+ }
+ return OK;
+}
+
/*
- * Access Handler
+ * Access Handler, classic flavour, for SSL/TLS up to v1.2
+ * where everything can be renegotiated and no one is happy.
*/
-int ssl_hook_Access(request_rec *r)
+static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
+ SSLConnRec *sslconn, SSL *ssl)
{
- SSLDirConfigRec *dc = myDirConfig(r);
- SSLSrvConfigRec *sc = mySrvConfig(r->server);
- SSLConnRec *sslconn = myConnConfig(r->connection);
- SSL *ssl = sslconn ? sslconn->ssl : NULL;
server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
SSLSrvConfigRec *hssc = handshakeserver? mySrvConfig(handshakeserver) : NULL;
SSL_CTX *ctx = NULL;
apr_array_header_t *requires;
ssl_require_t *ssl_requires;
- int ok, i;
+ int ok, i, rc;
BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
X509 *cert;
X509 *peercert;
@@ -446,66 +486,9 @@
X509_STORE_CTX *cert_store_ctx;
STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
const SSL_CIPHER *cipher = NULL;
- int depth, verify_old, verify, n, is_slave = 0;
+ int depth, verify_old, verify, n;
const char *ncipher_suite;
- /* On a slave connection, we do not expect to have an SSLConnRec, but
- * our master connection might have one. */
- if (!(sslconn && ssl) && r->connection->master) {
- sslconn = myConnConfig(r->connection->master);
- ssl = sslconn ? sslconn->ssl : NULL;
- handshakeserver = sslconn ? sslconn->server : NULL;
- hssc = handshakeserver? mySrvConfig(handshakeserver) : NULL;
- is_slave = 1;
- }
-
- if (ssl) {
- /*
- * We should have handshaken here (on handshakeserver),
- * otherwise we are being redirected (ErrorDocument) from
- * a renegotiation failure below. The access is still
- * forbidden in the latter case, let ap_die() handle
- * this recursive (same) error.
- */
- if (!SSL_is_init_finished(ssl)) {
- return HTTP_FORBIDDEN;
- }
- ctx = SSL_get_SSL_CTX(ssl);
- }
-
- /*
- * Support for SSLRequireSSL directive
- */
- if (dc->bSSLRequired && !ssl) {
- if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !is_slave) {
- /* This vhost was configured for optional SSL, just tell the
- * client that we need to upgrade.
- */
- apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
- apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
-
- return HTTP_UPGRADE_REQUIRED;
- }
-
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
- "access to %s failed, reason: %s",
- r->filename, "SSL connection required");
-
- /* remember forbidden access for strict require option */
- apr_table_setn(r->notes, "ssl-access-forbidden", "1");
-
- return HTTP_FORBIDDEN;
- }
-
- /*
- * Check to see whether SSL is in use; if it's not, then no
- * further access control checks are relevant. (the test for
- * sc->enabled is probably strictly unnecessary)
- */
- if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
- return DECLINED;
- }
-
#ifdef HAVE_SRP
/*
* Support for per-directory reconfigured SSL connection parameters
@@ -581,7 +564,7 @@
}
/* configure new state */
- if (is_slave) {
+ if (r->connection->master) {
/* TODO: this categorically fails changed cipher suite settings
* on slave connections. We could do better by
* - create a new SSL* from our SSL_CTX and set cipher suite there,
@@ -659,7 +642,7 @@
}
if (renegotiate) {
- if (is_slave) {
+ if (r->connection->master) {
/* The request causes renegotiation on a slave connection.
* This is not allowed since we might have concurrent requests
* on this connection.
@@ -732,7 +715,7 @@
(verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)))
{
renegotiate = TRUE;
- if (is_slave) {
+ if (r->connection->master) {
/* The request causes renegotiation on a slave connection.
* This is not allowed since we might have concurrent requests
* on this connection.
@@ -1050,30 +1033,8 @@
/*
* Finally check for acceptable renegotiation results
*/
- if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
- (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
- BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
- (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
-
- if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
- "Re-negotiation handshake failed: "
- "Client verification failed");
-
- return HTTP_FORBIDDEN;
- }
-
- if (do_verify) {
- if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
- "Re-negotiation handshake failed: "
- "Client certificate missing");
-
- return HTTP_FORBIDDEN;
- }
-
- X509_free(peercert);
- }
+ if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, ssl))) {
+ return rc;
}
/*
@@ -1167,6 +1128,195 @@
return DECLINED;
}
+#ifdef SSL_OP_NO_TLSv1_3
+/*
+ * Access Handler, modern flavour, for SSL/TLS v1.3 and onward.
+ * Only client certificates can be requested, everything else stays.
+ */
+static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
+ SSLConnRec *sslconn, SSL *ssl)
+{
+ if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
+ (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
+ int vmode_inplace, vmode_needed;
+ int change_vmode = FALSE;
+ int old_state, n, rc;
+
+ vmode_inplace = SSL_get_verify_mode(ssl);
+ vmode_needed = SSL_VERIFY_NONE;
+
+ if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
+ vmode_needed |= SSL_VERIFY_PEER_STRICT;
+ }
+
+ if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
+ (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
+ (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
+ {
+ vmode_needed |= SSL_VERIFY_PEER;
+ }
+
+ if (vmode_needed == SSL_VERIFY_NONE) {
+ return DECLINED;
+ }
+
+ vmode_needed |= SSL_VERIFY_CLIENT_ONCE;
+ if (vmode_inplace != vmode_needed) {
+ /* Need to change, if new setting is more restrictive than existing one */
+
+ if ((vmode_inplace == SSL_VERIFY_NONE)
+ || (!(vmode_inplace & SSL_VERIFY_PEER)
+ && (vmode_needed & SSL_VERIFY_PEER))
+ || (!(vmode_inplace & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
+ && (vmode_needed & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
+ /* need to change the effective verify mode */
+ change_vmode = TRUE;
+ }
+ else {
+ /* FIXME: does this work with TLSv1.3? Is this more than re-inspecting
+ * the certificate we should already have? */
+ /*
+ * override of SSLVerifyDepth
+ *
+ * The depth checks are handled by us manually inside the
+ * verify callback function and not by OpenSSL internally
+ * (and our function is aware of both the per-server and
+ * per-directory contexts). So we cannot ask OpenSSL about
+ * the currently verify depth. Instead we remember it in our
+ * SSLConnRec attached to the SSL* of OpenSSL. We've to force
+ * the renegotiation if the reconfigured/new verify depth is
+ * less than the currently active/remembered verify depth
+ * (because this means more restriction on the certificate
+ * chain).
+ */
+ n = (sslconn->verify_depth != UNSET)?
+ sslconn->verify_depth : sc->server->auth.verify_depth;
+ /* determine the new depth */
+ sslconn->verify_depth = (dc->nVerifyDepth != UNSET)
+ ? dc->nVerifyDepth
+ : sc->server->auth.verify_depth;
+ if (sslconn->verify_depth < n) {
+ change_vmode = TRUE;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "Reduced client verification depth will "
+ "force renegotiation");
+ }
+ }
+ }
+
+ if (change_vmode) {
+ char peekbuf[1];
+
+ if (r->connection->master) {
+ /* FIXME: modifying the SSL on a slave connection is no good.
+ * We would need to push this back to the master connection
+ * somehow.
+ */
+ apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "verify-client");
+ return HTTP_FORBIDDEN;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() "verify client post handshake");
+
+ SSL_set_verify(ssl, vmode_needed, ssl_callback_SSLVerify);
+ SSL_verify_client_post_handshake(ssl);
+
+ old_state = sslconn->reneg_state;
+ sslconn->reneg_state = RENEG_ALLOW;
+ modssl_set_app_data2(ssl, r);
+
+ SSL_do_handshake(ssl);
+ /* Need to trigger renegotiation handshake by reading.
+ * Peeking 0 bytes actually works.
+ * See: http://marc.info/?t=145493359200002&r=1&w=2
+ */
+ SSL_peek(ssl, peekbuf, 0);
+
+ sslconn->reneg_state = old_state;
+ modssl_set_app_data2(ssl, NULL);
+
+ /*
+ * Finally check for acceptable renegotiation results
+ */
+ if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, ssl))) {
+ return rc;
+ }
+ }
+ }
+
+ return DECLINED;
+}
+#endif
+
+int ssl_hook_Access(request_rec *r)
+{
+ SSLDirConfigRec *dc = myDirConfig(r);
+ SSLSrvConfigRec *sc = mySrvConfig(r->server);
+ SSLConnRec *sslconn = myConnConfig(r->connection);
+ SSL *ssl = sslconn ? sslconn->ssl : NULL;
+
+ /* On a slave connection, we do not expect to have an SSLConnRec, but
+ * our master connection might have one. */
+ if (!(sslconn && ssl) && r->connection->master) {
+ sslconn = myConnConfig(r->connection->master);
+ ssl = sslconn ? sslconn->ssl : NULL;
+ }
+
+ /*
+ * We should have handshaken here, otherwise we are being
+ * redirected (ErrorDocument) from a renegotiation failure below.
+ * The access is still forbidden in the latter case, let ap_die() handle
+ * this recursive (same) error.
+ */
+ if (ssl && !SSL_is_init_finished(ssl)) {
+ return HTTP_FORBIDDEN;
+ }
+
+ /*
+ * Support for SSLRequireSSL directive
+ */
+ if (dc->bSSLRequired && !ssl) {
+ if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !r->connection->master) {
+ /* This vhost was configured for optional SSL, just tell the
+ * client that we need to upgrade.
+ */
+ apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
+ apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
+
+ return HTTP_UPGRADE_REQUIRED;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
+ "access to %s failed, reason: %s",
+ r->filename, "SSL connection required");
+
+ /* remember forbidden access for strict require option */
+ apr_table_setn(r->notes, "ssl-access-forbidden", "1");
+
+ return HTTP_FORBIDDEN;
+ }
+
+ /*
+ * Check to see whether SSL is in use; if it's not, then no
+ * further access control checks are relevant. (the test for
+ * sc->enabled is probably strictly unnecessary)
+ */
+ if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
+ return DECLINED;
+ }
+
+#ifdef SSL_OP_NO_TLSv1_3
+ /* TLSv1.3+ is less complicated here. Branch off into a new codeline
+ * and avoid messing with the past. */
+ if (SSL_version(ssl) >= TLS1_3_VERSION) {
+ return ssl_hook_Access_modern(r, sc, dc, sslconn, ssl);
+ }
+#endif
+ return ssl_hook_Access_classic(r, sc, dc, sslconn, ssl);
+}
+
/*
* Authentication Handler:
* Fake a Basic authentication from the X509 client certificate.
--- httpd-2.4.34/modules/ssl/ssl_private.h.r1827912+
+++ httpd-2.4.34/modules/ssl/ssl_private.h
@@ -132,13 +132,14 @@
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
#define SSL_CTX_set_max_proto_version(ctx, version) \
SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
-#endif
-/* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not include most
- * changes from OpenSSL >= 1.1 (new functions, macros, deprecations, ...), so
- * we have to work around this...
+#elif LIBRESSL_VERSION_NUMBER < 0x2070000f
+/* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not
+ * include most changes from OpenSSL >= 1.1 (new functions, macros,
+ * deprecations, ...), so we have to work around this...
*/
#define MODSSL_USE_OPENSSL_PRE_1_1_API (1)
-#else
+#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */
+#else /* defined(LIBRESSL_VERSION_NUMBER) */
#define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
#endif
@@ -238,7 +239,8 @@
void free_bio_methods(void);
#endif
-#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x10002000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000f)
#define X509_STORE_CTX_get0_store(x) (x->ctx)
#endif
@@ -372,8 +374,17 @@
#ifdef HAVE_TLSV1_X
#define SSL_PROTOCOL_TLSV1_1 (1<<3)
#define SSL_PROTOCOL_TLSV1_2 (1<<4)
+#define SSL_PROTOCOL_TLSV1_3 (1<<5)
+
+#ifdef SSL_OP_NO_TLSv1_3
+#define SSL_HAVE_PROTOCOL_TLSV1_3 (1)
+#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_BASIC| \
+ SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2|SSL_PROTOCOL_TLSV1_3)
+#else
+#define SSL_HAVE_PROTOCOL_TLSV1_3 (0)
#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_BASIC| \
SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
+#endif
#else
#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_BASIC)
#endif
@@ -646,6 +657,11 @@
/** for client or downstream server authentication */
int verify_depth;
ssl_verify_t verify_mode;
+
+ /** TLSv1.3 has its separate cipher list, separate from the
+ settings for older TLS protocol versions. Since which one takes
+ effect is a matter of negotiation, we need separate settings */
+ const char *tls13_ciphers;
} modssl_auth_ctx_t;
#ifdef HAVE_TLS_SESSION_TICKETS
@@ -801,7 +817,7 @@
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
const char *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
-const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *, const char *);
const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
@@ -830,7 +846,7 @@
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
-const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *, const char *);
const char *ssl_cmd_SSLProxyVerify(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *);

View File

@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.34
Release: 3%{?dist}
Release: 4%{?dist}
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: index.html
@ -58,6 +58,7 @@ Source44: httpd@.service
Patch1: httpd-2.4.1-apctl.patch
Patch2: httpd-2.4.9-apxs.patch
Patch3: httpd-2.4.1-deplibs.patch
Patch4: httpd-2.4.34-layfix.patch
Patch6: httpd-2.4.3-apctl-systemd.patch
# Needed for socket activation and mod_systemd patch
Patch19: httpd-2.4.25-detect-systemd.patch
@ -74,6 +75,7 @@ Patch31: httpd-2.4.33-sslmultiproxy.patch
Patch34: httpd-2.4.17-socket-activation.patch
Patch35: httpd-2.4.33-sslciphdefault.patch
Patch36: httpd-2.4.33-r1830819+.patch
Patch37: httpd-2.4.34-r1827912+.patch
# Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
@ -218,6 +220,7 @@ interface for storing and accessing per-user session data.
%patch1 -p1 -b .apctl
%patch2 -p1 -b .apxs
%patch3 -p1 -b .deplibs
%patch4 -p1 -b .layfix
%patch6 -p1 -b .apctlsystemd
%patch19 -p1 -b .detectsystemd
@ -234,6 +237,7 @@ interface for storing and accessing per-user session data.
%patch34 -p1 -b .socketactivation
%patch35 -p1 -b .sslciphdefault
%patch36 -p1 -b .r1830819+
%patch37 -p1 -b .r1827912+
%patch58 -p1 -b .r1738878
%patch59 -p1 -b .r1555631
@ -725,6 +729,9 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
* Mon Aug 13 2018 Joe Orton <jorton@redhat.com> - 2.4.34-4
- mod_ssl: backport TLSv1.3 support changes from upstream (#1615059)
* Fri Jul 20 2018 Joe Orton <jorton@redhat.com> - 2.4.34-3
- mod_ssl: fix OCSP regression (upstream r1555631)