JDK-6547437 : REGRESSION:Client authenticated SSL sessions in 6.0 do not renegotiate
  • Type: Bug
  • Component: deploy
  • Sub-Component: deployment_toolkit
  • Affected Version: 6u1
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-04-18
  • Updated: 2010-04-26
  • Resolved: 2007-05-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u4Resolved 7Resolved
Related Reports
Duplicate :  
Relates :  
Description
J2SE Version (please include all output from java -version flag):
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)


Does this problem occur on J2SE 1.4.x or 5.0.x ?  Yes / No (pick one)
The problem does not seem to occur in release prior to JDK 6.0


Operating System Configuration Information (be specific):
Windows XP PRO SP2
IE 7.0

Hardware Configuration Information (be specific):
Sony VIAO laptop 2.8 Gz
1.25 GB RAM


Bug Description:

HTTPS renegotiation unreliable.

I am not sure how the internals of Java's SSL implementation work, but it seems that once an HTTPS session is established everything is fine.  However, if that connection ever times out or gets interrupted, that is it.  

We have a client server app with a webstart deployed application on the desktop connecting to a servlet running in Tomcat.  When using a secure connector with clientAuth = true, and sslProtocol = TLS, the network connection can be destroyed permanently.  This eventually happens when just using our app, however I can reproduce the problem regularly by disabling my network connection.  

I have been disabling my network connection by disabling and enabling my wireless adapter.  While the wireless adapter is disabled, I attempt a some transactions.  Then, once it is enabled again, I attempt more transactions.  5.0_11 recovers from this seamlessly, but 6.0 and 6.0_01 cannot recover at all.  

This is a big deal to us.  We have a government client that uses client certificates for HTTPS authentication.  If they would decided to upgrade to 6.0 (they probably wouldn't tell us ahead of time), all of a sudden things would stop working for them.  Hopefully they would still have Java 5 on their desktops, but they may not.  The people who control the desktops may not feel older versions of Java would still be necessary. 

(The seems to happen more often when I have more than one matching certificate in my IE keystore, however this my just be anecdotal.)

What happens when it fails:
---------- Throwable  Class (class javax.net.ssl.SSLException)  Message(java.lang.NullPointerException) V(4.05.272) ---------- 
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1520)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1487)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1470)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1063)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1040)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:836)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
	at dsi.joint.io.DConnection.createClientWriter(DConnection.java:229)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:195)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:164)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:135)
	at dsi.ext.document.client.action.ActLoadCatalogList.execute(ActLoadCatalogList.java:62)
	at dsi.client.request.AbstractRequest.processBackground(AbstractRequest.java:116)
	at dsi.client.request.RequestExecutor$Queue.processRequest(RequestExecutor.java:151)
	at dsi.client.request.RequestExecutor$Queue.run(RequestExecutor.java:187)
	at java.lang.Thread.run(Thread.java:619)
---------- Throwable  Class (class java.lang.NullPointerException)  Message(null) V(4.05.272) ---------- 
	at com.sun.deploy.security.X509ExtendedDeployTrustManager.isSupportedAlgorithm(Unknown Source)
	at com.sun.deploy.security.X509ExtendedDeployTrustManager.checkServerTrusted(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:954)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:123)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:511)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:449)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:817)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1029)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1056)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1040)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:836)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
	at dsi.joint.io.DConnection.createClientWriter(DConnection.java:229)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:195)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:164)
	at dsi.joint.io.DConnection.sendRequest(DConnection.java:135)
	at dsi.ext.document.client.action.ActLoadCatalogList.execute(ActLoadCatalogList.java:62)
	at dsi.client.request.AbstractRequest.processBackground(AbstractRequest.java:116)
	at dsi.client.request.RequestExecutor$Queue.processRequest(RequestExecutor.java:151)
	at dsi.client.request.RequestExecutor$Queue.run(RequestExecutor.java:187)
	at java.lang.Thread.run(Thread.java:619)


Steps to Reproduce (be specific):

Using a network sniffer, this is the last thing I get before the NPE


