This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 5c1b14a9e34bd965146c4941742ff6221a5110c8 Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Aug 18 21:12:50 2021 +0100 Refactor SSL tests to test both JSSE and OpenSSL implementations --- .../catalina/valves/rewrite/TestResolverSSL.java | 42 ++++++- test/org/apache/coyote/http2/TestHttp2Limits.java | 2 +- test/org/apache/coyote/http2/TestLargeUpload.java | 48 ++++++++ .../org/apache/tomcat/util/net/TestClientCert.java | 40 +++++++ .../tomcat/util/net/TestClientCertTls13.java | 52 ++++++++- .../tomcat/util/net/TestCustomSslTrustManager.java | 39 +++++++ .../tomcat/util/net/TestSSLHostConfigCompat.java | 30 +++-- .../util/net/TestSSLHostConfigIntegration.java | 39 +++++++ test/org/apache/tomcat/util/net/TestSsl.java | 84 +++++++++++-- test/org/apache/tomcat/util/net/TesterSupport.java | 46 +------- .../tomcat/util/net/openssl/TestOpenSSLConf.java | 45 +++---- .../websocket/TestWebSocketFrameClientSSL.java | 54 ++++++++- .../tomcat/websocket/TestWsWebSocketContainer.java | 42 ------- .../websocket/TestWsWebSocketContainerSSL.java | 130 +++++++++++++++++++++ 14 files changed, 551 insertions(+), 142 deletions(-) diff --git a/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java b/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java index c1bede6..e426dac 100644 --- a/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java +++ b/test/org/apache/catalina/valves/rewrite/TestResolverSSL.java @@ -18,15 +18,24 @@ package org.apache.catalina.valves.rewrite; import java.io.IOException; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import jakarta.servlet.ServletException; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.Container; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.catalina.valves.ValveBase; @@ -34,15 +43,37 @@ import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.TesterSupport; +@RunWith(Parameterized.class) public class TestResolverSSL extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testSslEnv() throws Exception { Tomcat tomcat = getTomcatInstance(); Container root = tomcat.getHost().findChild(""); root.getPipeline().addValve(new ResolverTestValve()); - // Enable session caching so the SSL Session is available when using APR + // Enable session caching so the SSL Session is available when using OpenSSL SSLHostConfig sslHostConfig = tomcat.getConnector().findSslHostConfigs()[0]; sslHostConfig.setSessionCacheSize(20 * 1024); @@ -138,5 +169,14 @@ public class TestResolverSSL extends TomcatBaseTest { TesterSupport.configureClientCertContext(tomcat); TesterSupport.configureClientSsl(); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } } } diff --git a/test/org/apache/coyote/http2/TestHttp2Limits.java b/test/org/apache/coyote/http2/TestHttp2Limits.java index bd7578c..2cc7792 100644 --- a/test/org/apache/coyote/http2/TestHttp2Limits.java +++ b/test/org/apache/coyote/http2/TestHttp2Limits.java @@ -42,7 +42,7 @@ public class TestHttp2Limits extends Http2TestBase { @Test public void testSettingsOverheadLimits() throws Exception { - http2Connect(false); + http2Connect(); for (int i = 0; i < 100; i++) { try { diff --git a/test/org/apache/coyote/http2/TestLargeUpload.java b/test/org/apache/coyote/http2/TestLargeUpload.java index 5049293..ea067d8 100644 --- a/test/org/apache/coyote/http2/TestLargeUpload.java +++ b/test/org/apache/coyote/http2/TestLargeUpload.java @@ -20,6 +20,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.concurrent.CountDownLatch; import jakarta.servlet.ServletException; @@ -27,15 +30,43 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.Context; import org.apache.catalina.LifecycleException; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.coyote.http11.AbstractHttp11Protocol; +@RunWith(Parameterized.class) public class TestLargeUpload extends Http2TestBase { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + int bodySize = 13107; int bodyCount = 5; @@ -115,4 +146,21 @@ public class TestLargeUpload extends Http2TestBase { } } } + + + @Override + public void setUp() throws Exception { + super.setUp(); + + Tomcat tomcat = getTomcatInstance(); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + } } diff --git a/test/org/apache/tomcat/util/net/TestClientCert.java b/test/org/apache/tomcat/util/net/TestClientCert.java index b759991..816500e 100644 --- a/test/org/apache/tomcat/util/net/TestClientCert.java +++ b/test/org/apache/tomcat/util/net/TestClientCert.java @@ -16,12 +16,21 @@ */ package org.apache.tomcat.util.net; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.Context; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.tomcat.util.buf.ByteChunk; @@ -31,8 +40,30 @@ import org.apache.tomcat.util.buf.ByteChunk; * generated using a test CA the files for which are in the Tomcat PMC private * repository since not all of them are AL2 licensed. */ +@RunWith(Parameterized.class) public class TestClientCert extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testClientCertGetWithoutPreemptive() throws Exception { doTestClientCertGet(false); @@ -171,5 +202,14 @@ public class TestClientCert extends TomcatBaseTest { TesterSupport.configureClientCertContext(tomcat); TesterSupport.configureClientSsl(); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } } } diff --git a/test/org/apache/tomcat/util/net/TestClientCertTls13.java b/test/org/apache/tomcat/util/net/TestClientCertTls13.java index 7444ae2..c21ae86 100644 --- a/test/org/apache/tomcat/util/net/TestClientCertTls13.java +++ b/test/org/apache/tomcat/util/net/TestClientCertTls13.java @@ -16,15 +16,24 @@ */ package org.apache.tomcat.util.net; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.jni.SSL; import org.apache.tomcat.util.buf.ByteChunk; /** @@ -36,8 +45,30 @@ import org.apache.tomcat.util.buf.ByteChunk; * initial handshake. This test requires TLSv1.3 on client and server so it is * skipped unless running on a Java version that supports TLSv1.3. */ +@RunWith(Parameterized.class) public class TestClientCertTls13 extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testClientCertGet() throws Exception { Tomcat tomcat = getTomcatInstance(); @@ -70,10 +101,23 @@ public class TestClientCertTls13 extends TomcatBaseTest { Tomcat tomcat = getTomcatInstance(); - Connector connector = tomcat.getConnector(); - Assume.assumeTrue(TesterSupport.isDefaultTLSProtocolForTesting13(connector)); - TesterSupport.configureClientCertContext(tomcat); + + TesterSupport.configureClientSsl(); + + Connector connector = tomcat.getConnector(); + Assert.assertTrue(connector.setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + // Need at least OpenSSL 1.1.1 for TLSv1.3 support + Assume.assumeTrue(SSL.version() >= 0x1010100f); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + + // Tests default to TLSv1.2 when client cert auth is used // Need to override some of the previous settings SSLHostConfig[] sslHostConfigs = connector.findSslHostConfigs(); Assert.assertNotNull(sslHostConfigs); @@ -85,7 +129,5 @@ public class TestClientCertTls13 extends TomcatBaseTest { sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1_3); // And add force authentication to occur on the initial handshake sslHostConfig.setCertificateVerification("required"); - - TesterSupport.configureClientSsl(); } } diff --git a/test/org/apache/tomcat/util/net/TestCustomSslTrustManager.java b/test/org/apache/tomcat/util/net/TestCustomSslTrustManager.java index f5d4c8d..f7ad272 100644 --- a/test/org/apache/tomcat/util/net/TestCustomSslTrustManager.java +++ b/test/org/apache/tomcat/util/net/TestCustomSslTrustManager.java @@ -17,13 +17,22 @@ package org.apache.tomcat.util.net; import java.net.SocketException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import javax.net.ssl.SSLException; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.coyote.ProtocolHandler; @@ -35,8 +44,30 @@ import org.apache.tomcat.util.buf.ByteChunk; * generated using a test CA the files for which are in the Tomcat PMC private * repository since not all of them are AL2 licensed. */ +@RunWith(Parameterized.class) public class TestCustomSslTrustManager extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + private enum TrustType { ALL, CA, @@ -66,6 +97,14 @@ public class TestCustomSslTrustManager extends TomcatBaseTest { TesterSupport.configureClientCertContext(tomcat); Connector connector = tomcat.getConnector(); + Assert.assertTrue(connector.setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } // Override the defaults ProtocolHandler handler = connector.getProtocolHandler(); diff --git a/test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java b/test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java index 7e35c8e..30647e0 100644 --- a/test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java +++ b/test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java @@ -51,11 +51,10 @@ public class TestSSLHostConfigCompat extends TomcatBaseTest { List<Object[]> parameterSets = new ArrayList<>(); for (StoreType storeType : new StoreType[] { StoreType.KEYSTORE, StoreType.PEM } ) { - parameterSets.add(new Object[] {"NIO-JSSE", "org.apache.coyote.http11.Http11NioProtocol", - "org.apache.tomcat.util.net.jsse.JSSEImplementation", storeType}); - - parameterSets.add(new Object[] {"NIO-OpenSSL", "org.apache.coyote.http11.Http11NioProtocol", - "org.apache.tomcat.util.net.openssl.OpenSSLImplementation", storeType}); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation", storeType}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation", storeType}); } return parameterSets; @@ -65,7 +64,7 @@ public class TestSSLHostConfigCompat extends TomcatBaseTest { public String connectorName; @Parameter(1) - public String protocolName; + public boolean needApr; @Parameter(2) public String sslImplementationName; @@ -301,18 +300,9 @@ public class TestSSLHostConfigCompat extends TomcatBaseTest { @Override - protected String getProtocol() { - return protocolName; - } - - - @Override public void setUp() throws Exception { super.setUp(); - AprLifecycleListener listener = new AprLifecycleListener(); - Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); - Tomcat tomcat = getTomcatInstance(); Connector connector = tomcat.getConnector(); @@ -323,8 +313,14 @@ public class TestSSLHostConfigCompat extends TomcatBaseTest { sslHostConfig.setProtocols("TLSv1.2"); connector.addSslHostConfig(sslHostConfig); - StandardServer server = (StandardServer) tomcat.getServer(); - server.addLifecycleListener(listener); + Assert.assertTrue(connector.setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } // Simple webapp Context ctxt = tomcat.addContext("", null); diff --git a/test/org/apache/tomcat/util/net/TestSSLHostConfigIntegration.java b/test/org/apache/tomcat/util/net/TestSSLHostConfigIntegration.java index cfadc80..34d4f5c 100644 --- a/test/org/apache/tomcat/util/net/TestSSLHostConfigIntegration.java +++ b/test/org/apache/tomcat/util/net/TestSSLHostConfigIntegration.java @@ -18,17 +18,48 @@ package org.apache.tomcat.util.net; import java.io.File; import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; import org.apache.tomcat.websocket.server.WsContextListener; +@RunWith(Parameterized.class) public class TestSSLHostConfigIntegration extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testSslHostConfigIsSerializable() throws Exception { Tomcat tomcat = getTomcatInstance(); @@ -39,6 +70,14 @@ public class TestSSLHostConfigIntegration extends TomcatBaseTest { ctxt.addApplicationListener(WsContextListener.class.getName()); TesterSupport.initSsl(tomcat); + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } tomcat.start(); diff --git a/test/org/apache/tomcat/util/net/TestSsl.java b/test/org/apache/tomcat/util/net/TestSsl.java index d7881cf..3ab33e3 100644 --- a/test/org/apache/tomcat/util/net/TestSsl.java +++ b/test/org/apache/tomcat/util/net/TestSsl.java @@ -23,7 +23,10 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; @@ -42,9 +45,15 @@ import jakarta.servlet.http.HttpServletResponse; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.Context; import org.apache.catalina.Wrapper; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.TesterServlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; @@ -56,8 +65,30 @@ import org.apache.tomcat.websocket.server.WsContextListener; * generated using a test CA the files for which are in the Tomcat PMC private * repository since not all of them are AL2 licensed. */ +@RunWith(Parameterized.class) public class TestSsl extends TomcatBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testSimpleSsl() throws Exception { TesterSupport.configureClientSsl(); @@ -70,6 +101,14 @@ public class TestSsl extends TomcatBaseTest { ctxt.addApplicationListener(WsContextListener.class.getName()); TesterSupport.initSsl(tomcat); + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } tomcat.start(); ByteChunk res = getUrl("https://localhost:" + getPort() + @@ -93,8 +132,17 @@ public class TestSsl extends TomcatBaseTest { Tomcat tomcat = getTomcatInstance(); TesterSupport.initSsl(tomcat); + Connector connector = tomcat.getConnector(); // Increase timeout as default (3s) can be too low for some CI systems - Assert.assertTrue(tomcat.getConnector().setProperty("connectionTimeout", "20000")); + Assert.assertTrue(connector.setProperty("connectionTimeout", "20000")); + Assert.assertTrue(connector.setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } Context ctxt = tomcat.addContext("", null); Tomcat.addServlet(ctxt, "post", new SimplePostServlet()); @@ -178,6 +226,15 @@ public class TestSsl extends TomcatBaseTest { TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS, TesterSupport.JKS_PASS, TesterSupport.JKS_KEY_PASS); + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + tomcat.start(); ByteChunk res = getUrl("https://localhost:" + getPort() + "/examples/servlets/servlet/HelloWorldExample"); @@ -191,28 +248,35 @@ public class TestSsl extends TomcatBaseTest { public void testRenegotiateWorks() throws Exception { Tomcat tomcat = getTomcatInstance(); + TesterSupport.initSsl(tomcat); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + Assume.assumeTrue("SSL renegotiation has to be supported for this test", TesterSupport.isClientRenegotiationSupported(getTomcatInstance())); + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + Context root = tomcat.addContext("", TEMP_DIR); Wrapper w = Tomcat.addServlet(root, "tester", new TesterServlet()); w.setAsyncSupported(true); root.addServletMappingDecoded("/", "tester"); - TesterSupport.initSsl(tomcat); tomcat.start(); SSLContext sslCtx; - if (TesterSupport.isDefaultTLSProtocolForTesting13(tomcat.getConnector())) { - // Force TLS 1.2 if TLS 1.3 is available as JSSE's TLS 1.3 - // implementation doesn't support Post Handshake Authentication - // which is required for this test to pass. - sslCtx = SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_2); - } else { - sslCtx = SSLContext.getInstance(Constants.SSL_PROTO_TLS); - } + // Force TLS 1.2 if TLS 1.3 is available as JSSE's TLS 1.3 + // implementation doesn't support Post Handshake Authentication + // which is required for this test to pass. + sslCtx = SSLContext.getInstance(Constants.SSL_PROTO_TLSv1_2); + sslCtx.init(null, TesterSupport.getTrustManagers(), null); SSLSocketFactory socketFactory = sslCtx.getSocketFactory(); SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", diff --git a/test/org/apache/tomcat/util/net/TesterSupport.java b/test/org/apache/tomcat/util/net/TesterSupport.java index 8ac02c3..02b0268 100644 --- a/test/org/apache/tomcat/util/net/TesterSupport.java +++ b/test/org/apache/tomcat/util/net/TesterSupport.java @@ -60,11 +60,11 @@ import org.apache.catalina.startup.Tomcat; import org.apache.tomcat.jni.Library; import org.apache.tomcat.jni.LibraryNotFoundError; import org.apache.tomcat.jni.SSL; -import org.apache.tomcat.util.compat.JrePlatform; import org.apache.tomcat.util.descriptor.web.LoginConfig; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type; +import org.apache.tomcat.util.net.jsse.JSSEImplementation; public final class TesterSupport { @@ -220,14 +220,10 @@ public final class TesterSupport { } protected static boolean isClientRenegotiationSupported(Tomcat tomcat) { - String protocol = tomcat.getConnector().getProtocolHandlerClassName(); - if (protocol.contains("NioProtocol") || (protocol.contains("Nio2Protocol") && JrePlatform.IS_MAC_OS)) { - // Doesn't work on all platforms - see BZ 56448. - return false; - } - String sslImplementation = System.getProperty("tomcat.test.sslImplementation"); - if (sslImplementation != null && !"${test.sslImplementation}".equals(sslImplementation)) { - // Assume custom SSL is not supporting this + // Disabled for Tomcat Native (part if response to CVE-2009-3555) + // Only JRE provided JSSE implementation supports this + String sslImplementation = (String) tomcat.getConnector().getProperty("sslImplementationName"); + if (!JSSEImplementation.class.getName().equals(sslImplementation)) { return false; } @@ -642,36 +638,4 @@ public final class TesterSupport { return socket; } } - - - /* - * We want to use TLS 1.3 where we can but this requires TLS 1.3 to be - * supported on the client and the server. - */ - public static String getDefaultTLSProtocolForTesting(Connector connector) { - // Clients always use JSSE - if (!TLSV13_AVAILABLE) { - // Client doesn't support TLS 1.3 so we have to use TLS 1.2 - return Constants.SSL_PROTO_TLSv1_2; - } - - if (connector.getProtocolHandlerClassName().contains("Apr")) { - // APR connector so OpenSSL is used for TLS. - if (SSL.version() >= 0x1010100f) { - return Constants.SSL_PROTO_TLSv1_3; - } else { - return Constants.SSL_PROTO_TLSv1_2; - } - } else { - // NIO or NIO2. Tests do not use JSSE+OpenSSL so JSSE will be used. - // Due to check above, it is known that TLS 1.3 is available - return Constants.SSL_PROTO_TLSv1_3; - } - } - - - public static boolean isDefaultTLSProtocolForTesting13(Connector connector) { - return Constants.SSL_PROTO_TLSv1_3.equals( - TesterSupport.getDefaultTLSProtocolForTesting(connector)); - } } diff --git a/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java b/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java index 3eb1f7a..06c80ab 100644 --- a/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java +++ b/test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java @@ -27,6 +27,9 @@ import org.junit.Assert; import org.junit.Assume; import org.junit.Test; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.tomcat.jni.SSLContext; @@ -49,19 +52,16 @@ public class TestOpenSSLConf extends TomcatBaseTest { return OPENSSL_VERSION >= OPENSSL_TLS13_SUPPORT_MIN_VERSION; } - public SSLHostConfig initOpenSSLConfCmd(String... commands) throws Exception { + private SSLHostConfig initOpenSSLConfCmd(String... commands) throws Exception { Assert.assertNotNull(commands); Assert.assertTrue("Invalid length", commands.length % 2 == 0); Tomcat tomcat = getTomcatInstance(); + Connector connector = tomcat.getConnector(); TesterSupport.initSsl(tomcat); - // The tests are only supported for OpenSSL - String sslImplementation = String.valueOf( - tomcat.getConnector().getProperty("sslImplementationName")); - Assume.assumeTrue("This test is only for OpenSSL based SSL connectors", - sslImplementation.contains("openssl")); + Assert.assertTrue(connector.setProperty("sslImplementationName", OpenSSLImplementation.class.getName())); OpenSSLConf conf = new OpenSSLConf(); for (int i = 0; i < commands.length;) { @@ -71,26 +71,19 @@ public class TestOpenSSLConf extends TomcatBaseTest { conf.addCmd(cmd); } - SSLHostConfig[] sslHostConfigs = tomcat.getConnector(). - getProtocolHandler().findSslHostConfigs(); + SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length); sslHostConfigs[0].setOpenSslConf(conf); tomcat.start(); - sslHostConfigs = tomcat.getConnector().getProtocolHandler().findSslHostConfigs(); + sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length); return sslHostConfigs[0]; } @Test public void testOpenSSLConfCmdCipher() throws Exception { - if (TesterSupport.isOpensslAvailable()) { - log.info("Found OpenSSL version 0x" + Integer.toHexString(OPENSSL_VERSION)); - } else { - log.warn("OpenSSL not found: " + TesterSupport.OPENSSL_ERROR); - } - SSLHostConfig sslHostConfig; if (hasTLS13()) { // Ensure TLSv1.3 ciphers aren't returned @@ -109,12 +102,6 @@ public class TestOpenSSLConf extends TomcatBaseTest { @Test public void testOpenSSLConfCmdProtocol() throws Exception { - if (TesterSupport.isOpensslAvailable()) { - log.info("Found OpenSSL version 0x" + Integer.toHexString(OPENSSL_VERSION)); - } else { - log.warn("OpenSSL not found: " + TesterSupport.OPENSSL_ERROR); - } - Set<String> disabledProtocols = new HashSet<>(Arrays.asList(DISABLED_PROTOCOLS)); StringBuilder sb = new StringBuilder(); for (String protocol : DISABLED_PROTOCOLS) { @@ -142,4 +129,20 @@ public class TestOpenSSLConf extends TomcatBaseTest { enabledProtocols.contains(protocol)); } } + + + @Override + public void setUp() throws Exception { + super.setUp(); + + // Tests are only intended for OpenSSL + Assume.assumeTrue(TesterSupport.isOpensslAvailable()); + + Tomcat tomcat = getTomcatInstance(); + + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } } diff --git a/test/org/apache/tomcat/websocket/TestWebSocketFrameClientSSL.java b/test/org/apache/tomcat/websocket/TestWebSocketFrameClientSSL.java index be84b5e..36751f4 100644 --- a/test/org/apache/tomcat/websocket/TestWebSocketFrameClientSSL.java +++ b/test/org/apache/tomcat/websocket/TestWebSocketFrameClientSSL.java @@ -17,6 +17,9 @@ package org.apache.tomcat.websocket; import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Queue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -28,9 +31,15 @@ import jakarta.websocket.Session; import jakarta.websocket.WebSocketContainer; import org.junit.Assert; +import org.junit.Assume; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; import org.apache.catalina.Context; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; import org.apache.catalina.servlets.DefaultServlet; import org.apache.catalina.startup.Tomcat; import org.apache.tomcat.util.net.TesterSupport; @@ -38,8 +47,30 @@ import org.apache.tomcat.websocket.TesterMessageCountClient.BasicText; import org.apache.tomcat.websocket.TesterMessageCountClient.SleepingText; import org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint; +@RunWith(Parameterized.class) public class TestWebSocketFrameClientSSL extends WebSocketBaseTest { + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + @Test public void testConnectToServerEndpoint() throws Exception { Tomcat tomcat = getTomcatInstance(); @@ -49,8 +80,6 @@ public class TestWebSocketFrameClientSSL extends WebSocketBaseTest { Tomcat.addServlet(ctx, "default", new DefaultServlet()); ctx.addServletMappingDecoded("/", "default"); - TesterSupport.initSsl(tomcat); - tomcat.start(); WebSocketContainer wsContainer = @@ -96,8 +125,6 @@ public class TestWebSocketFrameClientSSL extends WebSocketBaseTest { Tomcat.addServlet(ctx, "default", new DefaultServlet()); ctx.addServletMappingDecoded("/", "default"); - TesterSupport.initSsl(tomcat); - tomcat.start(); WebSocketContainer wsContainer = @@ -150,4 +177,23 @@ public class TestWebSocketFrameClientSSL extends WebSocketBaseTest { // Close the client session. wsSession.close(); } + + + @Override + public void setUp() throws Exception { + super.setUp(); + + Tomcat tomcat = getTomcatInstance(); + + TesterSupport.initSsl(tomcat); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + } } diff --git a/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java b/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java index df5a2db..347fa20 100644 --- a/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java +++ b/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java @@ -50,7 +50,6 @@ import org.junit.Test; import org.apache.catalina.Context; import org.apache.catalina.servlets.DefaultServlet; import org.apache.catalina.startup.Tomcat; -import org.apache.tomcat.util.net.TesterSupport; import org.apache.tomcat.websocket.TesterMessageCountClient.BasicBinary; import org.apache.tomcat.websocket.TesterMessageCountClient.BasicHandler; import org.apache.tomcat.websocket.TesterMessageCountClient.BasicText; @@ -895,47 +894,6 @@ public class TestWsWebSocketContainer extends WebSocketBaseTest { @Test - public void testConnectToServerEndpointSSL() throws Exception { - - Tomcat tomcat = getTomcatInstance(); - // No file system docBase required - Context ctx = tomcat.addContext("", null); - ctx.addApplicationListener(TesterEchoServer.Config.class.getName()); - Tomcat.addServlet(ctx, "default", new DefaultServlet()); - ctx.addServletMappingDecoded("/", "default"); - - TesterSupport.initSsl(tomcat); - - tomcat.start(); - - WebSocketContainer wsContainer = - ContainerProvider.getWebSocketContainer(); - ClientEndpointConfig clientEndpointConfig = - ClientEndpointConfig.Builder.create().build(); - clientEndpointConfig.getUserProperties().put( - org.apache.tomcat.websocket.Constants.SSL_TRUSTSTORE_PROPERTY, - TesterSupport.CA_JKS); - Session wsSession = wsContainer.connectToServer( - TesterProgrammaticEndpoint.class, - clientEndpointConfig, - new URI("wss://" + getHostName() + ":" + getPort() + - TesterEchoServer.Config.PATH_ASYNC)); - CountDownLatch latch = new CountDownLatch(1); - BasicText handler = new BasicText(latch); - wsSession.addMessageHandler(handler); - wsSession.getBasicRemote().sendText(MESSAGE_STRING_1); - - boolean latchResult = handler.getLatch().await(10, TimeUnit.SECONDS); - - Assert.assertTrue(latchResult); - - Queue<String> messages = handler.getMessages(); - Assert.assertEquals(1, messages.size()); - Assert.assertEquals(MESSAGE_STRING_1, messages.peek()); - } - - - @Test public void testMaxMessageSize01() throws Exception { doMaxMessageSize(TesterEchoServer.Config.PATH_BASIC_LIMIT_LOW, TesterEchoServer.BasicLimitLow.MAX_SIZE - 1, true); diff --git a/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSSL.java b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSSL.java new file mode 100644 index 0000000..12e4a4f --- /dev/null +++ b/test/org/apache/tomcat/websocket/TestWsWebSocketContainerSSL.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.websocket; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; + +import org.apache.catalina.Context; +import org.apache.catalina.core.AprLifecycleListener; +import org.apache.catalina.core.StandardServer; +import org.apache.catalina.servlets.DefaultServlet; +import org.apache.catalina.startup.Tomcat; +import org.apache.tomcat.util.net.TesterSupport; +import org.apache.tomcat.websocket.TesterMessageCountClient.BasicText; +import org.apache.tomcat.websocket.TesterMessageCountClient.TesterProgrammaticEndpoint; + +@RunWith(Parameterized.class) +public class TestWsWebSocketContainerSSL extends WebSocketBaseTest { + + @Parameterized.Parameters(name = "{0}") + public static Collection<Object[]> parameters() { + List<Object[]> parameterSets = new ArrayList<>(); + parameterSets.add(new Object[] { + "JSSE", Boolean.FALSE, "org.apache.tomcat.util.net.jsse.JSSEImplementation"}); + parameterSets.add(new Object[] { + "OpenSSL", Boolean.TRUE, "org.apache.tomcat.util.net.openssl.OpenSSLImplementation"}); + + return parameterSets; + } + + @Parameter(0) + public String connectorName; + + @Parameter(1) + public boolean needApr; + + @Parameter(2) + public String sslImplementationName; + + + private static final String MESSAGE_STRING_1 = "qwerty"; + + @Test + public void testConnectToServerEndpointSSL() throws Exception { + + Tomcat tomcat = getTomcatInstance(); + // No file system docBase required + Context ctx = tomcat.addContext("", null); + ctx.addApplicationListener(TesterEchoServer.Config.class.getName()); + Tomcat.addServlet(ctx, "default", new DefaultServlet()); + ctx.addServletMappingDecoded("/", "default"); + + tomcat.start(); + + WebSocketContainer wsContainer = + ContainerProvider.getWebSocketContainer(); + ClientEndpointConfig clientEndpointConfig = + ClientEndpointConfig.Builder.create().build(); + clientEndpointConfig.getUserProperties().put( + org.apache.tomcat.websocket.Constants.SSL_TRUSTSTORE_PROPERTY, + TesterSupport.CA_JKS); + Session wsSession = wsContainer.connectToServer( + TesterProgrammaticEndpoint.class, + clientEndpointConfig, + new URI("wss://localhost:" + getPort() + + TesterEchoServer.Config.PATH_ASYNC)); + CountDownLatch latch = new CountDownLatch(1); + BasicText handler = new BasicText(latch); + wsSession.addMessageHandler(handler); + wsSession.getBasicRemote().sendText(MESSAGE_STRING_1); + + boolean latchResult = handler.getLatch().await(10, TimeUnit.SECONDS); + + Assert.assertTrue(latchResult); + + Queue<String> messages = handler.getMessages(); + Assert.assertEquals(1, messages.size()); + Assert.assertEquals(MESSAGE_STRING_1, messages.peek()); + } + + + @Override + public void setUp() throws Exception { + super.setUp(); + + Tomcat tomcat = getTomcatInstance(); + + TesterSupport.initSsl(tomcat); + + Assert.assertTrue(tomcat.getConnector().setProperty("sslImplementationName", sslImplementationName)); + + if (needApr) { + AprLifecycleListener listener = new AprLifecycleListener(); + Assume.assumeTrue(AprLifecycleListener.isAprAvailable()); + StandardServer server = (StandardServer) tomcat.getServer(); + server.addLifecycleListener(listener); + } + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org