Commit d5943f3e authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the tlsv1.3-for-2.4.x branch:

Merged 1827912,1827924,1827992,1828222,1828720,1828723,1833588,1833589,1839920,1839946 from trunk

  *) mod_ssl: add experimental support for TLSv1.3 (tested with OpenSSL v1.1.1-pre9. 
     SSL(Proxy)CipherSuite now has an optional first parameter for the protocol the ciphers are for.
     Directive "SSLVerifyClient" now triggers certificate retrieval from the client.
     Verifying the client fails exactly the same for HTTP/2 connections for all SSL protocols,
     as this would need to trigger the master connection thread - which we do not support
     right now.
     Renegotiation of ciphers is intentionally ignored for TLSv1.3 connections. "SSLCipherSuite"
     does not allow to specify TLSv1.3 ciphers in a directory context (because it cannot work) and
     TLSv1.2 or lower ciphers are not relevant for 1.3, as cipher suites are completely separate.
     Sites which make use of such TLSv1.2 feature need to evaluate carefully if or how they 
     can match their needs onto the TLSv1.3 protocol.
     [Yann Ylavic, Stefan Eissing]



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/tlsv1.3-for-2.4.x@1840120 13f79535-47bb-0310-9956-ffa450edef68
parent ee5bbb7c
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.4.35

  *) mod_ssl: add experimental support for TLSv1.3 (tested with OpenSSL v1.1.1-pre9. 
     SSL(Proxy)CipherSuite now has an optional first parameter for the protocol the ciphers are for.
     Directive "SSLVerifyClient" now triggers certificate retrieval from the client.
     Verifying the client fails exactly the same for HTTP/2 connections for all SSL protocols,
     as this would need to trigger the master connection thread - which we do not support
     right now.
     Renegotiation of ciphers is intentionally ignored for TLSv1.3 connections. "SSLCipherSuite"
     does not allow to specify TLSv1.3 ciphers in a directory context (because it cannot work) and
     TLSv1.2 or lower ciphers are not relevant for 1.3, as cipher suites are completely separate.
     Sites which make use of such TLSv1.2 feature need to evaluate carefully if or how they 
     can match their needs onto the TLSv1.3 protocol.
     [Yann Ylavic, Stefan Eissing]

  *) mod_status: Cumulate CPU time of exited child processes in the
     "cu" and "cs" values. Add CPU time of the parent process to the
     "c" and "s" values.
+24 −6
Original line number Diff line number Diff line
@@ -654,6 +654,11 @@ The available (case-insensitive) <em>protocol</em>s are:</p>
    A revision of the TLS 1.1 protocol, as defined in
    <a href="http://www.ietf.org/rfc/rfc5246.txt">RFC 5246</a>.</p></li>

<li><code>TLSv1.3</code> (when using OpenSSL 1.1.1 and later)
    <p>
    A new version of the TLS protocol, as defined in
    <a href="https://github.com/tlswg/tls13-spec">RFC TBD</a>.</p></li>

<li><code>all</code>
    <p>
    This is a shortcut for ``<code>+SSLv3 +TLSv1</code>'' or
