From 635f7a3e2098360585e7fbfb1055073cf9f1b108 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Wed, 4 Feb 2015 11:13:14 +0000 Subject: [PATCH] 8067694: Improved certification checking Reviewed-by: mullan, jnimeh, coffeys, robm, asmotrak, ahgross --- .../share/classes/java/net/InetAddress.java | 23 +++++++++- .../classes/java/net/URLClassLoader.java | 6 ++- .../share/classes/sun/misc/JavaNetAccess.java | 9 +++- .../sun/security/ssl/SSLSocketImpl.java | 45 ++++++++++++++++++- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/net/InetAddress.java b/jdk/src/java.base/share/classes/java/net/InetAddress.java index b39fa5dc2d6..9988ce7f719 100644 --- a/jdk/src/java.base/share/classes/java/net/InetAddress.java +++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java @@ -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 @@ class InetAddress implements java.io.Serializable { 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 @@ class InetAddress implements java.io.Serializable { return hostName; } + String getOriginalHostName() { + return originalHostName; + } + /** * Holds a 32-bit IPv4 address. */ diff --git a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java index 3b5c1e264ff..fbf323d3fba 100644 --- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java @@ -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 class URLClassLoader extends SecureClassLoader implements Closeable { public URLClassPath getURLClassPath (URLClassLoader u) { return u.ucp; } + + public String getOriginalHostName(InetAddress ia) { + return ia.holder.getOriginalHostName(); + } } ); ClassLoader.registerAsParallelCapable(); diff --git a/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java b/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java index cc7bec12211..908783121d4 100644 --- a/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java +++ b/jdk/src/java.base/share/classes/sun/misc/JavaNetAccess.java @@ -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); } diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java index 88f5ec37a1d..5340f74e85e 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -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.crypto.BadPaddingException; 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { */ 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 @@ final public class SSLSocketImpl extends BaseSSLSocketImpl { 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