[Pkg-apache-commits] r1088 - in /trunk/apache2: changelog patches/00list patches/072_CVE-2009-3555.dpatch

sf at alioth.debian.org sf at alioth.debian.org
Sat Nov 7 13:35:44 UTC 2009


Author: sf
Date: Sat Nov  7 13:35:44 2009
New Revision: 1088

URL: http://svn.debian.org/wsvn/pkg-apache/?sc=1&rev=1088
Log:
Reject any client-initiated SSL/TLS renegotiations. This is a partial fix
for the TLS renegotiation prefix injection attack (CVE-2009-3555).

Added:
    trunk/apache2/patches/072_CVE-2009-3555.dpatch
Modified:
    trunk/apache2/changelog
    trunk/apache2/patches/00list

Modified: trunk/apache2/changelog
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/changelog?rev=1088&op=diff
==============================================================================
--- trunk/apache2/changelog (original)
+++ trunk/apache2/changelog Sat Nov  7 13:35:44 2009
@@ -1,5 +1,10 @@
 apache2 (2.2.14-2) UNRELEASED; urgency=low
 
+  * Security:
+    Reject any client-initiated SSL/TLS renegotiations. This is a partial fix
+    for the TLS renegotiation prefix injection attack (CVE-2009-3555).
+    Any configuration which requires renegotiation for per-directory/location
+    access control is still vulnerable.
   * Allow RemoveType to override the types from /etc/mime.types. This allows
     to use .es and .tr for Spanish and Turkish files in mod_negotiation.
     Closes: #496080

Modified: trunk/apache2/patches/00list
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/patches/00list?rev=1088&op=diff
==============================================================================
--- trunk/apache2/patches/00list (original)
+++ trunk/apache2/patches/00list Sat Nov  7 13:35:44 2009
@@ -21,6 +21,7 @@
 069_no_deflate_for_HEAD.dpatch
 070_RemoveType_override_mime.types.dpatch
 071_fix_cacheenable.dpatch
+072_CVE-2009-3555.dpatch
 099_config_guess_sub_update
 200_cp_suexec.dpatch
 201_build_suexec-custom.dpatch

