From: Rainer Jung Date: Tue, 28 Sep 2010 15:59:13 +0000 (+0000) Subject: Merge revisions 906039, 906057, 906485, 906491, 908015, 916733, 916817 X-Git-Tag: 2.0.64~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0915472c0824918e8dedcbff9d750c1d992f63a0;p=thirdparty%2Fapache%2Fhttpd.git Merge revisions 906039, 906057, 906485, 906491, 908015, 916733, 916817 from trunk resp. 917044 from 2.2.x: New releases of OpenSSL will only allow secure renegotiation by default. Add an "SSLInsecureRenegotiation" directive to enable renegotiation against unpatched clients, to ease transition. Submitted by: jorton Backport by: rjung Reviewed by: pgollucci, wrowe git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@1002233 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 8bb961296f9..d59dc5d4097 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,14 @@ Changes with Apache 2.0.64 mod_proxy_ftp: NULL pointer dereference on error paths. [Stefan Fritsch , Joe Orton] + *) SECURITY: CVE-2009-3555 (cve.mitre.org) + mod_ssl: Comprehensive fix of the TLS renegotiation prefix injection + attack when compiled against OpenSSL version 0.9.8m or later. Introduces + the 'SSLInsecureRenegotiation' directive to reopen this vulnerability + and offer unsafe legacy renegotiation with clients which do not yet + support the new secure renegotiation protocol, RFC 5746. + [Joe Orton, and with thanks to the OpenSSL Team] + *) SECURITY: CVE-2009-3555 (cve.mitre.org) mod_ssl: A partial fix for the TLS renegotiation prefix injection attack for OpenSSL versions prior to 0.9.8l; reject any client-initiated diff --git a/STATUS b/STATUS index 5ebb1eb17a0..199c0f7cb67 100644 --- a/STATUS +++ b/STATUS @@ -122,21 +122,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: Implement SSLInsecureRenegotiation - Trunk version of patch: - http://svn.apache.org/viewcvs.cgi?rev=906039&view=rev - http://svn.apache.org/viewcvs.cgi?rev=906057&view=rev - http://svn.apache.org/viewcvs.cgi?rev=906485&view=rev - http://svn.apache.org/viewcvs.cgi?rev=906491&view=rev - http://svn.apache.org/viewcvs.cgi?rev=908015&view=rev - http://svn.apache.org/viewcvs.cgi?rev=916733&view=rev - http://svn.apache.org/viewcvs.cgi?rev=916817&view=rev - Patch in 2.2.x branch: - http://svn.apache.org/viewvc?rev=917044&view=rev - Backport: - http://people.apache.org/~rjung/patches/SSLInsecureRenegotiation_httpd_2_0_x-backport-r917044.patch - +1: rjung, pgollucci (+1 2.0.64 w/ this), wrowe - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ please place SVN revisions from trunk here, so it is easy to identify exactly what the proposed changes are! Add all new diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index e09d8a856d5..8f8e21ee4fe 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -1511,4 +1511,46 @@ SSLUserName SSL_CLIENT_S_DN_CN + +SSLInsecureRenegotiation +Option to enable support for insecure renegotiation +SSLInsecureRenegotiation flag +SSLInsecureRenegotiation off +server config +virtual host +Available in httpd 2.0.64 and later, if using OpenSSL 0.9.8m or later + + +

As originally specified, all versions of the SSL and TLS protocols +(up to and including TLS/1.2) were vulnerable to a Man-in-the-Middle +attack +(CVE-2009-3555) +during a renegotiation. This vulnerability allowed an attacker to +"prefix" a chosen plaintext to the HTTP request as seen by the web +server. A protocol extension was developed which fixed this +vulnerability if supported by both client and server.

+ +

If mod_ssl is linked against OpenSSL version 0.9.8m +or later, by default renegotiation is only supported with +clients supporting the new protocol extension. If this directive is +enabled, renegotiation will be allowed with old (unpatched) clients, +albeit insecurely.

+ +Security warning +

If this directive is enabled, SSL connections will be vulnerable to +the Man-in-the-Middle prefix attack as described +in CVE-2009-3555.

+
+ +Example +SSLInsecureRenegotiation on + + +

The SSL_SECURE_RENEG environment variable can be used +from an SSI or CGI script to determine whether secure renegotiation is +supported for a given SSL connection.

