369db50
369db50
Pull all changes from upstream integration branch:
369db50
369db50
svn diff -r1840105:1841219 https://svn.apache.org/repos/asf/httpd/httpd/branches/tlsv1.3-for-2.4.x
2f9bc45
2f9bc45
--- httpd-2.4.34/modules/ssl/mod_ssl.c.r1827912+
2f9bc45
+++ httpd-2.4.34/modules/ssl/mod_ssl.c
2f9bc45
@@ -93,9 +93,9 @@
2f9bc45
     SSL_CMD_SRV(FIPS, FLAG,
2f9bc45
                 "Enable FIPS-140 mode "
2f9bc45
                 "(`on', `off')")
2f9bc45
-    SSL_CMD_ALL(CipherSuite, TAKE1,
2f9bc45
-                "Colon-delimited list of permitted SSL Ciphers "
2f9bc45
-                "('XXX:...:XXX' - see manual)")
2f9bc45
+    SSL_CMD_ALL(CipherSuite, TAKE12,
2f9bc45
+                "Colon-delimited list of permitted SSL Ciphers, optional preceeded "
2f9bc45
+                "by protocol identifier ('XXX:...:XXX' - see manual)")
2f9bc45
     SSL_CMD_SRV(CertificateFile, TAKE1,
2f9bc45
                 "SSL Server Certificate file "
2f9bc45
                 "('/path/to/file' - PEM or DER encoded)")
