hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Claassen <ma...@donnell.com>
Subject Webstart problems with SSL and the DEFAULT SSLSocketFactory
Date Thu, 17 Feb 2011 19:48:49 GMT
I have been using HttpClient for a while now with success.  However, I have recently encountering
some problems which I think have
an easy solution, although it is not accessible to me through the current API.

Situation (my test enviroment):

ServerA:
* Runs Tomcat 6
* Contains jar files that are downloaded via webstart
* Only accepts non-SSL connections

ServerB:
* Runs Tomcat 6
* Contains jar files that are downloaded via webstart
* Contains a servlet
* Only accepts SSL connections

If I connect to serverB (via webstart) and download the jars, my app connects to the servlet
on ServerB and everything is fine.
However, if I connect to ServerA (via webstart), download the jars, and then the app tries
to connect to ServerB, the SSL connection
cannot be established.

I need to use the default socket factory since it is managed by webstart and automatically
prompts for certificate issues and allows
for automatic use of client certificates.

Theory
------
Terminology:
javax.SSLSocketFactory = javax.net.ssl.SSLSocketFactory apache.SSLSocketFactory = org.apache.http.conn.ssl.SSLSocketFactory

I am confused about exactly why this is happening, but I have a theory.  In my theory, the
crux of the problem is that the DEFAULT
apache.SSLSocketFactory is set in the static initializer of the apache.SSLSocketFactory class.
 In the first scenario, webstart
creates a new javax.SSLSocketFactory for the jar download, and makes this the default.  This
happens way before the
apache.SSLSocketFactory is loaded.  In the second scenario, this happens in the other order
and the javax.SSLSocketFactory wrapped
by the apache.SSLSocketFactory is not the correct one.

If I could ensure that the javax.SSLSocketFactory is initialized first, and then create an
apache.SSLSocketFactory to wrap this, I
think I would be in good shape.  The apache.SSLSocketFactory does have a wrapping construtor,
but it is the private no-argument
constructor.  If this were public in some manner, I could ensure my apache.SSLSocketFactory
wraps the correct one.

I don't really see a down-side to making this public.  However, if this needed to be private
to prevent certain types of
subclassing, a static factory method could be added to create an apache.SSLSocketFactory that
wraps a javax.SSLSocketFactory.

Theory Corroborated
--------------------
I downloaded the httpclient 4.01 source (the version we are currently using), changed the
no-arg constructor to be public, and used
it to create a new apache.SSLSocketFactory after I initialized the HttpsURLConnection.  This
did, indeed, solve the problem.
Perhaps there is more going on here than I realize, but it was easy and it worked.

Formal Request:
---------------
I would like to request that the API of apache.SSLSocketFactory be adjusted to handle this
scenario.

My test Details:
----------------
This is how I initialized the default socket factory:

HttpsURLConnection conn = (HttpsURLConnection)new URL(urlString).openConnection(); conn.setDoOutput(true);
OutputStream os =
conn.getOutputStream(); os.close(); conn.disconnect();

apache.SSLSocketFactory fact = new SSLSocketFactory();			
schemeRegistry.register(new Scheme(scheme, fact, port));

Appreviated Stack Trace when error occurs:
------------------------------------------

 ---- (1) ---- Throwable - Class (class javax.net.ssl.SSLException)
 	Message (Connection has been shutdown: 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.SSLSocketImpl.checkEOF(Unknown Source)
 	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(Unknown Source)
 	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
 	at org.apache.http.impl.io.AbstractSessionOutputBuffer.flushBuffer(AbstractSessionOutputBuffer.java:106)
 	at org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:126)
 	at org.apache.http.impl.io.ChunkedOutputStream.flushCache(ChunkedOutputStream.java:99)
 	at org.apache.http.impl.io.ChunkedOutputStream.flush(ChunkedOutputStream.java:175)
 	...
 ---- (2) ---- Throwable - Class (class javax.net.ssl.SSLHandshakeException)
 	Message (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 org.apache.http.impl.io.AbstractSessionOutputBuffer.flushBuffer(AbstractSessionOutputBuffer.java:106)
 	at org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:126)
 	at org.apache.http.impl.io.ChunkedOutputStream.flushCache(ChunkedOutputStream.java:99)
 	at org.apache.http.impl.io.ChunkedOutputStream.flush(ChunkedOutputStream.java:175)
	...
 ---- (3) ---- Throwable - Class (class sun.security.validator.ValidatorException)
 	Message (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)
 	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 org.apache.http.impl.io.AbstractSessionOutputBuffer.flushBuffer(AbstractSessionOutputBuffer.java:106)
 	at org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:126)
 	at org.apache.http.impl.io.ChunkedOutputStream.flushCache(ChunkedOutputStream.java:99)
 	at org.apache.http.impl.io.ChunkedOutputStream.flush(ChunkedOutputStream.java:175)
	...
 ---- (4) ---- Throwable - Class (class sun.security.provider.certpath.SunCertPathBuilderException)
 	Message (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)
 	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)
 	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 org.apache.http.impl.io.AbstractSessionOutputBuffer.flushBuffer(AbstractSessionOutputBuffer.java:106)
 	at org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:126)
 	at org.apache.http.impl.io.ChunkedOutputStream.flushCache(ChunkedOutputStream.java:99)
 	at org.apache.http.impl.io.ChunkedOutputStream.flush(ChunkedOutputStream.java:175)
	...


 






---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org


Mime
View raw message