From: markt Date: Tue, 10 Nov 2009 14:26:01 +0000 (+0000) Subject: Use a connector attribute rather than a system property to control renegotiation X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=3ee940beffcf43f6d4f22c2c8c2e3f0d7c46a43b;p=tomcat7.0 Use a connector attribute rather than a system property to control renegotiation Fix some trivial Eclispe warnings in the test Don't try and invalidate the session in the client - an attacker probably won't do this Add a test that checks the connector attribute can be used to enable renegotiation git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@834477 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java b/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java index 74df1d9ea..956af3e68 100644 --- a/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java +++ b/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java @@ -95,9 +95,6 @@ public class JSSESocketFactory private static final int defaultSessionCacheSize = 0; private static final int defaultSessionTimeout = 86400; - private static final boolean midmMode = - "true".equals(System.getProperty("enable_ssl_mitm_vulnerability")); - static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(JSSESocketFactory.class); @@ -105,6 +102,7 @@ public class JSSESocketFactory protected String clientAuth = "false"; protected SSLServerSocketFactory sslProxy = null; protected String[] enabledCiphers; + protected boolean enableMitmVulnerability = false; /** * Flag to state that we require client authentication. @@ -159,7 +157,7 @@ public class JSSESocketFactory SSLSocket asock = null; try { asock = (SSLSocket)socket.accept(); - if (!midmMode) { + if (!enableMitmVulnerability) { asock.addHandshakeCompletedListener( new DisableSslRenegotiation()); } @@ -492,6 +490,9 @@ public class JSSESocketFactory getEnabledCiphers(requestedCiphers, sslProxy.getSupportedCipherSuites()); + enableMitmVulnerability = + "true".equals(attributes.get("enableMitmVulnerability")); + // Check the SSL config is OK checkConfig(); diff --git a/test/org/apache/catalina/startup/TestTomcatSSL.java b/test/org/apache/catalina/startup/TestTomcatSSL.java index 4248e1a72..ed7b4fd6f 100644 --- a/test/org/apache/catalina/startup/TestTomcatSSL.java +++ b/test/org/apache/catalina/startup/TestTomcatSSL.java @@ -20,11 +20,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.security.cert.X509Certificate; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; @@ -41,12 +41,16 @@ import org.apache.tomcat.util.buf.ByteChunk; public class TestTomcatSSL extends TomcatBaseTest { static TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { - public java.security.cert.X509Certificate[] getAcceptedIssuers() { + public X509Certificate[] getAcceptedIssuers() { return null; } - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) { + public void checkClientTrusted(X509Certificate[] certs, + String authType) { + // NOOP - Trust everything } - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) { + public void checkServerTrusted(X509Certificate[] certs, + String authType) { + // NOOP - Trust everything } } }; @@ -63,10 +67,9 @@ public class TestTomcatSSL extends TomcatBaseTest { public void testSimpleSsl() throws Exception { - // Install the all-trusting trust manager so https:// works + // Install the all-trusting trust manager so https:// works // with unsigned certs. - // TODO: cleanup ? try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); @@ -91,7 +94,7 @@ public class TestTomcatSSL extends TomcatBaseTest { boolean handshakeDone = false; - public void testReHandshake() throws Exception { + public void testRenegotiateFail() throws Exception { Tomcat tomcat = getTomcatInstance(); File appDir = @@ -100,6 +103,7 @@ public class TestTomcatSSL extends TomcatBaseTest { tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); initSsl(tomcat); + // Default - MITM not enabled tomcat.start(); SSLContext sslCtx = SSLContext.getInstance("TLS"); @@ -120,8 +124,6 @@ public class TestTomcatSSL extends TomcatBaseTest { InputStream is = socket.getInputStream(); - // Doesn't seem to work.. - socket.getSession().invalidate(); socket.startHandshake(); handshakeDone = false; byte[] b = new byte[0]; @@ -137,7 +139,6 @@ public class TestTomcatSSL extends TomcatBaseTest { break; } } - SSLSession session = socket.getSession(); os = socket.getOutputStream(); try { @@ -150,4 +151,61 @@ public class TestTomcatSSL extends TomcatBaseTest { fail("Re-negotiation worked"); } + + public void testRenegotiateWorks() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = + new File("output/build/webapps/examples"); + // app dir is relative to server home + tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath()); + + initSsl(tomcat); + // Enable MITM attack + tomcat.getConnector().setAttribute("enableMitmVulnerability", "true"); + + tomcat.start(); + SSLContext sslCtx = SSLContext.getInstance("TLS"); + sslCtx.init(null, trustAllCerts, new java.security.SecureRandom()); + SSLSocketFactory socketFactory = sslCtx.getSocketFactory(); + SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", getPort()); + + socket.addHandshakeCompletedListener(new HandshakeCompletedListener() { + @Override + public void handshakeCompleted(HandshakeCompletedEvent event) { + handshakeDone = true; + } + }); + + OutputStream os = socket.getOutputStream(); + os.write("GET /examples/servlets/servlet/HelloWorldExample HTTP/1.0\n".getBytes()); + os.flush(); + + InputStream is = socket.getInputStream(); + + socket.startHandshake(); + handshakeDone = false; + byte[] b = new byte[0]; + int maxTries = 60; // 60 * 1000 = example 1 minute time out + socket.setSoTimeout(1000); + for (int i = 0; i < maxTries; i++) { + try { + is.read(b); + } catch (IOException e) { + // timeout + } + if (handshakeDone) { + break; + } + } + os = socket.getOutputStream(); + + try { + os.write("Host: localhost\n\n".getBytes()); + } catch (IOException ex) { + fail("Re-negotiation failed"); + } + + } + }