United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6614957 HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets
JDK-6614957 : HttpsURLConnection not using the set SSLSocketFactory for creating all its Sockets

Details
Type:
Bug
Submit Date:
2007-10-10
Status:
Resolved
Updated Date:
2010-05-09
Project Name:
JDK
Resolved Date:
2010-04-14
Component:
security-libs
OS:
solaris_7,linux,windows_xp
Sub-Component:
javax.net.ssl
CPU:
x86,sparc
Priority:
P2
Resolution:
Fixed
Affected Versions:
1.4.2_10,6u10
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Backport:
Backport:
Backport:
Duplicate:
Relates:
Relates:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
NOTE:
  The JDK versions mentioned below are versions of a Java Licensees JDK implementation and do not map directly to Sun's JDK versions. This problem was first seen 
to happen between versions 1.4.2.10 and 1.4.2.11 of the licensees JDK implementation.  In this implementation 1.4.2.10 maps to Sun release 1.4.2.09; 1.4.2.11 maps to Sun release 1.4.2.12.  That means it might have changed in Sun's release 1.4.2.10, 1.4.2.11 or 1.4.2.12. In actual fact, we believe that this problem first occurred in 1.4.2_13 and 5.0 or greater.
--------------------------------

The issue in question is that there appears to be a change in behavior between 1.4.2.10 and 1.4.2.11
(and 1.5.*) with HTTPS URL connections.   It now requires the properties https.proxyHost and https.proxyPort to be defined.  However, these properties were not required in 1.4.2.10 and earlier; if the
user defines the SSLSocketFactory.  Using setSSLSocketFactory allows load balancing across several proxies instead of a single property value. 

if (myConnection instanceof com.sun.net.ssl.HttpsURLConnection) {
           ((com.sun.net.ssl.HttpsURLConnection)
myConnection).setSSLSocketFactory(new SSLTunnelSocketFactory
(System.getProperty("proxyHost"), System.getProperty("proxyPort")));
       }
  Simple reproducer can be found at:

http://forum.java.sun.com/thread.jspa?threadID=172539

While this example works "as is" with all java versions, if you
comment out the following section:

//set up system properties to indicate we are using a proxy
       System.setProperty("https.proxyHost", proxyHost);
       System.setProperty("https.proxyPort", proxyPort);


It will fail with 1.4.2.11 or higher.   it also fails on Windows, Linux, and OpenVMS.

I believe (however without the source for JSSE it is hard to tell
exactly) the change can be found in the class "HttpsClient" with the
doConnect method:

Decompile doConnect() method from 1.4.2.11

protected Socket doConnect(String s, int l)
       throws IOException, UnknownHostException
   {
       d = d == null ? getProxyHost() : d;
       e = e == 0 ? getProxyPort() : e;
       Socket socket = null;
       if(d == null || k())
       {
           socket = new Socket();
           if(NetworkClient.defaultConnectTimeout > 0)
               socket.connect(new InetSocketAddress(s, l),
NetworkClient.defaultConnectTimeout);
           else
               socket.connect(new InetSocketAddress(s, l));
       } else
       {
           try
           {
               socket = (Socket)AccessController.doPrivileged(new Object()     /* anonymous class not found */
   class _anm2 {}

);
           }
           catch(PrivilegedActionException privilegedactionexception)
           {
               throw (IOException)
privilegedactionexception.getException();
           }
           catch(IOException ioexception)
           {
               try
               {
                   socket = new Socket();
                   if(NetworkClient.defaultConnectTimeout > 0)
                       socket.connect(new InetSocketAddress(s, l),
NetworkClient.defaultConnectTimeout);
                   else
                       socket.connect(new InetSocketAddress(s, l));
               }
               catch(IOException ioexception1)
               {
                   throw ioexception;
               }
           }
       }
       if(NetworkClient.defaultSoTimeout > 0)
           socket.setSoTimeout(NetworkClient.defaultSoTimeout);
       return socket;
   }


Same code from 1.4.2.10, notice it honors the user defined
SSLSocketFactory after checking to see https.proxyHost has been
defined...

protected Socket doConnect(String s, int j)
       throws IOException, UnknownHostException
   {
       d = d == null ? getProxyHost() : d;
       e = e == 0 ? getProxyPort() : e;
       Object obj = null;
       SSLSocketFactory sslsocketfactory = c;
       if(d == null || i())
           obj = sslsocketfactory.createSocket(s, j);
       else
           try
           {
               obj = (Socket)AccessController.doPrivileged(new
PrivilegedExceptionAction() {

                   public Object run()
                       throws IOException
                   {
                       Socket socket = new Socket();
                       if(HttpsClient.e() > 0)
                           socket.connect(new InetSocketAddress
(HttpsClient.a(a), HttpsClient.b(a)), HttpsClient.f());
                       else
                           socket.connect(new InetSocketAddress
(HttpsClient.a(a), HttpsClient.b(a)));
                       return socket;
                   }

                   private final HttpsClient a; /* synthetic field */

               });
           }
           catch(PrivilegedActionException privilegedactionexception)
           {
               throw (IOException)
privilegedactionexception.getException();
           }
           catch(IOException ioexception)
           {
               try
               {
                   obj = (SSLSocket)sslsocketfactory.createSocket(s,
j);
               }
               catch(IOException ioexception1)
               {
                   throw ioexception;
               }
           }
       return ((Socket) (obj));
   }


