Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #6624 - Non-domain SNI on java17 #6640

Merged
merged 1 commit into from Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -60,14 +60,16 @@
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.toolchain.test.Net;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE;

import static org.hamcrest.MatcherAssert.assertThat;
Expand Down Expand Up @@ -365,7 +367,7 @@ public void handshakeSucceeded(Event event)

// Excluded in JDK 11+ because resumed sessions cannot be compared
// using their session IDs even though they are resumed correctly.
@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
@EnabledForJreRange(max = JRE.JAVA_10)
@Test
public void testHandshakeSucceededWithSessionResumption() throws Exception
{
Expand Down Expand Up @@ -445,7 +447,7 @@ public void handshakeSucceeded(Event event)

// Excluded in JDK 11+ because resumed sessions cannot be compared
// using their session IDs even though they are resumed correctly.
@EnabledOnJre({JRE.JAVA_8, JRE.JAVA_9, JRE.JAVA_10})
@EnabledForJreRange(max = JRE.JAVA_10)
@Test
public void testClientRawCloseDoesNotInvalidateSession() throws Exception
{
Expand Down Expand Up @@ -1013,7 +1015,6 @@ public void testForcedNonDomainSNI() throws Exception
// Force TLS-level hostName verification, as we want to receive the correspondent certificate.
clientTLS.setEndpointIdentificationAlgorithm("HTTPS");
startClient(clientTLS);

clientTLS.setSNIProvider(SslContextFactory.Client.SniProvider.NON_DOMAIN_SNI_PROVIDER);

// Send a request with SNI "localhost", we should get the certificate at alias=localhost.
Expand All @@ -1027,18 +1028,40 @@ public void testForcedNonDomainSNI() throws Exception
.scheme(HttpScheme.HTTPS.asString())
.send();
assertEquals(HttpStatus.OK_200, response2.getStatus());
}

/* TODO Fix. See #6624
if (Net.isIpv6InterfaceAvailable())
@Test
@EnabledForJreRange(max = JRE.JAVA_16, disabledReason = "Since Java 17, SNI host names can only have letter|digit|hyphen characters.")
public void testForcedNonDomainSNIWithIPv6() throws Exception
{
Assumptions.assumeTrue(Net.isIpv6InterfaceAvailable());

SslContextFactory.Server serverTLS = new SslContextFactory.Server();
serverTLS.setKeyStorePath("src/test/resources/keystore_sni_non_domain.p12");
serverTLS.setKeyStorePassword("storepwd");
serverTLS.setSNISelector((keyType, issuers, session, sniHost, certificates) ->
{
// Send a request with SNI "[::1]", we should get the certificate at alias=ip.
ContentResponse response3 = client.newRequest("[::1]", connector.getLocalPort())
.scheme(HttpScheme.HTTPS.asString())
.send();
// We have forced the client to send the non-domain SNI.
assertNotNull(sniHost);
return serverTLS.sniSelect(keyType, issuers, session, sniHost, certificates);
});
startServer(serverTLS, new EmptyServerHandler());

assertEquals(HttpStatus.OK_200, response3.getStatus());
}
*/
SslContextFactory.Client clientTLS = new SslContextFactory.Client();
// Trust any certificate received by the server.
clientTLS.setTrustStorePath("src/test/resources/keystore_sni_non_domain.p12");
clientTLS.setTrustStorePassword("storepwd");
// Force TLS-level hostName verification, as we want to receive the correspondent certificate.
clientTLS.setEndpointIdentificationAlgorithm("HTTPS");
startClient(clientTLS);
clientTLS.setSNIProvider(SslContextFactory.Client.SniProvider.NON_DOMAIN_SNI_PROVIDER);

// Send a request with SNI "[::1]", we should get the certificate at alias=ip.
ContentResponse response3 = client.newRequest("[::1]", connector.getLocalPort())
.scheme(HttpScheme.HTTPS.asString())
.send();

assertEquals(HttpStatus.OK_200, response3.getStatus());
}

@Test
Expand Down
Expand Up @@ -2178,9 +2178,9 @@ private static List<SNIServerName> getSniServerNames(SSLEngine sslEngine, List<S
String host = sslEngine.getPeerHost();
if (host != null)
{
// TODO Must handle : somehow as java17 SNIHostName never handles: See #6624
// Must use the byte[] constructor, because the character ':' is forbidden when
// using the String constructor (but typically present in IPv6 addresses).
// Since Java 17, only letter|digit|hyphen characters are allowed, even by the byte[] constructor.
return List.of(new SNIHostName(host.getBytes(StandardCharsets.US_ASCII)));
}
}
Expand Down