2f9bc45
@@ -185,9 +185,9 @@
2f9bc45
     SSL_CMD_PXY(ProxyProtocol, RAW_ARGS,
2f9bc45
                "SSL Proxy: enable or disable SSL protocol flavors "
2f9bc45
                 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
2f9bc45
-    SSL_CMD_PXY(ProxyCipherSuite, TAKE1,
2f9bc45
+    SSL_CMD_PXY(ProxyCipherSuite, TAKE12,
2f9bc45
                "SSL Proxy: colon-delimited list of permitted SSL ciphers "
2f9bc45
-               "('XXX:...:XXX' - see manual)")
2f9bc45
+               ", optionally preceeded by protocol specifier ('XXX:...:XXX' - see manual)")
2f9bc45
     SSL_CMD_PXY(ProxyVerify, TAKE1,
2f9bc45
                "SSL Proxy: whether to verify the remote certificate "
2f9bc45
                "('on' or 'off')")
2f9bc45
@@ -398,7 +398,7 @@
2f9bc45
     /* We must register the library in full, to ensure our configuration
2f9bc45
      * code can successfully test the SSL environment.
2f9bc45
      */
2f9bc45
-#if MODSSL_USE_OPENSSL_PRE_1_1_API
2f9bc45
+#if MODSSL_USE_OPENSSL_PRE_1_1_API || defined(LIBRESSL_VERSION_NUMBER)
2f9bc45
     (void)CRYPTO_malloc_init();
2f9bc45
 #else
2f9bc45
     OPENSSL_malloc_init();
2f9bc45
--- httpd-2.4.34/modules/ssl/ssl_engine_config.c.r1827912+
2f9bc45
+++ httpd-2.4.34/modules/ssl/ssl_engine_config.c
2f9bc45
@@ -136,6 +136,7 @@
2f9bc45
     mctx->auth.cipher_suite   = NULL;
2f9bc45
     mctx->auth.verify_depth   = UNSET;
2f9bc45
     mctx->auth.verify_mode    = SSL_CVERIFY_UNSET;
2f9bc45
+    mctx->auth.tls13_ciphers = NULL;
2f9bc45
 
2f9bc45
     mctx->ocsp_mask           = UNSET;
2f9bc45
     mctx->ocsp_force_default  = UNSET;
2f9bc45
@@ -280,6 +281,7 @@
2f9bc45
     cfgMergeString(auth.cipher_suite);
2f9bc45
     cfgMergeInt(auth.verify_depth);
2f9bc45
     cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
2f9bc45
+    cfgMergeString(auth.tls13_ciphers);
2f9bc45
 
2f9bc45
     cfgMergeInt(ocsp_mask);
2f9bc45
     cfgMergeBool(ocsp_force_default);
369db50
@@ -761,22 +763,37 @@
2f9bc45
 
2f9bc45
 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
2f9bc45
                                    void *dcfg,
2f9bc45
-                                   const char *arg)
2f9bc45
+                                   const char *arg1, const char *arg2)
2f9bc45
 {
2f9bc45
     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
2f9bc45
     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
2f9bc45
 
369db50
-    /* always disable null and export ciphers */
369db50
-    arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
2f9bc45
-
2f9bc45
-    if (cmd->path) {
2f9bc45
-        dc->szCipherSuite = arg;
2f9bc45
+    if (arg2 == NULL) {
2f9bc45
+        arg2 = arg1;
2f9bc45
+        arg1 = "SSL";
2f9bc45
     }
369db50
-    else {
369db50
-        sc->server->auth.cipher_suite = arg;
2f9bc45
+    
2f9bc45
+    if (!strcmp("SSL", arg1)) {
369db50
+        /* always disable null and export ciphers */
369db50
+        arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
2f9bc45
+        if (cmd->path) {
2f9bc45
+            dc->szCipherSuite = arg2;
2f9bc45
+        }
2f9bc45
+        else {
2f9bc45
+            sc->server->auth.cipher_suite = arg2;
2f9bc45
+        }
2f9bc45
+        return NULL;
369db50
     }
369db50
-
369db50
-    return NULL;
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    else if (!strcmp("TLSv1.3", arg1)) {
2f9bc45
+        if (cmd->path) {
2f9bc45
+            return "TLSv1.3 ciphers cannot be set inside a directory context";
2f9bc45
+        }
2f9bc45
+        sc->server->auth.tls13_ciphers = arg2;
2f9bc45
+        return NULL;
369db50
+    }
2f9bc45
+#endif
2f9bc45
+    return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
2f9bc45
 }
2f9bc45
 
2f9bc45
 #define SSL_FLAGS_CHECK_FILE \
369db50
@@ -1449,6 +1466,9 @@
2f9bc45
         else if (strcEQ(w, "TLSv1.2")) {
2f9bc45
             thisopt = SSL_PROTOCOL_TLSV1_2;
2f9bc45
         }
2f9bc45
+        else if (SSL_HAVE_PROTOCOL_TLSV1_3 && strcEQ(w, "TLSv1.3")) {
2f9bc45
+            thisopt = SSL_PROTOCOL_TLSV1_3;
2f9bc45
+        }
2f9bc45
 #endif
2f9bc45
         else if (strcEQ(w, "all")) {
2f9bc45
             thisopt = SSL_PROTOCOL_ALL;
369db50
@@ -1510,16 +1530,28 @@
2f9bc45
 
2f9bc45
 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
2f9bc45
                                         void *dcfg,
2f9bc45
-                                        const char *arg)
2f9bc45
+                                        const char *arg1, const char *arg2)
2f9bc45
 {
2f9bc45
     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
2f9bc45
-
369db50
-    /* always disable null and export ciphers */
369db50
-    arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
2f9bc45
-
2f9bc45
-    dc->proxy->auth.cipher_suite = arg;
2f9bc45
-
2f9bc45
-    return NULL;
2f9bc45
+    
2f9bc45
+    if (arg2 == NULL) {
2f9bc45
+        arg2 = arg1;
2f9bc45
+        arg1 = "SSL";
2f9bc45
+    }
2f9bc45
+    
2f9bc45
+    if (!strcmp("SSL", arg1)) {
369db50
+        /* always disable null and export ciphers */
369db50
+        arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
2f9bc45
+        dc->proxy->auth.cipher_suite = arg2;
2f9bc45
+        return NULL;
2f9bc45
+    }
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    else if (!strcmp("TLSv1.3", arg1)) {
2f9bc45
+        dc->proxy->auth.tls13_ciphers = arg2;
2f9bc45
+        return NULL;
2f9bc45
+    }
2f9bc45
+#endif
2f9bc45
+    return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
2f9bc45
 }
2f9bc45
 
2f9bc45
 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
2f9bc45
--- httpd-2.4.34/modules/ssl/ssl_engine_init.c.r1827912+
2f9bc45
+++ httpd-2.4.34/modules/ssl/ssl_engine_init.c
2f9bc45
@@ -568,6 +568,9 @@
2f9bc45
 #ifdef HAVE_TLSV1_X
2f9bc45
                      (protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
2f9bc45
                      (protocol & SSL_PROTOCOL_TLSV1_2 ? "TLSv1.2, " : ""),
2f9bc45
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+                     (protocol & SSL_PROTOCOL_TLSV1_3 ? "TLSv1.3, " : ""),
2f9bc45
+#endif
2f9bc45
 #endif
2f9bc45
                      NULL);
2f9bc45
     cp[strlen(cp)-2] = NUL;
2f9bc45
@@ -600,6 +603,13 @@
2f9bc45
             TLSv1_2_client_method() : /* proxy */
2f9bc45
             TLSv1_2_server_method();  /* server */
2f9bc45
     }
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    else if (protocol == SSL_PROTOCOL_TLSV1_3) {
2f9bc45
+        method = mctx->pkp ?
2f9bc45
+            TLSv1_3_client_method() : /* proxy */
2f9bc45
+            TLSv1_3_server_method();  /* server */
2f9bc45
+    }
2f9bc45
+#endif
2f9bc45
 #endif
2f9bc45
     else { /* For multiple protocols, we need a flexible method */
2f9bc45
         method = mctx->pkp ?
2f9bc45
@@ -617,7 +627,8 @@
2f9bc45
 
2f9bc45
     SSL_CTX_set_options(ctx, SSL_OP_ALL);
2f9bc45
 
2f9bc45
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
2f9bc45
+#if OPENSSL_VERSION_NUMBER < 0x10100000L  || \
2f9bc45
+	(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20800000L)
2f9bc45
     /* always disable SSLv2, as per RFC 6176 */
2f9bc45
     SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
2f9bc45
 
369db50
@@ -639,10 +650,19 @@
369db50
     if (!(protocol & SSL_PROTOCOL_TLSV1_2)) {
2f9bc45
         SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
2f9bc45
     }
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
369db50
+    ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1_3,
369db50
+                                protocol & SSL_PROTOCOL_TLSV1_3, "TLSv1.3");
2f9bc45
+#endif
369db50
 #endif
2f9bc45
 
2f9bc45
 #else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
