You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2015/10/14 14:10:11 UTC

svn commit: r1708593 - in /httpd/httpd/trunk: docs/manual/mod/mod_http2.xml modules/http2/h2_config.c modules/http2/h2_config.h modules/http2/h2_conn.c modules/http2/h2_h2.c modules/http2/h2_h2.h modules/http2/h2_switch.c

Author: icing
Date: Wed Oct 14 12:10:11 2015
New Revision: 1708593

URL: http://svn.apache.org/viewvc?rev=1708593&view=rev
Log:
mod_http2: new directive H2Compliance on/off, checking TLS protocol and cipher against RFC7540

Modified:
    httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
    httpd/httpd/trunk/modules/http2/h2_config.c
    httpd/httpd/trunk/modules/http2/h2_config.h
    httpd/httpd/trunk/modules/http2/h2_conn.c
    httpd/httpd/trunk/modules/http2/h2_h2.c
    httpd/httpd/trunk/modules/http2/h2_h2.h
    httpd/httpd/trunk/modules/http2/h2_switch.c

Modified: httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_http2.xml?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_http2.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_http2.xml Wed Oct 14 12:10:11 2015
@@ -74,11 +74,11 @@
                 Direct communication means that if the first bytes received by the 
                 server on a connection match the HTTP/2 preamble, the HTTP/2
                 protocol is switched to immediately without further negotiation.
-                This mode falls outside the RFC 7540 but has become widely implemented
-                on cleartext ports as it is very convenient for development and testing. 
+                This mode is defined in RFC 7540 for the cleartext (h2c) case. Its
+                use on TLS connections is not allowed by the standard.
             </p>
             <p>
-                Since this detection implies that the client will send data on
+                Since this detection requires that the client will send data on
                 new connection immediately, direct HTTP/2 mode is disabled by
                 default.
             </p>

Modified: httpd/httpd/trunk/modules/http2/h2_config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.c Wed Oct 14 12:10:11 2015
@@ -49,6 +49,7 @@ static h2_config defconf = {
     0,                /* serialize headers */
     0,                /* h2 direct mode */
     -1,               /* # session extra files */
+    1,                /* rfc 7540 compliance */
 };
 
 static int files_per_session = 0;
@@ -100,6 +101,7 @@ static void *h2_config_create(apr_pool_t
     conf->serialize_headers    = DEF_VAL;
     conf->h2_direct            = DEF_VAL;
     conf->session_extra_files  = DEF_VAL;
+    conf->rfc_compliance       = DEF_VAL;
     return conf;
 }
 
@@ -138,6 +140,7 @@ void *h2_config_merge(apr_pool_t *pool,
     n->serialize_headers = H2_CONFIG_GET(add, base, serialize_headers);
     n->h2_direct      = H2_CONFIG_GET(add, base, h2_direct);
     n->session_extra_files = H2_CONFIG_GET(add, base, session_extra_files);
+    n->rfc_compliance = H2_CONFIG_GET(add, base, rfc_compliance);
     
     return n;
 }
@@ -162,6 +165,8 @@ int h2_config_geti(h2_config *conf, h2_c
             return H2_CONFIG_GET(conf, &defconf, alt_svc_max_age);
         case H2_CONF_SER_HEADERS:
             return H2_CONFIG_GET(conf, &defconf, serialize_headers);
+        case H2_CONF_COMPLIANCE:
+            return H2_CONFIG_GET(conf, &defconf, rfc_compliance);
         case H2_CONF_DIRECT:
             return H2_CONFIG_GET(conf, &defconf, h2_direct);
         case H2_CONF_SESSION_FILES:
@@ -332,8 +337,25 @@ static const char *h2_conf_set_direct(cm
     return "value must be On or Off";
 }
 
-#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
+static const char *h2_conf_set_compliance(cmd_parms *parms,
+                                          void *arg, const char *value)
+{
+    h2_config *cfg = h2_config_sget(parms->server);
+    if (!strcasecmp(value, "On")) {
+        cfg->rfc_compliance = 1;
+        return NULL;
+    }
+    else if (!strcasecmp(value, "Off")) {
+        cfg->rfc_compliance = 0;
+        return NULL;
+    }
+    
+    (void)arg;
+    return "value must be On or Off";
+}
+
 
+#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
 
 const command_rec h2_cmds[] = {
     AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
@@ -354,6 +376,8 @@ const command_rec h2_cmds[] = {
                   RSRC_CONF, "set the maximum age (in seconds) that client can rely on alt-svc information"),
     AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
                   RSRC_CONF, "on to enable header serialization for compatibility"),
+    AP_INIT_TAKE1("H2Compliance", h2_conf_set_compliance, NULL,
+                  RSRC_CONF, "off to disable strict compliance to RFC 7540"),
     AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
                   RSRC_CONF, "on to enable direct HTTP/2 mode"),
     AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,

Modified: httpd/httpd/trunk/modules/http2/h2_config.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.h?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_config.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_config.h Wed Oct 14 12:10:11 2015
@@ -34,6 +34,7 @@ typedef enum {
     H2_CONF_SER_HEADERS,
     H2_CONF_DIRECT,
     H2_CONF_SESSION_FILES,
+    H2_CONF_COMPLIANCE,
 } h2_config_var_t;
 
 /* Apache httpd module configuration for h2. */
@@ -51,6 +52,7 @@ typedef struct h2_config {
                                      processing, better compatibility */
     int h2_direct;                /* if mod_h2 is active directly */
     int session_extra_files;      /* # of extra files a session may keep open */  
+    int rfc_compliance;           /* Comply with all aspects of RFC 7540 */  
 } h2_config;
 
 

Modified: httpd/httpd/trunk/modules/http2/h2_conn.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.c?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_conn.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_conn.c Wed Oct 14 12:10:11 2015
@@ -32,6 +32,7 @@
 #include "h2_session.h"
 #include "h2_stream.h"
 #include "h2_stream_set.h"
+#include "h2_h2.h"
 #include "h2_task.h"
 #include "h2_worker.h"
 #include "h2_workers.h"
@@ -177,6 +178,11 @@ apr_status_t h2_conn_main(conn_rec *c)
         return APR_EGENERAL;
     }
     