00000000  16 03 01 00 49 01 00 00  45 03 01 46 26 1f 27 2f ....I... E..F&.'/
00000010  1d 48 14 6f f5 88 6d a9  31 99 32 19 4e d4 d3 3f .H.o..m. 1.2.N..?
00000020  5f e6 0d 75 ea 30 ca ca  91 93 0b 00 00 1e 00 04 _..u.0.. ........
00000030  00 05 00 2f 00 33 00 32  00 0a 00 16 00 13 00 09 .../.3.2 ........
00000040  00 15 00 12 00 03 00 08  00 14 00 11 01 00       ........ ......
 .......
When testing the apache connector, resetting my wireless adapter will
destroy the connection in 1.6.  However, if I pass in initApacheWithJavaNet
to callUsingApache() and make this the catch block, it will recover.  Note
that the SocketFactory will not change, but something in the java.net stuff
needs to run to make the SocketFactory work.

In JRE 1.5 however, the socket factory will recover on its own and this
java.net stuff in the catch block is unnecessary.

		catch (Exception e) {
			e.printStackTrace();
			if (initApacheWithJavaNet) {
				try {
					System.err.println("callUsingJavaNet
0 default = " + HttpsURLConnection.getDefaultSSLSocketFactory());
					HttpsURLConnection conn =
(HttpsURLConnection)new URL(URL_STRING).openConnection();
					conn.setDoOutput(true);
					OutputStream os2 =
conn.getOutputStream();
					os2.close();
					conn.disconnect();
					System.err.println("callUsingJavaNet
1 default = " + HttpsURLConnection.getDefaultSSLSocketFactory());
				}
				catch (Exception e2) {
					e2.printStackTrace();
				}
			}


					HttpsURLConnection conn =
(HttpsURLConnection)new URL(URL_STRING).openConnection();
					conn.setDoOutput(true);
					OutputStream os2 =
conn.getOutputStream();
					os2.close();
					conn.disconnect();
More information forwarded by the submitter:
These are not the steps I used to reproduce the problem before, but I believe I found a 
quicker way to show the issue.

The attached project, as it is built right now, will run without errors in 1.5, but not in 1.6

Setting "sslTest.initJavaNetWithVerifier" to "false" in the JNLP file will get it to work in both 1.5 and 1.6

Now set:
	testJavaNet = false
	testApache = true
	initJavaNetWithVerifier = false
	initApacheWithJavaNet = false

It will not work in 1.5 or 1.6...with the same exception as in above test.
Setting initApacheWithJavaNet will fix the problem.

Notice also that the HttpsURLConnection's default socket factory changes after URL url = new URL(URL_STRING)!  This is in both 1.5 and 1.6, but seems wrong to me.  This makes it so you can't just get the default, first you need to know the trick and use it first.  This very necessary but undocumented side effect is terribly confusing and took me ages to track down.


In my company's main app, it seems to behave a bit differently if the app is brought down using HTTPS or HTTP.  I could not notice a difference in this one (note that the hardcoded codebase will need to change when you try this), although I didn't test this aspect too much.  





Java Web Start 1.6.0_01
Using JRE version 1.6.0_01 Java HotSpot(TM) Client VM
User home directory = C:\Documents and Settings\mac
----------------------------------------------------
c:   clear console window
f:   finalize objects on finalization queue
g:   garbage collect
h:   display this help message
m:   print memory usage
o:   trigger logging
p:   reload proxy configuration
q:   hide console
r:   reload policy configuration
s:   dump system and deployment properties
t:   dump thread list
v:   dump thread stack
0-5: set trace level to <n>
----------------------------------------------------
1: null
2: null
Testing:  JavaNet(true)  Apache (false)
Before init: com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@53fb57
callUsingJavaNet 0 default = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@53fb57
callUsingJavaNet 1 default = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@15db314
Trying HttpsURLConnection to https://frisky.dev.donnell.com:5406/OcieServlet/Ocie
callUsingJavaNet 1 inUse = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@15db314
Success HttpsURLConnection
callUsingJavaNet 0 default = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@15db314
callUsingJavaNet 1 default = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@15db314
Trying HttpsURLConnection to https://frisky.dev.donnell.com:5406/OcieServlet/Ocie
callUsingJavaNet 1 inUse = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@15db314
Success HttpsURLConnection

Comments
EVALUATION This is the same issue as bug 6514454, closed as duplicated.
22-05-2007