2f9bc45
     /* We first determine the maximum protocol version we should provide */
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
2f9bc45
+        prot = TLS1_3_VERSION;
369db50
+    } else  
2f9bc45
+#endif
2f9bc45
     if (protocol & SSL_PROTOCOL_TLSV1_2) {
2f9bc45
         prot = TLS1_2_VERSION;
2f9bc45
     } else if (protocol & SSL_PROTOCOL_TLSV1_1) {
369db50
@@ -664,6 +684,11 @@
2f9bc45
 
2f9bc45
     /* Next we scan for the minimal protocol version we should provide,
2f9bc45
      * but we do not allow holes between max and min */
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    if (prot == TLS1_3_VERSION && protocol & SSL_PROTOCOL_TLSV1_2) {
2f9bc45
+        prot = TLS1_2_VERSION;
2f9bc45
+    }
2f9bc45
+#endif
2f9bc45
     if (prot == TLS1_2_VERSION && protocol & SSL_PROTOCOL_TLSV1_1) {
2f9bc45
         prot = TLS1_1_VERSION;
2f9bc45
     }
369db50
@@ -736,6 +761,13 @@
369db50
         SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
369db50
 #endif
369db50
 
369db50
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
369db50
+    /* For OpenSSL >=1.1.1, disable auto-retry mode so it's possible
369db50
+     * to consume handshake records without blocking for app-data.
369db50
+     * https://github.com/openssl/openssl/issues/7178 */
369db50
+    SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
369db50
+#endif
369db50
+    
369db50
     return APR_SUCCESS;
369db50
 }
369db50
 
369db50
@@ -888,7 +920,15 @@
2f9bc45
         ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
2f9bc45
         return ssl_die(s);
2f9bc45
     }
2f9bc45
-
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    if (mctx->auth.tls13_ciphers 
2f9bc45
+        && !SSL_CTX_set_ciphersuites(ctx, mctx->auth.tls13_ciphers)) {
2f9bc45
+        ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()
2f9bc45
+                "Unable to configure permitted TLSv1.3 ciphers");
2f9bc45
+        ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
2f9bc45
+        return ssl_die(s);
2f9bc45
+    }
2f9bc45
+#endif
2f9bc45
     return APR_SUCCESS;
2f9bc45
 }
2f9bc45
 
369db50
@@ -1493,6 +1533,13 @@
369db50
     X509_STORE_CTX *sctx;
369db50
     X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
369db50
 
369db50
+#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
369db50
+    /* For OpenSSL >=1.1.1, turn on client cert support which is
369db50
+     * otherwise turned off by default (by design).
369db50
+     * https://github.com/openssl/openssl/issues/6933 */
369db50
+    SSL_CTX_set_post_handshake_auth(mctx->ssl_ctx, 1);
369db50
+#endif
369db50
+    
369db50
     SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
369db50
                                ssl_callback_proxy_cert);
369db50
 
2f9bc45
--- httpd-2.4.34/modules/ssl/ssl_engine_kernel.c.r1827912+
2f9bc45
+++ httpd-2.4.34/modules/ssl/ssl_engine_kernel.c
2f9bc45
@@ -188,6 +188,12 @@
2f9bc45
             || strcmp(a1->cipher_suite, a2->cipher_suite))) {
2f9bc45
         return 0;
2f9bc45
     }
2f9bc45
+    /* both have the same ca cipher suite string */
2f9bc45
+    if ((a1->tls13_ciphers != a2->tls13_ciphers)
2f9bc45
+        && (!a1->tls13_ciphers || !a2->tls13_ciphers 
2f9bc45
+            || strcmp(a1->tls13_ciphers, a2->tls13_ciphers))) {
2f9bc45
+        return 0;
2f9bc45
+    }
2f9bc45
     return 1;
2f9bc45
 }
2f9bc45
 
369db50
@@ -424,87 +430,70 @@
2f9bc45
     }
2f9bc45
 }
2f9bc45
 