@@ -674,7 +679,7 @@ SSLProtocol TLSv1
<name>SSLCipherSuite</name>
<description>Cipher Suite available for negotiation in SSL
handshake</description>
<syntax>SSLCipherSuite <em>cipher-spec</em></syntax>
<syntax>SSLCipherSuite [<em>protocol</em>] <em>cipher-spec</em></syntax>
<default>SSLCipherSuite DEFAULT (depends on OpenSSL version)</default>
<contextlist><context>server config</context>
<context>virtual host</context>
@@ -686,12 +691,25 @@ handshake</description>
<p>
This complex directive uses a colon-separated <em>cipher-spec</em> string
consisting of OpenSSL cipher specifications to configure the Cipher Suite the
client is permitted to negotiate in the SSL handshake phase. Notice that this
directive can be used both in per-server and per-directory context. In
per-server context it applies to the standard SSL handshake when a connection
client is permitted to negotiate in the SSL handshake phase. The optional 
protocol specifier can configure the Cipher Suite for a specific SSL version.
Possible values include "SSL" for all SSL Protocols up to and including TLSv1.2. 
<p>
Notice that this
directive can be used both in per-server and per-directory context. 
In per-server context it applies to the standard SSL handshake when a connection
is established. In per-directory context it forces a SSL renegotiation with the
reconfigured Cipher Suite after the HTTP request was read but before the HTTP
response is sent.</p>
response is sent. (Since renegotiation is not</p>
<p>
If the SSL library supports TLSv1.3 (OpenSSL 1.1.1 and later), the protocol 
specifier "TLSv1.3" can be used to configure the cipher suites for that protocol.
Since TLSv1.3 does not offer renegotiations, specifying ciphers for it in
a directory context is not allowed.</p>
<p>
For a list of TLSv1.3 cipher names, see 
<a href="https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_ciphersuites.html">the OpenSSL
documentation</a>.</p>
<p>
An SSL cipher specification in <em>cipher-spec</em> is composed of 4 major
attributes plus a few extra minor ones:</p>
@@ -2063,7 +2081,7 @@ for additional information.
<name>SSLProxyCipherSuite</name>
<description>Cipher Suite available for negotiation in SSL
proxy handshake</description>
<syntax>SSLProxyCipherSuite <em>cipher-spec</em></syntax>
<syntax>SSLProxyCipherSuite [<em>protocol</em>] <em>cipher-spec</em></syntax>
<default>SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP</default>
<contextlist><context>server config</context> <context>virtual host</context>
<context>proxy section</context></contextlist>
+6 −6
Original line number Diff line number Diff line
@@ -93,9 +93,9 @@ static const command_rec ssl_config_cmds[] = {
    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 @@ static const command_rec ssl_config_cmds[] = {
    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 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
    /* 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();
+50 −18
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
    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 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
    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,23 +763,38 @@ const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)

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;

    /* always disable null and export ciphers */
    arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
    if (arg2 == NULL) {
        arg2 = arg1;
        arg1 = "SSL";
    }
    
    if (!strcmp("SSL", arg1)) {
        /* always disable null and export ciphers */
        arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
        if (cmd->path) {
        dc->szCipherSuite = arg;
            dc->szCipherSuite = arg2;
        }
        else {
        sc->server->auth.cipher_suite = arg;
            sc->server->auth.cipher_suite = arg2;
        }

        return NULL;
    }
#if SSL_HAVE_PROTOCOL_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 \
    (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
@@ -1445,6 +1462,9 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
        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;
@@ -1506,17 +1526,29 @@ const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,

const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
                                        void *dcfg,
                                        const char *arg)
                                        const char *arg1, const char *arg2)
{
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
    
    /* always disable null and export ciphers */
    arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);

    dc->proxy->auth.cipher_suite = arg;
    if (arg2 == NULL) {
        arg2 = arg1;
        arg1 = "SSL";
    }
    
    if (!strcmp("SSL", arg1)) {
        /* always disable null and export ciphers */
        arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
        dc->proxy->auth.cipher_suite = arg2;
        return NULL;
    }
#if SSL_HAVE_PROTOCOL_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,
                                   void *dcfg,
+35 −2
Original line number Diff line number Diff line
@@ -568,6 +568,9 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
#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 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
            TLSv1_2_client_method() : /* proxy */
            TLSv1_2_server_method();  /* server */
    }
#if SSL_HAVE_PROTOCOL_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 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,

    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);

@@ -639,10 +650,19 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
    if (!(protocol & SSL_PROTOCOL_TLSV1_2)) {
        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
    }
#if SSL_HAVE_PROTOCOL_TLSV1_3
    ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1_3,
                                protocol & SSL_PROTOCOL_TLSV1_3, "TLSv1.3");
#endif
#endif

#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)) {
        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 +684,11 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,

    /* Next we scan for the minimal protocol version we should provide,
     * but we do not allow holes between max and min */
#if SSL_HAVE_PROTOCOL_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 +913,15 @@ static apr_status_t ssl_init_ctx_cipher_suite(server_rec *s,
        ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
        return ssl_die(s);
    }

#if SSL_HAVE_PROTOCOL_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;
}

Loading