+    if (!h2_is_security_compliant(c, 1)) {
+        nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
+                              NGHTTP2_INADEQUATE_SECURITY, NULL, 0);
+    } 
+
     status = h2_session_process(session);
 
     /* Make sure this connection gets closed properly. */

Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_h2.c Wed Oct 14 12:10:11 2015
@@ -54,6 +54,354 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_is_http
 static int (*opt_ssl_engine_disable)(conn_rec*);
 static int (*opt_ssl_is_https)(conn_rec*);
 /*******************************************************************************
+ * SSL var lookup
+ */
+APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
+                        (apr_pool_t *, server_rec *,
+                         conn_rec *, request_rec *,
+                         char *));
+static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
+                                   conn_rec *, request_rec *,
+                                   char *);
+
+/*******************************************************************************
+ * Check connection security requirements of RFC 7540
+ */
+
+/*
+ * Black Listed Ciphers from RFC 7549 Appendix A
+ *
+ */
+static const char *RFC7540_names[] = {
+    /* ciphers with NULL encrpytion */
+    "NULL-MD5",                         /* TLS_NULL_WITH_NULL_NULL */
+    /* same */                          /* TLS_RSA_WITH_NULL_MD5 */
+    "NULL-SHA",                         /* TLS_RSA_WITH_NULL_SHA */
+    "NULL-SHA256",                      /* TLS_RSA_WITH_NULL_SHA256 */
+    "PSK-NULL-SHA",                     /* TLS_PSK_WITH_NULL_SHA */
+    "DHE-PSK-NULL-SHA",                 /* TLS_DHE_PSK_WITH_NULL_SHA */
+    "RSA-PSK-NULL-SHA",                 /* TLS_RSA_PSK_WITH_NULL_SHA */
+    "PSK-NULL-SHA256",                  /* TLS_PSK_WITH_NULL_SHA256 */
+    "PSK-NULL-SHA384",                  /* TLS_PSK_WITH_NULL_SHA384 */
+    "DHE-PSK-NULL-SHA256",              /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+    "DHE-PSK-NULL-SHA384",              /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+    "RSA-PSK-NULL-SHA256",              /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+    "RSA-PSK-NULL-SHA384",              /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+    "ECDH-ECDSA-NULL-SHA",              /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+    "ECDHE-ECDSA-NULL-SHA",             /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+    "ECDH-RSA-NULL-SHA",                /* TLS_ECDH_RSA_WITH_NULL_SHA */
+    "ECDHE-RSA-NULL-SHA",               /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+    "AECDH-NULL-SHA",                   /* TLS_ECDH_anon_WITH_NULL_SHA */
+    "ECDHE-PSK-NULL-SHA",               /* TLS_ECDHE_PSK_WITH_NULL_SHA */
+    "ECDHE-PSK-NULL-SHA256",            /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
+    "ECDHE-PSK-NULL-SHA384",            /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
+    
+    /* DES/3DES ciphers */
+    "PSK-3DES-EDE-CBC-SHA",             /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
+    "DHE-PSK-3DES-EDE-CBC-SHA",         /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
+    "RSA-PSK-3DES-EDE-CBC-SHA",         /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
+    "ECDH-ECDSA-DES-CBC3-SHA",          /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
+    "ECDHE-ECDSA-DES-CBC3-SHA",         /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
+    "ECDH-RSA-DES-CBC3-SHA",            /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
+    "ECDHE-RSA-DES-CBC3-SHA",           /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
+    "AECDH-DES-CBC3-SHA",               /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+    "SRP-3DES-EDE-CBC-SHA",             /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
+    "SRP-RSA-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
+    "SRP-DSS-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
+    "ECDHE-PSK-3DES-EDE-CBC-SHA",       /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
+    "DES-CBC-SHA",                      /* TLS_RSA_WITH_DES_CBC_SHA */
+    "DES-CBC3-SHA",                     /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
+    "DHE-DSS-DES-CBC3-SHA",             /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
+    "DHE-RSA-DES-CBC-SHA",              /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
+    "DHE-RSA-DES-CBC3-SHA",             /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
+    "ADH-DES-CBC-SHA",                  /* TLS_DH_anon_WITH_DES_CBC_SHA */
+    "ADH-DES-CBC3-SHA",                 /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
+    "EXP-DH-DSS-DES-CBC-SHA",           /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
+    "DH-DSS-DES-CBC-SHA",               /* TLS_DH_DSS_WITH_DES_CBC_SHA */
+    "DH-DSS-DES-CBC3-SHA",              /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
+    "EXP-DH-RSA-DES-CBC-SHA",           /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
+    "DH-RSA-DES-CBC-SHA",               /* TLS_DH_RSA_WITH_DES_CBC_SHA */
+    "DH-RSA-DES-CBC3-SHA",              /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
+
+    /* blacklisted EXPORT ciphers */
+    "EXP-RC4-MD5",                      /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
+    "EXP-RC2-CBC-MD5",                  /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
+    "EXP-DES-CBC-SHA",                  /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
+    "EXP-DHE-DSS-DES-CBC-SHA",          /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
+    "EXP-DHE-RSA-DES-CBC-SHA",          /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
+    "EXP-ADH-DES-CBC-SHA",              /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
+    "EXP-ADH-RC4-MD5",                  /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
+
+    /* blacklisted RC4 encryption */
+    "RC4-MD5",                          /* TLS_RSA_WITH_RC4_128_MD5 */
+    "RC4-SHA",                          /* TLS_RSA_WITH_RC4_128_SHA */
+    "ADH-RC4-MD5",                      /* TLS_DH_anon_WITH_RC4_128_MD5 */
+    "KRB5-RC4-SHA",                     /* TLS_KRB5_WITH_RC4_128_SHA */
+    "KRB5-RC4-MD5",                     /* TLS_KRB5_WITH_RC4_128_MD5 */
+    "EXP-KRB5-RC4-SHA",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
+    "EXP-KRB5-RC4-MD5",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
+    "PSK-RC4-SHA",                      /* TLS_PSK_WITH_RC4_128_SHA */
+    "DHE-PSK-RC4-SHA",                  /* TLS_DHE_PSK_WITH_RC4_128_SHA */
+    "RSA-PSK-RC4-SHA",                  /* TLS_RSA_PSK_WITH_RC4_128_SHA */
+    "ECDH-ECDSA-RC4-SHA",               /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
+    "ECDHE-ECDSA-RC4-SHA",              /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
+    "ECDH-RSA-RC4-SHA",                 /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
+    "ECDHE-RSA-RC4-SHA",                /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+    "AECDH-RC4-SHA",                    /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+    "ECDHE-PSK-RC4-SHA",                /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
+
+    /* blacklisted AES128 encrpytion ciphers */
+    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA */
+    "DH-DSS-AES128-SHA",                /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
+    "DH-RSA-AES128-SHA",                /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
+    "DHE-DSS-AES128-SHA",               /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
+    "DHE-RSA-AES128-SHA",               /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+    "ADH-AES128-SHA",                   /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
+    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
+    "DH-DSS-AES128-SHA256",             /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
+    "DH-RSA-AES128-SHA256",             /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
+    "DHE-DSS-AES128-SHA256",            /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
+    "DHE-RSA-AES128-SHA256",            /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+    "ECDH-ECDSA-AES128-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
+    "ECDHE-ECDSA-AES128-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
+    "ECDH-RSA-AES128-SHA",              /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
+    "ECDHE-RSA-AES128-SHA",             /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
+    "AECDH-AES128-SHA",                 /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+    "ECDHE-ECDSA-AES128-SHA256",        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
+    "ECDH-ECDSA-AES128-SHA256",         /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
+    "ECDHE-RSA-AES128-SHA256",          /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
+    "ECDH-RSA-AES128-SHA256",           /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
+    "ADH-AES128-SHA256",                /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+    "PSK-AES128-CBC-SHA",               /* TLS_PSK_WITH_AES_128_CBC_SHA */
+    "DHE-PSK-AES128-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
+    "RSA-PSK-AES128-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
+    "PSK-AES128-CBC-SHA256",            /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
+    "DHE-PSK-AES128-CBC-SHA256",        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
+    "RSA-PSK-AES128-CBC-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
+    "ECDHE-PSK-AES128-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
+    "ECDHE-PSK-AES128-CBC-SHA256",      /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
+    "AES128-CCM",                       /* TLS_RSA_WITH_AES_128_CCM */
+    "AES128-CCM8",                      /* TLS_RSA_WITH_AES_128_CCM_8 */
+    "PSK-AES128-CCM",                   /* TLS_PSK_WITH_AES_128_CCM */
+    "PSK-AES128-CCM8",                  /* TLS_PSK_WITH_AES_128_CCM_8 */
+    "AES128-GCM-SHA256",                /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
+    "DH-RSA-AES128-GCM-SHA256",         /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
+    "DH-DSS-AES128-GCM-SHA256",         /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
+    "ADH-AES128-GCM-SHA256",            /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+    "PSK-AES128-GCM-SHA256",            /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
+    "RSA-PSK-AES128-GCM-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
+    "ECDH-ECDSA-AES128-GCM-SHA256",     /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
+    "ECDH-RSA-AES128-GCM-SHA256",       /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
+    "SRP-AES-128-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
+    "SRP-RSA-AES-128-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
+    "SRP-DSS-AES-128-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
+    
+    /* blacklisted AES256 encrpytion ciphers */
+    "AES256-SHA",                       /* TLS_RSA_WITH_AES_256_CBC_SHA */
+    "DH-DSS-AES256-SHA",                /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
+    "DH-RSA-AES256-SHA",                /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
+    "DHE-DSS-AES256-SHA",               /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
+    "DHE-RSA-AES256-SHA",               /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
+    "ADH-AES256-SHA",                   /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
+    "AES256-SHA256",                    /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
+    "DH-DSS-AES256-SHA256",             /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
+    "DH-RSA-AES256-SHA256",             /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
+    "DHE-DSS-AES256-SHA256",            /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
+    "DHE-RSA-AES256-SHA256",            /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
+    "ADH-AES256-SHA256",                /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+    "ECDH-ECDSA-AES256-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
+    "ECDHE-ECDSA-AES256-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
+    "ECDH-RSA-AES256-SHA",              /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
+    "ECDHE-RSA-AES256-SHA",             /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
+    "AECDH-AES256-SHA",                 /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+    "ECDHE-ECDSA-AES256-SHA384",        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
+    "ECDH-ECDSA-AES256-SHA384",         /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
+    "ECDHE-RSA-AES256-SHA384",          /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
+    "ECDH-RSA-AES256-SHA384",           /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
+    "PSK-AES256-CBC-SHA",               /* TLS_PSK_WITH_AES_256_CBC_SHA */
+    "DHE-PSK-AES256-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
+    "RSA-PSK-AES256-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
+    "PSK-AES256-CBC-SHA384",            /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
+    "DHE-PSK-AES256-CBC-SHA384",        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
+    "RSA-PSK-AES256-CBC-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
+    "ECDHE-PSK-AES256-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
+    "ECDHE-PSK-AES256-CBC-SHA384",      /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
+    "SRP-AES-256-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
+    "SRP-RSA-AES-256-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
+    "SRP-DSS-AES-256-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
+    "AES256-CCM",                       /* TLS_RSA_WITH_AES_256_CCM */
+    "AES256-CCM8",                      /* TLS_RSA_WITH_AES_256_CCM_8 */
+    "PSK-AES256-CCM",                   /* TLS_PSK_WITH_AES_256_CCM */
+    "PSK-AES256-CCM8",                  /* TLS_PSK_WITH_AES_256_CCM_8 */
+    "AES256-GCM-SHA384",                /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
+    "DH-RSA-AES256-GCM-SHA384",         /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
+    "DH-DSS-AES256-GCM-SHA384",         /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
+    "ADH-AES256-GCM-SHA384",            /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+    "PSK-AES256-GCM-SHA384",            /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
+    "RSA-PSK-AES256-GCM-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
+    "ECDH-ECDSA-AES256-GCM-SHA384",     /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
+    "ECDH-RSA-AES256-GCM-SHA384",       /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
+    
+    /* blacklisted CAMELLIA128 encrpytion ciphers */
+    "CAMELLIA128-SHA",                  /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
+    "DH-DSS-CAMELLIA128-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
+    "DH-RSA-CAMELLIA128-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
+    "DHE-DSS-CAMELLIA128-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
+    "DHE-RSA-CAMELLIA128-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
+    "ADH-CAMELLIA128-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
+    "ECDHE-ECDSA-CAMELLIA128-SHA256",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "ECDH-ECDSA-CAMELLIA128-SHA256",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "ECDHE-RSA-CAMELLIA128-SHA256",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "ECDH-RSA-CAMELLIA128-SHA256",      /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "PSK-CAMELLIA128-SHA256",           /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+    "DHE-PSK-CAMELLIA128-SHA256",       /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+    "RSA-PSK-CAMELLIA128-SHA256",       /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+    "ECDHE-PSK-CAMELLIA128-SHA256",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
+    "CAMELLIA128-GCM-SHA256",           /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+    "DH-RSA-CAMELLIA128-GCM-SHA256",    /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+    "DH-DSS-CAMELLIA128-GCM-SHA256",    /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
+    "ADH-CAMELLIA128-GCM-SHA256",       /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
+    "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
+    "ECDH-RSA-CAMELLIA128-GCM-SHA256",  /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
+    "PSK-CAMELLIA128-GCM-SHA256",       /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
+    "RSA-PSK-CAMELLIA128-GCM-SHA256",   /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
+    "CAMELLIA128-SHA256",               /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "DH-DSS-CAMELLIA128-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
+    "DH-RSA-CAMELLIA128-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "DHE-DSS-CAMELLIA128-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
+    "DHE-RSA-CAMELLIA128-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
+    "ADH-CAMELLIA128-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
+    
+    /* blacklisted CAMELLIA256 encrpytion ciphers */
+    "CAMELLIA256-SHA",                  /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
+    "DH-RSA-CAMELLIA256-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
+    "DH-DSS-CAMELLIA256-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
+    "DHE-DSS-CAMELLIA256-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
+    "DHE-RSA-CAMELLIA256-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
+    "ADH-CAMELLIA256-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
+    "ECDHE-ECDSA-CAMELLIA256-SHA384",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
+    "ECDH-ECDSA-CAMELLIA256-SHA384",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
+    "ECDHE-RSA-CAMELLIA256-SHA384",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
+    "ECDH-RSA-CAMELLIA256-SHA384",      /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
+    "PSK-CAMELLIA256-SHA384",           /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+    "DHE-PSK-CAMELLIA256-SHA384",       /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+    "RSA-PSK-CAMELLIA256-SHA384",       /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+    "ECDHE-PSK-CAMELLIA256-SHA384",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
+    "CAMELLIA256-SHA256",               /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+    "DH-DSS-CAMELLIA256-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
+    "DH-RSA-CAMELLIA256-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+    "DHE-DSS-CAMELLIA256-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
+    "DHE-RSA-CAMELLIA256-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
+    "ADH-CAMELLIA256-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
+    "CAMELLIA256-GCM-SHA384",           /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+    "DH-RSA-CAMELLIA256-GCM-SHA384",    /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+    "DH-DSS-CAMELLIA256-GCM-SHA384",    /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
+    "ADH-CAMELLIA256-GCM-SHA384",       /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
+    "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
+    "ECDH-RSA-CAMELLIA256-GCM-SHA384",  /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
+    "PSK-CAMELLIA256-GCM-SHA384",       /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
+    "RSA-PSK-CAMELLIA256-GCM-SHA384",   /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
+    
+    /* The blacklisted ARIA encrpytion ciphers */
+    "ARIA128-SHA256",                   /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
+    "ARIA256-SHA384",                   /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
+    "DH-DSS-ARIA128-SHA256",            /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
+    "DH-DSS-ARIA256-SHA384",            /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
+    "DH-RSA-ARIA128-SHA256",            /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
+    "DH-RSA-ARIA256-SHA384",            /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
+    "DHE-DSS-ARIA128-SHA256",           /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
+    "DHE-DSS-ARIA256-SHA384",           /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
+    "DHE-RSA-ARIA128-SHA256",           /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
+    "DHE-RSA-ARIA256-SHA384",           /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
+    "ADH-ARIA128-SHA256",               /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
+    "ADH-ARIA256-SHA384",               /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
+    "ECDHE-ECDSA-ARIA128-SHA256",       /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
+    "ECDHE-ECDSA-ARIA256-SHA384",       /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
+    "ECDH-ECDSA-ARIA128-SHA256",        /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
+    "ECDH-ECDSA-ARIA256-SHA384",        /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
+    "ECDHE-RSA-ARIA128-SHA256",         /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
+    "ECDHE-RSA-ARIA256-SHA384",         /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
+    "ECDH-RSA-ARIA128-SHA256",          /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
+    "ECDH-RSA-ARIA256-SHA384",          /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
+    "ARIA128-GCM-SHA256",               /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
+    "ARIA256-GCM-SHA384",               /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
+    "DH-DSS-ARIA128-GCM-SHA256",        /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
+    "DH-DSS-ARIA256-GCM-SHA384",        /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
+    "DH-RSA-ARIA128-GCM-SHA256",        /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
+    "DH-RSA-ARIA256-GCM-SHA384",        /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
+    "ADH-ARIA128-GCM-SHA256",           /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
+    "ADH-ARIA256-GCM-SHA384",           /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
+    "ECDH-ECDSA-ARIA128-GCM-SHA256",    /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
+    "ECDH-ECDSA-ARIA256-GCM-SHA384",    /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
+    "ECDH-RSA-ARIA128-GCM-SHA256",      /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
+    "ECDH-RSA-ARIA256-GCM-SHA384",      /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
+    "PSK-ARIA128-SHA256",               /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
+    "PSK-ARIA256-SHA384",               /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
+    "DHE-PSK-ARIA128-SHA256",           /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
+    "DHE-PSK-ARIA256-SHA384",           /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
+    "RSA-PSK-ARIA128-SHA256",           /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
+    "RSA-PSK-ARIA256-SHA384",           /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
+    "ARIA128-GCM-SHA256",               /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
+    "ARIA256-GCM-SHA384",               /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
+    "RSA-PSK-ARIA128-GCM-SHA256",       /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
+    "RSA-PSK-ARIA256-GCM-SHA384",       /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
+    "ECDHE-PSK-ARIA128-SHA256",         /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
+    "ECDHE-PSK-ARIA256-SHA384",         /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
+
+    /* blacklisted SEED encryptions */
+    "SEED-SHA",                         /*TLS_RSA_WITH_SEED_CBC_SHA */
+    "DH-DSS-SEED-SHA",                  /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
+    "DH-RSA-SEED-SHA",                  /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
+    "DHE-DSS-SEED-SHA",                 /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
+    "DHE-RSA-SEED-SHA",                 /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */               
+    "ADH-SEED-SHA",                     /* TLS_DH_anon_WITH_SEED_CBC_SHA */
+
+    /* blacklisted KRB5 ciphers */
+    "KRB5-DES-CBC-SHA",                 /* TLS_KRB5_WITH_DES_CBC_SHA */
+    "KRB5-DES-CBC3-SHA",                /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
+    "KRB5-IDEA-CBC-SHA",                /* TLS_KRB5_WITH_IDEA_CBC_SHA */
+    "KRB5-DES-CBC-MD5",                 /* TLS_KRB5_WITH_DES_CBC_MD5 */
+    "KRB5-DES-CBC3-MD5",                /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
+    "KRB5-IDEA-CBC-MD5",                /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
+    "EXP-KRB5-DES-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
+    "EXP-KRB5-DES-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
+    "EXP-KRB5-RC2-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
+    "EXP-KRB5-RC2-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
+  
+    /* blacklisted exoticas */
+    "DHE-DSS-CBC-SHA",                  /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
+    "IDEA-CBC-SHA",                     /* TLS_RSA_WITH_IDEA_CBC_SHA */
+    
+    /* not really sure if the following names are correct */
+    "SSL3_CK_SCSV",                     /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+    "SSL3_CK_FALLBACK_SCSV"
+};
+static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
+
+
+static apr_hash_t *BLCNames;
+
+static void cipher_init(apr_pool_t *pool)
+{
+    apr_hash_t *hash = apr_hash_make(pool);
+    const char *source;
+    int i;
+    
+    source = "rfc7540";
+    for (i = 0; i < RFC7540_names_LEN; ++i) {
+        apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
+    }
+    
+    BLCNames = hash;
+}
+
+static int cipher_is_blacklisted(const char *cipher, const char **psource)
+{   
+    *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
+    return !!*psource;
+}
+
+/*******************************************************************************
  * Hooks for processing incoming connections:
  * - pre_conn_before_tls switches SSL off for stream connections
  * - process_conn take over connection in case of h2
@@ -72,12 +420,15 @@ apr_status_t h2_h2_init(apr_pool_t *pool
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_h2, child_init");
     opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
     opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
+    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
     
-    if (!opt_ssl_is_https) {
+    if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
                      APLOGNO(02951) "mod_ssl does not seem to be enabled");
     }
     
+    cipher_init(pool);
+    
     return APR_SUCCESS;
 }
 
@@ -94,6 +445,63 @@ int h2_tls_disable(conn_rec *c)
     return 0;
 }
 
+int h2_is_security_compliant(conn_rec *c, int require_all) 
+{
+    int is_tls = h2_h2_is_tls(c);
+    h2_config *cfg = h2_config_get(c);
+
+    if (is_tls && h2_config_geti(cfg, H2_CONF_COMPLIANCE) > 0) {
+        /* Check TLS connection for RFC 7540 compliance
+         */
+        apr_pool_t *pool = c->pool;
+        server_rec *s = c->base_server;
+        char *val;
+        
+        if (!opt_ssl_var_lookup) {
+            /* unable to check */
+            return 0;
+        }
+        
+        /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
+         */
+        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_PROTOCOL");
+        if (val && *val) {
+            if (strncmp("TLS", val, 3) 
+                || !strcmp("TLSv1", val) 
+                || !strcmp("TLSv1.1", val)) {
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                          "h2_h2(%ld): tls protocol not suitable: %s", 
+                          (long)c->id, val);
+                return 0;
+            }
+        }
+        else if (require_all) {
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                          "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
+            return 0;
+        }
+
+        /* Check TLS cipher blacklist
+         */
+        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_CIPHER");
+        if (val && *val) {
+            const char *source;
+            if (cipher_is_blacklisted(val, &source)) {
+                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                              "h2_h2(%ld): tls cipher %s blacklisted by %s", 
+                              (long)c->id, val, source);
+                return 0;
+            }
+        }
+        else if (require_all) {
+            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                          "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
+            return 0;
+        }
+    }
+    return 1;
+}
+
 /*******************************************************************************
  * Register various hooks
  */