369db50
-/*
2f9bc45
- *  Access Handler
369db50
- */
2f9bc45
-int ssl_hook_Access(request_rec *r)
369db50
+static int ssl_check_post_client_verify(request_rec *r, SSLSrvConfigRec *sc, 
369db50
+                                        SSLDirConfigRec *dc, SSLConnRec *sslconn,
369db50
+                                        SSL *ssl)
2f9bc45
 {
2f9bc45
-    SSLDirConfigRec *dc         = myDirConfig(r);
2f9bc45
-    SSLSrvConfigRec *sc         = mySrvConfig(r->server);
2f9bc45
-    SSLConnRec *sslconn         = myConnConfig(r->connection);
2f9bc45
-    SSL *ssl                    = sslconn ? sslconn->ssl : NULL;
369db50
-    server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
369db50
-    SSLSrvConfigRec *hssc       = handshakeserver? mySrvConfig(handshakeserver) : NULL;
369db50
-    SSL_CTX *ctx = NULL;
369db50
-    apr_array_header_t *requires;
369db50
-    ssl_require_t *ssl_requires;
2f9bc45
-    int ok, i;
369db50
-    BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
2f9bc45
     X509 *cert;
369db50
-    X509 *peercert;
369db50
-    X509_STORE *cert_store = NULL;
369db50
-    X509_STORE_CTX *cert_store_ctx;
369db50
-    STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
369db50
-    const SSL_CIPHER *cipher = NULL;
2f9bc45
-    int depth, verify_old, verify, n, is_slave = 0;
369db50
-    const char *ncipher_suite;
369db50
-
2f9bc45
-    /* On a slave connection, we do not expect to have an SSLConnRec, but
2f9bc45
-     * our master connection might have one. */
2f9bc45
-    if (!(sslconn && ssl) && r->connection->master) {
2f9bc45
-        sslconn         = myConnConfig(r->connection->master);
2f9bc45
-        ssl             = sslconn ? sslconn->ssl : NULL;
2f9bc45
-        handshakeserver = sslconn ? sslconn->server : NULL;
2f9bc45
-        hssc            = handshakeserver? mySrvConfig(handshakeserver) : NULL;
2f9bc45
-        is_slave        = 1;
2f9bc45
-    }
369db50
     
2f9bc45
-    if (ssl) {
2f9bc45
-        /*
2f9bc45
-         * We should have handshaken here (on handshakeserver),
2f9bc45
-         * otherwise we are being redirected (ErrorDocument) from
2f9bc45
-         * a renegotiation failure below. The access is still 
2f9bc45
-         * forbidden in the latter case, let ap_die() handle
2f9bc45
-         * this recursive (same) error.
2f9bc45
-         */
2f9bc45
-        if (!SSL_is_init_finished(ssl)) {
2f9bc45
-            return HTTP_FORBIDDEN;
369db50
+    /*
369db50
+     * Remember the peer certificate's DN
369db50
+     */
369db50
+    if ((cert = SSL_get_peer_certificate(ssl))) {
369db50
+        if (sslconn->client_cert) {
369db50
+            X509_free(sslconn->client_cert);
369db50
         }
2f9bc45
-        ctx = SSL_get_SSL_CTX(ssl);
369db50
+        sslconn->client_cert = cert;
369db50
+        sslconn->client_dn = NULL;
369db50
     }
2f9bc45
-
369db50
+    
369db50
     /*
2f9bc45
-     * Support for SSLRequireSSL directive
369db50
+     * Finally check for acceptable renegotiation results
369db50
      */
2f9bc45
-    if (dc->bSSLRequired && !ssl) {
2f9bc45
-        if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !is_slave) {
2f9bc45
-            /* This vhost was configured for optional SSL, just tell the
2f9bc45
-             * client that we need to upgrade.
2f9bc45
-             */
2f9bc45
-            apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
2f9bc45
-            apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
369db50
+    if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
369db50
+        (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
369db50
+        BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
369db50
+                          (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
369db50
+
369db50
+        if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
369db50
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
369db50
+                          "Re-negotiation handshake failed: "
369db50
+                          "Client verification failed");
369db50
 
2f9bc45
-            return HTTP_UPGRADE_REQUIRED;
369db50
+            return HTTP_FORBIDDEN;
369db50
         }
369db50
 
2f9bc45
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
2f9bc45
-                      "access to %s failed, reason: %s",
2f9bc45
-                      r->filename, "SSL connection required");
2f9bc45
-
2f9bc45
-        /* remember forbidden access for strict require option */
2f9bc45
-        apr_table_setn(r->notes, "ssl-access-forbidden", "1");
369db50
+        if (do_verify) {
369db50
+            if (cert == NULL) {
369db50
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
369db50
+                              "Re-negotiation handshake failed: "
369db50
+                              "Client certificate missing");
369db50
 
2f9bc45
-        return HTTP_FORBIDDEN;
369db50
+                return HTTP_FORBIDDEN;
369db50
+            }
369db50
+        }
369db50
     }
369db50
+    return OK;
369db50
+}
369db50
 
