init
This commit is contained in:
141
test/org/apache/tomcat/util/net/IPv6UtilsTest.java
Normal file
141
test/org/apache/tomcat/util/net/IPv6UtilsTest.java
Normal 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"));
|
||||
}
|
||||
}
|
||||
182
test/org/apache/tomcat/util/net/TestClientCert.java
Normal file
182
test/org/apache/tomcat/util/net/TestClientCert.java
Normal 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();
|
||||
}
|
||||
}
|
||||
84
test/org/apache/tomcat/util/net/TestClientCertTls13.java
Normal file
84
test/org/apache/tomcat/util/net/TestClientCertTls13.java
Normal 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();
|
||||
}
|
||||
}
|
||||
184
test/org/apache/tomcat/util/net/TestCustomSsl.java
Normal file
184
test/org/apache/tomcat/util/net/TestCustomSsl.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
112
test/org/apache/tomcat/util/net/TestSSLHostConfig.java
Normal file
112
test/org/apache/tomcat/util/net/TestSSLHostConfig.java
Normal 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());
|
||||
}
|
||||
}
|
||||
349
test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java
Normal file
349
test/org/apache/tomcat/util/net/TestSSLHostConfigCompat.java
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
198
test/org/apache/tomcat/util/net/TestSsl.java
Normal file
198
test/org/apache/tomcat/util/net/TestSsl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
198
test/org/apache/tomcat/util/net/TestXxxEndpoint.java
Normal file
198
test/org/apache/tomcat/util/net/TestXxxEndpoint.java
Normal 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();
|
||||
}
|
||||
}
|
||||
698
test/org/apache/tomcat/util/net/TesterSupport.java
Normal file
698
test/org/apache/tomcat/util/net/TesterSupport.java
Normal file
File diff suppressed because it is too large
Load Diff
38
test/org/apache/tomcat/util/net/ca-cert.pem
Normal file
38
test/org/apache/tomcat/util/net/ca-cert.pem
Normal 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-----
|
||||
BIN
test/org/apache/tomcat/util/net/ca.jks
Normal file
BIN
test/org/apache/tomcat/util/net/ca.jks
Normal file
Binary file not shown.
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
test/org/apache/tomcat/util/net/keystore-info.txt
Normal file
28
test/org/apache/tomcat/util/net/keystore-info.txt
Normal 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
|
||||
86
test/org/apache/tomcat/util/net/localhost-ec-cert.pem
Normal file
86
test/org/apache/tomcat/util/net/localhost-ec-cert.pem
Normal 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-----
|
||||
5
test/org/apache/tomcat/util/net/localhost-ec-key.pem
Normal file
5
test/org/apache/tomcat/util/net/localhost-ec-key.pem
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg0U7ZRpeTEzVDXCCP
|
||||
oKwgWnN0tf7CMaE9dJmLIPpNgnChRANCAAQQzCS3DCr+pq/qstwm8YEGrgvr8MBf
|
||||
o+5a49N8ArBYbEcObgisMOF25ZwGgK9CzqdvSbXslQixqeN694RP4gVg
|
||||
-----END PRIVATE KEY-----
|
||||
BIN
test/org/apache/tomcat/util/net/localhost-ec.jks
Normal file
BIN
test/org/apache/tomcat/util/net/localhost-ec.jks
Normal file
Binary file not shown.
109
test/org/apache/tomcat/util/net/localhost-rsa-cert.pem
Normal file
109
test/org/apache/tomcat/util/net/localhost-rsa-cert.pem
Normal 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-----
|
||||
BIN
test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks
Normal file
BIN
test/org/apache/tomcat/util/net/localhost-rsa-copy1.jks
Normal file
Binary file not shown.
28
test/org/apache/tomcat/util/net/localhost-rsa-key.pem
Normal file
28
test/org/apache/tomcat/util/net/localhost-rsa-key.pem
Normal 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-----
|
||||
BIN
test/org/apache/tomcat/util/net/localhost-rsa.jks
Normal file
BIN
test/org/apache/tomcat/util/net/localhost-rsa.jks
Normal file
Binary file not shown.
137
test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java
Normal file
137
test/org/apache/tomcat/util/net/openssl/TestOpenSSLConf.java
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
1117
test/org/apache/tomcat/util/net/openssl/ciphers/TestCipher.java
Normal file
1117
test/org/apache/tomcat/util/net/openssl/ciphers/TestCipher.java
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
BIN
test/org/apache/tomcat/util/net/user1.jks
Normal file
BIN
test/org/apache/tomcat/util/net/user1.jks
Normal file
Binary file not shown.
Reference in New Issue
Block a user