+ +
+
+ diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index 557c265808d..dd22ec9a8a3 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -136,6 +136,8 @@ static const command_rec ssl_config_cmds[] = { "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)") SSL_CMD_ALL(UserName, TAKE1, "Set user name to SSL variable value") + SSL_CMD_SRV(InsecureRenegotiation, FLAG, + "Enable support for insecure renegotiation") /* * Proxy configuration for remote SSL connections diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h index 7ce2d62e011..6f69c26f390 100644 --- a/modules/ssl/mod_ssl.h +++ b/modules/ssl/mod_ssl.h @@ -496,6 +496,7 @@ struct SSLSrvConfigRec { const char *vhost_id; int vhost_id_len; int session_cache_timeout; + BOOL insecure_reneg; modssl_ctx_t *server; modssl_ctx_t *proxy; }; @@ -559,6 +560,7 @@ const char *ssl_cmd_SSLOptions(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLRequireSSL(cmd_parms *, void *); const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); +const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index 7be0bc24ee2..f597d2a483d 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -176,6 +176,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) sc->vhost_id = NULL; /* set during module init */ sc->vhost_id_len = 0; /* set during module init */ sc->session_cache_timeout = UNSET; + sc->insecure_reneg = UNSET; modssl_ctx_init_proxy(sc, p); @@ -260,6 +261,7 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) cfgMergeBool(enabled); cfgMergeBool(proxy_enabled); cfgMergeInt(session_cache_timeout); + cfgMergeBool(insecure_reneg); modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); @@ -671,6 +673,19 @@ static const char *ssl_cmd_check_file(cmd_parms *parms, } +const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag) +{ +#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + sc->insecure_reneg = flag?TRUE:FALSE; + return NULL; +#else + return "The SSLInsecureRenegotiation directive is not available " + "with this SSL library"; +#endif +} + + static const char *ssl_cmd_check_dir(cmd_parms *parms, const char **dir) { diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c index b82d02801d0..92c3395d7a1 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c @@ -365,6 +365,7 @@ static void ssl_init_ctx_protocol(server_rec *s, SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; + SSLSrvConfigRec *sc = mySrvConfig(s); /* * Create the new per-server SSL context @@ -414,6 +415,12 @@ static void ssl_init_ctx_protocol(server_rec *s, SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); } +#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION + if (sc->insecure_reneg == TRUE) { + SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); + } +#endif + SSL_CTX_set_app_data(ctx, s); /* diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 8aec2fdb317..60133f7c4ab 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -642,10 +642,17 @@ int ssl_hook_Access(request_rec *r) r->connection->keepalive = AP_CONN_CLOSE; } - /* do a full renegotiation */ - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "Performing full renegotiation: " - "complete handshake protocol"); + /* Perform a full renegotiation. */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "Performing full renegotiation: complete handshake " + "protocol (%s support secure renegotiation)", +#if defined(SSL_get_secure_renegotiation_support) + SSL_get_secure_renegotiation_support(ssl) ? + "client does" : "client does not" +#else + "server does not" +#endif + ); SSL_set_session_id_context(ssl, (unsigned char *)&id, @@ -661,6 +668,7 @@ int ssl_hook_Access(request_rec *r) if (SSL_get_state(ssl) != SSL_ST_OK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "Re-negotiation request failed"); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); r->connection->aborted = 1; return HTTP_FORBIDDEN; @@ -942,6 +950,7 @@ static const char *ssl_hook_Fixup_vars[] = { "SSL_VERSION_INTERFACE", "SSL_VERSION_LIBRARY", "SSL_PROTOCOL", + "SSL_SECURE_RENEG", "SSL_CIPHER", "SSL_CIPHER_EXPORT", "SSL_CIPHER_USEKEYSIZE", @@ -1080,6 +1089,12 @@ int ssl_hook_Fixup(request_rec *r) } } + +#ifdef SSL_get_secure_renegotiation_support + apr_table_setn(r->notes, "ssl-secure-reneg", + SSL_get_secure_renegotiation_support(ssl) ? "1" : "0"); +#endif + return DECLINED; } diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c index 9eca42afa69..661e99d8419 100644 --- a/modules/ssl/ssl_engine_vars.c +++ b/modules/ssl/ssl_engine_vars.c @@ -283,6 +283,14 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var) if ((xs = SSL_get_certificate(ssl)) != NULL) result = ssl_var_lookup_ssl_cert(p, xs, var+7); } + else if (ssl != NULL && strcEQ(var, "SECURE_RENEG")) { + int flag = 0; +#ifdef SSL_get_secure_renegotiation_support + flag = SSL_get_secure_renegotiation_support(ssl); +#endif + result = apr_pstrdup(p, flag ? "true" : "false"); + } + return result; }