2f9bc45
-    /*
2f9bc45
-     * Check to see whether SSL is in use; if it's not, then no
2f9bc45
-     * further access control checks are relevant.  (the test for
2f9bc45
-     * sc->enabled is probably strictly unnecessary)
2f9bc45
-     */
2f9bc45
-    if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
2f9bc45
-        return DECLINED;
2f9bc45
-    }
369db50
+/*
369db50
+ *  Access Handler, classic flavour, for SSL/TLS up to v1.2 
369db50
+ *  where everything can be renegotiated and no one is happy.
369db50
+ */
369db50
+static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
369db50
+                                   SSLConnRec *sslconn, SSL *ssl)
369db50
+{
369db50
+    server_rec *handshakeserver = sslconn ? sslconn->server : NULL;
369db50
+    SSLSrvConfigRec *hssc       = handshakeserver? mySrvConfig(handshakeserver) : NULL;
369db50
+    SSL_CTX *ctx = NULL;
369db50
+    BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
369db50
+    X509 *peercert;
369db50
+    X509_STORE *cert_store = NULL;
369db50
+    X509_STORE_CTX *cert_store_ctx;
369db50
+    STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
369db50
+    const SSL_CIPHER *cipher = NULL;
369db50
+    int depth, verify_old, verify, n, rc;
369db50
+    const char *ncipher_suite;
369db50
 
2f9bc45
 #ifdef HAVE_SRP
2f9bc45
     /*
369db50
@@ -581,7 +570,7 @@
2f9bc45
         }
2f9bc45
 
2f9bc45
         /* configure new state */
2f9bc45
-        if (is_slave) {
2f9bc45
+        if (r->connection->master) {
2f9bc45
             /* TODO: this categorically fails changed cipher suite settings
2f9bc45
              * on slave connections. We could do better by
2f9bc45
              * - create a new SSL* from our SSL_CTX and set cipher suite there,
369db50
@@ -659,7 +648,7 @@
2f9bc45
         }
2f9bc45
 
2f9bc45
         if (renegotiate) {
2f9bc45
-            if (is_slave) {
2f9bc45
+            if (r->connection->master) {
2f9bc45
                 /* The request causes renegotiation on a slave connection.
2f9bc45
                  * This is not allowed since we might have concurrent requests
2f9bc45
                  * on this connection.
369db50
@@ -732,7 +721,7 @@
2f9bc45
                   (verify     & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)))
2f9bc45
             {
2f9bc45
                 renegotiate = TRUE;
2f9bc45
-                if (is_slave) {
2f9bc45
+                if (r->connection->master) {
2f9bc45
                     /* The request causes renegotiation on a slave connection.
2f9bc45
                      * This is not allowed since we might have concurrent requests
2f9bc45
                      * on this connection.
369db50
@@ -885,6 +874,7 @@
369db50
 
369db50
         if (renegotiate_quick) {
369db50
             STACK_OF(X509) *cert_stack;
369db50
+            X509 *cert;
369db50
 
369db50
             /* perform just a manual re-verification of the peer */
369db50
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02258)
369db50
@@ -1037,43 +1027,10 @@
369db50
         }
369db50
 
2f9bc45
         /*
369db50
-         * Remember the peer certificate's DN
369db50
-         */
369db50
-        if ((cert = SSL_get_peer_certificate(ssl))) {
369db50
-            if (sslconn->client_cert) {
369db50
-                X509_free(sslconn->client_cert);
369db50
-            }
369db50
-            sslconn->client_cert = cert;
369db50
-            sslconn->client_dn = NULL;
369db50
-        }
369db50
-
369db50
-        /*
2f9bc45
          * Finally check for acceptable renegotiation results
2f9bc45
          */
2f9bc45
-        if ((dc->nVerifyClient != SSL_CVERIFY_NONE) ||
2f9bc45
-            (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) {
2f9bc45
-            BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
2f9bc45
-                              (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
2f9bc45
-
2f9bc45
-            if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
2f9bc45
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
2f9bc45
-                              "Re-negotiation handshake failed: "
2f9bc45
-                              "Client verification failed");
2f9bc45
-
2f9bc45
-                return HTTP_FORBIDDEN;
2f9bc45
-            }
2f9bc45
-
2f9bc45
-            if (do_verify) {
2f9bc45
-                if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
2f9bc45
-                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
2f9bc45
-                                  "Re-negotiation handshake failed: "
2f9bc45
-                                  "Client certificate missing");
2f9bc45
-
2f9bc45
-                    return HTTP_FORBIDDEN;
2f9bc45
-                }
2f9bc45
-
2f9bc45
-                X509_free(peercert);
2f9bc45
-            }
369db50
+        if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) {
2f9bc45
+            return rc;
2f9bc45
         }
2f9bc45
 