Modified: httpd/httpd/trunk/modules/http2/h2_h2.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.h?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_h2.h (original)
+++ httpd/httpd/trunk/modules/http2/h2_h2.h Wed Oct 14 12:10:11 2015
@@ -53,5 +53,16 @@ int h2_tls_disable(conn_rec *c);
  */
 void h2_h2_register_hooks(void);
 
+/**
+ * Check if the given connection fulfills the security requirements
+ * of RFC 7540.
+ * @param c the connection
+ * @param require_all != 0 iff any missing connection properties make
+ *    the test fail. For example, a cipher might not have been selected while
+ *    the handshake is still ongoing.
+ * @return != 0 iff security requirements are met
+ */
+int h2_is_security_compliant(conn_rec *c, int require_all);
+
 
 #endif /* defined(__mod_h2__h2_h2__) */

Modified: httpd/httpd/trunk/modules/http2/h2_switch.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_switch.c?rev=1708593&r1=1708592&r2=1708593&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/http2/h2_switch.c (original)
+++ httpd/httpd/trunk/modules/http2/h2_switch.c Wed Oct 14 12:10:11 2015
@@ -35,24 +35,12 @@
 #include "h2_switch.h"
 
 /*******************************************************************************
- * SSL var lookup
- */
-APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
-                        (apr_pool_t *, server_rec *,
-                         conn_rec *, request_rec *,
-                         char *));
-static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
-                                   conn_rec *, request_rec *,
-                                   char *);
-
-/*******************************************************************************
  * Once per lifetime init, retrieve optional functions
  */
 apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s)
 {
     (void)pool;
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_switch init");
-    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
 
     return APR_SUCCESS;
 }
