--- container/webapps/docs/changelog.xml.orig	2010-02-11 12:10:36.000000000 -0700
+++ container/webapps/docs/changelog.xml	2010-02-11 12:11:24.000000000 -0700
@@ -226,6 +226,10 @@
       <fix>
         <bug>38483</bug>: Thread safety issues in AccessLogValve classes. (kkolinko)
       </fix>
+      <fix>
+         CVE-2009-3555. Provide option to disable legacy SSL renegotiation.
+         (markt/costin)
+      </fix>
       <add>
         Allow log file encoding to be configured for JULI FileHandler. (kkolinko)
       </add>
--- container/webapps/docs/config/http.xml.orig	2010-02-11 12:12:11.000000000 -0700
+++ container/webapps/docs/config/http.xml	2010-02-11 12:15:07.000000000 -0700
@@ -493,6 +493,14 @@
       TrustStore then you are using for the KeyStore.</p>
     </attribute>
 
+    <attribute name="allowUnsafeLegacyRenegotiation" required="false">
+       <p>Is unsafe legacy TLS renegotiation allowed which is likely to 
+       expose users to CVE-2009-3555, a man-in-the-middle vulnerability
+       in the TLS protocol that allows an attacker to inject arbitrary
+       data into the user's request. If not specified, a default of
+       <code>false</code> is used.</p>
+    </attribute>
+
   </attributes>
 
   <p>For more information, see the
--- connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java.orig	2010-02-11 09:44:43.000000000 -0700
+++ connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java	2010-02-11 10:47:57.000000000 -0700
@@ -75,6 +75,8 @@
     protected String clientAuth = "false";
     protected SSLServerSocketFactory sslProxy = null;
     protected String[] enabledCiphers;
+  
+    protected boolean allowUnsafeLegacyRenegotiation = false;
    
 
     public JSSESocketFactory () {
@@ -124,6 +126,11 @@
 
     public void handshake(Socket sock) throws IOException {
         ((SSLSocket)sock).startHandshake();
+
+        if (!allowUnsafeLegacyRenegotiation) {
+           // Prevent further handshakes by removing all cipher suites
+           ((SSLSocket)sock).setEnabledCipherSuites(new String[0]);
+        }
     }
 
     /*
--- connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14Support.java.orig	2010-02-11 10:51:26.000000000 -0700
+++ connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14Support.java	2010-02-11 11:02:17.000000000 -0700
@@ -96,7 +96,9 @@
                 break;
             }
         }
-        socket.setSoTimeout(oldTimeout);
+        if(!socket.isClosed()) {
+           socket.setSoTimeout(oldTimeout);
+        }
         if (listener.completed == false) {
             throw new SocketException("SSL Cert handshake timeout");
         }
--- connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java.orig	2010-02-11 10:50:35.000000000 -0700
+++ connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE13SocketFactory.java	2010-02-11 10:54:38.000000000 -0700
@@ -129,6 +129,9 @@
             enabledCiphers = getEnabledCiphers(requestedCiphers,
                      sslProxy.getSupportedCipherSuites());
 
+            allowUnsafeLegacyRenegotiation = 
+                "true".equals(attributes.get("allowUnsafeLegacyRenegotiation"));
+
             // Check the SSL config is OK
             checkConfig();
 
--- connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java.orig	2010-02-11 10:50:57.000000000 -0700
+++ connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java	2010-02-11 10:57:02.000000000 -0700
@@ -118,7 +118,10 @@
             // Determine which cipher suites to enable
             String requestedCiphers = (String)attributes.get("ciphers");
             enabledCiphers = getEnabledCiphers(requestedCiphers,
-                                               sslProxy.getSupportedCipherSuites());
+                                     sslProxy.getSupportedCipherSuites());
+
+            allowUnsafeLegacyRenegotiation =
+               "true".equals(attributes.get("allowUnsafeLegacyRenegotiation"));
 
             // Check the SSL config is OK
             checkConfig();