2f9bc45
         /*
369db50
@@ -1096,6 +1053,215 @@
369db50
         }
369db50
     }
2f9bc45
 
369db50
+    return DECLINED;
369db50
+}
369db50
+
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+/*
2f9bc45
+ *  Access Handler, modern flavour, for SSL/TLS v1.3 and onward. 
2f9bc45
+ *  Only client certificates can be requested, everything else stays.
2f9bc45
+ */
2f9bc45
+static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirConfigRec *dc,
2f9bc45
+                                  SSLConnRec *sslconn, SSL *ssl)
2f9bc45
+{
2f9bc45
+    if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
2f9bc45
+        (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
2f9bc45
+        int vmode_inplace, vmode_needed;
2f9bc45
+        int change_vmode = FALSE;
2f9bc45
+        int old_state, n, rc;
2f9bc45
+
2f9bc45
+        vmode_inplace = SSL_get_verify_mode(ssl);
2f9bc45
+        vmode_needed = SSL_VERIFY_NONE;
2f9bc45
+
2f9bc45
+        if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) ||
2f9bc45
+            (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) {
2f9bc45
+            vmode_needed |= SSL_VERIFY_PEER_STRICT;
2f9bc45
+        }
2f9bc45
+
2f9bc45
+        if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
2f9bc45
+            (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) ||
2f9bc45
+            (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
2f9bc45
+            (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
2f9bc45
+        {
2f9bc45
+            vmode_needed |= SSL_VERIFY_PEER;
2f9bc45
+        }
2f9bc45
+
2f9bc45
+        if (vmode_needed == SSL_VERIFY_NONE) {
2f9bc45
+            return DECLINED;
2f9bc45
+        }
2f9bc45
+
2f9bc45
+        vmode_needed |= SSL_VERIFY_CLIENT_ONCE;
2f9bc45
+        if (vmode_inplace != vmode_needed) {
2f9bc45
+            /* Need to change, if new setting is more restrictive than existing one */
2f9bc45
+
2f9bc45
+            if ((vmode_inplace == SSL_VERIFY_NONE)
2f9bc45
+                || (!(vmode_inplace   & SSL_VERIFY_PEER) 
2f9bc45
+                    && (vmode_needed  & SSL_VERIFY_PEER))
2f9bc45
+                || (!(vmode_inplace   & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) 
2f9bc45
+                    && (vmode_needed & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) {
2f9bc45
+                /* need to change the effective verify mode */
2f9bc45
+                change_vmode = TRUE;
2f9bc45
+            }
2f9bc45
+            else {
2f9bc45
+                /* FIXME: does this work with TLSv1.3? Is this more than re-inspecting
2f9bc45
+                 * the certificate we should already have? */
2f9bc45
+                /*
2f9bc45
+                 * override of SSLVerifyDepth
2f9bc45
+                 *
2f9bc45
+                 * The depth checks are handled by us manually inside the
2f9bc45
+                 * verify callback function and not by OpenSSL internally
2f9bc45
+                 * (and our function is aware of both the per-server and
2f9bc45
+                 * per-directory contexts). So we cannot ask OpenSSL about
2f9bc45
+                 * the currently verify depth. Instead we remember it in our
2f9bc45
+                 * SSLConnRec attached to the SSL* of OpenSSL.  We've to force
2f9bc45
+                 * the renegotiation if the reconfigured/new verify depth is
2f9bc45
+                 * less than the currently active/remembered verify depth
2f9bc45
+                 * (because this means more restriction on the certificate
2f9bc45
+                 * chain).
2f9bc45
+                 */
2f9bc45
+                n = (sslconn->verify_depth != UNSET)? 
2f9bc45
+                    sslconn->verify_depth : sc->server->auth.verify_depth;
2f9bc45
+                /* determine the new depth */
2f9bc45
+                sslconn->verify_depth = (dc->nVerifyDepth != UNSET)
2f9bc45
+                                        ? dc->nVerifyDepth
2f9bc45
+                                        : sc->server->auth.verify_depth;
2f9bc45
+                if (sslconn->verify_depth < n) {
2f9bc45
+                    change_vmode = TRUE;
2f9bc45
+                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
2f9bc45
+                                  "Reduced client verification depth will "
2f9bc45
+                                  "force renegotiation");
2f9bc45
+                }
2f9bc45
+            }
2f9bc45
+        }
2f9bc45
+
2f9bc45
+        if (change_vmode) {
2f9bc45
+            char peekbuf[1];
2f9bc45
+
2f9bc45
+            if (r->connection->master) {
2f9bc45
+                /* FIXME: modifying the SSL on a slave connection is no good.
2f9bc45
+                 * We would need to push this back to the master connection
2f9bc45
+                 * somehow.
2f9bc45
+                 */
2f9bc45
+                apr_table_setn(r->notes, "ssl-renegotiate-forbidden", "verify-client");
2f9bc45
+                return HTTP_FORBIDDEN;
2f9bc45
+            }
2f9bc45
+
2f9bc45
+            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() "verify client post handshake");
2f9bc45
+
2f9bc45
+            SSL_set_verify(ssl, vmode_needed, ssl_callback_SSLVerify);
2f9bc45
+
369db50
+            if (SSL_verify_client_post_handshake(ssl) != 1) {
369db50
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10158)
369db50
+                              "cannot perform post-handshake authentication");
369db50
+                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
369db50
+                apr_table_setn(r->notes, "error-notes",
369db50
+                               "Reason: Cannot perform Post-Handshake Authentication.
");
369db50
+                return HTTP_FORBIDDEN;
369db50
+            }
369db50
+            
2f9bc45
+            old_state = sslconn->reneg_state;
2f9bc45
+            sslconn->reneg_state = RENEG_ALLOW;
2f9bc45
+            modssl_set_app_data2(ssl, r);
2f9bc45
+
2f9bc45
+            SSL_do_handshake(ssl);
2f9bc45
+            /* Need to trigger renegotiation handshake by reading.
2f9bc45
+             * Peeking 0 bytes actually works.
2f9bc45
+             * See: http://marc.info/?t=145493359200002&r=1&w=2
2f9bc45
+             */
2f9bc45
+            SSL_peek(ssl, peekbuf, 0);
2f9bc45
+
2f9bc45
+            sslconn->reneg_state = old_state;
2f9bc45
+            modssl_set_app_data2(ssl, NULL);
2f9bc45
+
2f9bc45
+            /*
2f9bc45
+             * Finally check for acceptable renegotiation results
2f9bc45
+             */
369db50
+            if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) {
2f9bc45
+                return rc;
2f9bc45
+            }
2f9bc45
+        }
2f9bc45
+    }
2f9bc45
+
2f9bc45
+    return DECLINED;
2f9bc45
+}
2f9bc45
+#endif
2f9bc45
+
2f9bc45
+int ssl_hook_Access(request_rec *r)
2f9bc45
+{
2f9bc45
+    SSLDirConfigRec *dc         = myDirConfig(r);
2f9bc45
+    SSLSrvConfigRec *sc         = mySrvConfig(r->server);
2f9bc45
+    SSLConnRec *sslconn         = myConnConfig(r->connection);
2f9bc45
+    SSL *ssl                    = sslconn ? sslconn->ssl : NULL;
369db50
+    apr_array_header_t *requires;
369db50
+    ssl_require_t *ssl_requires;
369db50
+    int ok, i, ret;
2f9bc45
+
2f9bc45
+    /* On a slave connection, we do not expect to have an SSLConnRec, but
2f9bc45
+     * our master connection might have one. */
2f9bc45
+    if (!(sslconn && ssl) && r->connection->master) {
2f9bc45
+        sslconn         = myConnConfig(r->connection->master);
2f9bc45
+        ssl             = sslconn ? sslconn->ssl : NULL;
2f9bc45
+    }
2f9bc45
+
2f9bc45
+    /*
2f9bc45
+     * We should have handshaken here, otherwise we are being 
2f9bc45
+     * redirected (ErrorDocument) from a renegotiation failure below. 
2f9bc45
+     * The access is still forbidden in the latter case, let ap_die() handle
2f9bc45
+     * this recursive (same) error.
2f9bc45
+     */
2f9bc45
+    if (ssl && !SSL_is_init_finished(ssl)) {
2f9bc45
+        return HTTP_FORBIDDEN;
2f9bc45
+    }
2f9bc45
+
2f9bc45
+    /*
2f9bc45
+     * Support for SSLRequireSSL directive
2f9bc45
+     */
2f9bc45
+    if (dc->bSSLRequired && !ssl) {
2f9bc45
+        if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !r->connection->master) {
2f9bc45
+            /* This vhost was configured for optional SSL, just tell the
2f9bc45
+             * client that we need to upgrade.
2f9bc45
+             */
2f9bc45
+            apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
2f9bc45
+            apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
2f9bc45
+
2f9bc45
+            return HTTP_UPGRADE_REQUIRED;
2f9bc45
+        }
2f9bc45
+
2f9bc45
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
2f9bc45
+                      "access to %s failed, reason: %s",
2f9bc45
+                      r->filename, "SSL connection required");
2f9bc45
+
2f9bc45
+        /* remember forbidden access for strict require option */
2f9bc45
+        apr_table_setn(r->notes, "ssl-access-forbidden", "1");
2f9bc45
+
2f9bc45
+        return HTTP_FORBIDDEN;
2f9bc45
+    }
2f9bc45
+
2f9bc45
+    /*
2f9bc45
+     * Check to see whether SSL is in use; if it's not, then no
2f9bc45
+     * further access control checks are relevant.  (the test for
2f9bc45
+     * sc->enabled is probably strictly unnecessary)
2f9bc45
+     */
2f9bc45
+    if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
2f9bc45
+        return DECLINED;
2f9bc45
+    }
2f9bc45
+
369db50
+#if SSL_HAVE_PROTOCOL_TLSV1_3
2f9bc45
+    /* TLSv1.3+ is less complicated here. Branch off into a new codeline
2f9bc45
+     * and avoid messing with the past. */
2f9bc45
+    if (SSL_version(ssl) >= TLS1_3_VERSION) {
369db50
+        ret = ssl_hook_Access_modern(r, sc, dc, sslconn, ssl);
369db50
+    }
369db50
+    else
2f9bc45
+#endif
369db50
+    {
369db50
+        ret = ssl_hook_Access_classic(r, sc, dc, sslconn, ssl);
369db50
+    }
2f9bc45
+
369db50
+    if (ret != DECLINED) {
369db50
+        return ret;
369db50
+    }
369db50
+
369db50
     /* If we're trying to have the user name set from a client
369db50
      * certificate then we need to set it here. This should be safe as
369db50
      * the user name probably isn't important from an auth checking point
369db50
@@ -2080,31 +2246,43 @@
b52ebeb
 {
b52ebeb
     conn_rec *c;
b52ebeb
     server_rec *s;
b52ebeb
-    SSLConnRec *scr;
b52ebeb
 
b52ebeb
     /* Retrieve the conn_rec and the associated SSLConnRec. */