@@ -63,7 +51,8 @@ static int h2_protocol_propose(conn_rec
                                apr_array_header_t *proposals)
 {
     int proposed = 0;
-    const char **protos = h2_h2_is_tls(c)? h2_tls_protos : h2_clear_protos;
+    int is_tls = h2_h2_is_tls(c);
+    const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
     
     (void)s;
     if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
@@ -74,6 +63,12 @@ static int h2_protocol_propose(conn_rec
         return DECLINED;
     }
     
+    if (!h2_is_security_compliant(c, 0)) {
+        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                      "protocol propose: security requirements not met, declined");
+        return DECLINED;
+    }
+    
     if (r) {
         const char *p;
         /* So far, this indicates an HTTP/1 Upgrade header initiated




Re: svn commit: r1708593 - in /httpd/httpd/trunk: docs/manual/mod/mod_http2.xml modules/http2/h2_config.c modules/http2/h2_config.h modules/http2/h2_conn.c modules/http2/h2_h2.c modules/http2/h2_h2.h modules/http2/h2_switch.c

Posted by Stefan Eissing <st...@greenbytes.de>.
And we were all just getting so warm and fuzzy here... ;-)

There are several areas where RFC 7540 says something that - let's say it 
like this - applies maybe to the Internet - whatever that is - but that
Apache httpd should and will work in environments that have other needs.

Instead of a unspecific "H2Compliance", we can make individual directive
to address these parts. 

We already have:
- H2Direct on|off, can enable direct mode on cleartext and TLS connections

We can add
- H2ModernTLSOnly on|off, to enforce TLS params as specified in the RFC and also enforced by modern browsers as described in https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
- H2UpgradeInTLS on|off, to allow HTTP/1.1 style Upgrade: on TLS connections
...
(insert your wishes here)

//Stefan

> Am 14.10.2015 um 16:55 schrieb Roy T. Fielding <fi...@gbiv.com>:
> 
> Can you please choose a more specific directive name? Like "LimitTLSunderH2".
> 
> We don't have switches for RFC compliance. We do have switches for stupid WG political positions that contradict common sense and are not applicable to non-Internet deployments.
> 
> ....Roy
> 
> 
>> On Oct 14, 2015, at 5:10 AM, icing@apache.org wrote:
>> 
>> Author: icing
>> Date: Wed Oct 14 12:10:11 2015
>> New Revision: 1708593
>> 
>> URL: http://svn.apache.org/viewvc?rev=1708593&view=rev
>> Log:
>> mod_http2: new directive H2Compliance on/off, checking TLS protocol and cipher against RFC7540
>> 
>> Modified:
>>   httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
>>   httpd/httpd/trunk/modules/http2/h2_config.c
>>   httpd/httpd/trunk/modules/http2/h2_config.h
>>   httpd/httpd/trunk/modules/http2/h2_conn.c
>>   httpd/httpd/trunk/modules/http2/h2_h2.c
>>   httpd/httpd/trunk/modules/http2/h2_h2.h
>>   httpd/httpd/trunk/modules/http2/h2_switch.c
>> 
>> Modified: httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_http2.xml?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/docs/manual/mod/mod_http2.xml (original)
>> +++ httpd/httpd/trunk/docs/manual/mod/mod_http2.xml Wed Oct 14 12:10:11 2015
>> @@ -74,11 +74,11 @@
>>                Direct communication means that if the first bytes received by the 
>>                server on a connection match the HTTP/2 preamble, the HTTP/2
>>                protocol is switched to immediately without further negotiation.
>> -                This mode falls outside the RFC 7540 but has become widely implemented
>> -                on cleartext ports as it is very convenient for development and testing. 
>> +                This mode is defined in RFC 7540 for the cleartext (h2c) case. Its
>> +                use on TLS connections is not allowed by the standard.
>>            </p>
>>            <p>
>> -                Since this detection implies that the client will send data on
>> +                Since this detection requires that the client will send data on
>>                new connection immediately, direct HTTP/2 mode is disabled by
>>                default.
>>            </p>
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_config.c
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_config.c (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_config.c Wed Oct 14 12:10:11 2015
>> @@ -49,6 +49,7 @@ static h2_config defconf = {
>>    0,                /* serialize headers */
>>    0,                /* h2 direct mode */
>>    -1,               /* # session extra files */
>> +    1,                /* rfc 7540 compliance */
>> };
>> 
>> static int files_per_session = 0;
>> @@ -100,6 +101,7 @@ static void *h2_config_create(apr_pool_t
>>    conf->serialize_headers    = DEF_VAL;
>>    conf->h2_direct            = DEF_VAL;
>>    conf->session_extra_files  = DEF_VAL;
>> +    conf->rfc_compliance       = DEF_VAL;
>>    return conf;
>> }
>> 
>> @@ -138,6 +140,7 @@ void *h2_config_merge(apr_pool_t *pool,
>>    n->serialize_headers = H2_CONFIG_GET(add, base, serialize_headers);
>>    n->h2_direct      = H2_CONFIG_GET(add, base, h2_direct);
>>    n->session_extra_files = H2_CONFIG_GET(add, base, session_extra_files);
>> +    n->rfc_compliance = H2_CONFIG_GET(add, base, rfc_compliance);
>> 
>>    return n;
>> }
>> @@ -162,6 +165,8 @@ int h2_config_geti(h2_config *conf, h2_c
>>            return H2_CONFIG_GET(conf, &defconf, alt_svc_max_age);
>>        case H2_CONF_SER_HEADERS:
>>            return H2_CONFIG_GET(conf, &defconf, serialize_headers);
>> +        case H2_CONF_COMPLIANCE:
>> +            return H2_CONFIG_GET(conf, &defconf, rfc_compliance);
>>        case H2_CONF_DIRECT:
>>            return H2_CONFIG_GET(conf, &defconf, h2_direct);
>>        case H2_CONF_SESSION_FILES:
>> @@ -332,8 +337,25 @@ static const char *h2_conf_set_direct(cm
>>    return "value must be On or Off";
>> }
>> 
>> -#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
>> +static const char *h2_conf_set_compliance(cmd_parms *parms,
>> +                                          void *arg, const char *value)
>> +{
>> +    h2_config *cfg = h2_config_sget(parms->server);
>> +    if (!strcasecmp(value, "On")) {
>> +        cfg->rfc_compliance = 1;
>> +        return NULL;
>> +    }
>> +    else if (!strcasecmp(value, "Off")) {
>> +        cfg->rfc_compliance = 0;
>> +        return NULL;
>> +    }
>> +    
>> +    (void)arg;
>> +    return "value must be On or Off";
>> +}
>> +
>> 
>> +#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
>> 
>> const command_rec h2_cmds[] = {
>>    AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
>> @@ -354,6 +376,8 @@ const command_rec h2_cmds[] = {
>>                  RSRC_CONF, "set the maximum age (in seconds) that client can rely on alt-svc information"),
>>    AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
>>                  RSRC_CONF, "on to enable header serialization for compatibility"),
>> +    AP_INIT_TAKE1("H2Compliance", h2_conf_set_compliance, NULL,
>> +                  RSRC_CONF, "off to disable strict compliance to RFC 7540"),
>>    AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
>>                  RSRC_CONF, "on to enable direct HTTP/2 mode"),
>>    AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_config.h
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.h?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_config.h (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_config.h Wed Oct 14 12:10:11 2015
>> @@ -34,6 +34,7 @@ typedef enum {
>>    H2_CONF_SER_HEADERS,
>>    H2_CONF_DIRECT,
>>    H2_CONF_SESSION_FILES,
>> +    H2_CONF_COMPLIANCE,
>> } h2_config_var_t;
>> 
>> /* Apache httpd module configuration for h2. */
>> @@ -51,6 +52,7 @@ typedef struct h2_config {
>>                                     processing, better compatibility */
>>    int h2_direct;                /* if mod_h2 is active directly */
>>    int session_extra_files;      /* # of extra files a session may keep open */  
>> +    int rfc_compliance;           /* Comply with all aspects of RFC 7540 */  
>> } h2_config;
>> 
>> 
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_conn.c
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.c?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_conn.c (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_conn.c Wed Oct 14 12:10:11 2015
>> @@ -32,6 +32,7 @@
>> #include "h2_session.h"
>> #include "h2_stream.h"
>> #include "h2_stream_set.h"
>> +#include "h2_h2.h"
>> #include "h2_task.h"
>> #include "h2_worker.h"
>> #include "h2_workers.h"
>> @@ -177,6 +178,11 @@ apr_status_t h2_conn_main(conn_rec *c)
>>        return APR_EGENERAL;
>>    }
>> 
>> +    if (!h2_is_security_compliant(c, 1)) {
>> +        nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
>> +                              NGHTTP2_INADEQUATE_SECURITY, NULL, 0);
>> +    } 
>> +
>>    status = h2_session_process(session);
>> 
>>    /* Make sure this connection gets closed properly. */
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_h2.c Wed Oct 14 12:10:11 2015
>> @@ -54,6 +54,354 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_is_http
>> static int (*opt_ssl_engine_disable)(conn_rec*);
>> static int (*opt_ssl_is_https)(conn_rec*);
>> /*******************************************************************************
>> + * SSL var lookup
>> + */
>> +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
>> +                        (apr_pool_t *, server_rec *,
>> +                         conn_rec *, request_rec *,
>> +                         char *));
>> +static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
>> +                                   conn_rec *, request_rec *,
>> +                                   char *);
>> +
>> +/*******************************************************************************
>> + * Check connection security requirements of RFC 7540
>> + */
>> +
>> +/*
>> + * Black Listed Ciphers from RFC 7549 Appendix A
>> + *
>> + */
>> +static const char *RFC7540_names[] = {
>> +    /* ciphers with NULL encrpytion */
>> +    "NULL-MD5",                         /* TLS_NULL_WITH_NULL_NULL */
>> +    /* same */                          /* TLS_RSA_WITH_NULL_MD5 */
>> +    "NULL-SHA",                         /* TLS_RSA_WITH_NULL_SHA */
>> +    "NULL-SHA256",                      /* TLS_RSA_WITH_NULL_SHA256 */
>> +    "PSK-NULL-SHA",                     /* TLS_PSK_WITH_NULL_SHA */
>> +    "DHE-PSK-NULL-SHA",                 /* TLS_DHE_PSK_WITH_NULL_SHA */
>> +    "RSA-PSK-NULL-SHA",                 /* TLS_RSA_PSK_WITH_NULL_SHA */
>> +    "PSK-NULL-SHA256",                  /* TLS_PSK_WITH_NULL_SHA256 */
>> +    "PSK-NULL-SHA384",                  /* TLS_PSK_WITH_NULL_SHA384 */
>> +    "DHE-PSK-NULL-SHA256",              /* TLS_DHE_PSK_WITH_NULL_SHA256 */
>> +    "DHE-PSK-NULL-SHA384",              /* TLS_DHE_PSK_WITH_NULL_SHA384 */
>> +    "RSA-PSK-NULL-SHA256",              /* TLS_RSA_PSK_WITH_NULL_SHA256 */
>> +    "RSA-PSK-NULL-SHA384",              /* TLS_RSA_PSK_WITH_NULL_SHA384 */
>> +    "ECDH-ECDSA-NULL-SHA",              /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
>> +    "ECDHE-ECDSA-NULL-SHA",             /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
>> +    "ECDH-RSA-NULL-SHA",                /* TLS_ECDH_RSA_WITH_NULL_SHA */
>> +    "ECDHE-RSA-NULL-SHA",               /* TLS_ECDHE_RSA_WITH_NULL_SHA */
>> +    "AECDH-NULL-SHA",                   /* TLS_ECDH_anon_WITH_NULL_SHA */
>> +    "ECDHE-PSK-NULL-SHA",               /* TLS_ECDHE_PSK_WITH_NULL_SHA */
>> +    "ECDHE-PSK-NULL-SHA256",            /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
>> +    "ECDHE-PSK-NULL-SHA384",            /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
>> +    
>> +    /* DES/3DES ciphers */
>> +    "PSK-3DES-EDE-CBC-SHA",             /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
>> +    "DHE-PSK-3DES-EDE-CBC-SHA",         /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
>> +    "RSA-PSK-3DES-EDE-CBC-SHA",         /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
>> +    "ECDH-ECDSA-DES-CBC3-SHA",          /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
>> +    "ECDHE-ECDSA-DES-CBC3-SHA",         /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
>> +    "ECDH-RSA-DES-CBC3-SHA",            /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
>> +    "ECDHE-RSA-DES-CBC3-SHA",           /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
>> +    "AECDH-DES-CBC3-SHA",               /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
>> +    "SRP-3DES-EDE-CBC-SHA",             /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
>> +    "SRP-RSA-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
>> +    "SRP-DSS-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
>> +    "ECDHE-PSK-3DES-EDE-CBC-SHA",       /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
>> +    "DES-CBC-SHA",                      /* TLS_RSA_WITH_DES_CBC_SHA */
>> +    "DES-CBC3-SHA",                     /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
>> +    "DHE-DSS-DES-CBC3-SHA",             /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
>> +    "DHE-RSA-DES-CBC-SHA",              /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
>> +    "DHE-RSA-DES-CBC3-SHA",             /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
>> +    "ADH-DES-CBC-SHA",                  /* TLS_DH_anon_WITH_DES_CBC_SHA */
>> +    "ADH-DES-CBC3-SHA",                 /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
>> +    "EXP-DH-DSS-DES-CBC-SHA",           /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
>> +    "DH-DSS-DES-CBC-SHA",               /* TLS_DH_DSS_WITH_DES_CBC_SHA */
>> +    "DH-DSS-DES-CBC3-SHA",              /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
>> +    "EXP-DH-RSA-DES-CBC-SHA",           /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
>> +    "DH-RSA-DES-CBC-SHA",               /* TLS_DH_RSA_WITH_DES_CBC_SHA */
>> +    "DH-RSA-DES-CBC3-SHA",              /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
>> +
>> +    /* blacklisted EXPORT ciphers */
>> +    "EXP-RC4-MD5",                      /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
>> +    "EXP-RC2-CBC-MD5",                  /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
>> +    "EXP-DES-CBC-SHA",                  /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
>> +    "EXP-DHE-DSS-DES-CBC-SHA",          /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
>> +    "EXP-DHE-RSA-DES-CBC-SHA",          /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
>> +    "EXP-ADH-DES-CBC-SHA",              /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
>> +    "EXP-ADH-RC4-MD5",                  /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
>> +
>> +    /* blacklisted RC4 encryption */
>> +    "RC4-MD5",                          /* TLS_RSA_WITH_RC4_128_MD5 */
>> +    "RC4-SHA",                          /* TLS_RSA_WITH_RC4_128_SHA */
>> +    "ADH-RC4-MD5",                      /* TLS_DH_anon_WITH_RC4_128_MD5 */
>> +    "KRB5-RC4-SHA",                     /* TLS_KRB5_WITH_RC4_128_SHA */
>> +    "KRB5-RC4-MD5",                     /* TLS_KRB5_WITH_RC4_128_MD5 */
>> +    "EXP-KRB5-RC4-SHA",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
>> +    "EXP-KRB5-RC4-MD5",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
>> +    "PSK-RC4-SHA",                      /* TLS_PSK_WITH_RC4_128_SHA */
>> +    "DHE-PSK-RC4-SHA",                  /* TLS_DHE_PSK_WITH_RC4_128_SHA */
>> +    "RSA-PSK-RC4-SHA",                  /* TLS_RSA_PSK_WITH_RC4_128_SHA */
>> +    "ECDH-ECDSA-RC4-SHA",               /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
>> +    "ECDHE-ECDSA-RC4-SHA",              /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
>> +    "ECDH-RSA-RC4-SHA",                 /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
>> +    "ECDHE-RSA-RC4-SHA",                /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
>> +    "AECDH-RC4-SHA",                    /* TLS_ECDH_anon_WITH_RC4_128_SHA */
>> +    "ECDHE-PSK-RC4-SHA",                /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
>> +
>> +    /* blacklisted AES128 encrpytion ciphers */
>> +    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA */
>> +    "DH-DSS-AES128-SHA",                /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
>> +    "DH-RSA-AES128-SHA",                /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
>> +    "DHE-DSS-AES128-SHA",               /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
>> +    "DHE-RSA-AES128-SHA",               /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
>> +    "ADH-AES128-SHA",                   /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
>> +    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
>> +    "DH-DSS-AES128-SHA256",             /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
>> +    "DH-RSA-AES128-SHA256",             /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
>> +    "DHE-DSS-AES128-SHA256",            /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
>> +    "DHE-RSA-AES128-SHA256",            /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
>> +    "ECDH-ECDSA-AES128-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
>> +    "ECDHE-ECDSA-AES128-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
>> +    "ECDH-RSA-AES128-SHA",              /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
>> +    "ECDHE-RSA-AES128-SHA",             /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
>> +    "AECDH-AES128-SHA",                 /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
>> +    "ECDHE-ECDSA-AES128-SHA256",        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
>> +    "ECDH-ECDSA-AES128-SHA256",         /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
>> +    "ECDHE-RSA-AES128-SHA256",          /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
>> +    "ECDH-RSA-AES128-SHA256",           /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
>> +    "ADH-AES128-SHA256",                /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
>> +    "PSK-AES128-CBC-SHA",               /* TLS_PSK_WITH_AES_128_CBC_SHA */
>> +    "DHE-PSK-AES128-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
>> +    "RSA-PSK-AES128-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
>> +    "PSK-AES128-CBC-SHA256",            /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
>> +    "DHE-PSK-AES128-CBC-SHA256",        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
>> +    "RSA-PSK-AES128-CBC-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
>> +    "ECDHE-PSK-AES128-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
>> +    "ECDHE-PSK-AES128-CBC-SHA256",      /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
>> +    "AES128-CCM",                       /* TLS_RSA_WITH_AES_128_CCM */
>> +    "AES128-CCM8",                      /* TLS_RSA_WITH_AES_128_CCM_8 */
>> +    "PSK-AES128-CCM",                   /* TLS_PSK_WITH_AES_128_CCM */
>> +    "PSK-AES128-CCM8",                  /* TLS_PSK_WITH_AES_128_CCM_8 */
>> +    "AES128-GCM-SHA256",                /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
>> +    "DH-RSA-AES128-GCM-SHA256",         /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
>> +    "DH-DSS-AES128-GCM-SHA256",         /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
>> +    "ADH-AES128-GCM-SHA256",            /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
>> +    "PSK-AES128-GCM-SHA256",            /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
>> +    "RSA-PSK-AES128-GCM-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
>> +    "ECDH-ECDSA-AES128-GCM-SHA256",     /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
>> +    "ECDH-RSA-AES128-GCM-SHA256",       /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
>> +    "SRP-AES-128-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
>> +    "SRP-RSA-AES-128-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
>> +    "SRP-DSS-AES-128-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
>> +    
>> +    /* blacklisted AES256 encrpytion ciphers */
>> +    "AES256-SHA",                       /* TLS_RSA_WITH_AES_256_CBC_SHA */
>> +    "DH-DSS-AES256-SHA",                /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
>> +    "DH-RSA-AES256-SHA",                /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
>> +    "DHE-DSS-AES256-SHA",               /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
>> +    "DHE-RSA-AES256-SHA",               /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
>> +    "ADH-AES256-SHA",                   /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
>> +    "AES256-SHA256",                    /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
>> +    "DH-DSS-AES256-SHA256",             /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
>> +    "DH-RSA-AES256-SHA256",             /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
>> +    "DHE-DSS-AES256-SHA256",            /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
>> +    "DHE-RSA-AES256-SHA256",            /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
>> +    "ADH-AES256-SHA256",                /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
>> +    "ECDH-ECDSA-AES256-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
>> +    "ECDHE-ECDSA-AES256-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
>> +    "ECDH-RSA-AES256-SHA",              /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
>> +    "ECDHE-RSA-AES256-SHA",             /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
>> +    "AECDH-AES256-SHA",                 /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
>> +    "ECDHE-ECDSA-AES256-SHA384",        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
>> +    "ECDH-ECDSA-AES256-SHA384",         /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
>> +    "ECDHE-RSA-AES256-SHA384",          /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
>> +    "ECDH-RSA-AES256-SHA384",           /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
>> +    "PSK-AES256-CBC-SHA",               /* TLS_PSK_WITH_AES_256_CBC_SHA */
>> +    "DHE-PSK-AES256-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
>> +    "RSA-PSK-AES256-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
>> +    "PSK-AES256-CBC-SHA384",            /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
>> +    "DHE-PSK-AES256-CBC-SHA384",        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
>> +    "RSA-PSK-AES256-CBC-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
>> +    "ECDHE-PSK-AES256-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
>> +    "ECDHE-PSK-AES256-CBC-SHA384",      /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
>> +    "SRP-AES-256-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
>> +    "SRP-RSA-AES-256-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
>> +    "SRP-DSS-AES-256-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
>> +    "AES256-CCM",                       /* TLS_RSA_WITH_AES_256_CCM */
>> +    "AES256-CCM8",                      /* TLS_RSA_WITH_AES_256_CCM_8 */
>> +    "PSK-AES256-CCM",                   /* TLS_PSK_WITH_AES_256_CCM */
>> +    "PSK-AES256-CCM8",                  /* TLS_PSK_WITH_AES_256_CCM_8 */
>> +    "AES256-GCM-SHA384",                /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
>> +    "DH-RSA-AES256-GCM-SHA384",         /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
>> +    "DH-DSS-AES256-GCM-SHA384",         /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
>> +    "ADH-AES256-GCM-SHA384",            /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
>> +    "PSK-AES256-GCM-SHA384",            /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
>> +    "RSA-PSK-AES256-GCM-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
>> +    "ECDH-ECDSA-AES256-GCM-SHA384",     /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
>> +    "ECDH-RSA-AES256-GCM-SHA384",       /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
>> +    
>> +    /* blacklisted CAMELLIA128 encrpytion ciphers */
>> +    "CAMELLIA128-SHA",                  /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
>> +    "DH-DSS-CAMELLIA128-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
>> +    "DH-RSA-CAMELLIA128-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
>> +    "DHE-DSS-CAMELLIA128-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
>> +    "DHE-RSA-CAMELLIA128-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
>> +    "ADH-CAMELLIA128-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
>> +    "ECDHE-ECDSA-CAMELLIA128-SHA256",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "ECDH-ECDSA-CAMELLIA128-SHA256",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "ECDHE-RSA-CAMELLIA128-SHA256",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "ECDH-RSA-CAMELLIA128-SHA256",      /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "PSK-CAMELLIA128-SHA256",           /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "DHE-PSK-CAMELLIA128-SHA256",       /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "RSA-PSK-CAMELLIA128-SHA256",       /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "ECDHE-PSK-CAMELLIA128-SHA256",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "CAMELLIA128-GCM-SHA256",           /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "DH-RSA-CAMELLIA128-GCM-SHA256",    /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "DH-DSS-CAMELLIA128-GCM-SHA256",    /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "ADH-CAMELLIA128-GCM-SHA256",       /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "ECDH-RSA-CAMELLIA128-GCM-SHA256",  /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "PSK-CAMELLIA128-GCM-SHA256",       /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "RSA-PSK-CAMELLIA128-GCM-SHA256",   /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
>> +    "CAMELLIA128-SHA256",               /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "DH-DSS-CAMELLIA128-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "DH-RSA-CAMELLIA128-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "DHE-DSS-CAMELLIA128-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "DHE-RSA-CAMELLIA128-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    "ADH-CAMELLIA128-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
>> +    
>> +    /* blacklisted CAMELLIA256 encrpytion ciphers */
>> +    "CAMELLIA256-SHA",                  /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
>> +    "DH-RSA-CAMELLIA256-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
>> +    "DH-DSS-CAMELLIA256-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
>> +    "DHE-DSS-CAMELLIA256-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
>> +    "DHE-RSA-CAMELLIA256-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
>> +    "ADH-CAMELLIA256-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
>> +    "ECDHE-ECDSA-CAMELLIA256-SHA384",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "ECDH-ECDSA-CAMELLIA256-SHA384",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "ECDHE-RSA-CAMELLIA256-SHA384",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "ECDH-RSA-CAMELLIA256-SHA384",      /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "PSK-CAMELLIA256-SHA384",           /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "DHE-PSK-CAMELLIA256-SHA384",       /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "RSA-PSK-CAMELLIA256-SHA384",       /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "ECDHE-PSK-CAMELLIA256-SHA384",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
>> +    "CAMELLIA256-SHA256",               /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "DH-DSS-CAMELLIA256-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "DH-RSA-CAMELLIA256-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "DHE-DSS-CAMELLIA256-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "DHE-RSA-CAMELLIA256-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "ADH-CAMELLIA256-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
>> +    "CAMELLIA256-GCM-SHA384",           /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "DH-RSA-CAMELLIA256-GCM-SHA384",    /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "DH-DSS-CAMELLIA256-GCM-SHA384",    /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "ADH-CAMELLIA256-GCM-SHA384",       /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "ECDH-RSA-CAMELLIA256-GCM-SHA384",  /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "PSK-CAMELLIA256-GCM-SHA384",       /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    "RSA-PSK-CAMELLIA256-GCM-SHA384",   /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
>> +    
>> +    /* The blacklisted ARIA encrpytion ciphers */
>> +    "ARIA128-SHA256",                   /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "ARIA256-SHA384",                   /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "DH-DSS-ARIA128-SHA256",            /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
>> +    "DH-DSS-ARIA256-SHA384",            /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
>> +    "DH-RSA-ARIA128-SHA256",            /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "DH-RSA-ARIA256-SHA384",            /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "DHE-DSS-ARIA128-SHA256",           /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
>> +    "DHE-DSS-ARIA256-SHA384",           /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
>> +    "DHE-RSA-ARIA128-SHA256",           /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "DHE-RSA-ARIA256-SHA384",           /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "ADH-ARIA128-SHA256",               /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
>> +    "ADH-ARIA256-SHA384",               /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
>> +    "ECDHE-ECDSA-ARIA128-SHA256",       /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "ECDHE-ECDSA-ARIA256-SHA384",       /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "ECDH-ECDSA-ARIA128-SHA256",        /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "ECDH-ECDSA-ARIA256-SHA384",        /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "ECDHE-RSA-ARIA128-SHA256",         /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "ECDHE-RSA-ARIA256-SHA384",         /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "ECDH-RSA-ARIA128-SHA256",          /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
>> +    "ECDH-RSA-ARIA256-SHA384",          /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
>> +    "ARIA128-GCM-SHA256",               /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
>> +    "ARIA256-GCM-SHA384",               /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
>> +    "DH-DSS-ARIA128-GCM-SHA256",        /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
>> +    "DH-DSS-ARIA256-GCM-SHA384",        /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
>> +    "DH-RSA-ARIA128-GCM-SHA256",        /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
>> +    "DH-RSA-ARIA256-GCM-SHA384",        /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
>> +    "ADH-ARIA128-GCM-SHA256",           /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
>> +    "ADH-ARIA256-GCM-SHA384",           /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
>> +    "ECDH-ECDSA-ARIA128-GCM-SHA256",    /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
>> +    "ECDH-ECDSA-ARIA256-GCM-SHA384",    /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
>> +    "ECDH-RSA-ARIA128-GCM-SHA256",      /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
>> +    "ECDH-RSA-ARIA256-GCM-SHA384",      /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
>> +    "PSK-ARIA128-SHA256",               /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
>> +    "PSK-ARIA256-SHA384",               /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
>> +    "DHE-PSK-ARIA128-SHA256",           /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
>> +    "DHE-PSK-ARIA256-SHA384",           /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
>> +    "RSA-PSK-ARIA128-SHA256",           /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
>> +    "RSA-PSK-ARIA256-SHA384",           /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
>> +    "ARIA128-GCM-SHA256",               /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
>> +    "ARIA256-GCM-SHA384",               /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
>> +    "RSA-PSK-ARIA128-GCM-SHA256",       /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
>> +    "RSA-PSK-ARIA256-GCM-SHA384",       /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
>> +    "ECDHE-PSK-ARIA128-SHA256",         /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
>> +    "ECDHE-PSK-ARIA256-SHA384",         /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
>> +
>> +    /* blacklisted SEED encryptions */
>> +    "SEED-SHA",                         /*TLS_RSA_WITH_SEED_CBC_SHA */
>> +    "DH-DSS-SEED-SHA",                  /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
>> +    "DH-RSA-SEED-SHA",                  /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
>> +    "DHE-DSS-SEED-SHA",                 /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
>> +    "DHE-RSA-SEED-SHA",                 /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */               
>> +    "ADH-SEED-SHA",                     /* TLS_DH_anon_WITH_SEED_CBC_SHA */
>> +
>> +    /* blacklisted KRB5 ciphers */
>> +    "KRB5-DES-CBC-SHA",                 /* TLS_KRB5_WITH_DES_CBC_SHA */
>> +    "KRB5-DES-CBC3-SHA",                /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
>> +    "KRB5-IDEA-CBC-SHA",                /* TLS_KRB5_WITH_IDEA_CBC_SHA */
>> +    "KRB5-DES-CBC-MD5",                 /* TLS_KRB5_WITH_DES_CBC_MD5 */
>> +    "KRB5-DES-CBC3-MD5",                /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
>> +    "KRB5-IDEA-CBC-MD5",                /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
>> +    "EXP-KRB5-DES-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
>> +    "EXP-KRB5-DES-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
>> +    "EXP-KRB5-RC2-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
>> +    "EXP-KRB5-RC2-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
>> +  
>> +    /* blacklisted exoticas */
>> +    "DHE-DSS-CBC-SHA",                  /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
>> +    "IDEA-CBC-SHA",                     /* TLS_RSA_WITH_IDEA_CBC_SHA */
>> +    
>> +    /* not really sure if the following names are correct */
>> +    "SSL3_CK_SCSV",                     /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
>> +    "SSL3_CK_FALLBACK_SCSV"
>> +};
>> +static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
>> +
>> +
>> +static apr_hash_t *BLCNames;
>> +
>> +static void cipher_init(apr_pool_t *pool)
>> +{
>> +    apr_hash_t *hash = apr_hash_make(pool);
>> +    const char *source;
>> +    int i;
>> +    
>> +    source = "rfc7540";
>> +    for (i = 0; i < RFC7540_names_LEN; ++i) {
>> +        apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
>> +    }
>> +    
>> +    BLCNames = hash;
>> +}
>> +
>> +static int cipher_is_blacklisted(const char *cipher, const char **psource)
>> +{   
>> +    *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
>> +    return !!*psource;
>> +}
>> +
>> +/*******************************************************************************
>> * Hooks for processing incoming connections:
>> * - pre_conn_before_tls switches SSL off for stream connections
>> * - process_conn take over connection in case of h2
>> @@ -72,12 +420,15 @@ apr_status_t h2_h2_init(apr_pool_t *pool
>>    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_h2, child_init");
>>    opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
>>    opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
>> +    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
>> 
>> -    if (!opt_ssl_is_https) {
>> +    if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
>>        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
>>                     APLOGNO(02951) "mod_ssl does not seem to be enabled");
>>    }
>> 
>> +    cipher_init(pool);
>> +    
>>    return APR_SUCCESS;
>> }
>> 
>> @@ -94,6 +445,63 @@ int h2_tls_disable(conn_rec *c)
>>    return 0;
>> }
>> 
>> +int h2_is_security_compliant(conn_rec *c, int require_all) 
>> +{
>> +    int is_tls = h2_h2_is_tls(c);
>> +    h2_config *cfg = h2_config_get(c);
>> +
>> +    if (is_tls && h2_config_geti(cfg, H2_CONF_COMPLIANCE) > 0) {
>> +        /* Check TLS connection for RFC 7540 compliance
>> +         */
>> +        apr_pool_t *pool = c->pool;
>> +        server_rec *s = c->base_server;
>> +        char *val;
>> +        
>> +        if (!opt_ssl_var_lookup) {
>> +            /* unable to check */
>> +            return 0;
>> +        }
>> +        
>> +        /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
>> +         */
>> +        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_PROTOCOL");
>> +        if (val && *val) {
>> +            if (strncmp("TLS", val, 3) 
>> +                || !strcmp("TLSv1", val) 
>> +                || !strcmp("TLSv1.1", val)) {
>> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
>> +                          "h2_h2(%ld): tls protocol not suitable: %s", 
>> +                          (long)c->id, val);
>> +                return 0;
>> +            }
>> +        }
>> +        else if (require_all) {
>> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
>> +                          "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
>> +            return 0;
>> +        }
>> +
>> +        /* Check TLS cipher blacklist
>> +         */
>> +        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_CIPHER");
>> +        if (val && *val) {
>> +            const char *source;
>> +            if (cipher_is_blacklisted(val, &source)) {
>> +                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
>> +                              "h2_h2(%ld): tls cipher %s blacklisted by %s", 
>> +                              (long)c->id, val, source);
>> +                return 0;
>> +            }
>> +        }
>> +        else if (require_all) {
>> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
>> +                          "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
>> +            return 0;
>> +        }
>> +    }
>> +    return 1;
>> +}
>> +
>> /*******************************************************************************
>> * Register various hooks
>> */
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_h2.h
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.h?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_h2.h (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_h2.h Wed Oct 14 12:10:11 2015
>> @@ -53,5 +53,16 @@ int h2_tls_disable(conn_rec *c);
>> */
>> void h2_h2_register_hooks(void);
>> 
>> +/**
>> + * Check if the given connection fulfills the security requirements
>> + * of RFC 7540.
>> + * @param c the connection
>> + * @param require_all != 0 iff any missing connection properties make
>> + *    the test fail. For example, a cipher might not have been selected while
>> + *    the handshake is still ongoing.
>> + * @return != 0 iff security requirements are met
>> + */
>> +int h2_is_security_compliant(conn_rec *c, int require_all);
>> +
>> 
>> #endif /* defined(__mod_h2__h2_h2__) */
>> 
>> Modified: httpd/httpd/trunk/modules/http2/h2_switch.c
>> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_switch.c?rev=1708593&r1=1708592&r2=1708593&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/http2/h2_switch.c (original)
>> +++ httpd/httpd/trunk/modules/http2/h2_switch.c Wed Oct 14 12:10:11 2015
>> @@ -35,24 +35,12 @@
>> #include "h2_switch.h"
>> 
>> /*******************************************************************************
>> - * SSL var lookup
>> - */
>> -APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
>> -                        (apr_pool_t *, server_rec *,
>> -                         conn_rec *, request_rec *,
>> -                         char *));
>> -static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
>> -                                   conn_rec *, request_rec *,
>> -                                   char *);
>> -
>> -/*******************************************************************************
>> * Once per lifetime init, retrieve optional functions
>> */
>> apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s)
>> {
>>    (void)pool;
>>    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_switch init");
>> -    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
>> 
>>    return APR_SUCCESS;
>> }
>> @@ -63,7 +51,8 @@ static int h2_protocol_propose(conn_rec
>>                               apr_array_header_t *proposals)
>> {
>>    int proposed = 0;
>> -    const char **protos = h2_h2_is_tls(c)? h2_tls_protos : h2_clear_protos;
>> +    int is_tls = h2_h2_is_tls(c);
>> +    const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
>> 
>>    (void)s;
>>    if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
>> @@ -74,6 +63,12 @@ static int h2_protocol_propose(conn_rec
>>        return DECLINED;
>>    }
>> 
>> +    if (!h2_is_security_compliant(c, 0)) {
>> +        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
>> +                      "protocol propose: security requirements not met, declined");
>> +        return DECLINED;
>> +    }
>> +    
>>    if (r) {
>>        const char *p;
>>        /* So far, this indicates an HTTP/1 Upgrade header initiated
>> 
>> 
>> 
> 



Re: svn commit: r1708593 - in /httpd/httpd/trunk: docs/manual/mod/mod_http2.xml modules/http2/h2_config.c modules/http2/h2_config.h modules/http2/h2_conn.c modules/http2/h2_h2.c modules/http2/h2_h2.h modules/http2/h2_switch.c

Posted by "Roy T. Fielding" <fi...@gbiv.com>.
Can you please choose a more specific directive name? Like "LimitTLSunderH2".

We don't have switches for RFC compliance. We do have switches for stupid WG political positions that contradict common sense and are not applicable to non-Internet deployments.

....Roy


> On Oct 14, 2015, at 5:10 AM, icing@apache.org wrote:
> 
> Author: icing
> Date: Wed Oct 14 12:10:11 2015
> New Revision: 1708593
> 
> URL: http://svn.apache.org/viewvc?rev=1708593&view=rev
> Log:
> mod_http2: new directive H2Compliance on/off, checking TLS protocol and cipher against RFC7540
> 
> Modified:
>    httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
>    httpd/httpd/trunk/modules/http2/h2_config.c
>    httpd/httpd/trunk/modules/http2/h2_config.h
>    httpd/httpd/trunk/modules/http2/h2_conn.c
>    httpd/httpd/trunk/modules/http2/h2_h2.c
>    httpd/httpd/trunk/modules/http2/h2_h2.h
>    httpd/httpd/trunk/modules/http2/h2_switch.c
> 
> Modified: httpd/httpd/trunk/docs/manual/mod/mod_http2.xml
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/mod_http2.xml?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/docs/manual/mod/mod_http2.xml (original)
> +++ httpd/httpd/trunk/docs/manual/mod/mod_http2.xml Wed Oct 14 12:10:11 2015
> @@ -74,11 +74,11 @@
>                 Direct communication means that if the first bytes received by the 
>                 server on a connection match the HTTP/2 preamble, the HTTP/2
>                 protocol is switched to immediately without further negotiation.
> -                This mode falls outside the RFC 7540 but has become widely implemented
> -                on cleartext ports as it is very convenient for development and testing. 
> +                This mode is defined in RFC 7540 for the cleartext (h2c) case. Its
> +                use on TLS connections is not allowed by the standard.
>             </p>
>             <p>
> -                Since this detection implies that the client will send data on
> +                Since this detection requires that the client will send data on
>                 new connection immediately, direct HTTP/2 mode is disabled by
>                 default.
>             </p>
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_config.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.c?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_config.c (original)
> +++ httpd/httpd/trunk/modules/http2/h2_config.c Wed Oct 14 12:10:11 2015
> @@ -49,6 +49,7 @@ static h2_config defconf = {
>     0,                /* serialize headers */
>     0,                /* h2 direct mode */
>     -1,               /* # session extra files */
> +    1,                /* rfc 7540 compliance */
> };
> 
> static int files_per_session = 0;
> @@ -100,6 +101,7 @@ static void *h2_config_create(apr_pool_t
>     conf->serialize_headers    = DEF_VAL;
>     conf->h2_direct            = DEF_VAL;
>     conf->session_extra_files  = DEF_VAL;
> +    conf->rfc_compliance       = DEF_VAL;
>     return conf;
> }
> 
> @@ -138,6 +140,7 @@ void *h2_config_merge(apr_pool_t *pool,
>     n->serialize_headers = H2_CONFIG_GET(add, base, serialize_headers);
>     n->h2_direct      = H2_CONFIG_GET(add, base, h2_direct);
>     n->session_extra_files = H2_CONFIG_GET(add, base, session_extra_files);
> +    n->rfc_compliance = H2_CONFIG_GET(add, base, rfc_compliance);
> 
>     return n;
> }
> @@ -162,6 +165,8 @@ int h2_config_geti(h2_config *conf, h2_c
>             return H2_CONFIG_GET(conf, &defconf, alt_svc_max_age);
>         case H2_CONF_SER_HEADERS:
>             return H2_CONFIG_GET(conf, &defconf, serialize_headers);
> +        case H2_CONF_COMPLIANCE:
> +            return H2_CONFIG_GET(conf, &defconf, rfc_compliance);
>         case H2_CONF_DIRECT:
>             return H2_CONFIG_GET(conf, &defconf, h2_direct);
>         case H2_CONF_SESSION_FILES:
> @@ -332,8 +337,25 @@ static const char *h2_conf_set_direct(cm
>     return "value must be On or Off";
> }
> 
> -#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
> +static const char *h2_conf_set_compliance(cmd_parms *parms,
> +                                          void *arg, const char *value)
> +{
> +    h2_config *cfg = h2_config_sget(parms->server);
> +    if (!strcasecmp(value, "On")) {
> +        cfg->rfc_compliance = 1;
> +        return NULL;
> +    }
> +    else if (!strcasecmp(value, "Off")) {
> +        cfg->rfc_compliance = 0;
> +        return NULL;
> +    }
> +    
> +    (void)arg;
> +    return "value must be On or Off";
> +}
> +
> 
> +#define AP_END_CMD     AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
> 
> const command_rec h2_cmds[] = {
>     AP_INIT_TAKE1("H2MaxSessionStreams", h2_conf_set_max_streams, NULL,
> @@ -354,6 +376,8 @@ const command_rec h2_cmds[] = {
>                   RSRC_CONF, "set the maximum age (in seconds) that client can rely on alt-svc information"),
>     AP_INIT_TAKE1("H2SerializeHeaders", h2_conf_set_serialize_headers, NULL,
>                   RSRC_CONF, "on to enable header serialization for compatibility"),
> +    AP_INIT_TAKE1("H2Compliance", h2_conf_set_compliance, NULL,
> +                  RSRC_CONF, "off to disable strict compliance to RFC 7540"),
>     AP_INIT_TAKE1("H2Direct", h2_conf_set_direct, NULL,
>                   RSRC_CONF, "on to enable direct HTTP/2 mode"),
>     AP_INIT_TAKE1("H2SessionExtraFiles", h2_conf_set_session_extra_files, NULL,
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_config.h
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_config.h?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_config.h (original)
> +++ httpd/httpd/trunk/modules/http2/h2_config.h Wed Oct 14 12:10:11 2015
> @@ -34,6 +34,7 @@ typedef enum {
>     H2_CONF_SER_HEADERS,
>     H2_CONF_DIRECT,
>     H2_CONF_SESSION_FILES,
> +    H2_CONF_COMPLIANCE,
> } h2_config_var_t;
> 
> /* Apache httpd module configuration for h2. */
> @@ -51,6 +52,7 @@ typedef struct h2_config {
>                                      processing, better compatibility */
>     int h2_direct;                /* if mod_h2 is active directly */
>     int session_extra_files;      /* # of extra files a session may keep open */  
> +    int rfc_compliance;           /* Comply with all aspects of RFC 7540 */  
> } h2_config;
> 
> 
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_conn.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_conn.c?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_conn.c (original)
> +++ httpd/httpd/trunk/modules/http2/h2_conn.c Wed Oct 14 12:10:11 2015
> @@ -32,6 +32,7 @@
> #include "h2_session.h"
> #include "h2_stream.h"
> #include "h2_stream_set.h"
> +#include "h2_h2.h"
> #include "h2_task.h"
> #include "h2_worker.h"
> #include "h2_workers.h"
> @@ -177,6 +178,11 @@ apr_status_t h2_conn_main(conn_rec *c)
>         return APR_EGENERAL;
>     }
> 
> +    if (!h2_is_security_compliant(c, 1)) {
> +        nghttp2_submit_goaway(session->ngh2, NGHTTP2_FLAG_NONE, 0,
> +                              NGHTTP2_INADEQUATE_SECURITY, NULL, 0);
> +    } 
> +
>     status = h2_session_process(session);
> 
>     /* Make sure this connection gets closed properly. */
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_h2.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.c?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_h2.c (original)
> +++ httpd/httpd/trunk/modules/http2/h2_h2.c Wed Oct 14 12:10:11 2015
> @@ -54,6 +54,354 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_is_http
> static int (*opt_ssl_engine_disable)(conn_rec*);
> static int (*opt_ssl_is_https)(conn_rec*);
> /*******************************************************************************
> + * SSL var lookup
> + */
> +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
> +                        (apr_pool_t *, server_rec *,
> +                         conn_rec *, request_rec *,
> +                         char *));
> +static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
> +                                   conn_rec *, request_rec *,
> +                                   char *);
> +
> +/*******************************************************************************
> + * Check connection security requirements of RFC 7540
> + */
> +
> +/*
> + * Black Listed Ciphers from RFC 7549 Appendix A
> + *
> + */
> +static const char *RFC7540_names[] = {
> +    /* ciphers with NULL encrpytion */
> +    "NULL-MD5",                         /* TLS_NULL_WITH_NULL_NULL */
> +    /* same */                          /* TLS_RSA_WITH_NULL_MD5 */
> +    "NULL-SHA",                         /* TLS_RSA_WITH_NULL_SHA */
> +    "NULL-SHA256",                      /* TLS_RSA_WITH_NULL_SHA256 */
> +    "PSK-NULL-SHA",                     /* TLS_PSK_WITH_NULL_SHA */
> +    "DHE-PSK-NULL-SHA",                 /* TLS_DHE_PSK_WITH_NULL_SHA */
> +    "RSA-PSK-NULL-SHA",                 /* TLS_RSA_PSK_WITH_NULL_SHA */
> +    "PSK-NULL-SHA256",                  /* TLS_PSK_WITH_NULL_SHA256 */
> +    "PSK-NULL-SHA384",                  /* TLS_PSK_WITH_NULL_SHA384 */
> +    "DHE-PSK-NULL-SHA256",              /* TLS_DHE_PSK_WITH_NULL_SHA256 */
> +    "DHE-PSK-NULL-SHA384",              /* TLS_DHE_PSK_WITH_NULL_SHA384 */
> +    "RSA-PSK-NULL-SHA256",              /* TLS_RSA_PSK_WITH_NULL_SHA256 */
> +    "RSA-PSK-NULL-SHA384",              /* TLS_RSA_PSK_WITH_NULL_SHA384 */
> +    "ECDH-ECDSA-NULL-SHA",              /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
> +    "ECDHE-ECDSA-NULL-SHA",             /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
> +    "ECDH-RSA-NULL-SHA",                /* TLS_ECDH_RSA_WITH_NULL_SHA */
> +    "ECDHE-RSA-NULL-SHA",               /* TLS_ECDHE_RSA_WITH_NULL_SHA */
> +    "AECDH-NULL-SHA",                   /* TLS_ECDH_anon_WITH_NULL_SHA */
> +    "ECDHE-PSK-NULL-SHA",               /* TLS_ECDHE_PSK_WITH_NULL_SHA */
> +    "ECDHE-PSK-NULL-SHA256",            /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
> +    "ECDHE-PSK-NULL-SHA384",            /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
> +    
> +    /* DES/3DES ciphers */
> +    "PSK-3DES-EDE-CBC-SHA",             /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
> +    "DHE-PSK-3DES-EDE-CBC-SHA",         /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
> +    "RSA-PSK-3DES-EDE-CBC-SHA",         /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
> +    "ECDH-ECDSA-DES-CBC3-SHA",          /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
> +    "ECDHE-ECDSA-DES-CBC3-SHA",         /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
> +    "ECDH-RSA-DES-CBC3-SHA",            /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
> +    "ECDHE-RSA-DES-CBC3-SHA",           /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
> +    "AECDH-DES-CBC3-SHA",               /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
> +    "SRP-3DES-EDE-CBC-SHA",             /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
> +    "SRP-RSA-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
> +    "SRP-DSS-3DES-EDE-CBC-SHA",         /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
> +    "ECDHE-PSK-3DES-EDE-CBC-SHA",       /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
> +    "DES-CBC-SHA",                      /* TLS_RSA_WITH_DES_CBC_SHA */
> +    "DES-CBC3-SHA",                     /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
> +    "DHE-DSS-DES-CBC3-SHA",             /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
> +    "DHE-RSA-DES-CBC-SHA",              /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
> +    "DHE-RSA-DES-CBC3-SHA",             /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
> +    "ADH-DES-CBC-SHA",                  /* TLS_DH_anon_WITH_DES_CBC_SHA */
> +    "ADH-DES-CBC3-SHA",                 /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
> +    "EXP-DH-DSS-DES-CBC-SHA",           /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
> +    "DH-DSS-DES-CBC-SHA",               /* TLS_DH_DSS_WITH_DES_CBC_SHA */
> +    "DH-DSS-DES-CBC3-SHA",              /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
> +    "EXP-DH-RSA-DES-CBC-SHA",           /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
> +    "DH-RSA-DES-CBC-SHA",               /* TLS_DH_RSA_WITH_DES_CBC_SHA */
> +    "DH-RSA-DES-CBC3-SHA",              /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
> +
> +    /* blacklisted EXPORT ciphers */
> +    "EXP-RC4-MD5",                      /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
> +    "EXP-RC2-CBC-MD5",                  /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
> +    "EXP-DES-CBC-SHA",                  /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
> +    "EXP-DHE-DSS-DES-CBC-SHA",          /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
> +    "EXP-DHE-RSA-DES-CBC-SHA",          /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
> +    "EXP-ADH-DES-CBC-SHA",              /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
> +    "EXP-ADH-RC4-MD5",                  /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
> +
> +    /* blacklisted RC4 encryption */
> +    "RC4-MD5",                          /* TLS_RSA_WITH_RC4_128_MD5 */
> +    "RC4-SHA",                          /* TLS_RSA_WITH_RC4_128_SHA */
> +    "ADH-RC4-MD5",                      /* TLS_DH_anon_WITH_RC4_128_MD5 */
> +    "KRB5-RC4-SHA",                     /* TLS_KRB5_WITH_RC4_128_SHA */
> +    "KRB5-RC4-MD5",                     /* TLS_KRB5_WITH_RC4_128_MD5 */
> +    "EXP-KRB5-RC4-SHA",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
> +    "EXP-KRB5-RC4-MD5",                 /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
> +    "PSK-RC4-SHA",                      /* TLS_PSK_WITH_RC4_128_SHA */
> +    "DHE-PSK-RC4-SHA",                  /* TLS_DHE_PSK_WITH_RC4_128_SHA */
> +    "RSA-PSK-RC4-SHA",                  /* TLS_RSA_PSK_WITH_RC4_128_SHA */
> +    "ECDH-ECDSA-RC4-SHA",               /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
> +    "ECDHE-ECDSA-RC4-SHA",              /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
> +    "ECDH-RSA-RC4-SHA",                 /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
> +    "ECDHE-RSA-RC4-SHA",                /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
> +    "AECDH-RC4-SHA",                    /* TLS_ECDH_anon_WITH_RC4_128_SHA */
> +    "ECDHE-PSK-RC4-SHA",                /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
> +
> +    /* blacklisted AES128 encrpytion ciphers */
> +    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA */
> +    "DH-DSS-AES128-SHA",                /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
> +    "DH-RSA-AES128-SHA",                /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
> +    "DHE-DSS-AES128-SHA",               /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
> +    "DHE-RSA-AES128-SHA",               /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
> +    "ADH-AES128-SHA",                   /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
> +    "AES128-SHA256",                    /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
> +    "DH-DSS-AES128-SHA256",             /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
> +    "DH-RSA-AES128-SHA256",             /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
> +    "DHE-DSS-AES128-SHA256",            /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
> +    "DHE-RSA-AES128-SHA256",            /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
> +    "ECDH-ECDSA-AES128-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
> +    "ECDHE-ECDSA-AES128-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
> +    "ECDH-RSA-AES128-SHA",              /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
> +    "ECDHE-RSA-AES128-SHA",             /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
> +    "AECDH-AES128-SHA",                 /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
> +    "ECDHE-ECDSA-AES128-SHA256",        /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
> +    "ECDH-ECDSA-AES128-SHA256",         /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
> +    "ECDHE-RSA-AES128-SHA256",          /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
> +    "ECDH-RSA-AES128-SHA256",           /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
> +    "ADH-AES128-SHA256",                /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
> +    "PSK-AES128-CBC-SHA",               /* TLS_PSK_WITH_AES_128_CBC_SHA */
> +    "DHE-PSK-AES128-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
> +    "RSA-PSK-AES128-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
> +    "PSK-AES128-CBC-SHA256",            /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
> +    "DHE-PSK-AES128-CBC-SHA256",        /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
> +    "RSA-PSK-AES128-CBC-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
> +    "ECDHE-PSK-AES128-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
> +    "ECDHE-PSK-AES128-CBC-SHA256",      /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
> +    "AES128-CCM",                       /* TLS_RSA_WITH_AES_128_CCM */
> +    "AES128-CCM8",                      /* TLS_RSA_WITH_AES_128_CCM_8 */
> +    "PSK-AES128-CCM",                   /* TLS_PSK_WITH_AES_128_CCM */
> +    "PSK-AES128-CCM8",                  /* TLS_PSK_WITH_AES_128_CCM_8 */
> +    "AES128-GCM-SHA256",                /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
> +    "DH-RSA-AES128-GCM-SHA256",         /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
> +    "DH-DSS-AES128-GCM-SHA256",         /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
> +    "ADH-AES128-GCM-SHA256",            /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
> +    "PSK-AES128-GCM-SHA256",            /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
> +    "RSA-PSK-AES128-GCM-SHA256",        /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
> +    "ECDH-ECDSA-AES128-GCM-SHA256",     /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
> +    "ECDH-RSA-AES128-GCM-SHA256",       /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
> +    "SRP-AES-128-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
> +    "SRP-RSA-AES-128-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
> +    "SRP-DSS-AES-128-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
> +    
> +    /* blacklisted AES256 encrpytion ciphers */
> +    "AES256-SHA",                       /* TLS_RSA_WITH_AES_256_CBC_SHA */
> +    "DH-DSS-AES256-SHA",                /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
> +    "DH-RSA-AES256-SHA",                /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
> +    "DHE-DSS-AES256-SHA",               /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
> +    "DHE-RSA-AES256-SHA",               /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
> +    "ADH-AES256-SHA",                   /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
> +    "AES256-SHA256",                    /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
> +    "DH-DSS-AES256-SHA256",             /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
> +    "DH-RSA-AES256-SHA256",             /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
> +    "DHE-DSS-AES256-SHA256",            /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
> +    "DHE-RSA-AES256-SHA256",            /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
> +    "ADH-AES256-SHA256",                /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
> +    "ECDH-ECDSA-AES256-SHA",            /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
> +    "ECDHE-ECDSA-AES256-SHA",           /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
> +    "ECDH-RSA-AES256-SHA",              /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
> +    "ECDHE-RSA-AES256-SHA",             /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
> +    "AECDH-AES256-SHA",                 /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
> +    "ECDHE-ECDSA-AES256-SHA384",        /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
> +    "ECDH-ECDSA-AES256-SHA384",         /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
> +    "ECDHE-RSA-AES256-SHA384",          /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
> +    "ECDH-RSA-AES256-SHA384",           /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
> +    "PSK-AES256-CBC-SHA",               /* TLS_PSK_WITH_AES_256_CBC_SHA */
> +    "DHE-PSK-AES256-CBC-SHA",           /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
> +    "RSA-PSK-AES256-CBC-SHA",           /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
> +    "PSK-AES256-CBC-SHA384",            /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
> +    "DHE-PSK-AES256-CBC-SHA384",        /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
> +    "RSA-PSK-AES256-CBC-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
> +    "ECDHE-PSK-AES256-CBC-SHA",         /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
> +    "ECDHE-PSK-AES256-CBC-SHA384",      /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
> +    "SRP-AES-256-CBC-SHA",              /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
> +    "SRP-RSA-AES-256-CBC-SHA",          /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
> +    "SRP-DSS-AES-256-CBC-SHA",          /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
> +    "AES256-CCM",                       /* TLS_RSA_WITH_AES_256_CCM */
> +    "AES256-CCM8",                      /* TLS_RSA_WITH_AES_256_CCM_8 */
> +    "PSK-AES256-CCM",                   /* TLS_PSK_WITH_AES_256_CCM */
> +    "PSK-AES256-CCM8",                  /* TLS_PSK_WITH_AES_256_CCM_8 */
> +    "AES256-GCM-SHA384",                /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
> +    "DH-RSA-AES256-GCM-SHA384",         /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
> +    "DH-DSS-AES256-GCM-SHA384",         /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
> +    "ADH-AES256-GCM-SHA384",            /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
> +    "PSK-AES256-GCM-SHA384",            /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
> +    "RSA-PSK-AES256-GCM-SHA384",        /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
> +    "ECDH-ECDSA-AES256-GCM-SHA384",     /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
> +    "ECDH-RSA-AES256-GCM-SHA384",       /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
> +    
> +    /* blacklisted CAMELLIA128 encrpytion ciphers */
> +    "CAMELLIA128-SHA",                  /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
> +    "DH-DSS-CAMELLIA128-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
> +    "DH-RSA-CAMELLIA128-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
> +    "DHE-DSS-CAMELLIA128-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
> +    "DHE-RSA-CAMELLIA128-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
> +    "ADH-CAMELLIA128-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
> +    "ECDHE-ECDSA-CAMELLIA128-SHA256",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "ECDH-ECDSA-CAMELLIA128-SHA256",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "ECDHE-RSA-CAMELLIA128-SHA256",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "ECDH-RSA-CAMELLIA128-SHA256",      /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "PSK-CAMELLIA128-SHA256",           /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "DHE-PSK-CAMELLIA128-SHA256",       /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "RSA-PSK-CAMELLIA128-SHA256",       /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "ECDHE-PSK-CAMELLIA128-SHA256",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "CAMELLIA128-GCM-SHA256",           /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "DH-RSA-CAMELLIA128-GCM-SHA256",    /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "DH-DSS-CAMELLIA128-GCM-SHA256",    /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "ADH-CAMELLIA128-GCM-SHA256",       /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "ECDH-RSA-CAMELLIA128-GCM-SHA256",  /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "PSK-CAMELLIA128-GCM-SHA256",       /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "RSA-PSK-CAMELLIA128-GCM-SHA256",   /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
> +    "CAMELLIA128-SHA256",               /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "DH-DSS-CAMELLIA128-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "DH-RSA-CAMELLIA128-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "DHE-DSS-CAMELLIA128-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "DHE-RSA-CAMELLIA128-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
> +    "ADH-CAMELLIA128-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
> +    
> +    /* blacklisted CAMELLIA256 encrpytion ciphers */
> +    "CAMELLIA256-SHA",                  /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
> +    "DH-RSA-CAMELLIA256-SHA",           /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
> +    "DH-DSS-CAMELLIA256-SHA",           /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
> +    "DHE-DSS-CAMELLIA256-SHA",          /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
> +    "DHE-RSA-CAMELLIA256-SHA",          /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
> +    "ADH-CAMELLIA256-SHA",              /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
> +    "ECDHE-ECDSA-CAMELLIA256-SHA384",   /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "ECDH-ECDSA-CAMELLIA256-SHA384",    /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "ECDHE-RSA-CAMELLIA256-SHA384",     /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "ECDH-RSA-CAMELLIA256-SHA384",      /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "PSK-CAMELLIA256-SHA384",           /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "DHE-PSK-CAMELLIA256-SHA384",       /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "RSA-PSK-CAMELLIA256-SHA384",       /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "ECDHE-PSK-CAMELLIA256-SHA384",     /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
> +    "CAMELLIA256-SHA256",               /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "DH-DSS-CAMELLIA256-SHA256",        /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "DH-RSA-CAMELLIA256-SHA256",        /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "DHE-DSS-CAMELLIA256-SHA256",       /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "DHE-RSA-CAMELLIA256-SHA256",       /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "ADH-CAMELLIA256-SHA256",           /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
> +    "CAMELLIA256-GCM-SHA384",           /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "DH-RSA-CAMELLIA256-GCM-SHA384",    /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "DH-DSS-CAMELLIA256-GCM-SHA384",    /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "ADH-CAMELLIA256-GCM-SHA384",       /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "ECDH-RSA-CAMELLIA256-GCM-SHA384",  /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "PSK-CAMELLIA256-GCM-SHA384",       /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
> +    "RSA-PSK-CAMELLIA256-GCM-SHA384",   /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
> +    
> +    /* The blacklisted ARIA encrpytion ciphers */
> +    "ARIA128-SHA256",                   /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
> +    "ARIA256-SHA384",                   /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
> +    "DH-DSS-ARIA128-SHA256",            /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
> +    "DH-DSS-ARIA256-SHA384",            /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
> +    "DH-RSA-ARIA128-SHA256",            /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
> +    "DH-RSA-ARIA256-SHA384",            /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
> +    "DHE-DSS-ARIA128-SHA256",           /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
> +    "DHE-DSS-ARIA256-SHA384",           /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
> +    "DHE-RSA-ARIA128-SHA256",           /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
> +    "DHE-RSA-ARIA256-SHA384",           /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
> +    "ADH-ARIA128-SHA256",               /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
> +    "ADH-ARIA256-SHA384",               /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
> +    "ECDHE-ECDSA-ARIA128-SHA256",       /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
> +    "ECDHE-ECDSA-ARIA256-SHA384",       /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
> +    "ECDH-ECDSA-ARIA128-SHA256",        /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
> +    "ECDH-ECDSA-ARIA256-SHA384",        /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
> +    "ECDHE-RSA-ARIA128-SHA256",         /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
> +    "ECDHE-RSA-ARIA256-SHA384",         /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
> +    "ECDH-RSA-ARIA128-SHA256",          /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
> +    "ECDH-RSA-ARIA256-SHA384",          /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
> +    "ARIA128-GCM-SHA256",               /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
> +    "ARIA256-GCM-SHA384",               /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
> +    "DH-DSS-ARIA128-GCM-SHA256",        /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
> +    "DH-DSS-ARIA256-GCM-SHA384",        /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
> +    "DH-RSA-ARIA128-GCM-SHA256",        /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
> +    "DH-RSA-ARIA256-GCM-SHA384",        /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
> +    "ADH-ARIA128-GCM-SHA256",           /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
> +    "ADH-ARIA256-GCM-SHA384",           /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
> +    "ECDH-ECDSA-ARIA128-GCM-SHA256",    /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
> +    "ECDH-ECDSA-ARIA256-GCM-SHA384",    /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
> +    "ECDH-RSA-ARIA128-GCM-SHA256",      /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
> +    "ECDH-RSA-ARIA256-GCM-SHA384",      /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
> +    "PSK-ARIA128-SHA256",               /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
> +    "PSK-ARIA256-SHA384",               /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
> +    "DHE-PSK-ARIA128-SHA256",           /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
> +    "DHE-PSK-ARIA256-SHA384",           /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
> +    "RSA-PSK-ARIA128-SHA256",           /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
> +    "RSA-PSK-ARIA256-SHA384",           /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
> +    "ARIA128-GCM-SHA256",               /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
> +    "ARIA256-GCM-SHA384",               /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
> +    "RSA-PSK-ARIA128-GCM-SHA256",       /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
> +    "RSA-PSK-ARIA256-GCM-SHA384",       /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
> +    "ECDHE-PSK-ARIA128-SHA256",         /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
> +    "ECDHE-PSK-ARIA256-SHA384",         /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
> +
> +    /* blacklisted SEED encryptions */
> +    "SEED-SHA",                         /*TLS_RSA_WITH_SEED_CBC_SHA */
> +    "DH-DSS-SEED-SHA",                  /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
> +    "DH-RSA-SEED-SHA",                  /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
> +    "DHE-DSS-SEED-SHA",                 /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
> +    "DHE-RSA-SEED-SHA",                 /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */               
> +    "ADH-SEED-SHA",                     /* TLS_DH_anon_WITH_SEED_CBC_SHA */
> +
> +    /* blacklisted KRB5 ciphers */
> +    "KRB5-DES-CBC-SHA",                 /* TLS_KRB5_WITH_DES_CBC_SHA */
> +    "KRB5-DES-CBC3-SHA",                /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
> +    "KRB5-IDEA-CBC-SHA",                /* TLS_KRB5_WITH_IDEA_CBC_SHA */
> +    "KRB5-DES-CBC-MD5",                 /* TLS_KRB5_WITH_DES_CBC_MD5 */
> +    "KRB5-DES-CBC3-MD5",                /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
> +    "KRB5-IDEA-CBC-MD5",                /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
> +    "EXP-KRB5-DES-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
> +    "EXP-KRB5-DES-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
> +    "EXP-KRB5-RC2-CBC-SHA",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
> +    "EXP-KRB5-RC2-CBC-MD5",             /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
> +  
> +    /* blacklisted exoticas */
> +    "DHE-DSS-CBC-SHA",                  /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
> +    "IDEA-CBC-SHA",                     /* TLS_RSA_WITH_IDEA_CBC_SHA */
> +    
> +    /* not really sure if the following names are correct */
> +    "SSL3_CK_SCSV",                     /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
> +    "SSL3_CK_FALLBACK_SCSV"
> +};
> +static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
> +
> +
> +static apr_hash_t *BLCNames;
> +
> +static void cipher_init(apr_pool_t *pool)
> +{
> +    apr_hash_t *hash = apr_hash_make(pool);
> +    const char *source;
> +    int i;
> +    
> +    source = "rfc7540";
> +    for (i = 0; i < RFC7540_names_LEN; ++i) {
> +        apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
> +    }
> +    
> +    BLCNames = hash;
> +}
> +
> +static int cipher_is_blacklisted(const char *cipher, const char **psource)
> +{   
> +    *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
> +    return !!*psource;
> +}
> +
> +/*******************************************************************************
>  * Hooks for processing incoming connections:
>  * - pre_conn_before_tls switches SSL off for stream connections
>  * - process_conn take over connection in case of h2
> @@ -72,12 +420,15 @@ apr_status_t h2_h2_init(apr_pool_t *pool
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_h2, child_init");
>     opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
>     opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
> +    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
> 
> -    if (!opt_ssl_is_https) {
> +    if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
>         ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
>                      APLOGNO(02951) "mod_ssl does not seem to be enabled");
>     }
> 
> +    cipher_init(pool);
> +    
>     return APR_SUCCESS;
> }
> 
> @@ -94,6 +445,63 @@ int h2_tls_disable(conn_rec *c)
>     return 0;
> }
> 
> +int h2_is_security_compliant(conn_rec *c, int require_all) 
> +{
> +    int is_tls = h2_h2_is_tls(c);
> +    h2_config *cfg = h2_config_get(c);
> +
> +    if (is_tls && h2_config_geti(cfg, H2_CONF_COMPLIANCE) > 0) {
> +        /* Check TLS connection for RFC 7540 compliance
> +         */
> +        apr_pool_t *pool = c->pool;
> +        server_rec *s = c->base_server;
> +        char *val;
> +        
> +        if (!opt_ssl_var_lookup) {
> +            /* unable to check */
> +            return 0;
> +        }
> +        
> +        /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
> +         */
> +        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_PROTOCOL");
> +        if (val && *val) {
> +            if (strncmp("TLS", val, 3) 
> +                || !strcmp("TLSv1", val) 
> +                || !strcmp("TLSv1.1", val)) {
> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
> +                          "h2_h2(%ld): tls protocol not suitable: %s", 
> +                          (long)c->id, val);
> +                return 0;
> +            }
> +        }
> +        else if (require_all) {
> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
> +                          "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
> +            return 0;
> +        }
> +
> +        /* Check TLS cipher blacklist
> +         */
> +        val = opt_ssl_var_lookup(pool, s, c, NULL, "SSL_CIPHER");
> +        if (val && *val) {
> +            const char *source;
> +            if (cipher_is_blacklisted(val, &source)) {
> +                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
> +                              "h2_h2(%ld): tls cipher %s blacklisted by %s", 
> +                              (long)c->id, val, source);
> +                return 0;
> +            }
> +        }
> +        else if (require_all) {
> +            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
> +                          "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
> +            return 0;
> +        }
> +    }
> +    return 1;
> +}
> +
> /*******************************************************************************
>  * Register various hooks
>  */
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_h2.h
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_h2.h?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_h2.h (original)
> +++ httpd/httpd/trunk/modules/http2/h2_h2.h Wed Oct 14 12:10:11 2015
> @@ -53,5 +53,16 @@ int h2_tls_disable(conn_rec *c);
>  */
> void h2_h2_register_hooks(void);
> 
> +/**
> + * Check if the given connection fulfills the security requirements
> + * of RFC 7540.
> + * @param c the connection
> + * @param require_all != 0 iff any missing connection properties make
> + *    the test fail. For example, a cipher might not have been selected while
> + *    the handshake is still ongoing.
> + * @return != 0 iff security requirements are met
> + */
> +int h2_is_security_compliant(conn_rec *c, int require_all);
> +
> 
> #endif /* defined(__mod_h2__h2_h2__) */
> 
> Modified: httpd/httpd/trunk/modules/http2/h2_switch.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/http2/h2_switch.c?rev=1708593&r1=1708592&r2=1708593&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/modules/http2/h2_switch.c (original)
> +++ httpd/httpd/trunk/modules/http2/h2_switch.c Wed Oct 14 12:10:11 2015
> @@ -35,24 +35,12 @@
> #include "h2_switch.h"
> 
> /*******************************************************************************
> - * SSL var lookup
> - */
> -APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
> -                        (apr_pool_t *, server_rec *,
> -                         conn_rec *, request_rec *,
> -                         char *));
> -static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
> -                                   conn_rec *, request_rec *,
> -                                   char *);
> -
> -/*******************************************************************************
>  * Once per lifetime init, retrieve optional functions
>  */
> apr_status_t h2_switch_init(apr_pool_t *pool, server_rec *s)
> {
>     (void)pool;
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_switch init");
> -    opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
> 
>     return APR_SUCCESS;
> }
> @@ -63,7 +51,8 @@ static int h2_protocol_propose(conn_rec
>                                apr_array_header_t *proposals)
> {
>     int proposed = 0;
> -    const char **protos = h2_h2_is_tls(c)? h2_tls_protos : h2_clear_protos;
> +    int is_tls = h2_h2_is_tls(c);
> +    const char **protos = is_tls? h2_tls_protos : h2_clear_protos;
> 
>     (void)s;
>     if (strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))) {
> @@ -74,6 +63,12 @@ static int h2_protocol_propose(conn_rec
>         return DECLINED;
>     }
> 
> +    if (!h2_is_security_compliant(c, 0)) {
> +        ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
> +                      "protocol propose: security requirements not met, declined");
> +        return DECLINED;
> +    }
> +    
>     if (r) {
>         const char *p;
>         /* So far, this indicates an HTTP/1 Upgrade header initiated
> 
> 
>