JDK-6596946 : Using org.apache.commons.httpclient.* cause SunCertPathBuilderException
  • Type: Bug
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 6u3
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-08-24
  • Updated: 2010-09-29
  • Resolved: 2008-04-07
Related Reports
Relates :  
Relates :  
J2SE Version (please include all output from java -version flag):
C:\Documents and Settings\mac>java -version
java version "1.6.0_03-ea"
Java(TM) SE Runtime Environment (build 1.6.0_03-ea-b02)
Java HotSpot(TM) Client VM (build 1.6.0_03-ea-b02, mixed mode, sharing)

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

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

Bug Description:

This is a follow-up on 6547437 which is stated as fixed, however it is only partially fixed.  The renegotiation is fixed, but the initial socket still causes a exception
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
	at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
	at java.io.BufferedOutputStream.flush(Unknown Source)
	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(Unknown Source)
	at org.apache.commons.httpclient.HttpMethodBase.writeRequest(Unknown Source)
	at org.apache.commons.httpclient.HttpMethodBase.execute(Unknown Source)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(Unknown Source)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(Unknown Source)
	at org.apache.commons.httpclient.HttpClient.executeMethod(Unknown Source)
	at org.apache.commons.httpclient.HttpClient.executeMethod(Unknown Source)
	at ssltest.Main.callUsingApache(Main.java:178)
	at ssltest.Main.main(Main.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.sun.javaws.Launcher.executeApplication(Unknown Source)
	at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
	at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
	at com.sun.javaws.Launcher.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
	at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
	at sun.security.validator.Validator.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	... 28 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
	at java.security.cert.CertPathBuilder.build(Unknown Source)
	... 34 more

Attached is a modified version of the test program submitted in for 6547437.  

Steps to Reproduce (be specific):

No changes are necessary to the .java file

Make sure the URLs in the jnlp file are both specified correctly.  
They should both have the host name : port of the machine with the JNLP file

As submitted, the program will throw an exception
	"sslTest.listProxies" is "false"
	"sslTest.initJavaNetWithVerifier" is "false"

Now change the JNLP file:
In the jnlp file, set:
	"sslTest.listProxies" to "true"
	"sslTest.initJavaNetWithVerifier" to "false"
The exception will not occur

In the jnlp file, set 
	"sslTest.listProxies" to "false"
	"sslTest.initJavaNetWithVerifier" to "true"
The exception will not occur

EVALUATION After exchange message with deployment team, the bug description scenarios work with jdk 6 update 4. It's not a bug any more, so close the bug as not a defect. -------------------------- It's glade to hear the fix works for your application. I will close the bug. Thanks, Andrew Mark Claassen wrote: > Thanks for the reply, but I believe this issue was fixed already in 6.0 > update 4. I worked with Dennis Gu (who was on the deployment team) to work > on the test case. I appreciate the information, but I don't think it is > necessary anymore. > > For Java 6 releases < update 4, I implemented a work-around by simply > retrying the connection if I detect this error. I put it in a loop that, I > think, tries up to 4 times. I found that this NPE rarely happens in back to > back invocations. > > Mark > > -----Original Message----- > From: ###@###.### [mailto:###@###.### On Behalf Of Andrew Fan > Sent: Saturday, March 22, 2008 7:46 AM > To: ###@###.### > Cc: ###@###.### > Subject: [Fwd: Re: CR 6596946 Updated P3 jsse/runtime Using > org.apache.commons.httpclient.* cause SunCertPathBuilderException] > > Hi, > > I'm working the bug, using org.apache.commons.httpclient.* cause > SunCertPathBuilderException. I think the issue is caused by that the client > failed to build a certificate path, generally, when the server doesn't send > a complete cert path to the client, the client will have to build a path > based on its trusted key store, if client cannot find the proper cert for > the path building, the handshaking will failed. > > I think there are two workaround for the issue, 1. add the server root > certificate to the client trusted key store, and configure the http server > send a complete cert path to the client. > 2. implement a trust manager that accept the server certificate, refer to > http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuid > e.html > for details. > > Thanks, > Andrew > >

EVALUATION The exception stack tells that the certificate path validator failed to build a valid certificate path. And in SUNJsse implementation, the trust manager factory will try to initialize the default certificate authority(ca) key store if no explicity ca key store specified by programmer or application. During cert path validating, a valid cert path will depend on the key store. Accorind to the description, exception stack, and the test case, I think the org.apache.commons.HttpClient.* need do more on introduce the trusted key store for cert path validating. Maybe the customers does not use those org.apache.commons.httpClient classes correctly or the org.apache.commons.httpClient implement has some issues on trust anchor. I will close the bug if the customer agree. After reading org.apache.commons.HttpClient classes, I need to re-evaluate the bug.

EVALUATION The testcase is attached to the bug report, I have tested and reproduce the bug. There are several props value in jnlp file to manipulate the testcase: <property name="sslTest.testJavaNet" value= "false"/> <property name="sslTest.testApache" value= "true"/> <property name="sslTest.initJavaNetWithVerifier" value= "false"/> <property name="sslTest.initApacheWithJavaNet" value= "false"/> <property name="sslTest.listProxies" value= "false"/> 1. If testJavaNet is set to true, then testcase works fine, the bug is only reproduced when testJavaNet is false and testApache is true. (Customer complain that Sun has continually refused to fix this. The calls block, even the call to open the connection, until at least some data arrives. I have found no way to reliably and quickly cancel a request while using HttpURLConnection, so finally I gave up trying. Also, in performance tests, HttpClient is remarkably faster. I don't remember the results I got when I ran the tests, but I think it was something on the order 10 times. My test case was to establish a connection and then read a small amount of data from a URL 1000s of times. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6313207) 2. Bug is reproduced when both listProxies and initApacheWithJavaNet is set to false. 3. This bug is not a regression, and I reproduced it using JRE1.5 as well. Customer complain that the SSLSocket factory cannot be used unless it is first used by HttpsURLConnection. There are no public initialization methods that I can see, so my options are limited. If there is a mandatory initialization phase, then this should be available for use and documented in some fashion. I think this is an bug related to httpclient class or HttpURLConnection class, this is nothing to do with Java webstart, it will happened to standalone application as well, I transfter this to Java Network group for further evaluation. Please let me know if you have questions.