# HG changeset patch # User michaelm # Date 1522340057 -3600 # Node ID c10279a27b41172d2e5bd0aca5224a775fb73a62 # Parent 875d856999818f122da8decc731db01557f922f3 http-client-branch: Fixed 8200351: problem verifying certificate of literal IP address connection diff -r 875d85699981 -r c10279a27b41 src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java Thu Mar 29 15:32:18 2018 +0100 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java Thu Mar 29 17:14:17 2018 +0100 @@ -37,6 +37,7 @@ import jdk.internal.net.http.common.SSLTube; import jdk.internal.net.http.common.Log; import jdk.internal.net.http.common.Utils; +import static jdk.internal.net.http.common.Utils.ServerName; /** @@ -69,14 +70,14 @@ AbstractAsyncSSLConnection(InetSocketAddress addr, HttpClientImpl client, - String serverName, int port, + ServerName serverName, int port, String[] alpn) { super(addr, client); - this.serverName = serverName; + this.serverName = serverName.getName(); SSLContext context = client.theSSLContext(); sslParameters = createSSLParameters(client, serverName, alpn); Log.logParams(sslParameters); - engine = createEngine(context, serverName, port, sslParameters); + engine = createEngine(context, serverName.getName(), port, sslParameters); } abstract HttpConnection plainConnection(); @@ -90,7 +91,7 @@ final SSLEngine getEngine() { return engine; } private static SSLParameters createSSLParameters(HttpClientImpl client, - String serverName, + ServerName serverName, String[] alpn) { SSLParameters sslp = client.sslParameters(); SSLParameters sslParameters = Utils.copySSLParameters(sslp); @@ -103,8 +104,11 @@ } else { Log.logSSL("AbstractAsyncSSLConnection: no applications set!"); } - if (serverName != null) { - sslParameters.setServerNames(List.of(new SNIHostName(serverName))); + if (!serverName.isLiteral()) { + String name = serverName.getName(); + if (name != null && name.length() > 0) { + sslParameters.setServerNames(List.of(new SNIHostName(name))); + } } return sslParameters; } diff -r 875d85699981 -r c10279a27b41 src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Thu Mar 29 15:32:18 2018 +0100 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Thu Mar 29 17:14:17 2018 +0100 @@ -322,36 +322,37 @@ return !token.isEmpty(); } + public static class ServerName { + ServerName(String name, boolean isLiteral) { + this.name = name; + this.isLiteral = isLiteral; + } + + final String name; + final boolean isLiteral; + + public String getName() { + return name; + } + + public boolean isLiteral() { + return isLiteral; + } + } + /** - * If the address was created with a domain name, then return - * the domain name string. If created with a literal IP address - * then return null except if the literal is loopback. - * We do this to avoid doing a reverse lookup - * Used to populate the TLS SNI parameter. So, SNI is only set - * when a domain name was supplied except in case of loopback - * where we return "localhost". + * Analyse the given address and determine if it is literal or not, + * returning the address in String form. */ - public static String getServerName(InetSocketAddress addr) { + public static ServerName getServerName(InetSocketAddress addr) { String host = addr.getHostString(); byte[] literal = IPAddressUtil.textToNumericFormatV4(host); if (literal == null) { - // not IPv4 literal + // not IPv4 literal. Check IPv6 literal = IPAddressUtil.textToNumericFormatV6(host); - if (literal == null) { - // not IPv6 literal. Must be domain name - return host; - } else { // check if loopback - if (isLoopbackLiteral(literal)) - return "localhost"; - else - return null; - } + return new ServerName(host, literal != null); } else { - // check if IPv4 loopback - if (isLoopbackLiteral(literal)) - return "localhost"; - else - return null; + return new ServerName(host, true); } } diff -r 875d85699981 -r c10279a27b41 test/jdk/java/net/httpclient/ssltest/CertificateTest.java --- a/test/jdk/java/net/httpclient/ssltest/CertificateTest.java Thu Mar 29 15:32:18 2018 +0100 +++ b/test/jdk/java/net/httpclient/ssltest/CertificateTest.java Thu Mar 29 17:14:17 2018 +0100 @@ -48,6 +48,7 @@ * @run main/othervm * -Djdk.internal.httpclient.disableHostnameVerification=xxyyzz * CertificateTest bad.keystore expectFailure + * @run main/othervm CertificateTest loopback.keystore expectSuccess */ /** @@ -102,7 +103,11 @@ static void test(String[] args) throws Exception { - String uri_s = "https://localhost:" + Integer.toString(port) + "/foo"; + String uri_s; + if (args[0].equals("loopback.keystore")) + uri_s = "https://127.0.0.1:" + Integer.toString(port) + "/foo"; + else + uri_s = "https://localhost:" + Integer.toString(port) + "/foo"; String error = null; Exception exception = null; System.out.println("Making request to " + uri_s); diff -r 875d85699981 -r c10279a27b41 test/jdk/java/net/httpclient/ssltest/loopback.keystore Binary file test/jdk/java/net/httpclient/ssltest/loopback.keystore has changed