Skip to content
Permalink
Browse files

8234718: java/net/httpclient tests should cover TLSv1.3

Reviewed-by: dfuchs
  • Loading branch information
John Jiang
John Jiang committed Feb 13, 2020
1 parent cafdbcc commit 446f59a26c9de704f133a06c8a2887d2deac73b1
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,35 +21,40 @@
* questions.
*/

import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import static java.lang.System.out;
import static java.net.http.HttpResponse.BodyHandlers.discarding;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.URI;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Version;
import java.net.http.HttpResponse;
import java.net.http.HttpRequest;
import static java.lang.System.out;
import static java.net.http.HttpResponse.BodyHandlers.discarding;
import java.net.http.HttpResponse;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;

/**
* @test
* @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest
* @run main/othervm -Djdk.internal.httpclient.debug=false HandshakeFailureTest TLSv1.2
* @run main/othervm -Djdk.internal.httpclient.debug=false HandshakeFailureTest TLSv1.3
* @summary Verify SSLHandshakeException is received when the handshake fails,
* either because the server closes ( EOF ) the connection during handshaking
* or no cipher suite ( or similar ) can be negotiated.
* either because the server closes (EOF) the connection during handshaking,
* or no cipher suite can be negotiated (TLSv1.2) or no available authentication
* scheme (TLSv1.3).
*/
// To switch on debugging use:
// @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest
@@ -59,9 +64,13 @@
// when running standalone testing.
static final int TIMES = 10;

private static String tlsProtocol;

public static void main(String[] args) throws Exception {
tlsProtocol = args[0];

HandshakeFailureTest test = new HandshakeFailureTest();
List<AbstractServer> servers = List.of( new PlainServer(), new SSLServer());
List<AbstractServer> servers = List.of(new PlainServer(), new SSLServer());

for (AbstractServer server : servers) {
try (server) {
@@ -83,7 +92,7 @@ public static void main(String[] args) throws Exception {

static HttpClient getClient() {
SSLParameters params = new SSLParameters();
params.setProtocols(new String[] {"TLSv1.2"});
params.setProtocols(new String[] { tlsProtocol });
return HttpClient.newBuilder()
.sslParameters(params)
.build();
@@ -103,7 +112,7 @@ void testSyncSameClient(URI uri, Version version) throws Exception {
throw new RuntimeException(msg);
} catch (IOException expected) {
out.printf("Client: caught expected exception: %s%n", expected);
checkExceptionOrCause(SSLHandshakeException.class, expected);
checkExceptionOrCause(expected);
}
}
}
@@ -123,7 +132,7 @@ void testSyncDiffClient(URI uri, Version version) throws Exception {
throw new RuntimeException(msg);
} catch (IOException expected) {
out.printf("Client: caught expected exception: %s%n", expected);
checkExceptionOrCause(SSLHandshakeException.class, expected);
checkExceptionOrCause(expected);
}
}
}
@@ -145,7 +154,7 @@ void testAsyncSameClient(URI uri, Version version) throws Exception {
} catch (CompletionException ce) {
Throwable expected = ce.getCause();
out.printf("Client: caught expected exception: %s%n", expected);
checkExceptionOrCause(SSLHandshakeException.class, expected);
checkExceptionOrCause(expected);
}
}
}
@@ -169,24 +178,31 @@ void testAsyncDiffClient(URI uri, Version version) throws Exception {
ce.printStackTrace(out);
Throwable expected = ce.getCause();
out.printf("Client: caught expected exception: %s%n", expected);
checkExceptionOrCause(SSLHandshakeException.class, expected);
checkExceptionOrCause(expected);
}
}
}

static void checkExceptionOrCause(Class<? extends Throwable> clazz, Throwable t) {
static void checkExceptionOrCause(Throwable t) {
final Throwable original = t;
do {
if (clazz.isInstance(t)) {
if (SSLHandshakeException.class.isInstance(t)
// For TLSv1.3, possibly the server is (being) closed when
// the client read the input alert. In this case, the client
// just gets SocketException instead of SSLHandshakeException.
|| (tlsProtocol.equalsIgnoreCase("TLSv1.3")
&& SocketException.class.isInstance(t))) {
System.out.println("Found expected exception/cause: " + t);
return; // found
}
} while ((t = t.getCause()) != null);
original.printStackTrace(System.out);
throw new RuntimeException("Expected " + clazz + "in " + original);
throw new RuntimeException(
"Not found expected SSLHandshakeException or SocketException in "
+ original);
}

/** Common supertype for PlainServer and SSLServer. */
/** Common super type for PlainServer and SSLServer. */
static abstract class AbstractServer extends Thread implements AutoCloseable {
protected final ServerSocket ss;
protected volatile boolean closed;
@@ -271,14 +287,15 @@ public void run() {
}

/** Emulates a server-side, using SSL Sockets, that will fail during
* handshaking, as there are no cipher suites in common. */
* handshaking, as there are no cipher suites in common (TLSv1.2)
* or no available authentication scheme (TLSv1.3). */
static class SSLServer extends AbstractServer {
static final SSLContext sslContext = createUntrustingContext();
static final ServerSocketFactory factory = sslContext.getServerSocketFactory();

static SSLContext createUntrustingContext() {
try {
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
return sslContext;
} catch (Throwable t) {
@@ -298,7 +315,8 @@ public void run() {

throw new AssertionError("Should not reach here");
} catch (SSLHandshakeException expected) {
// Expected: SSLHandshakeException: no cipher suites in common
// Expected: SSLHandshakeException: no cipher suites in common (TLSv1.2)
// or no available authentication scheme (TLSv1.3)
out.printf("Server: caught expected exception: %s%n", expected);
} catch (IOException e) {
if (!closed)
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,7 +50,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -386,7 +385,6 @@ void testAsynchronousPOST(String url, String expectedMsg, boolean sameClient)
if (ee.getCause() instanceof IOException) {
IOException ioe = (IOException) ee.getCause();
out.println("Caught expected exception:" + ioe);
String msg = ioe.getMessage();

List<String> expectedMessages = new ArrayList<>();
expectedMessages.add(expectedMsg);
@@ -714,7 +712,6 @@ public void setup() throws Exception {
SSLContext.setDefault(sslContext);

sslParameters = new SSLParameters();
sslParameters.setProtocols(new String[] {"TLSv1.2"});

closeImmediatelyServer = new PlainCloseImmediatelyServer();
httpURIClsImed = "http://" + serverAuthority(closeImmediatelyServer)

0 comments on commit 446f59a

Please sign in to comment.