8067694: Improved certification checking
Reviewed-by: mullan, jnimeh, coffeys, robm, asmotrak, ahgross
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Feb 04 11:13:14 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -205,16 +205,33 @@
static transient boolean preferIPv6Address = false;
static class InetAddressHolder {
+ /**
+ * Reserve the original application specified hostname.
+ *
+ * The original hostname is useful for domain-based endpoint
+ * identification (see RFC 2818 and RFC 6125). If an address
+ * was created with a raw IP address, a reverse name lookup
+ * may introduce endpoint identification security issue via
+ * DNS forging.
+ *
+ * Oracle JSSE provider is using this original hostname, via
+ * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification.
+ *
+ * Note: May define a new public method in the future if necessary.
+ */
+ private String originalHostName;
InetAddressHolder() {}
InetAddressHolder(String hostName, int address, int family) {
+ this.originalHostName = hostName;
this.hostName = hostName;
this.address = address;
this.family = family;
}
void init(String hostName, int family) {
+ this.originalHostName = hostName;
this.hostName = hostName;
if (family != -1) {
this.family = family;
@@ -227,6 +244,10 @@
return hostName;
}
+ String getOriginalHostName() {
+ return originalHostName;
+ }
+
/**
* Holds a 32-bit IPv4 address.
*/
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Feb 04 11:13:14 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -774,6 +774,10 @@
public URLClassPath getURLClassPath (URLClassLoader u) {
return u.ucp;
}
+
+ public String getOriginalHostName(InetAddress ia) {
+ return ia.holder.getOriginalHostName();
+ }
}
);
ClassLoader.registerAsParallelCapable();
--- a/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java Wed Feb 04 11:13:14 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, 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
@@ -26,10 +26,17 @@
package sun.misc;
import java.net.URLClassLoader;
+import java.net.InetAddress;
public interface JavaNetAccess {
/**
* return the URLClassPath belonging to the given loader
*/
URLClassPath getURLClassPath (URLClassLoader u);
+
+ /**
+ * Return the original application specified hostname of
+ * the given InetAddress object.
+ */
+ String getOriginalHostName(InetAddress ia);
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Wed Feb 04 11:13:14 2015 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -42,6 +42,9 @@
import javax.net.ssl.*;
import sun.misc.ManagedLocalsThread;
+import sun.misc.JavaNetAccess;
+import sun.misc.SharedSecrets;
+
/**
* Implementation of an SSL socket. This is a normal connection type
* socket, implementing SSL over some lower level socket, such as TCP.
@@ -377,6 +380,15 @@
*/
private int maximumPacketSize = 0;
+ /*
+ * Is the local name service trustworthy?
+ *
+ * If the local name service is not trustworthy, reverse host name
+ * resolution should not be performed for endpoint identification.
+ */
+ static final boolean trustNameService =
+ Debug.getBooleanProperty("jdk.tls.trustNameService", false);
+
//
// CONSTRUCTORS AND INITIALIZATION CODE
//
@@ -2063,11 +2075,40 @@
synchronized String getHost() {
// Note that the host may be null or empty for localhost.
if (host == null || host.length() == 0) {
- host = getInetAddress().getHostName();
+ if (!trustNameService) {
+ // If the local name service is not trustworthy, reverse host
+ // name resolution should not be performed for endpoint
+ // identification. Use the application original specified
+ // hostname or IP address instead.
+ host = getOriginalHostname(getInetAddress());
+ } else {
+ host = getInetAddress().getHostName();
+ }
}
+
return host;
}
+ /*
+ * Get the original application specified hostname.
+ */
+ private static String getOriginalHostname(InetAddress inetAddress) {
+ /*
+ * Get the original hostname via sun.misc.SharedSecrets.
+ */
+ JavaNetAccess jna = SharedSecrets.getJavaNetAccess();
+ String originalHostname = jna.getOriginalHostName(inetAddress);
+
+ /*
+ * If no application specified hostname, use the IP address.
+ */
+ if (originalHostname == null || originalHostname.length() == 0) {
+ originalHostname = inetAddress.getHostAddress();
+ }
+
+ return originalHostname;
+ }
+
// ONLY used by HttpsClient to setup the URI specified hostname
//
// Please NOTE that this method MUST be called before calling to