This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
/*
* 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.util.net;
import org.junit.Assert;
import org.junit.Test;
/**
* Mostly examples from RFC 5952
*/
public class IPv6UtilsTest {
@Test
public void testMayBeIPv6Address() {
Assert.assertFalse(IPv6Utils.mayBeIPv6Address(null));
Assert.assertTrue(IPv6Utils.mayBeIPv6Address("::1"));
Assert.assertTrue(IPv6Utils.mayBeIPv6Address("::"));
Assert.assertTrue(IPv6Utils.mayBeIPv6Address("2001:db8:0:0:1:0:0:1"));
Assert.assertFalse(IPv6Utils.mayBeIPv6Address(""));
Assert.assertFalse(IPv6Utils.mayBeIPv6Address(":1"));
Assert.assertFalse(IPv6Utils.mayBeIPv6Address("123.123.123.123"));
Assert.assertFalse(IPv6Utils.mayBeIPv6Address("tomcat.eu.apache.org:443"));
}
@Test
public void testCanonize() {
Assert.assertNull(IPv6Utils.canonize(null));
Assert.assertEquals("", IPv6Utils.canonize(""));
// IPv4-safe
Assert.assertEquals("123.123.123.123", IPv6Utils.canonize("123.123.123.123"));
Assert.assertEquals("123.1.2.23", IPv6Utils.canonize("123.1.2.23"));
// Introductory RFC 5952 examples
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8:0:0:1:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:0db8:0:0:1:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8::1:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8::0:1:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:0db8::1:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8:0:0:1::1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8:0000:0:1::1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:DB8:0:0:1::1"));
// Strip leading zeros (2.1)
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:001"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:01"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:1"));
// Zero compression (2.2)
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:0:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd::1"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:0:1", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:0:1"));
Assert.assertEquals("2001:db8::1", IPv6Utils.canonize("2001:db8:0:0:0::1"));
Assert.assertEquals("2001:db8::1", IPv6Utils.canonize("2001:db8:0:0::1"));
Assert.assertEquals("2001:db8::1", IPv6Utils.canonize("2001:db8:0::1"));
Assert.assertEquals("2001:db8::1", IPv6Utils.canonize("2001:db8::1"));
Assert.assertEquals("2001:db8::aaaa:0:0:1", IPv6Utils.canonize("2001:db8::aaaa:0:0:1"));
Assert.assertEquals("2001:db8::aaaa:0:0:1", IPv6Utils.canonize("2001:db8:0:0:aaaa::1"));
// Uppercase or lowercase (2.3)
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA"));
Assert.assertEquals("2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa", IPv6Utils.canonize("2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa"));
// Some more zero compression for localhost addresses
Assert.assertEquals("::1", IPv6Utils.canonize("0:0:0:0:0:0:0:1"));
Assert.assertEquals("::1", IPv6Utils.canonize("0000:0:0:0:0:0:0:0001"));
Assert.assertEquals("::1", IPv6Utils.canonize("00:00:0:0:00:00:0:01"));
Assert.assertEquals("::1", IPv6Utils.canonize("::0001"));
Assert.assertEquals("::1", IPv6Utils.canonize("::1"));
// IPv6 unspecified address
Assert.assertEquals("::", IPv6Utils.canonize("0:0:0:0:0:0:0:0"));
Assert.assertEquals("::", IPv6Utils.canonize("0000:0:0:0:0:0:0:0000"));
Assert.assertEquals("::", IPv6Utils.canonize("00:00:0:0:00:00:0:00"));
Assert.assertEquals("::", IPv6Utils.canonize("::0000"));
Assert.assertEquals("::", IPv6Utils.canonize("::0"));
Assert.assertEquals("::", IPv6Utils.canonize("::"));
// Leading zeros (4.1)
Assert.assertEquals("2001:db8::1", IPv6Utils.canonize("2001:0db8::0001"));
// Shorten as much as possible (4.2.1)
Assert.assertEquals("2001:db8::2:1", IPv6Utils.canonize("2001:db8:0:0:0:0:2:1"));
Assert.assertEquals("2001:db8::", IPv6Utils.canonize("2001:db8:0:0:0:0:0:0"));
// Handling One 16-Bit 0 Field (4.2.2)
Assert.assertEquals("2001:db8:0:1:1:1:1:1", IPv6Utils.canonize("2001:db8:0:1:1:1:1:1"));
Assert.assertEquals("2001:db8:0:1:1:1:1:1", IPv6Utils.canonize("2001:db8::1:1:1:1:1"));
// Choice in Placement of "::" (4.2.3)
Assert.assertEquals("2001:0:0:1::1", IPv6Utils.canonize("2001:0:0:1:0:0:0:1"));
Assert.assertEquals("2001:db8::1:0:0:1", IPv6Utils.canonize("2001:db8:0:0:1:0:0:1"));
// IPv4 inside IPv6
Assert.assertEquals("::ffff:192.0.2.1", IPv6Utils.canonize("::ffff:192.0.2.1"));
Assert.assertEquals("::ffff:192.0.2.1", IPv6Utils.canonize("0:0:0:0:0:ffff:192.0.2.1"));
Assert.assertEquals("::192.0.2.1", IPv6Utils.canonize("::192.0.2.1"));
Assert.assertEquals("::192.0.2.1", IPv6Utils.canonize("0:0:0:0:0:0:192.0.2.1"));
// Zone ID
Assert.assertEquals("fe80::f0f0:c0c0:1919:1234%4", IPv6Utils.canonize("fe80::f0f0:c0c0:1919:1234%4"));
Assert.assertEquals("fe80::f0f0:c0c0:1919:1234%4", IPv6Utils.canonize("fe80:0:0:0:f0f0:c0c0:1919:1234%4"));
Assert.assertEquals("::%4", IPv6Utils.canonize("::%4"));
Assert.assertEquals("::%4", IPv6Utils.canonize("::0%4"));
Assert.assertEquals("::%4", IPv6Utils.canonize("0:0::0%4"));
Assert.assertEquals("::%4", IPv6Utils.canonize("0:0:0:0:0:0:0:0%4"));
Assert.assertEquals("::1%4", IPv6Utils.canonize("::1%4"));
Assert.assertEquals("::1%4", IPv6Utils.canonize("0:0::1%4"));
Assert.assertEquals("::1%4", IPv6Utils.canonize("0:0:0:0:0:0:0:1%4"));
Assert.assertEquals("::1%eth0", IPv6Utils.canonize("::1%eth0"));
Assert.assertEquals("::1%eth0", IPv6Utils.canonize("0:0::1%eth0"));
Assert.assertEquals("::1%eth0", IPv6Utils.canonize("0:0:0:0:0:0:0:1%eth0"));
// Hostname safety
Assert.assertEquals("www.apache.org", IPv6Utils.canonize("www.apache.org"));
Assert.assertEquals("ipv6.google.com", IPv6Utils.canonize("ipv6.google.com"));
}
}

View File