b52ebeb
     if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) {
b52ebeb
         return;
b52ebeb
     }
b52ebeb
 
b52ebeb
-    if ((scr = myConnConfig(c)) == NULL) {
b52ebeb
-        return;
b52ebeb
-    }
b52ebeb
+    /* With TLS 1.3 this callback may be called multiple times on the first
b52ebeb
+     * negotiation, so the below logic to detect renegotiations can't work.
b52ebeb
+     * Fortunately renegotiations are forbidden starting with TLS 1.3, and
b52ebeb
+     * this is enforced by OpenSSL so there's nothing to be done here.
b52ebeb
+     */
b52ebeb
+#if SSL_HAVE_PROTOCOL_TLSV1_3
b52ebeb
+    if (SSL_version(ssl) < TLS1_3_VERSION)
b52ebeb
+#endif
b52ebeb
+    {
b52ebeb
+        SSLConnRec *sslconn;
369db50
+
369db50
+        if ((sslconn = myConnConfig(c)) == NULL) {
369db50
+            return;
369db50
+        }
b52ebeb
 
b52ebeb
-    /* If the reneg state is to reject renegotiations, check the SSL
b52ebeb
-     * state machine and move to ABORT if a Client Hello is being
b52ebeb
-     * read. */
b52ebeb
-    if (!scr->is_proxy &&
b52ebeb
-        (where & SSL_CB_HANDSHAKE_START) &&
b52ebeb
-        scr->reneg_state == RENEG_REJECT) {
b52ebeb
-            scr->reneg_state = RENEG_ABORT;
b52ebeb
+        /* If the reneg state is to reject renegotiations, check the SSL
b52ebeb
+         * state machine and move to ABORT if a Client Hello is being
b52ebeb
+         * read. */
b52ebeb
+        if (!sslconn->is_proxy &&
b52ebeb
+                (where & SSL_CB_HANDSHAKE_START) &&
b52ebeb
+                sslconn->reneg_state == RENEG_REJECT) {
b52ebeb
+            sslconn->reneg_state = RENEG_ABORT;
b52ebeb
             ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042)
b52ebeb
                           "rejecting client initiated renegotiation");
b52ebeb
-    }
b52ebeb
-    /* If the first handshake is complete, change state to reject any
b52ebeb
-     * subsequent client-initiated renegotiation. */
b52ebeb
-    else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) {
b52ebeb
-        scr->reneg_state = RENEG_REJECT;
b52ebeb
+        }
b52ebeb
+        /* If the first handshake is complete, change state to reject any
b52ebeb
+         * subsequent client-initiated renegotiation. */
b52ebeb
+        else if ((where & SSL_CB_HANDSHAKE_DONE)
b52ebeb
+                 && sslconn->reneg_state == RENEG_INIT) {
b52ebeb
+            sslconn->reneg_state = RENEG_REJECT;
b52ebeb
+        }
b52ebeb
     }
