Author: mturk
Date: Thu Nov 12 10:29:34 2009
New Revision: 835322

URL: http://svn.apache.org/viewvc?rev=835322&view=rev
Log:
Port mod_ssl fix for CVE-2009-3555

Modified:
    tomcat/native/trunk/native/include/ssl_private.h
    tomcat/native/trunk/native/src/sslcontext.c
    tomcat/native/trunk/native/src/sslnetwork.c
    tomcat/native/trunk/native/src/sslutils.c

Modified: tomcat/native/trunk/native/include/ssl_private.h
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/include/ssl_private.h?rev=835322&r1=835321&r2=835322&view=diff
==============================================================================
--- tomcat/native/trunk/native/include/ssl_private.h (original)
+++ tomcat/native/trunk/native/include/ssl_private.h Thu Nov 12 10:29:34 2009
@@ -256,12 +256,29 @@
     tcn_pass_cb_t   *cb_data;
 };
 
+  
 typedef struct {
     apr_pool_t     *pool;
     tcn_ssl_ctxt_t *ctx;
     SSL            *ssl;
     X509           *peer;
     int             shutdown_type;
+    /* 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;
     apr_socket_t   *sock;
     apr_pollset_t  *pollset;
 } tcn_ssl_conn_t;
@@ -287,6 +304,7 @@
 DH         *SSL_dh_get_param_from_file(const char *);
 RSA        *SSL_callback_tmp_RSA(SSL *, int, int);
 DH         *SSL_callback_tmp_DH(SSL *, int, int);
+void        SSL_callback_handshake(const SSL *, int, int);
 void        SSL_vhost_algo_id(const unsigned char *, unsigned char *, int);
 int         SSL_CTX_use_certificate_chain(SSL_CTX *, const char *, int);
 int         SSL_callback_SSL_verify(int, X509_STORE_CTX *);

Modified: tomcat/native/trunk/native/src/sslcontext.c
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslcontext.c?rev=835322&r1=835321&r2=835322&view=diff
==============================================================================
--- tomcat/native/trunk/native/src/sslcontext.c (original)
+++ tomcat/native/trunk/native/src/sslcontext.c Thu Nov 12 10:29:34 2009
@@ -162,6 +162,7 @@
     /* Set default password callback */
     SSL_CTX_set_default_passwd_cb(c->ctx, (pem_password_cb 
*)SSL_password_callback);
     SSL_CTX_set_default_passwd_cb_userdata(c->ctx, (void 
*)(&tcn_password_callback));
+    SSL_CTX_set_info_callback(c->ctx, SSL_callback_handshake);
     /*
      * Let us cleanup the ssl context when the pool is destroyed
      */

Modified: tomcat/native/trunk/native/src/sslnetwork.c
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslnetwork.c?rev=835322&r1=835321&r2=835322&view=diff
==============================================================================
--- tomcat/native/trunk/native/src/sslnetwork.c (original)
+++ tomcat/native/trunk/native/src/sslnetwork.c Thu Nov 12 10:29:34 2009
@@ -575,6 +575,11 @@
      *  ssl->state = SSL_ST_ACCEPT
      *  SSL_do_handshake()
      */
+    
+    /* Toggle the renegotiation state to allow the new
+     * handshake to proceed.
+     */
+    con->reneg_state = RENEG_ALLOW;      
     retVal = SSL_renegotiate(con->ssl);
     if (retVal <= 0)
         return APR_EGENERAL;
@@ -603,6 +608,7 @@
         } else
             break;
     }
+    con->reneg_state = RENEG_REJECT;
    
     if (SSL_get_state(con->ssl) != SSL_ST_OK) {
         return APR_EGENERAL;

Modified: tomcat/native/trunk/native/src/sslutils.c
URL: 
http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslutils.c?rev=835322&r1=835321&r2=835322&view=diff
==============================================================================
--- tomcat/native/trunk/native/src/sslutils.c (original)
+++ tomcat/native/trunk/native/src/sslutils.c Thu Nov 12 10:29:34 2009
@@ -672,4 +672,41 @@
     return ok;
 }
 
+/*
+ * 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_handshake(const SSL *ssl, int where, int rc)
+{
+    tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
+
+    /* Retrieve the conn_rec and the associated SSLConnRec. */
+    if (con == 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) && con->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) {
+            con->reneg_state = RENEG_ABORT;
+            /* XXX: 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) && con->reneg_state == 
RENEG_INIT) {
+        con->reneg_state = RENEG_REJECT;
+    }
+
+}
+ 
 #endif



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to