This change broke the customer's application.  As a workaround they
might be able to implement the https.proxyHost property; however they
believe they have several proxies that the application might load
balance across.  This can not be done by setting a single
https.proxyHost property.

                                    

Comments
EVALUATION

This appears to be a regression due to some significant rework of the https protocol handler in 1.5. Some of this work, specifically connect and read timeouts, was backported to 1.4.2_13 as part of CR 6432143. It is this that caused the problem in the 1.4.2_13 and future 1.4.2_0x release train.

The issue here seems to be that the protocol handlers implementation only uses the socket factory to wrap java.net.Sockets that it has already created. Previous to 1.4.2_13 the handler used the socket factory for all sockets that it created.

I have attached a simple testcase, HttpsSocketFacTest.java, that demonstrates the problem. 

Output of the testcase with various JDKs:
  >: 1.4.2_17; javac HttpsSocketFacTest.java
  >: 1.4.2_12; java -version
  java version "1.4.2_12"
  Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_12-b03)
  Java HotSpot(TM) Client VM (build 1.4.2_12-b03, mixed mode)
  >: java HttpsSocketFacTest https://www.thawte.com/
  SimpleSSLSocketFactory.socketCreated = true
  SimpleSSLSocketFactory.socketWrapped = true
  >: 1.4.2_13; java -version
  java version "1.4.2_13"
  Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_13-b06)
  Java HotSpot(TM) Client VM (build 1.4.2_13-b06, mixed mode)
  >: java HttpsSocketFacT est https://www.thawte.com/
  SimpleSSLSocketFactory.socketCreated = false
  SimpleSSLSocketFactory.socketWrapped = true
  Exception in thread "main" java.lang.RuntimeException: Failed: Socket Factory
  not being called to create Socket
        at HttpsSocketFacTest.<init>(HttpsSocketFacTest.java:52)
        at HttpsSocketFacTest.main(HttpsSocketFacTest.java:31)
  >: 5.0u14; java -version
  java version "1.5.0_14"
  Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)
  Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode)
  >: java HttpsSocketFacTest https://www.thawte.com/
  SimpleSSLSocketFactory.socketCreated = false
  SimpleSSLSocketFactory.socketWrapped = true
  Exception in thread "main" java.lang.RuntimeException: Failed: Socket Factory
  not being called to create Socket
        at HttpsSocketFacTest.<init>(HttpsSocketFacTest.java:52)
        at HttpsSocketFacTest.main(HttpsSocketFacTest.java:31)
  >: 6.0u4; java -version
  java version "1.6.0_04"
  Java(TM) SE Runtime Environment (build 1.6.0_04-b05)
  Java HotSpot(TM) Server VM (build 10.0-b18, mixed mode)
  >: java  HttpsSocketFacTest https://www.thawte.com/
  SimpleSSLSocketFactory.socketCreated = false
  SimpleSSLSocketFactory.socketWrapped = true
  Exception in thread "main" java.lang.RuntimeException: Failed: Socket Factory
  not being called to create Sock et
        at HttpsSocketFacTest.<init>(HttpsSocketFacTest.java:52)
        at HttpsSocketFacTest.main(HttpsSocketFacTest.java:31)
  >: 7; java -version
  java version "1.7.0-ea"
  Java(TM) SE Runtime Environment (build 1.7.0-ea-b21)
  Java HotSpot(TM) Server VM (build 11.0-b07, mixed mode)
  >: java HttpsSocketFacTest https://www.thawte.com/
  SimpleSSLSocketFactory.socketCreated = false
  SimpleSSLSocketFactory.socketWrapped = true
  Exception in thread "main" java.lang.RuntimeException: Failed: Socket Factory
  not being called to create Sock et
        at HttpsSocketFacTest.<init>(HttpsSocketFacTest.java:52)
        at HttpsSocketFacTest.main(HttpsSocketFacTest.java:31)

-------------------

The https protocol handler need to be changed so it invokes the appropriate createSocket method when it needs to create sockets.
                                     
2007-10-12
SUGGESTED FIX

The fix at 6u10 would break the client identity, so when have it fixed at jdk 7, I would suggest combine the fix with 6766775.
                                     
2008-12-12
EVALUATION

changeset for JDK7 (includes fixes for 6614957, 6771432, 6766775 )
  http://hg.openjdk.java.net/jdk7/tl/jdk/rev/8a9ebdc27045
                                     
2010-03-23



Hardware and Software, Engineered to Work Together