@@ -0,0 +1,182 @@
/*
* 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.util.net;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.util.buf.ByteChunk;
/**
* The keys and certificates used in this file are all available in svn and were
* generated using a test CA the files for which are in the Tomcat PMC private
* repository since not all of them are AL2 licensed.
*/
public class TestClientCert extends TomcatBaseTest {
@Test
public void testClientCertGetWithoutPreemptive() throws Exception {
doTestClientCertGet(false);
}
@Test
public void testClientCertGetWithPreemptive() throws Exception {
doTestClientCertGet(true);
}
private void doTestClientCertGet(boolean preemptive) throws Exception {
Assume.assumeTrue("SSL renegotiation has to be supported for this test",
TesterSupport.isRenegotiationSupported(getTomcatInstance()));
if (preemptive) {
Tomcat tomcat = getTomcatInstance();
// Only one context deployed
Context c = (Context) tomcat.getHost().findChildren()[0];
// Enable pre-emptive auth
c.setPreemptiveAuthentication(true);
}
getTomcatInstance().start();
// Unprotected resource
ByteChunk res = getUrl("https://localhost:" + getPort() + "/unprotected");
int count = TesterSupport.getLastClientAuthRequestedIssuerCount();
if (log.isDebugEnabled()) {
log.debug("Last client KeyManager usage: " + TesterSupport.getLastClientAuthKeyManagerUsage() +
", " + count + " requested Issuers, first one: " +
(count > 0 ? TesterSupport.getLastClientAuthRequestedIssuer(0).getName() : "NONE"));
log.debug("Expected requested Issuer: " +
(preemptive ? TesterSupport.getClientAuthExpectedIssuer() : "NONE"));
}
if (preemptive) {
Assert.assertTrue("Checking requested client issuer against " +
TesterSupport.getClientAuthExpectedIssuer(),
TesterSupport.checkLastClientAuthRequestedIssuers());
Assert.assertEquals("OK-" + TesterSupport.ROLE, res.toString());
} else {
Assert.assertEquals(0, count);
Assert.assertEquals("OK", res.toString());
}
// Protected resource
res = getUrl("https://localhost:" + getPort() + "/protected");
if (log.isDebugEnabled()) {
count = TesterSupport.getLastClientAuthRequestedIssuerCount();
log.debug("Last client KeyManager usage: " + TesterSupport.getLastClientAuthKeyManagerUsage() +
", " + count + " requested Issuers, first one: " +
(count > 0 ? TesterSupport.getLastClientAuthRequestedIssuer(0).getName() : "NONE"));
log.debug("Expected requested Issuer: " + TesterSupport.getClientAuthExpectedIssuer());
}
Assert.assertTrue("Checking requested client issuer against " +
TesterSupport.getClientAuthExpectedIssuer(),
TesterSupport.checkLastClientAuthRequestedIssuers());
Assert.assertEquals("OK-" + TesterSupport.ROLE, res.toString());
}
@Test
public void testClientCertPostSmaller() throws Exception {
Tomcat tomcat = getTomcatInstance();
int bodySize = tomcat.getConnector().getMaxSavePostSize() / 2;
doTestClientCertPost(bodySize, false);
}
@Test
public void testClientCertPostSame() throws Exception {
Tomcat tomcat = getTomcatInstance();
int bodySize = tomcat.getConnector().getMaxSavePostSize();
doTestClientCertPost(bodySize, false);
}
@Test
public void testClientCertPostLarger() throws Exception {
Tomcat tomcat = getTomcatInstance();
int bodySize = tomcat.getConnector().getMaxSavePostSize() * 2;
doTestClientCertPost(bodySize, true);
}
private void doTestClientCertPost(int bodySize, boolean expectProtectedFail)
throws Exception {
Assume.assumeTrue("SSL renegotiation has to be supported for this test",
TesterSupport.isRenegotiationSupported(getTomcatInstance()));
getTomcatInstance().start();
byte[] body = new byte[bodySize];
Arrays.fill(body, TesterSupport.DATA);
// Unprotected resource
ByteChunk res = postUrl(body, "https://localhost:" + getPort() + "/unprotected");
int count = TesterSupport.getLastClientAuthRequestedIssuerCount();
if (log.isDebugEnabled()) {
log.debug("Last client KeyManager usage: " + TesterSupport.getLastClientAuthKeyManagerUsage() +
", " + count + " requested Issuers, first one: " +
(count > 0 ? TesterSupport.getLastClientAuthRequestedIssuer(0).getName() : "NONE"));
log.debug("Expected requested Issuer: NONE");
}
// Unprotected resource with no preemptive authentication
Assert.assertEquals(0, count);
// No authentication no need to buffer POST body during TLS handshake so
// no possibility of hitting buffer limit
Assert.assertEquals("OK-" + bodySize, res.toString());
// Protected resource
res.recycle();
int rc = postUrl(body, "https://localhost:" + getPort() + "/protected", res, null);
count = TesterSupport.getLastClientAuthRequestedIssuerCount();
if (log.isDebugEnabled()) {
log.debug("Last client KeyManager usage: " + TesterSupport.getLastClientAuthKeyManagerUsage() +
", " + count + " requested Issuers, first one: " +
(count > 0 ? TesterSupport.getLastClientAuthRequestedIssuer(0).getName() : "NONE"));
log.debug("Expected requested Issuer: " + TesterSupport.getClientAuthExpectedIssuer());
}
if (expectProtectedFail) {
Assert.assertEquals(401, rc);
// POST body buffer fails so TLS handshake never happens
Assert.assertEquals(0, count);
} else {
Assert.assertTrue("Checking requested client issuer against " +
TesterSupport.getClientAuthExpectedIssuer(),
TesterSupport.checkLastClientAuthRequestedIssuers());
Assert.assertEquals("OK-" + bodySize, res.toString());
}
}
@Override
public void setUp() throws Exception {
super.setUp();
Tomcat tomcat = getTomcatInstance();
TesterSupport.configureClientCertContext(tomcat);
TesterSupport.configureClientSsl();
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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.util.net;
import java.util.Arrays;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.util.buf.ByteChunk;
/**
* The keys and certificates used in this file are all available in svn and were
* generated using a test CA the files for which are in the Tomcat PMC private
* repository since not all of them are AL2 licensed.
*
* The JSSE implementation of TLSv1.3 only supports authentication during the
* 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.
*/
public class TestClientCertTls13 extends TomcatBaseTest {
@Test
public void testClientCertGet() throws Exception {
Tomcat tomcat = getTomcatInstance();
tomcat.start();
ByteChunk res = getUrl("https://localhost:" + getPort() + "/protected");
Assert.assertEquals("OK-" + TesterSupport.ROLE, res.toString());
}
@Test
public void testClientCertPost() throws Exception {
Tomcat tomcat = getTomcatInstance();
tomcat.start();
int size = 32 * 1024;
byte[] body = new byte[size];
Arrays.fill(body, TesterSupport.DATA);
// Protected resource
ByteChunk res = new ByteChunk();
int rc = postUrl(body, "https://localhost:" + getPort() + "/protected", res, null);
Assert.assertEquals(200, rc);
Assert.assertEquals("OK-" + size, res.toString());
}
@Override
public void setUp() throws Exception {
super.setUp();
Tomcat tomcat = getTomcatInstance();
Connector connector = tomcat.getConnector();
Assume.assumeTrue(TesterSupport.isDefaultTLSProtocolForTesting13(connector));
TesterSupport.configureClientCertContext(tomcat);
// Need to override some of the previous settings
Assert.assertTrue(tomcat.getConnector().setProperty("sslEnabledProtocols", Constants.SSL_PROTO_TLSv1_3));
// And add force authentication to occur on the initial handshake
Assert.assertTrue(tomcat.getConnector().setProperty("clientAuth", "required"));
TesterSupport.configureClientSsl();
}
}

View File

@@ -0,0 +1,184 @@
/*
* 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.util.net;
import java.io.File;
import java.net.SocketException;
import javax.net.ssl.SSLException;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.AbstractHttp11JsseProtocol;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
import org.apache.tomcat.util.net.jsse.TesterBug50640SslImpl;
import org.apache.tomcat.websocket.server.WsContextListener;
/**
* The keys and certificates used in this file are all available in svn and were
* generated using a test CA the files for which are in the Tomcat PMC private
* repository since not all of them are AL2 licensed.
*/
public class TestCustomSsl extends TomcatBaseTest {
private static enum TrustType {
ALL,
CA,
NONE
}
@Test
public void testCustomSslImplementation() throws Exception {
TesterSupport.configureClientSsl();
Tomcat tomcat = getTomcatInstance();
Connector connector = tomcat.getConnector();
Assume.assumeFalse("This test is only for JSSE based SSL connectors",
connector.getProtocolHandlerClassName().contains("Apr"));
SSLHostConfig sslHostConfig = new SSLHostConfig();
SSLHostConfigCertificate certificate = new SSLHostConfigCertificate(sslHostConfig, Type.UNDEFINED);
sslHostConfig.addCertificate(certificate);
connector.addSslHostConfig(sslHostConfig);
Assert.assertTrue(connector.setProperty(
"sslImplementationName", "org.apache.tomcat.util.net.jsse.TesterBug50640SslImpl"));
// This setting will break ssl configuration unless the custom
// implementation is used.
sslHostConfig.setProtocols(TesterBug50640SslImpl.PROPERTY_VALUE);
sslHostConfig.setSslProtocol("tls");
File keystoreFile = new File(TesterSupport.LOCALHOST_RSA_JKS);
certificate.setCertificateKeystoreFile(keystoreFile.getAbsolutePath());
connector.setSecure(true);
Assert.assertTrue(connector.setProperty("SSLEnabled", "true"));
File appDir = new File(getBuildDirectory(), "webapps/examples");
Context ctxt = tomcat.addWebapp(
null, "/examples", appDir.getAbsolutePath());
ctxt.addApplicationListener(WsContextListener.class.getName());
tomcat.start();
ByteChunk res = getUrl("https://localhost:" + getPort() +
"/examples/servlets/servlet/HelloWorldExample");
Assert.assertTrue(res.toString().indexOf("<a href=\"../helloworld.html\">") > 0);
}
@Test
public void testCustomTrustManagerAll() throws Exception {
doTestCustomTrustManager(TrustType.ALL);
}
@Test
public void testCustomTrustManagerCA() throws Exception {
doTestCustomTrustManager(TrustType.CA);
}
@Test
public void testCustomTrustManagerNone() throws Exception {
doTestCustomTrustManager(TrustType.NONE);
}
private void doTestCustomTrustManager(TrustType trustType)
throws Exception {
Tomcat tomcat = getTomcatInstance();
Assume.assumeTrue("SSL renegotiation has to be supported for this test",
TesterSupport.isRenegotiationSupported(tomcat));
TesterSupport.configureClientCertContext(tomcat);
Connector connector = tomcat.getConnector();
// Override the defaults
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11JsseProtocol) {
connector.findSslHostConfigs()[0].setTruststoreFile(null);
} else {
// Unexpected
Assert.fail("Unexpected handler type");
}
if (trustType.equals(TrustType.ALL)) {
connector.findSslHostConfigs()[0].setTrustManagerClassName(
"org.apache.tomcat.util.net.TesterSupport$TrustAllCerts");
} else if (trustType.equals(TrustType.CA)) {
connector.findSslHostConfigs()[0].setTrustManagerClassName(
"org.apache.tomcat.util.net.TesterSupport$SequentialTrustManager");
}
// Start Tomcat
tomcat.start();
TesterSupport.configureClientSsl();
// Unprotected resource
ByteChunk res = getUrl("https://localhost:" + getPort() + "/unprotected");
Assert.assertEquals("OK", res.toString());
// Protected resource
res.recycle();
int rc = -1;
try {
rc = getUrl("https://localhost:" + getPort() + "/protected", res, null, null);
} catch (SocketException se) {
if (!trustType.equals(TrustType.NONE)) {
Assert.fail(se.getMessage());
se.printStackTrace();
}
} catch (SSLException he) {
if (!trustType.equals(TrustType.NONE)) {
Assert.fail(he.getMessage());
he.printStackTrace();
}
}
if (trustType.equals(TrustType.CA)) {
if (log.isDebugEnabled()) {
int count = TesterSupport.getLastClientAuthRequestedIssuerCount();
log.debug("Last client KeyManager usage: " + TesterSupport.getLastClientAuthKeyManagerUsage() +
", " + count + " requested Issuers, first one: " +
(count > 0 ? TesterSupport.getLastClientAuthRequestedIssuer(0).getName() : "NONE"));
log.debug("Expected requested Issuer: " + TesterSupport.getClientAuthExpectedIssuer());
}
Assert.assertTrue("Checking requested client issuer against " +
TesterSupport.getClientAuthExpectedIssuer(),
TesterSupport.checkLastClientAuthRequestedIssuers());
}
if (trustType.equals(TrustType.NONE)) {
Assert.assertTrue(rc != 200);
Assert.assertEquals("", res.toString());
} else {
Assert.assertEquals(200, rc);
Assert.assertEquals("OK-" + TesterSupport.ROLE, res.toString());
}
}
}

View File

@@ -0,0 +1,112 @@
/*
* 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.util.net;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.apache.tomcat.util.net.openssl.OpenSSLConf;
import org.apache.tomcat.util.net.openssl.OpenSSLConfCmd;
import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
public class TestSSLHostConfig {
@Test
public void testCipher01() {
SSLHostConfig hc = new SSLHostConfig();
Cipher c = Cipher.TLS_RSA_WITH_NULL_MD5;
// Single JSSE name
hc.setCiphers(c.getJsseNames().iterator().next());
Assert.assertEquals(c.getOpenSSLAlias(), hc.getCiphers());
}
@Test
public void testCipher02() {
SSLHostConfig hc = new SSLHostConfig();
Cipher c1 = Cipher.TLS_RSA_WITH_NULL_MD5;
Cipher c2 = Cipher.TLS_RSA_WITH_NULL_SHA;
// Two JSSE names
hc.setCiphers(c1.getJsseNames().iterator().next() + "," +
c2.getJsseNames().iterator().next());
Assert.assertEquals(c1.getOpenSSLAlias() + ":" + c2.getOpenSSLAlias(), hc.getCiphers());
}
@Test
public void testCipher03() {
SSLHostConfig hc = new SSLHostConfig();
// Single OpenSSL alias
hc.setCiphers("ALL");
Assert.assertEquals("ALL", hc.getCiphers());
}
@Test
public void testCipher04() {
SSLHostConfig hc = new SSLHostConfig();
Cipher c = Cipher.TLS_RSA_WITH_NULL_MD5;
// Single OpenSSLName name
hc.setCiphers(c.getOpenSSLAlias());
Assert.assertEquals(c.getOpenSSLAlias(), hc.getCiphers());
}
@Test
public void testSerialization() throws IOException, ClassNotFoundException {
// Dummy OpenSSL command name/value pair
String name = "foo";
String value = "bar";
// Set up the object
SSLHostConfig sslHostConfig = new SSLHostConfig();
OpenSSLConf openSSLConf = new OpenSSLConf();
OpenSSLConfCmd openSSLConfCmd = new OpenSSLConfCmd();
openSSLConfCmd.setName(name);
openSSLConfCmd.setValue(value);
openSSLConf.addCmd(openSSLConfCmd);
sslHostConfig.setOpenSslConf(openSSLConf);
// Serialize
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(sslHostConfig);
oos.close();
// Deserialize
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
SSLHostConfig output = (SSLHostConfig) ois.readObject();
// Check values
List<OpenSSLConfCmd> commands = output.getOpenSslConf().getCommands();
Assert.assertEquals(1, commands.size());
OpenSSLConfCmd command = commands.get(0);
Assert.assertEquals(name, command.getName());
Assert.assertEquals(value, command.getValue());
}
}

View File

@@ -0,0 +1,349 @@
/*
* 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.util.net;
import java.io.File;
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.Context;
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;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.compat.JreCompat;
import org.apache.tomcat.util.net.SSLHostConfigCertificate.StoreType;
import org.apache.tomcat.util.net.SSLHostConfigCertificate.Type;
import org.apache.tomcat.util.net.TesterSupport.ClientSSLSocketFactory;
/*
* Tests compatibility of JSSE and OpenSSL settings.
*/
@RunWith(Parameterized.class)
public class TestSSLHostConfigCompat extends TomcatBaseTest {
@Parameterized.Parameters(name = "{0}-{3}")
public static Collection<Object[]> parameters() {
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[] { "APR/Native", "org.apache.coyote.http11.Http11AprProtocol",
"org.apache.tomcat.util.net.openssl.OpenSSLImplementation", storeType});
}
return parameterSets;
}
@Parameter(0)
public String connectorName;
@Parameter(1)
public String protocolName;
@Parameter(2)
public String sslImplementationName;
@Parameter(3)
public StoreType storeType;
private SSLHostConfig sslHostConfig = new SSLHostConfig();
@Test
public void testHostEC() throws Exception {
configureHostEC();
doTest();
}
@Test
public void testHostRSA() throws Exception {
configureHostRSA();
doTest();
}
@Test
public void testHostRSAandECwithDefaultClient() throws Exception {
configureHostRSA();
configureHostEC();
doTest();
}
/*
* This test and the next just swap the order in which the server certs are
* configured to ensure correct operation isn't dependent on order.
*/
@Test
public void testHostRSAandECwithRSAClient() throws Exception {
configureHostRSA();
configureHostEC();
// Configure cipher suite that requires an RSA certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
/*
* This test and the previous just swap the order in which the server certs
* are configured to ensure correct operation isn't dependent on order.
*/
@Test
public void testHostECandRSAwithRSAClient() throws Exception {
configureHostEC();
configureHostRSA();
// Configure cipher suite that requires an RSA certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
/*
* This test and the next just swap the order in which the server certs are
* configured to ensure correct operation isn't dependent on order.
*/
@Test
public void testHostRSAandECwithECClient() throws Exception {
configureHostRSA();
configureHostEC();
// Configure cipher suite that requires an EC certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
/*
* This test and the previous just swap the order in which the server certs
* are configured to ensure correct operation isn't dependent on order.
*/
@Test
public void testHostECandRSAwithECClient() throws Exception {
configureHostEC();
configureHostRSA();
// Configure cipher suite that requires an EC certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test
public void testHostRSAwithRSAClient() throws Exception {
configureHostRSA();
// Configure cipher suite that requires an RSA certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test(expected=javax.net.ssl.SSLHandshakeException.class)
public void testHostRSAwithECClient() throws Exception {
configureHostRSA();
// Configure cipher suite that requires an EC certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test
public void testHostRSAwithRSAandECClient() throws Exception {
configureHostRSA();
// Configure cipher suite that requires an EC certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test(expected=javax.net.ssl.SSLHandshakeException.class)
public void testHostECwithRSAClient() throws Exception {
configureHostEC();
// Configure cipher suite that requires an RSA certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test
public void testHostECwithECClient() throws Exception {
configureHostEC();
// Configure cipher suite that requires an EC certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
@Test
public void testHostECwithRSAandECClient() throws Exception {
configureHostEC();
// Configure cipher suite that requires an RSA certificate on the server
ClientSSLSocketFactory clientSSLSocketFactory = TesterSupport.configureClientSsl();
clientSSLSocketFactory.setCipher(new String[] {
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"});
doTest(false);
}
private void configureHostRSA() {
switch (storeType) {
case KEYSTORE: {
SSLHostConfigCertificate sslHostConfigCertificateRsa = new SSLHostConfigCertificate(sslHostConfig, Type.RSA);
sslHostConfigCertificateRsa.setCertificateKeystoreFile(getPath(TesterSupport.LOCALHOST_RSA_JKS));
sslHostConfig.addCertificate(sslHostConfigCertificateRsa);
break;
}
case PEM: {
SSLHostConfigCertificate sslHostConfigCertificateRsa = new SSLHostConfigCertificate(sslHostConfig, Type.RSA);
sslHostConfigCertificateRsa.setCertificateFile(getPath(TesterSupport.LOCALHOST_RSA_CERT_PEM));
sslHostConfigCertificateRsa.setCertificateKeyFile(getPath(TesterSupport.LOCALHOST_RSA_KEY_PEM));
sslHostConfig.addCertificate(sslHostConfigCertificateRsa);
break;
}
}
}
private void configureHostEC() {
switch (storeType) {
case KEYSTORE: {
SSLHostConfigCertificate sslHostConfigCertificateEc = new SSLHostConfigCertificate(sslHostConfig, Type.EC);
sslHostConfigCertificateEc.setCertificateKeystoreFile(getPath(TesterSupport.LOCALHOST_EC_JKS));
sslHostConfig.addCertificate(sslHostConfigCertificateEc);
break;
}
case PEM: {
SSLHostConfigCertificate sslHostConfigCertificateEc = new SSLHostConfigCertificate(sslHostConfig, Type.EC);
sslHostConfigCertificateEc.setCertificateFile(getPath(TesterSupport.LOCALHOST_EC_CERT_PEM));
sslHostConfigCertificateEc.setCertificateKeyFile(getPath(TesterSupport.LOCALHOST_EC_KEY_PEM));
sslHostConfig.addCertificate(sslHostConfigCertificateEc);
break;
}
}
}
private void doTest() throws Exception {
// Use the default client TLS config
doTest(true);
}
private void doTest(boolean configureClientSsl) throws Exception {
if (configureClientSsl) {
TesterSupport.configureClientSsl();
}
Tomcat tomcat = getTomcatInstance();
tomcat.start();
// Check a request can be made
ByteChunk res = getUrl("https://localhost:" + getPort() + "/");
Assert.assertEquals("OK", res.toString());
}
@Override
protected String getProtocol() {
return protocolName;
}
@Override
public void setUp() throws Exception {
super.setUp();
AprLifecycleListener listener = new AprLifecycleListener();
Assume.assumeTrue(AprLifecycleListener.isAprAvailable());
Assume.assumeTrue(JreCompat.isJre8Available());
Tomcat tomcat = getTomcatInstance();
Connector connector = tomcat.getConnector();
connector.setPort(0);
connector.setScheme("https");
connector.setSecure(true);
Assert.assertTrue(connector.setProperty("SSLEnabled", "true"));
if (!connector.getProtocolHandlerClassName().contains("Apr")) {
// Skip this for APR. It is not supported.
Assert.assertTrue(connector.setProperty("sslImplementationName", sslImplementationName));
}
sslHostConfig.setProtocols("TLSv1.2");
connector.addSslHostConfig(sslHostConfig);
StandardServer server = (StandardServer) tomcat.getServer();
server.addLifecycleListener(listener);
// Simple webapp
Context ctxt = tomcat.addContext("", null);
Tomcat.addServlet(ctxt, "TesterServlet", new TesterServlet());
ctxt.addServletMappingDecoded("/*", "TesterServlet");
}
private static String getPath(String relativePath) {
File f = new File(relativePath);
return f.getAbsolutePath();
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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.util.net;
import java.io.File;
import java.io.ObjectOutputStream;
import org.junit.Assert;
import org.junit.Test;
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;
public class TestSSLHostConfigIntegration extends TomcatBaseTest {
@Test
public void testSslHostConfigIsSerializable() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(), "webapps/examples");
org.apache.catalina.Context ctxt = tomcat.addWebapp(
null, "/examples", appDir.getAbsolutePath());
ctxt.addApplicationListener(WsContextListener.class.getName());
TesterSupport.initSsl(tomcat);
tomcat.start();
SSLHostConfig[] sslHostConfigs =
tomcat.getConnector().getProtocolHandler().findSslHostConfigs();
boolean written = false;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
for (SSLHostConfig sslHostConfig : sslHostConfigs) {
oos.writeObject(sslHostConfig);
written = true;
}
}
Assert.assertTrue(written);
}
}

View File

@@ -0,0 +1,198 @@
/*
* 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.util.net;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.TesterServlet;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.websocket.server.WsContextListener;
/**
* The keys and certificates used in this file are all available in svn and were
* generated using a test CA the files for which are in the Tomcat PMC private
* repository since not all of them are AL2 licensed.
*/
public class TestSsl extends TomcatBaseTest {
@Test
public void testSimpleSsl() throws Exception {
TesterSupport.configureClientSsl();
Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(), "webapps/examples");
org.apache.catalina.Context ctxt = tomcat.addWebapp(
null, "/examples", appDir.getAbsolutePath());
ctxt.addApplicationListener(WsContextListener.class.getName());
TesterSupport.initSsl(tomcat);
tomcat.start();
ByteChunk res = getUrl("https://localhost:" + getPort() +
"/examples/servlets/servlet/HelloWorldExample");
Assert.assertTrue(res.toString().indexOf("<a href=\"../helloworld.html\">") > 0);
Assert.assertTrue("Checking no client issuer has been requested",
TesterSupport.getLastClientAuthRequestedIssuerCount() == 0);
}
@Test
public void testKeyPass() throws Exception {
TesterSupport.configureClientSsl();
Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(), "webapps/examples");
org.apache.catalina.Context ctxt = tomcat.addWebapp(
null, "/examples", appDir.getAbsolutePath());
ctxt.addApplicationListener(WsContextListener.class.getName());
TesterSupport.initSsl(tomcat, TesterSupport.LOCALHOST_KEYPASS_JKS,
TesterSupport.JKS_PASS, TesterSupport.JKS_KEY_PASS);
tomcat.start();
ByteChunk res = getUrl("https://localhost:" + getPort() +
"/examples/servlets/servlet/HelloWorldExample");
Assert.assertTrue(res.toString().indexOf("<a href=\"../helloworld.html\">") > 0);
Assert.assertTrue("Checking no client issuer has been requested",
TesterSupport.getLastClientAuthRequestedIssuerCount() == 0);
}
@Test
public void testRenegotiateWorks() throws Exception {
Tomcat tomcat = getTomcatInstance();
Assume.assumeTrue("SSL renegotiation has to be supported for this test",
TesterSupport.isClientRenegotiationSupported(getTomcatInstance()));
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);
}
sslCtx.init(null, TesterSupport.getTrustManagers(), null);
SSLSocketFactory socketFactory = sslCtx.getSocketFactory();
SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost",
getPort());
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
Reader r = new InputStreamReader(is);
doRequest(os, r);
Assert.assertTrue("Checking no client issuer has been requested",
TesterSupport.getLastClientAuthRequestedIssuerCount() == 0);
TesterHandshakeListener listener = new TesterHandshakeListener();
socket.addHandshakeCompletedListener(listener);
socket.startHandshake();
doRequest(os, r);
// Handshake complete appears to be called asynchronously
int wait = 0;
while (wait < 5000 && !listener.isComplete()) {
wait += 50;
Thread.sleep(50);
}
Assert.assertTrue("Checking no client issuer has been requested",
TesterSupport.getLastClientAuthRequestedIssuerCount() == 0);
Assert.assertTrue(listener.isComplete());
System.out.println("Renegotiation completed after " + wait + " ms");
}
private void doRequest(OutputStream os, Reader r) throws IOException {
char[] expectedResponseLine = "HTTP/1.1 200 \r\n".toCharArray();
os.write("GET /tester HTTP/1.1\r\n".getBytes());
os.write("Host: localhost\r\n".getBytes());
os.write("Connection: Keep-Alive\r\n\r\n".getBytes());
os.flush();
// First check we get the expected response line
for (char c : expectedResponseLine) {
int read = r.read();
Assert.assertEquals(c, read);
}
// Skip to the end of the headers
char[] endOfHeaders ="\r\n\r\n".toCharArray();
int found = 0;
while (found != endOfHeaders.length) {
if (r.read() == endOfHeaders[found]) {
found++;
} else {
found = 0;
}
}
// Read the body
char[] expectedBody = "OK".toCharArray();
for (char c : expectedBody) {
int read = r.read();
Assert.assertEquals(c, read);
}
}
private static class TesterHandshakeListener implements HandshakeCompletedListener {
private volatile boolean complete = false;
@Override
public void handshakeCompleted(HandshakeCompletedEvent event) {
complete = true;
}
public boolean isComplete() {
return complete;
}
}
}

View File

@@ -0,0 +1,89 @@
/*
* 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.util.net;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.junit.Assert;
import org.junit.Test;
import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
public class TestTLSClientHelloExtractor {
@Test
public void testInputNeedRead01() throws IOException {
ByteBuffer testInput = ByteBuffer.allocate(1024);
doTestInputNeedRead(testInput);
}
@Test(expected=IOException.class)
public void testInputMalformed01() throws IOException {
ByteBuffer testInput = ByteBuffer.allocate(1024);
// TLS handshake
testInput.put((byte) 22);
// TLS 1.0
testInput.put((byte) 3);
testInput.put((byte) 1);
// Record length 0 (correct, but not legal)
testInput.put((byte) 0);
testInput.put((byte) 0);
doTestInputNeedRead(testInput);
}
@Test(expected=IOException.class)
public void testInputMalformed02() throws IOException {
ByteBuffer testInput = ByteBuffer.allocate(1024);
// TLS handshake
testInput.put((byte) 22);
// TLS 1.0
testInput.put((byte) 3);
testInput.put((byte) 1);
// Record length 4
testInput.put((byte) 0);
testInput.put((byte) 4);
// Type 1 (client hello)
testInput.put((byte) 1);
// Client hello size 0 (correct, but not legal)
testInput.put((byte) 0);
testInput.put((byte) 0);
testInput.put((byte) 0);
doTestInputNeedRead(testInput);
}
public void doTestInputMalformed(ByteBuffer input) throws IOException {
TLSClientHelloExtractor extractor = new TLSClientHelloExtractor(input);
// Expect this to fail
extractor.getResult();
}
public void doTestInputNeedRead(ByteBuffer input) throws IOException {
TLSClientHelloExtractor extractor = new TLSClientHelloExtractor(input);
// Expect this to fail
ExtractorResult result = extractor.getResult();
Assert.assertEquals(ExtractorResult.NEED_READ, result);
}
}

View File

@@ -0,0 +1,198 @@
/*
* 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.util.net;
import java.io.File;
import java.net.InetAddress;
import java.net.ServerSocket;
import org.junit.Assert;
import org.junit.Test;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.jni.Address;
import org.apache.tomcat.jni.Error;
import org.apache.tomcat.jni.Library;
import org.apache.tomcat.jni.OS;
import org.apache.tomcat.jni.Pool;
import org.apache.tomcat.jni.Socket;
/**
* Test case for the Endpoint implementations. The testing framework will ensure
* that each implementation is tested.
*/
public class TestXxxEndpoint extends TomcatBaseTest {
private long createAprPool() {
// Create the pool for the server socket
try {
return Pool.create(0);
} catch (UnsatisfiedLinkError e) {
log.error("Could not create socket pool", e);
return 0;
}
}
private long createAprSocket(int port, long pool)
throws Exception {
/**
* Server socket "pointer".
*/
long serverSock = 0;
String address = InetAddress.getByName("localhost").getHostAddress();
// Create the APR address that will be bound
int family = Socket.APR_INET;
if (Library.APR_HAVE_IPV6) {
if (!OS.IS_BSD && !OS.IS_WIN32 && !OS.IS_WIN64)
family = Socket.APR_UNSPEC;
}
long inetAddress = 0;
try {
inetAddress = Address.info(address, family,
port, 0, pool);
// Create the APR server socket
serverSock = Socket.create(Address.getInfo(inetAddress).family,
Socket.SOCK_STREAM,
Socket.APR_PROTO_TCP, pool);
} catch (Exception ex) {
log.error("Could not create socket for address '" + address + "'");
return 0;
}
if (OS.IS_UNIX) {
Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
}
// Deal with the firewalls that tend to drop the inactive sockets
Socket.optSet(serverSock, Socket.APR_SO_KEEPALIVE, 1);
// Bind the server socket
int ret = Socket.bind(serverSock, inetAddress);
if (ret != 0) {
log.error("Could not bind: " + Error.strerror(ret));
throw (new Exception(Error.strerror(ret)));
}
return serverSock;
}
private void destroyAprSocket(long serverSock, long pool) {
if (serverSock != 0) {
Socket.shutdown(serverSock, Socket.APR_SHUTDOWN_READWRITE);
Socket.close(serverSock);
Socket.destroy(serverSock);
}
if (pool != 0) {
Pool.destroy(pool);
pool = 0;
}
}
@Test
public void testStartStopBindOnInit() throws Exception {
Tomcat tomcat = getTomcatInstance();
File appDir = new File(getBuildDirectory(), "webapps/examples");
tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
tomcat.start();
int port = getPort();
tomcat.getConnector().stop();
Exception e = null;
ServerSocket s = null;
long pool = 0;
long nativeSocket = 0;
boolean isApr = tomcat.getConnector().getProtocolHandlerClassName().contains("Apr");
try {
// This should throw an Exception
if (isApr) {
pool = createAprPool();
Assert.assertTrue(pool != 0);
nativeSocket = createAprSocket(port, pool);
Assert.assertTrue(nativeSocket != 0);
} else {
s = new ServerSocket(port, 100,
InetAddress.getByName("localhost"));
}
} catch (Exception e1) {
e = e1;
} finally {
try {
if (isApr) {
destroyAprSocket(nativeSocket, pool);
} else if (s != null) {
s.close();
}
} catch (Exception e2) { /* Ignore */ }
}
if (e != null) {
log.info("Exception was", e);
}
Assert.assertNotNull(e);
tomcat.getConnector().start();
}
@Test
public void testStartStopBindOnStart() throws Exception {
Tomcat tomcat = getTomcatInstance();
Connector c = tomcat.getConnector();
Assert.assertTrue(c.setProperty("bindOnInit", "false"));
File appDir = new File(getBuildDirectory(), "webapps/examples");
tomcat.addWebapp(null, "/examples", appDir.getAbsolutePath());
tomcat.start();
int port = getPort();
tomcat.getConnector().stop();
Exception e = null;
ServerSocket s = null;
long pool = 0;
long nativeSocket = 0;
boolean isApr = tomcat.getConnector().getProtocolHandlerClassName().contains("Apr");
try {
// This should not throw an Exception
if (isApr) {
pool = createAprPool();
Assert.assertTrue(pool != 0);
nativeSocket = createAprSocket(port, pool);
Assert.assertTrue(nativeSocket != 0);
} else {
s = new ServerSocket(port, 100,
InetAddress.getByName("localhost"));
}
} catch (Exception e1) {
e = e1;
} finally {
try {
if (isApr) {
destroyAprSocket(nativeSocket, pool);
} else if (s != null) {
s.close();
}
} catch (Exception e2) { /* Ignore */ }
}
Assert.assertNull(e);
tomcat.getConnector().start();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
-----BEGIN CERTIFICATE-----
MIIGpzCCBI+gAwIBAgIJAL51xu6EZW62MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCTUExEjAQBgNVBAcTCVdha2VmaWVsZDEnMCUGA1UE
ChMeVGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMRowGAYDVQQLExFBcGFj
aGUgVG9tY2F0IFBNQzEeMBwGA1UEAxMVQXBhY2hlIFRvbWNhdCBUZXN0IENBMB4X
DTE3MDgwODEwMzYzNloXDTI3MDgwNjEwMzYzNlowgZMxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZpZWxkMScwJQYDVQQKEx5UaGUgQXBh
Y2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21jYXQg
UE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EwggIiMA0GCSqGSIb3
DQEBAQUAA4ICDwAwggIKAoICAQCuokXuzdQ8HToRVcL07AdxHW9WmaMpcPWb/vyQ
dcuha+JXJ9Wu+d7fpxppeuxnjDmDCZNo0kimI7nYIEDMd3WVen75aoMZnQ7+vN/G
ZQXxzSPz2vzTZyEETAqs7DsGwO5CK2y5sWKl57+QCz/N+xM7EwOyNkmt+7xI1eQ+
z2sUNLRMK7abom8nm/wVftGAXIiribmTqukoxjr8dpEDg77VCy9eqe6kcil6Fvnr
mYrJqmrwzGldUlw4jqHl1IJnJ5z281vzzQ0U5ULeiuBpDGXcOHoaH8zYxilBVpPu
RDRBOcX17e5NouZtDTFemkJq5ns3PDt+WjJvuYNSELLBbnP+S1V6mt+MU9PsF6Td
lVZZxxFD9hPYqAzymwJGzTKbE8juZruQswL4iftyELmLPjIsetVtXifsUNay6CfD
r5sN6r+KLrhJWUqhii2mH1jx4cLmlf308TOc80TldvvI9cfrb596954cEE+7dlaU
vnRbBAeVNHNHl5e68fvwpKgtvQhtg1rZ2w1foSkAyyNRkYrUZKe4ztUx9E2w9qIm
3OkZyMcPTKYkBVahR6K1bCo69uaUrxY4NaYlPfKdJmGfio/J2WGdqLq9na4iHRyY
pb5zKvYmH9cNpmn5V42yhmX7tjMJzUyWw8KxXpE/qEVB2wl11wNguEL8CaZy+3u0
iaCqbQIDAQABo4H7MIH4MB0GA1UdDgQWBBQA8phNISwAPECbhPTeKvAm7jIOnzCB
yAYDVR0jBIHAMIG9gBQA8phNISwAPECbhPTeKvAm7jIOn6GBmaSBljCBkzELMAkG
A1UEBhMCVVMxCzAJBgNVBAgTAk1BMRIwEAYDVQQHEwlXYWtlZmllbGQxJzAlBgNV
BAoTHlRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbjEaMBgGA1UECxMRQXBh
Y2hlIFRvbWNhdCBQTUMxHjAcBgNVBAMTFUFwYWNoZSBUb21jYXQgVGVzdCBDQYIJ
AL51xu6EZW62MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAAJx4rzn
rtrcic/F0keS2BSazERFmRlSOlHUsREk+6fq35h7ktnijBHsPXyLEPa5w9x5qJZf
a2zFGiiiHqRBiX1E8JhKR6jjcX3D3VODfLomXWInHgEDcwNNcnvspG0RUX2jUh7m
p1i1c32r1s51P0AEB4zmT6KZ7gAZThqwtkpf6FQXmKdVXQFbf8EP0+6HFpHhV4lc
Ee4tDGJnc8X59Yzhu2rg8tF8OmNwcccTXthCH4I/4wymbw6YLg/B/V7AXH1/lui3
B15MKabYgZOU3TeOmQ9sqFPztekEKe+sE3Mvdf90Fh4EBZCENWULGUJE9uVJuT8S
2WVGOMmIkDlMP0t8Wnb3gMwUzhGyWp2FjzixVg8vS85ZE5wX4kGPD6nx+cAPDKrd
j3TCdr0VHoxVoGkzvijDjf6+aNhHp87VYSOZDQh1ToNgDFHum362iXt7n+ppu3u4
LDG3c1ztmUjgGrki+bQvnVyeYSprNWO1houo7xvZ61gWtzo1jwvcOwU0NxWtQMAg
NLZeketZSAL2834Xhkj1tjP2HT5HffkYbg6QRWKPYk/vBUKU40VilDCXf2ieOR9A
UtbcjjB5dRbR0CTnbwu33XeuhqobhaaAbp9gGt71WnOZpKIrkvVG3Z+YLpotRiYd
cl3dVVqvg/CTCpwd/VOOAmW1ynLpflLR8rH/
-----END CERTIFICATE-----

Binary file not shown.

View File

@@ -0,0 +1,45 @@
/*
* 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.util.net.jsse;
import org.apache.tomcat.util.compat.JreCompat;
import org.apache.tomcat.util.net.Constants;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
import org.apache.tomcat.util.net.SSLUtil;
public class TesterBug50640SslImpl extends JSSEImplementation {
public static final String PROPERTY_VALUE = "magic";
@Override
public SSLUtil getSSLUtil(SSLHostConfigCertificate certificate) {
SSLHostConfig sslHostConfig = certificate.getSSLHostConfig();
if (sslHostConfig.getProtocols().size() == 1 &&
sslHostConfig.getProtocols().contains(PROPERTY_VALUE)) {
if (JreCompat.isJre8Available()) {
sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1_2);
} else {
sslHostConfig.setProtocols(Constants.SSL_PROTO_TLSv1);
}
return super.getSSLUtil(certificate);
} else {
return null;
}
}
}

View File

@@ -0,0 +1,28 @@
================================================================================
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.
================================================================================
ca.jks (changeit)
ca CN=Apache Tomcat Test CA
localhost-rsa.jks (changeit)
tomcat CN=localhost
localhost-rsa-copy1.jks (changeit)
tomcat CN=localhost (tomcatpass)
user1.jks (changeit)
user1 CN=user1

View File

@@ -0,0 +1,86 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4098 (0x1002)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA
Validity
Not Before: Feb 15 19:32:18 2019 GMT
Not After : Feb 14 19:32:18 2021 GMT
Subject: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=localhost
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:10:cc:24:b7:0c:2a:fe:a6:af:ea:b2:dc:26:f1:
81:06:ae:0b:eb:f0:c0:5f:a3:ee:5a:e3:d3:7c:02:
b0:58:6c:47:0e:6e:08:ac:30:e1:76:e5:9c:06:80:
af:42:ce:a7:6f:49:b5:ec:95:08:b1:a9:e3:7a:f7:
84:4f:e2:05:60
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
F8:98:B3:3A:75:F3:09:EB:FF:CC:6E:26:39:F0:B5:FF:1F:0F:FB:01
X509v3 Authority Key Identifier:
keyid:00:F2:98:4D:21:2C:00:3C:40:9B:84:F4:DE:2A:F0:26:EE:32:0E:9F
Signature Algorithm: sha256WithRSAEncryption
66:3f:a4:8e:4b:e0:3c:a2:54:d3:8d:6a:6d:83:fe:02:13:a8:
79:41:55:68:33:7a:13:84:2f:92:db:aa:06:ab:4c:69:a7:fe:
47:2f:31:a0:16:e8:cb:df:a8:d7:b3:21:27:2b:51:e2:77:05:
65:40:17:40:ff:9c:b8:3c:9f:c7:bf:65:8e:00:6f:ce:01:6d:
30:37:84:96:bd:78:11:26:be:27:22:53:67:c8:ac:cb:04:cb:
e2:96:a3:9e:a3:16:af:bf:97:be:c6:3d:0a:0f:1d:e9:45:0b:
ea:77:47:a7:d5:79:b2:5a:bc:83:4c:8c:2a:ca:b7:4c:0c:d4:
17:d5:24:b1:b1:5b:2c:6e:59:5d:30:40:b5:72:6f:3a:b1:f4:
f9:0d:7e:b9:aa:99:26:19:21:b0:07:4d:49:c3:e7:c2:3d:c8:
98:62:cd:b6:d5:9a:21:f8:c7:b0:1a:72:59:02:80:0f:83:af:
d7:3b:8a:7e:53:38:8c:0d:e9:03:9d:c8:f9:1d:5c:82:7f:49:
8d:87:d3:89:69:a1:39:d3:fd:04:17:e5:63:af:55:02:ef:60:
d7:70:1d:60:6c:aa:53:43:13:f1:82:f6:b6:41:71:7b:38:ff:
82:78:73:73:11:e7:48:2f:f8:e8:77:27:7a:0f:a3:14:b0:33:
f9:aa:65:0c:8f:69:3b:2f:ee:b3:51:d6:5d:8a:67:80:47:1e:
a3:bd:d2:03:c3:62:45:1a:ac:dd:79:2e:84:a7:3d:8a:27:89:
c4:31:cc:1c:0b:37:a6:9d:a4:e4:65:03:8b:a3:5a:63:60:fb:
b9:7b:44:7f:8d:6a:74:9f:52:0e:b8:e7:12:52:98:5f:e9:34:
20:5a:f6:b7:15:a1:81:5e:f4:18:6c:18:c7:e8:dc:64:f8:d1:
a2:6f:98:a6:fd:36:e8:be:e7:a8:3f:a5:cb:de:1f:8f:ef:4a:
29:ee:69:f3:81:cd:ce:ec:5f:d7:b8:61:c1:41:4b:b0:49:5c:
29:eb:dd:e8:a6:54:4c:61:72:af:9c:50:da:16:1d:da:14:c9:
5f:8a:ae:2a:41:3b:9d:1e:72:7d:c8:eb:28:f2:a5:49:9b:ca:
0c:38:88:09:b3:5f:a9:83:13:6a:93:03:f9:3c:92:22:b8:cb:
ad:ba:dc:9b:6d:a6:9e:b0:d5:5a:57:ea:ae:f7:e9:8f:03:c2:
24:80:f8:50:21:94:7c:58:ac:b0:86:58:13:f2:d4:ef:f3:c1:
53:96:88:f9:dd:19:a7:83:fe:a9:d1:0a:1c:d0:10:23:6e:24:
47:41:3b:d4:dd:a1:06:2d:8a:ba:51:ef:34:e7:81:f0:94:51:
28:3a:44:8e:de:25:fa:e3
-----BEGIN CERTIFICATE-----
MIIESDCCAjCgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAlVT
MQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZpZWxkMScwJQYDVQQKEx5UaGUg
QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21j
YXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EwHhcNMTkwMjE1
MTkzMjE4WhcNMjEwMjE0MTkzMjE4WjCBhzELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
Ak1BMRIwEAYDVQQHDAlXYWtlZmllbGQxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29m
dHdhcmUgRm91bmRhdGlvbjEaMBgGA1UECwwRQXBhY2hlIFRvbWNhdCBQTUMxEjAQ
BgNVBAMMCWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBDMJLcM
Kv6mr+qy3CbxgQauC+vwwF+j7lrj03wCsFhsRw5uCKww4XblnAaAr0LOp29JteyV
CLGp43r3hE/iBWCjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5T
U0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBT4mLM6dfMJ6//MbiY5
8LX/Hw/7ATAfBgNVHSMEGDAWgBQA8phNISwAPECbhPTeKvAm7jIOnzANBgkqhkiG
9w0BAQsFAAOCAgEAZj+kjkvgPKJU041qbYP+AhOoeUFVaDN6E4QvktuqBqtMaaf+
Ry8xoBboy9+o17MhJytR4ncFZUAXQP+cuDyfx79ljgBvzgFtMDeElr14ESa+JyJT
Z8isywTL4pajnqMWr7+XvsY9Cg8d6UUL6ndHp9V5slq8g0yMKsq3TAzUF9UksbFb
LG5ZXTBAtXJvOrH0+Q1+uaqZJhkhsAdNScPnwj3ImGLNttWaIfjHsBpyWQKAD4Ov
1zuKflM4jA3pA53I+R1cgn9JjYfTiWmhOdP9BBflY69VAu9g13AdYGyqU0MT8YL2
tkFxezj/gnhzcxHnSC/46Hcneg+jFLAz+aplDI9pOy/us1HWXYpngEceo73SA8Ni
RRqs3XkuhKc9iieJxDHMHAs3pp2k5GUDi6NaY2D7uXtEf41qdJ9SDrjnElKYX+k0
IFr2txWhgV70GGwYx+jcZPjRom+Ypv026L7nqD+ly94fj+9KKe5p84HNzuxf17hh
wUFLsElcKevd6KZUTGFyr5xQ2hYd2hTJX4quKkE7nR5yfcjrKPKlSZvKDDiICbNf
qYMTapMD+TySIrjLrbrcm22mnrDVWlfqrvfpjwPCJID4UCGUfFissIZYE/LU7/PB
U5aI+d0Zp4P+qdEKHNAQI24kR0E71N2hBi2KulHvNOeB8JRRKDpEjt4l+uM=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0U7ZRpeTEzVDXCCP
oKwgWnN0tf7CMaE9dJmLIPpNgnChRANCAAQQzCS3DCr+pq/qstwm8YEGrgvr8MBf
o+5a49N8ArBYbEcObgisMOF25ZwGgK9CzqdvSbXslQixqeN694RP4gVg
-----END PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,109 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4102 (0x1006)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=Apache Tomcat Test CA
Validity
Not Before: Aug 7 20:30:28 2019 GMT
Not After : Aug 6 20:30:28 2021 GMT
Subject: C=US, ST=MA, L=Wakefield, O=The Apache Software Foundation, OU=Apache Tomcat PMC, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:cf:e2:56:a6:67:a6:e8:e7:f3:94:86:6e:f9:06:
46:cf:20:66:b5:cd:b1:c7:d6:50:ea:4d:46:44:ed:
45:65:ea:b6:9b:2e:49:a5:25:c1:8e:36:f6:2c:bc:
8e:09:35:0b:2f:43:70:73:07:47:1d:78:a1:12:e9:
56:5d:ab:84:15:16:0e:38:01:bb:81:87:2d:c4:3b:
dc:2e:4a:e1:d4:66:1b:ce:87:2c:a9:b8:e3:aa:80:
75:79:b1:98:f3:dd:df:66:d0:0d:e1:06:d8:6c:6c:
50:f0:00:80:32:70:55:7b:dd:eb:ae:f2:6a:bf:93:
3d:15:e1:25:f8:75:ce:d8:46:dc:c4:6b:ee:f9:f5:
93:39:ad:90:47:15:4b:fa:ca:5b:fe:ca:1b:29:8a:
74:19:2a:cb:1e:4f:20:d9:74:75:24:a0:06:d1:3a:
ed:9b:88:87:f3:1b:0f:a6:14:67:e9:ed:47:2e:a1:
25:6a:c2:97:04:13:f4:9f:62:38:cd:5a:e7:ad:c2:
64:2c:8f:9c:3d:04:58:12:42:e5:0c:8e:8c:ce:78:
3d:60:38:ce:06:ff:9c:ea:9c:c9:0f:73:90:b2:1a:
4a:16:99:c9:fe:95:88:7b:3c:7f:19:d0:26:27:11:
78:f9:92:5c:b4:f5:d4:cb:b0:84:0c:74:37:3d:87:
1a:0b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
0D:86:88:1D:07:59:CE:14:B4:89:81:58:C6:0B:FF:4C:CA:25:52:80
X509v3 Authority Key Identifier:
keyid:00:F2:98:4D:21:2C:00:3C:40:9B:84:F4:DE:2A:F0:26:EE:32:0E:9F
Authority Information Access:
OCSP - URI:http://127.0.0.1:8888
X509v3 Subject Alternative Name:
DNS:localhost, IP Address:127.0.0.1
Signature Algorithm: sha256WithRSAEncryption
7d:dc:b1:0f:dd:34:df:26:63:73:02:8a:d6:39:64:73:c3:fc:
40:75:26:b6:9b:42:72:af:c9:63:41:68:d0:78:c7:47:ef:c2:
44:5a:b3:58:95:a3:2c:f3:b1:f4:a3:3d:0b:94:ff:b4:97:6a:
e9:4b:4b:c2:3a:f6:36:43:af:ee:2f:39:3e:f2:5f:2c:a2:b7:
43:3c:13:42:d8:4e:e0:36:bc:23:c5:43:88:46:92:f7:77:14:
67:73:14:5b:43:0e:3d:b5:1a:69:e9:ca:84:08:20:27:9f:23:
4d:60:db:cb:98:4a:b3:3e:71:e6:e8:a1:11:1c:7e:7e:43:fb:
6d:a5:41:c0:7e:3f:84:ed:06:28:dc:aa:80:17:76:ec:8a:e6:
65:45:21:85:13:48:e0:5b:87:c8:2a:1a:0f:37:0f:2a:64:53:
a8:e3:49:04:84:88:fe:8b:a2:3c:cc:41:c7:c0:ad:26:d6:e1:
67:69:9a:50:c7:eb:3d:1c:7f:da:88:08:24:14:6e:a1:ab:3e:
77:3f:88:12:55:98:97:9f:db:ad:09:e2:20:fe:8d:1f:ea:4f:
46:7e:d8:aa:ba:14:bd:a8:c2:6f:1b:47:62:d9:05:ca:c7:30:
7b:1e:95:2e:55:10:1d:b1:e3:44:95:07:25:6e:8c:9d:69:5b:
5c:ad:5f:56:27:e8:60:9f:d2:f4:64:7f:f7:8f:dc:bb:ee:bf:
be:0b:ea:34:9b:37:de:f0:5c:e0:64:c2:52:42:a6:0d:20:7d:
78:34:42:c1:1c:43:a1:98:e8:48:7b:92:49:2b:d9:63:91:6a:
70:02:d0:1b:a5:2a:ee:e5:1b:12:4f:cb:c9:e7:18:ae:66:f5:
04:d9:d2:68:95:c1:31:fe:57:9d:51:f5:fc:ed:43:3b:79:bf:
c3:9d:85:68:d8:98:a5:3c:a2:bb:fb:5b:19:5b:de:f0:7e:c8:
5e:47:ba:5d:8a:5b:44:f1:44:54:64:c0:da:95:a6:f0:bf:a9:
3f:5d:4c:72:97:86:ae:1e:0d:cd:20:4b:85:e0:4e:26:4d:29:
4e:96:43:b0:fd:30:5f:53:24:97:bc:35:d8:31:4b:6c:ea:a7:
f9:64:f9:cb:a0:14:c4:fc:54:78:13:52:b5:06:8f:7a:c2:00:
14:97:18:06:ef:bc:2f:2a:31:fc:11:25:7f:47:e3:3b:54:e7:
46:62:78:ba:52:07:32:41:48:9d:47:bd:1c:f4:eb:49:11:42:
40:9c:36:5a:e0:84:bd:09:44:91:bb:5c:d1:c4:28:6a:68:34:
f9:2c:22:b7:fc:43:bb:c4:96:02:ce:73:43:be:de:02:9c:e1:
d2:2a:4a:76:19:d6:3f:b0
-----BEGIN CERTIFICATE-----
MIIFZDCCA0ygAwIBAgICEAYwDQYJKoZIhvcNAQELBQAwgZMxCzAJBgNVBAYTAlVT
MQswCQYDVQQIEwJNQTESMBAGA1UEBxMJV2FrZWZpZWxkMScwJQYDVQQKEx5UaGUg
QXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xGjAYBgNVBAsTEUFwYWNoZSBUb21j
YXQgUE1DMR4wHAYDVQQDExVBcGFjaGUgVG9tY2F0IFRlc3QgQ0EwHhcNMTkwODA3
MjAzMDI4WhcNMjEwODA2MjAzMDI4WjCBhzELMAkGA1UEBhMCVVMxCzAJBgNVBAgT
Ak1BMRIwEAYDVQQHEwlXYWtlZmllbGQxJzAlBgNVBAoTHlRoZSBBcGFjaGUgU29m
dHdhcmUgRm91bmRhdGlvbjEaMBgGA1UECxMRQXBhY2hlIFRvbWNhdCBQTUMxEjAQ
BgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AM/iVqZnpujn85SGbvkGRs8gZrXNscfWUOpNRkTtRWXqtpsuSaUlwY429iy8jgk1
Cy9DcHMHRx14oRLpVl2rhBUWDjgBu4GHLcQ73C5K4dRmG86HLKm446qAdXmxmPPd
32bQDeEG2GxsUPAAgDJwVXvd667yar+TPRXhJfh1zthG3MRr7vn1kzmtkEcVS/rK
W/7KGymKdBkqyx5PINl0dSSgBtE67ZuIh/MbD6YUZ+ntRy6hJWrClwQT9J9iOM1a
563CZCyPnD0EWBJC5QyOjM54PWA4zgb/nOqcyQ9zkLIaShaZyf6ViHs8fxnQJicR
ePmSXLT11MuwhAx0Nz2HGgsCAwEAAaOByzCByDAJBgNVHRMEAjAAMCwGCWCGSAGG
+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU
DYaIHQdZzhS0iYFYxgv/TMolUoAwHwYDVR0jBBgwFoAUAPKYTSEsADxAm4T03irw
Ju4yDp8wMQYIKwYBBQUHAQEEJTAjMCEGCCsGAQUFBzABhhVodHRwOi8vMTI3LjAu
MC4xOjg4ODgwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEB
CwUAA4ICAQB93LEP3TTfJmNzAorWOWRzw/xAdSa2m0Jyr8ljQWjQeMdH78JEWrNY
laMs87H0oz0LlP+0l2rpS0vCOvY2Q6/uLzk+8l8sordDPBNC2E7gNrwjxUOIRpL3
dxRncxRbQw49tRpp6cqECCAnnyNNYNvLmEqzPnHm6KERHH5+Q/ttpUHAfj+E7QYo
3KqAF3bsiuZlRSGFE0jgW4fIKhoPNw8qZFOo40kEhIj+i6I8zEHHwK0m1uFnaZpQ
x+s9HH/aiAgkFG6hqz53P4gSVZiXn9utCeIg/o0f6k9GftiquhS9qMJvG0di2QXK
xzB7HpUuVRAdseNElQclboydaVtcrV9WJ+hgn9L0ZH/3j9y77r++C+o0mzfe8Fzg
ZMJSQqYNIH14NELBHEOhmOhIe5JJK9ljkWpwAtAbpSru5RsST8vJ5xiuZvUE2dJo
lcEx/ledUfX87UM7eb/DnYVo2JilPKK7+1sZW97wfsheR7pdiltE8URUZMDalabw
v6k/XUxyl4auHg3NIEuF4E4mTSlOlkOw/TBfUySXvDXYMUts6qf5ZPnLoBTE/FR4
E1K1Bo96wgAUlxgG77wvKjH8ESV/R+M7VOdGYni6UgcyQUidR70c9OtJEUJAnDZa
4IS9CUSRu1zRxChqaDT5LCK3/EO7xJYCznNDvt4CnOHSKkp2GdY/sA==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDP4lamZ6bo5/OU
hm75BkbPIGa1zbHH1lDqTUZE7UVl6rabLkmlJcGONvYsvI4JNQsvQ3BzB0cdeKES
6VZdq4QVFg44AbuBhy3EO9wuSuHUZhvOhyypuOOqgHV5sZjz3d9m0A3hBthsbFDw
AIAycFV73euu8mq/kz0V4SX4dc7YRtzEa+759ZM5rZBHFUv6ylv+yhspinQZKsse
TyDZdHUkoAbROu2biIfzGw+mFGfp7UcuoSVqwpcEE/SfYjjNWuetwmQsj5w9BFgS
QuUMjozOeD1gOM4G/5zqnMkPc5CyGkoWmcn+lYh7PH8Z0CYnEXj5kly09dTLsIQM
dDc9hxoLAgMBAAECggEAXfOqO6yux6ZE9MRJFSzcBbJcGSBsj6dxjGL+NhqR+by5
aKrjx8qnjpGScqeI/epGMsck5CfO4SfqjDR+vvjMSgdcx70otCKW8ZAoM5fONoMr
YAzBh7cy1ZUXArfcK6MD22B+VUwVtfLCJaXkSmdwivnCEaAn1ItD2UaXNZJwuFeF
pT9Veif4MwfRhrVvHeEK+hEsrUePOOZ7bvfvIyd2pKtBuniiaoP9LIE2E/s+G458
xFZUHDxSgumEekZLv1mt03rcNDW9B9kLELaDuVbO4mQBn3edolvmL7N2iZpPIhM/
UDMqs7HfZ70bLcENa26UAZqIenbkueg7UkZgCF5RWQKBgQDxVTizo8vF+f7BhY8o
VSvGEhyRsJsyt9wb5AkVUCSM6Q+fKTimRBoDBQijDVc20uV5HpYIy35THphmXYX8
qIYNQiaGyLwBk6YWJDfqcfCjKBm6P7vtSFWjroRj2c0GjmXBZPk4sGYj16P4Qy00
ZssPsa+ENYgc4mox6szTp5Zp1wKBgQDchLRPaz1tWoLIlIl35a5GLHZwf6GGDeDI
2bxTMhBAohbjW9NSWf7GeZgeigRd7p5s6m2EriEJwsn61W0IWUzPLJ7iTHKOrVxU
tGxHd+SV3KhOkGn1EJ8zFiNIma/nAZraGW9zH/lhq09G8ygf1y3lSCQIABG8pAbK
xHmn3BoS7QKBgQCi0hSHXqNE1v4CItILLCt0XxPXV4feGB3w01Eth/yg9T0M7QrD
Yn8KOoMxPvbwjik0JmajWGfKPIIlzkNvy2Nl3pOPrC7sAWm01orDKkxoR83T0tw/
ouXkoQHBPFkPa1NLv4xFqv2+gOanwOrmx9OIqyD32gYTNs7fDsNSqWbZ0QKBgCup
WsoewZrVQO/V+SH0J/1c8FZ17tVMCiW6dr9COlWRwlZh6AV2LCvAB46EZTjz9go6
oFSU5ZW5K6SufVgZ1ktu2kaUPFpjmNRspMPByVCiz/A+R7xt/hdvWq0VQO7MMozc
XGS+//GGqbuyiU9Em6G6Fug+m0RudanQHQZPXhpBAoGBAIuWHrYCOWJRHDw8WdOE
811QFYHpMbYc0G4/50+O/1qKADWKbqAZpnbIW8NpHrcfggkgJw6E9kmtt8HbBu/3
NuCWK1K/0aLwQQMXqgrwuNYvk1QRXbAx86fbC1XVrY2KwmuCg6snXjJZqsTI91xm
jO0LxqN3mDyK11I9/XuearPH
-----END PRIVATE KEY-----

Binary file not shown.

View File

@@ -0,0 +1,137 @@
/*
* 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.util.net.openssl;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;
import org.apache.tomcat.jni.SSLContext;
import org.apache.tomcat.util.net.SSLHostConfig;
import org.apache.tomcat.util.net.TesterSupport;
public class TestOpenSSLConf extends TomcatBaseTest {
private static final String ENABLED_CIPHER = "AES256-SHA256";
private static final String[] EXPECTED_CIPHERS = {ENABLED_CIPHER};
private static final String[] ENABLED_PROTOCOLS = {"TLSv1.1"};
private static final String[] DISABLED_PROTOCOLS = {"SSLv3", "TLSv1", "TLSv1.2"};
private static final String[] DISABLED_PROTOCOLS_TLS13 = {"TLSv1.3"};
// Test behavior needs to adjust for OpenSSL 1.1.1-pre3 and above
private static final int OPENSSL_TLS13_SUPPORT_MIN_VERSION = 0x10101003;
private static int OPENSSL_VERSION = TesterSupport.getOpensslVersion();
private static boolean hasTLS13() {
return OPENSSL_VERSION >= OPENSSL_TLS13_SUPPORT_MIN_VERSION;
}
public SSLHostConfig initOpenSSLConfCmd(String... commands) throws Exception {
Assert.assertNotNull(commands);
Assert.assertTrue("Invalid length", commands.length % 2 == 0);
Tomcat tomcat = getTomcatInstance();
TesterSupport.initSsl(tomcat);
String protocol = tomcat.getConnector().getProtocolHandlerClassName();
// The tests are only supported for APR and OpenSSL
if (!protocol.contains("Apr")) {
String sslImplementation = String.valueOf(
tomcat.getConnector().getProperty("sslImplementationName"));
Assume.assumeTrue("This test is only for OpenSSL based SSL connectors",
sslImplementation.contains("openssl"));
}
OpenSSLConf conf = new OpenSSLConf();
for (int i = 0; i < commands.length;) {
OpenSSLConfCmd cmd = new OpenSSLConfCmd();
cmd.setName(commands[i++]);
cmd.setValue(commands[i++]);
conf.addCmd(cmd);
}
SSLHostConfig[] sslHostConfigs = tomcat.getConnector().
getProtocolHandler().findSslHostConfigs();
Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length);
sslHostConfigs[0].setOpenSslConf(conf);
tomcat.start();
sslHostConfigs = tomcat.getConnector().getProtocolHandler().findSslHostConfigs();
Assert.assertEquals("Wrong SSLHostConfigCount", 1, sslHostConfigs.length);
return sslHostConfigs[0];
}
@Test
public void testOpenSSLConfCmdCipher() throws Exception {
log.info("Found OpenSSL version 0x" + Integer.toHexString(OPENSSL_VERSION));
SSLHostConfig sslHostConfig;
if (hasTLS13()) {
// Ensure TLSv1.3 ciphers aren't returned
sslHostConfig = initOpenSSLConfCmd("CipherString", ENABLED_CIPHER,
"CipherSuites", "");
} else {
sslHostConfig = initOpenSSLConfCmd("CipherString", ENABLED_CIPHER);
}
String[] ciphers = sslHostConfig.getEnabledCiphers();
Assert.assertThat("Wrong HostConfig ciphers", ciphers,
CoreMatchers.is(EXPECTED_CIPHERS));
ciphers = SSLContext.getCiphers(sslHostConfig.getOpenSslContext().longValue());
Assert.assertThat("Wrong native SSL context ciphers", ciphers,
CoreMatchers.is(EXPECTED_CIPHERS));
}
@Test
public void testOpenSSLConfCmdProtocol() throws Exception {
log.info("Found OpenSSL version 0x" + Integer.toHexString(OPENSSL_VERSION));
Set<String> disabledProtocols = new HashSet<>(Arrays.asList(DISABLED_PROTOCOLS));
StringBuilder sb = new StringBuilder();
for (String protocol : DISABLED_PROTOCOLS) {
sb.append(",").append("-").append(protocol);
}
if (hasTLS13()) {
// Also disable TLSv1.3
for (String protocol : DISABLED_PROTOCOLS_TLS13) {
sb.append(",").append("-").append(protocol);
disabledProtocols.add(protocol);
}
}
for (String protocol : ENABLED_PROTOCOLS) {
sb.append(",").append(protocol);
}
SSLHostConfig sslHostConfig = initOpenSSLConfCmd("Protocol", sb.substring(1));
String[] protocols = sslHostConfig.getEnabledProtocols();
for (String protocol : protocols) {
Assert.assertFalse("Protocol " + protocol + " is not allowed",
disabledProtocols.contains(protocol));
}
Set<String> enabledProtocols = new HashSet<>(Arrays.asList(protocols));
for (String protocol : ENABLED_PROTOCOLS) {
Assert.assertTrue("Protocol " + protocol + " is not enabled",
enabledProtocols.contains(protocol));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
/*
* 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.util.net.openssl.ciphers;
import java.util.LinkedHashSet;
import org.junit.Assert;
import org.junit.Test;
/*
* The unit test is independent of OpenSSL version and does not require OpenSSL
* to be present.
*/
public class TestOpenSSLCipherConfigurationParserOnly {
@Test
public void testDefaultSort01() throws Exception {
// Reproducing a failure observed on Gump with OpenSSL 1.1.x
// Everything else being equal, AES is preferred
LinkedHashSet<Cipher> input = new LinkedHashSet<>();
input.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
input.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
input.add(Cipher.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
input.add(Cipher.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
LinkedHashSet<Cipher> result = OpenSSLCipherConfigurationParser.defaultSort(input);
LinkedHashSet<Cipher> expected = new LinkedHashSet<>();
expected.add(Cipher.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
expected.add(Cipher.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
expected.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
expected.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
Assert.assertEquals(expected.toString(), result.toString());
}
@Test
public void testDefaultSort02() throws Exception {
// Reproducing a failure observed on Gump with OpenSSL 1.1.x
// ECHDE should beat AES
LinkedHashSet<Cipher> input = new LinkedHashSet<>();
input.add(Cipher.TLS_RSA_WITH_AES_256_CBC_SHA);
input.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
LinkedHashSet<Cipher> result = OpenSSLCipherConfigurationParser.defaultSort(input);
LinkedHashSet<Cipher> expected = new LinkedHashSet<>();
expected.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
expected.add(Cipher.TLS_RSA_WITH_AES_256_CBC_SHA);
Assert.assertEquals(expected.toString(), result.toString());
}
@Test
public void testDefaultSort03() throws Exception {
// Reproducing a failure observed on Gump with OpenSSL 1.1.x
// AES should beat CAMELLIA
LinkedHashSet<Cipher> input = new LinkedHashSet<>();
input.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
input.add(Cipher.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384);
LinkedHashSet<Cipher> result = OpenSSLCipherConfigurationParser.defaultSort(input);
LinkedHashSet<Cipher> expected = new LinkedHashSet<>();
expected.add(Cipher.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384);
expected.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
Assert.assertEquals(expected.toString(), result.toString());
}
@Test
public void testRename01() throws Exception {
// EDH -> DHE
LinkedHashSet<Cipher> result =
OpenSSLCipherConfigurationParser.parse("EXP-EDH-DSS-DES-CBC-SHA");
LinkedHashSet<Cipher> expected = new LinkedHashSet<>();
expected.add(Cipher.TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
Assert.assertEquals(expected, result);
}
@Test
public void testCustomOrdering() throws Exception {
// https://bz.apache.org/bugzilla/show_bug.cgi?id=59081
LinkedHashSet<Cipher> result = OpenSSLCipherConfigurationParser.parse(
"ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:" +
"DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DES-CBC3-SHA");
LinkedHashSet<Cipher> expected = new LinkedHashSet<>();
expected.add(Cipher.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
expected.add(Cipher.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
expected.add(Cipher.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
expected.add(Cipher.TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
expected.add(Cipher.TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
expected.add(Cipher.TLS_RSA_WITH_3DES_EDE_CBC_SHA);
Assert.assertEquals(expected.toString(), result.toString());
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.