Added: trunk/apache2/patches/072_CVE-2009-3555.dpatch
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/patches/072_CVE-2009-3555.dpatch?rev=1088&op=file
==============================================================================
--- trunk/apache2/patches/072_CVE-2009-3555.dpatch (added)
+++ trunk/apache2/patches/072_CVE-2009-3555.dpatch Sat Nov  7 13:35:44 2009
@@ -1,0 +1,313 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: TLS/SSL partial fix for CVE-2009-3555
+
+ at DPATCH@
+   *) SECURITY: CVE-2009-3555 (cve.mitre.org)
+      A partial fix for the TLS renegotiation prefix injection attack by
+      rejecting any client-initiated renegotiations.  Any configuration
+      which requires renegotiation for per-directory/location access 
+      control is still vulnerable, unless using OpenSSL >= 0.9.8l.  
+      [Joe Orton, Ruediger Pluem]
+Modified: httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_init.c
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_init.c?rev=833622&r1=833621&r2=833622&view=diff
+==============================================================================
+--- 1/modules/ssl/ssl_engine_init.c (original)
++++ 1/modules/ssl/ssl_engine_init.c Sat Nov  7 00:56:23 2009
+@@ -501,10 +501,7 @@
+     SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
+     SSL_CTX_set_tmp_dh_callback(ctx,  ssl_callback_TmpDH);
+ 
+-    if (s->loglevel >= APLOG_DEBUG) {
+-        /* this callback only logs if LogLevel >= info */
+-        SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState);
+-    }
++    SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
+ }
+ 
+ static void ssl_init_ctx_verify(server_rec *s,
+
+Modified: httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_io.c
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_io.c?rev=833622&r1=833621&r2=833622&view=diff
+==============================================================================
+--- 1/modules/ssl/ssl_engine_io.c (original)
++++ 1/modules/ssl/ssl_engine_io.c Sat Nov  7 00:56:23 2009
+@@ -103,6 +103,7 @@
+     ap_filter_t        *pInputFilter;
+     ap_filter_t        *pOutputFilter;
+     int                nobuffer; /* non-zero to prevent buffering */
++    SSLConnRec         *config;
+ } ssl_filter_ctx_t;
+ 
+ typedef struct {
+@@ -193,7 +194,13 @@
+ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
+ {
+     bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr);
+-
++    
++    /* Abort early if the client has initiated a renegotiation. */
++    if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
++        outctx->rc = APR_ECONNABORTED;
++        return -1;
++    }
++    
+     /* when handshaking we'll have a small number of bytes.
+      * max size SSL will pass us here is about 16k.
+      * (16413 bytes to be exact)
+@@ -466,6 +473,12 @@
+     if (!in)
+         return 0;
+ 
++    /* Abort early if the client has initiated a renegotiation. */
++    if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
++        inctx->rc = APR_ECONNABORTED;
++        return -1;
++    }
++
+     /* XXX: flush here only required for SSLv2;
+      * OpenSSL calls BIO_flush() at the appropriate times for
+      * the other protocols.
+@@ -1724,6 +1737,8 @@
+ 
+     filter_ctx = apr_palloc(c->pool, sizeof(ssl_filter_ctx_t));
+ 
++    filter_ctx->config          = myConnConfig(c);
++
+     filter_ctx->nobuffer        = 0;
+     filter_ctx->pOutputFilter   = ap_add_output_filter(ssl_io_filter,
+                                                    filter_ctx, NULL, c);
+
+Modified: httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_kernel.c
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/ssl/ssl_engine_kernel.c?rev=833622&r1=833621&r2=833622&view=diff
+==============================================================================
+--- 1/modules/ssl/ssl_engine_kernel.c (original)
++++ 1/modules/ssl/ssl_engine_kernel.c Sat Nov  7 00:56:23 2009
+@@ -729,6 +729,10 @@
+                                        (unsigned char *)&id,
+                                        sizeof(id));
+ 
++            /* Toggle the renegotiation state to allow the new
++             * handshake to proceed. */
++            sslconn->reneg_state = RENEG_ALLOW;
++            
+             SSL_renegotiate(ssl);
+             SSL_do_handshake(ssl);
+ 
+@@ -750,6 +754,8 @@
+             SSL_set_state(ssl, SSL_ST_ACCEPT);
+             SSL_do_handshake(ssl);
+ 
++            sslconn->reneg_state = RENEG_REJECT;
++
+             if (SSL_get_state(ssl) != SSL_ST_OK) {
+                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                               "Re-negotiation handshake failed: "
+@@ -1844,76 +1850,55 @@
+     return;
+ }
+ 
+-/*
+- * This callback function is executed while OpenSSL processes the
+- * SSL handshake and does SSL record layer stuff. We use it to
+- * trace OpenSSL's processing in out SSL logfile.
+- */
+-void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc)
++/* Dump debugginfo trace to the log file. */
++static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c, 
++                              server_rec *s, int where, int rc)
+ {
+-    conn_rec *c;
+-    server_rec *s;
+-    SSLSrvConfigRec *sc;
+-
+-    /*
+-     * find corresponding server
+-     */
+-    if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) {
+-        return;
+-    }
+-
+-    s = mySrvFromConn(c);
+-    if (!(sc = mySrvConfig(s))) {
+-        return;
+-    }
+-
+     /*
+      * create the various trace messages
+      */
+-    if (s->loglevel >= APLOG_DEBUG) {
+-        if (where & SSL_CB_HANDSHAKE_START) {
+-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Handshake: start", SSL_LIBRARY_NAME);
+-        }
+-        else if (where & SSL_CB_HANDSHAKE_DONE) {
+-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Handshake: done", SSL_LIBRARY_NAME);
+-        }
+-        else if (where & SSL_CB_LOOP) {
+-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Loop: %s",
+-                         SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+-        }
+-        else if (where & SSL_CB_READ) {
++    if (where & SSL_CB_HANDSHAKE_START) {
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Handshake: start", SSL_LIBRARY_NAME);
++    }
++    else if (where & SSL_CB_HANDSHAKE_DONE) {
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Handshake: done", SSL_LIBRARY_NAME);
++    }
++    else if (where & SSL_CB_LOOP) {
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Loop: %s",
++                     SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
++    }
++    else if (where & SSL_CB_READ) {
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Read: %s",
++                     SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
++    }
++    else if (where & SSL_CB_WRITE) {
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Write: %s",
++                     SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
++    }
++    else if (where & SSL_CB_ALERT) {
++        char *str = (where & SSL_CB_READ) ? "read" : "write";
++        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
++                     "%s: Alert: %s:%s:%s",
++                     SSL_LIBRARY_NAME, str,
++                     SSL_alert_type_string_long(rc),
++                     SSL_alert_desc_string_long(rc));
++    }
++    else if (where & SSL_CB_EXIT) {
++        if (rc == 0) {
+             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Read: %s",
++                         "%s: Exit: failed in %s",
+                          SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+         }
+-        else if (where & SSL_CB_WRITE) {
++        else if (rc < 0) {
+             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Write: %s",
++                         "%s: Exit: error in %s",
+                          SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+         }
+-        else if (where & SSL_CB_ALERT) {
+-            char *str = (where & SSL_CB_READ) ? "read" : "write";
+-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                         "%s: Alert: %s:%s:%s",
+-                         SSL_LIBRARY_NAME, str,
+-                         SSL_alert_type_string_long(rc),
+-                         SSL_alert_desc_string_long(rc));
+-        }
+-        else if (where & SSL_CB_EXIT) {
+-            if (rc == 0) {
+-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                             "%s: Exit: failed in %s",
+-                             SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+-            }
+-            else if (rc < 0) {
+-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+-                             "%s: Exit: error in %s",
+-                             SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+-            }
+-        }
+     }
+ 
+     /*
+@@ -1933,6 +1918,52 @@
+     }
+ }
+ 
++/*
++ * This callback function is executed while OpenSSL processes the SSL
++ * handshake and does SSL record layer stuff.  It's used to trap
++ * client-initiated renegotiations, and for dumping everything to the
++ * log.
++ */
++void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc)
++{
++    conn_rec *c;
++    server_rec *s;
++    SSLConnRec *scr;
++
++    /* Retrieve the conn_rec and the associated SSLConnRec. */
++    if ((c = (conn_rec *)SSL_get_app_data((SSL *)ssl)) == NULL) {
++        return;
++    }
++
++    if ((scr = myConnConfig(c)) == NULL) {
++        return;
++    }
++
++    /* If the reneg state is to reject renegotiations, check the SSL
++     * state machine and move to ABORT if a Client Hello is being
++     * read. */
++    if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) {
++        int state = SSL_get_state(ssl);
++        
++        if (state == SSL3_ST_SR_CLNT_HELLO_A 
++            || state == SSL23_ST_SR_CLNT_HELLO_A) {
++            scr->reneg_state = RENEG_ABORT;
++            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
++                          "rejecting client initiated renegotiation");
++        }
++    }
++    /* If the first handshake is complete, change state to reject any
++     * subsequent client-initated renegotiation. */
++    else if ((where & SSL_CB_HANDSHAKE_DONE) && scr->reneg_state == RENEG_INIT) {
++        scr->reneg_state = RENEG_REJECT;
++    }
++
++    s = mySrvFromConn(c);
++    if (s && s->loglevel >= APLOG_DEBUG) {
++        log_tracing_state(ssl, c, s, where, rc);
++    }
++}
++
+ #ifndef OPENSSL_NO_TLSEXT
+ /*
+  * This callback function is executed when OpenSSL encounters an extended
+
+Modified: httpd/httpd/branches/2.2.x/modules/ssl/ssl_private.h
+URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/ssl/ssl_private.h?rev=833622&r1=833621&r2=833622&view=diff
+==============================================================================
+--- 1/modules/ssl/ssl_private.h (original)
++++ 1/modules/ssl/ssl_private.h Sat Nov  7 00:56:23 2009
+@@ -356,6 +356,20 @@
+     int is_proxy;
+     int disabled;
+     int non_ssl_request;
++
++    /* Track the handshake/renegotiation state for the connection so
++     * that all client-initiated renegotiations can be rejected, as a
++     * partial fix for CVE-2009-3555. */
++    enum { 
++        RENEG_INIT = 0, /* Before initial handshake */
++        RENEG_REJECT, /* After initial handshake; any client-initiated
++                       * renegotiation should be rejected */
++        RENEG_ALLOW, /* A server-initated renegotiation is taking
++                      * place (as dictated by configuration) */
++        RENEG_ABORT /* Renegotiation initiated by client, abort the
++                     * connection */
++    } reneg_state;
++    
+     server_rec *server;
+ } SSLConnRec;
+ 
+@@ -574,7 +588,7 @@
+ int          ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *);
+ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
+ void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
+-void         ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int);
++void         ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int);
+ #ifndef OPENSSL_NO_TLSEXT
+ int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
+ #endif
+
+




More information about the Pkg-apache-commits mailing list