--- httpd-2.4.4/modules/ssl/mod_ssl.c 2012-12-11 09:55:03.000000000 +0000 +++ httpd-2.4.4/modules/ssl/mod_ssl.c 2013-06-23 16:20:35.000000000 +0100 @@ -138,6 +138,8 @@ "('[+-][" SSL_PROTOCOLS "] ...' - see manual)") SSL_CMD_SRV(HonorCipherOrder, FLAG, "Use the server's cipher ordering preference") + SSL_CMD_SRV(EnableEmptyFragments, FLAG, + "Enable countermeasure against SSL3.0/TLS1.0 protocol vulnerability") SSL_CMD_SRV(Compression, FLAG, "Enable SSL level compression" "(`on', `off')") --- httpd-2.4.4/modules/ssl/ssl_engine_config.c 2012-12-11 09:55:03.000000000 +0000 +++ httpd-2.4.4/modules/ssl/ssl_engine_config.c 2013-06-23 18:29:34.000000000 +0100 @@ -204,6 +204,7 @@ sc->vhost_id_len = 0; /* set during module init */ sc->session_cache_timeout = UNSET; sc->cipher_server_pref = UNSET; + sc->enable_empty_fragments = UNSET; sc->insecure_reneg = UNSET; sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET; sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET; @@ -333,6 +334,7 @@ cfgMergeBool(proxy_enabled); cfgMergeInt(session_cache_timeout); cfgMergeBool(cipher_server_pref); + cfgMergeBool(enable_empty_fragments); cfgMergeBool(insecure_reneg); cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET); cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET); @@ -708,6 +710,19 @@ #endif } +const char *ssl_cmd_SSLEnableEmptyFragments(cmd_parms *cmd, + void *dcfg, int flag) +{ +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + sc->enable_empty_fragments = flag?TRUE:FALSE; + return NULL; +#else + return "SSLEnableEmptyFragments unsupported; " + "not implemented by the SSL library"; +#endif +} + const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag) { #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION --- httpd-2.4.4/modules/ssl/ssl_engine_init.c 2012-12-11 09:55:03.000000000 +0000 +++ httpd-2.4.4/modules/ssl/ssl_engine_init.c 2013-06-23 18:10:10.000000000 +0100 @@ -571,6 +571,7 @@ char *cp; int protocol = mctx->protocol; SSLSrvConfigRec *sc = mySrvConfig(s); + long ssl_initial_options; /* * Create the new per-server SSL context @@ -625,7 +626,25 @@ mctx->ssl_ctx = ctx; - SSL_CTX_set_options(ctx, SSL_OP_ALL); + /* We can not rely on SSL_CTX_clear_options being available, + so we unset from SSL_OP_ALL before we call SSL_CTX_set_options */ + /* Use a generic variable in case we ever wish to unmask other options */ + ssl_initial_options = SSL_OP_ALL; +#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + /* We check TRUE and FALSE as the default is UNSET, in which case + no manipulation of the default SSL_OP_ALL bits is done */ + if (sc->enable_empty_fragments == TRUE) { + /* we must UNSET the "DONT_INSERT" bit to enable empty fragments */ + ssl_initial_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + } + else if (sc->enable_empty_fragments == FALSE) { + /* we SET the "DONT_INSERT" bit to disable empty fragments */ + /* This is redundant, as this bit is SET in SSL_OP_ALL + however it could be removed in the future */ + ssl_initial_options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + } +#endif + SSL_CTX_set_options(ctx, ssl_initial_options); /* always disable SSLv2, as per RFC 6176 */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); --- httpd-2.4.4/modules/ssl/ssl_private.h 2012-12-11 09:55:03.000000000 +0000 +++ httpd-2.4.4/modules/ssl/ssl_private.h 2013-06-23 16:26:47.000000000 +0100 @@ -682,6 +682,7 @@ int vhost_id_len; int session_cache_timeout; BOOL cipher_server_pref; + BOOL enable_empty_fragments; BOOL insecure_reneg; modssl_ctx_t *server; modssl_ctx_t *proxy; @@ -750,6 +751,7 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag); +const char *ssl_cmd_SSLEnableEmptyFragments(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag); const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);