b52ebeb
 
b52ebeb
     s = mySrvFromConn(c);
2f9bc45
--- httpd-2.4.34/modules/ssl/ssl_private.h.r1827912+
2f9bc45
+++ httpd-2.4.34/modules/ssl/ssl_private.h
2f9bc45
@@ -132,13 +132,14 @@
2f9bc45
         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
2f9bc45
 #define SSL_CTX_set_max_proto_version(ctx, version) \
2f9bc45
         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
2f9bc45
-#endif
2f9bc45
-/* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not include most
2f9bc45
- * changes from OpenSSL >= 1.1 (new functions, macros, deprecations, ...), so
2f9bc45
- * we have to work around this...
2f9bc45
+#elif LIBRESSL_VERSION_NUMBER < 0x2070000f
2f9bc45
+/* LibreSSL before 2.7 declares OPENSSL_VERSION_NUMBER == 2.0 but does not
2f9bc45
+ * include most changes from OpenSSL >= 1.1 (new functions, macros, 
2f9bc45
+ * deprecations, ...), so we have to work around this...
2f9bc45
  */
2f9bc45
 #define MODSSL_USE_OPENSSL_PRE_1_1_API (1)
2f9bc45
-#else
2f9bc45
+#endif /* LIBRESSL_VERSION_NUMBER < 0x2060000f */
2f9bc45
+#else /* defined(LIBRESSL_VERSION_NUMBER) */
2f9bc45
 #define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
2f9bc45
 #endif
2f9bc45
 
2f9bc45
@@ -238,7 +239,8 @@
2f9bc45
 void free_bio_methods(void);
2f9bc45
 #endif
2f9bc45
 
2f9bc45
-#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
2f9bc45
+#if OPENSSL_VERSION_NUMBER < 0x10002000L || \
2f9bc45
+	(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000f)
2f9bc45
 #define X509_STORE_CTX_get0_store(x) (x->ctx)
2f9bc45
 #endif
2f9bc45
 
2f9bc45
@@ -372,8 +374,17 @@
2f9bc45
 #ifdef HAVE_TLSV1_X
2f9bc45
 #define SSL_PROTOCOL_TLSV1_1 (1<<3)
2f9bc45
 #define SSL_PROTOCOL_TLSV1_2 (1<<4)
2f9bc45
+#define SSL_PROTOCOL_TLSV1_3 (1<<5)
2f9bc45
+
2f9bc45
+#ifdef SSL_OP_NO_TLSv1_3
2f9bc45
+#define SSL_HAVE_PROTOCOL_TLSV1_3   (1)
2f9bc45
+#define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC| \
2f9bc45
+                            SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2|SSL_PROTOCOL_TLSV1_3)
2f9bc45
+#else
2f9bc45
+#define SSL_HAVE_PROTOCOL_TLSV1_3   (0)
2f9bc45
 #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC| \
2f9bc45
                             SSL_PROTOCOL_TLSV1_1|SSL_PROTOCOL_TLSV1_2)
2f9bc45
+#endif
2f9bc45
 #else
2f9bc45
 #define SSL_PROTOCOL_ALL   (SSL_PROTOCOL_BASIC)
2f9bc45
 #endif
2f9bc45
@@ -646,6 +657,11 @@
2f9bc45
     /** for client or downstream server authentication */
2f9bc45
     int          verify_depth;
2f9bc45
     ssl_verify_t verify_mode;
2f9bc45
+
2f9bc45
+    /** TLSv1.3 has its separate cipher list, separate from the
2f9bc45
+     settings for older TLS protocol versions. Since which one takes
2f9bc45
+     effect is a matter of negotiation, we need separate settings */
2f9bc45
+    const char  *tls13_ciphers;
2f9bc45
 } modssl_auth_ctx_t;
2f9bc45
 
2f9bc45
 #ifdef HAVE_TLS_SESSION_TICKETS
2f9bc45
@@ -801,7 +817,7 @@
2f9bc45
 const char  *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
2f9bc45
-const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
2f9bc45
+const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
2f9bc45
@@ -830,7 +846,7 @@
2f9bc45
 
2f9bc45
 const char  *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
2f9bc45
 const char  *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
2f9bc45
-const char  *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *);
2f9bc45
+const char  *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLProxyVerify(cmd_parms *, void *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *, void *, const char *);
2f9bc45
 const char  *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *);