JDK-8132662 : Preserving mechanism of original hostnames in SSLSocketImpl fails
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 8u51
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2015-07-27
  • Updated: 2015-09-14
  • Resolved: 2015-08-20
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) Client VM (build 25.51-b03, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux host.example.org 2.6.18-406.el5 #1 SMP Tue Jun 2 17:26:20 EDT 2015 i686 i686 i386 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
Preserving mechanism of original hostnames in SSLSocketImpl, which is introduced in order to fix CVE-2015-2625, does not work as expected.

You can access the original hostname via JavaNetAccess.getOriginalHostName(InetAddress ia) but it always returns null.

As a consequence, sslSession.getPeerHost() and other methods depending on that returns IP address instead of hostname.

If you call createSocket(String host, int port) instead of createSocket(InetAddress ia, int port), the original hostname is stored in this.host in SSLSocketImpl.java:420 and JavaNetAccess.getOriginalHostName() will be never called and it works as expected.


REGRESSION.  Last worked in version 8u51

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Just execute my test case.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JavaNetAccess.getOriginalHostName() returns original hostname hence sslSession.getPeerHost() can return it.

$ java GetPeerHostTest
InetAddress: www.oracle.com/23.67.182.140
via JavaNetAccess: www.oracle.com
getPeerHost(): www.oracle.com

ACTUAL -
JavaNetAccess.getOriginalHostName() returns null and sslSession.getPeerHost() returns IP address.

$ java GetPeerHostTest
InetAddress: www.oracle.com/23.67.182.140
via JavaNetAccess: null
getPeerHost(): 23.67.182.140


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.net.InetAddress;
import java.security.GeneralSecurityException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import sun.misc.JavaNetAccess;
import sun.misc.SharedSecrets;

  public class GetPeerHostTest {
        
     public static void main(String[] args) throws Exception {
        test2();
     }

public static void test2() throws java.security.GeneralSecurityException,java.io.IOException {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, null, null);
InetAddress ia = null;
//SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket("www.oracle.com", 443);
SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(ia = InetAddress.getByName("www.oracle.com"), 443);
if (ia != null) {
System.out.println("InetAddress: "+ia);
JavaNetAccess jna = SharedSecrets.getJavaNetAccess();
System.out.println("via JavaNetAccess: "+jna.getOriginalHostName(ia));
}
SSLSession sslSession = sslSocket.getSession();
System.out.println("getPeerHost(): "+sslSession.getPeerHost());
}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Set -Djdk.tls.trustNameService=true option.
Result:
InetAddress: www.oracle.com/23.67.182.140
via JavaNetAccess: null
getPeerHost(): www.oracle.com