You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Mark Claassen <ma...@donnell.com> on 2012/04/04 23:01:19 UTC

Access to "system" SSL socket factory.

We are still using HttpClient 4.01 and were considering upgrading to 4.1, but I see a feature we were using is gone.  In 4.01, there
was a DEFAULT_FACTORY which was the defined from HttpsURLConnection.getDefaultSSLSocketFactory();

This was very useful to us.  The reason for this was because our app is launched by Java Webstart.  When using the default socket
factory, we can benefit from Webstart handling the prompting for things like host name verification.

More importantly, however, was webstart's ability to interface with the Window's keystore.  We have a client that uses certificated
based authentication for their SSL connections.  Using the default socket factory makes everything just work.  The users would get
prompted for a certificate and then they could activate it off their hardware devices.  (Presumably, then, the SSL encryption is
handled by the device.  I have no idea how I would do this without webstart.)

I guess I would like to know what is my best path to take to get this working.  Could I just subclass it and then override the
connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...

Thanks,
Mark




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


RE: Access to "system" SSL socket factory.

Posted by Mark Claassen <ma...@donnell.com>.
So I created an issue for this:
https://issues.apache.org/jira/browse/HTTPCLIENT-1182

I attached the small patch that it would take.  I made and tested it with 4.1.3, but it should work with 4.2 as well.  I don't think there is much of a downside risk to this.  The only think I can really think of is that the internal SSLSocketFactory is not completely private...meaning that whatever code passed in the socket factory could still be using it separately.  Not sure if this is a much of an issue though.

Hopefully this can be included in some near-future release.

Thanks,
Mark

-----Original Message-----
From: Mark Claassen [mailto:mac01@donnell.com] 
Sent: Monday, April 09, 2012 4:24 PM
To: 'HttpClient User Discussion'
Subject: RE: Access to "system" SSL socket factory.

I only included the hostname resolver in my constructor because it was a final variable.

> There is a SSLSocketFactory(SSLContext, X509HostnameVerifier) constructor which is effectively equivalent to SSLSocketFactory(javax.net.ssl.SSLSocketFactory X509HostnameVerifier) as far as I can tell.

I don't think so.  This is the similar to what is in 4.2 beta1.  I think I just need to use the default one from HttpsURLConnection.  All the certificate stuff is handled internally to Webstart.  Webstart has its own keystore information, but can also access the System's.  I have not asked the Oracle deployment folks for all these gritty details, but the wrapping concept seems to work.  I could try to check with Oracle, but I don't think another similar one could be created.

I think I will submit a patch to HttpClient as you suggested and see what happens.

Mark


-----Original Message-----
From: Oleg Kalnichevski [mailto:olegk@apache.org]
Sent: Monday, April 09, 2012 4:11 PM
To: HttpClient User Discussion
Subject: RE: Access to "system" SSL socket factory.

On Mon, 2012-04-09 at 15:18 -0400, Mark Claassen wrote:
> I have had some success wrapping the socket factory in HTTP Client
> (v4.1.3) and getting that to work. :) However, I have a few
> questions:
> 
> First, how do you feel about having a constructor that would set the final variables directly:
> - javax.net.ssl.SSLSocketFactory
> - HostNameResolver
> - X509HostnameVerifier
> Having this would have made what I needed to do very straight-forward 
> and simple since I could have just passed in the socket factory I wanted to use.
> 

Hi Mark

HostNameResolver has been deprecated in 4.2 because it does not support multi-home hostnames. Moreover, the DNS resolution logic has been moved from scheme socket factory level to the connection operator level.

There is a SSLSocketFactory(SSLContext, X509HostnameVerifier) constructor which is effectively equivalent to SSLSocketFactory(javax.net.ssl.SSLSocketFactory X509HostnameVerifier) as far as I can tell. But by all of means feel free to submit a patch.

> Second, in this class there is a Socket created not through the 
> SocketFactory in one place, and I was wondering why.  Here is what it 
> looks like in org.apache.http.conn.ssl.SSLSocketFactory
> 
>     public Socket connectSocket(
>             final Socket socket,
>             final InetSocketAddress remoteAddress,
>             final InetSocketAddress localAddress,
>             final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
>         if (remoteAddress == null) {
>             throw new IllegalArgumentException("Remote address may not be null");
>         }
>         if (params == null) {
>             throw new IllegalArgumentException("HTTP parameters may not be null");
>         }
> >>>>    Socket sock = socket != null ? socket : new Socket(); <<<<
> 
> Shouldn't this be
>         Socket sock = socket != null ? socket : 
> socketfactory.createSocket();
> 

Yes, this is obviously conceptually wrong. Fixed in SVN trunk.

Oleg

> Later in the code, it then checks the Socket type, and since it will not be an SSL socket, it will then call:
>         this.socketfactory.createSocket(sock, hostname, port, true);
> 
> This seemed an odd pattern to me.  I can see a potential reason for 
> it, but wasn't sure about it and was not sure if this would be a possible point of failure in my situation.
>
> Thanks,
> Mark
> 
> -----Original Message-----
> From: Mark Claassen [mailto:mac01@donnell.com]
> Sent: Wednesday, April 04, 2012 5:01 PM
> To: httpclient-users@hc.apache.org
> Subject: Access to "system" SSL socket factory.
> 
> We are still using HttpClient 4.01 and were considering upgrading to 
> 4.1, but I see a feature we were using is gone.  In 4.01, there was a 
> DEFAULT_FACTORY which was the defined from 
> HttpsURLConnection.getDefaultSSLSocketFactory();
> 
> This was very useful to us.  The reason for this was because our app 
> is launched by Java Webstart.  When using the default socket factory, we can benefit from Webstart handling the prompting for things like host name verification.
> 
> More importantly, however, was webstart's ability to interface with 
> the Window's keystore.  We have a client that uses certificated based 
> authentication for their SSL connections.  Using the default socket 
> factory makes everything just work.  The users would get prompted for 
> a certificate and then they could activate it off their hardware 
> devices.  (Presumably, then, the SSL encryption is handled by the 
> device.  I have no idea how I would do this without webstart.)
> 
> I guess I would like to know what is my best path to take to get this 
> working.  Could I just subclass it and then override the
> connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...
> 
> Thanks,
> Mark
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 



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


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


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


RE: Access to "system" SSL socket factory.

Posted by Mark Claassen <ma...@donnell.com>.
I only included the hostname resolver in my constructor because it was a final variable.

> There is a SSLSocketFactory(SSLContext, X509HostnameVerifier) constructor which is effectively equivalent to SSLSocketFactory(javax.net.ssl.SSLSocketFactory X509HostnameVerifier) as far as I can tell.

I don't think so.  This is the similar to what is in 4.2 beta1.  I think I just need to use the default one from HttpsURLConnection.  All the certificate stuff is handled internally to Webstart.  Webstart has its own keystore information, but can also access the System's.  I have not asked the Oracle deployment folks for all these gritty details, but the wrapping concept seems to work.  I could try to check with Oracle, but I don't think another similar one could be created.

I think I will submit a patch to HttpClient as you suggested and see what happens.

Mark


-----Original Message-----
From: Oleg Kalnichevski [mailto:olegk@apache.org] 
Sent: Monday, April 09, 2012 4:11 PM
To: HttpClient User Discussion
Subject: RE: Access to "system" SSL socket factory.

On Mon, 2012-04-09 at 15:18 -0400, Mark Claassen wrote:
> I have had some success wrapping the socket factory in HTTP Client 
> (v4.1.3) and getting that to work. :) However, I have a few
> questions:
> 
> First, how do you feel about having a constructor that would set the final variables directly:
> - javax.net.ssl.SSLSocketFactory
> - HostNameResolver
> - X509HostnameVerifier
> Having this would have made what I needed to do very straight-forward 
> and simple since I could have just passed in the socket factory I wanted to use.
> 

Hi Mark

HostNameResolver has been deprecated in 4.2 because it does not support multi-home hostnames. Moreover, the DNS resolution logic has been moved from scheme socket factory level to the connection operator level.

There is a SSLSocketFactory(SSLContext, X509HostnameVerifier) constructor which is effectively equivalent to SSLSocketFactory(javax.net.ssl.SSLSocketFactory X509HostnameVerifier) as far as I can tell. But by all of means feel free to submit a patch.

> Second, in this class there is a Socket created not through the 
> SocketFactory in one place, and I was wondering why.  Here is what it 
> looks like in org.apache.http.conn.ssl.SSLSocketFactory
> 
>     public Socket connectSocket(
>             final Socket socket,
>             final InetSocketAddress remoteAddress,
>             final InetSocketAddress localAddress,
>             final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
>         if (remoteAddress == null) {
>             throw new IllegalArgumentException("Remote address may not be null");
>         }
>         if (params == null) {
>             throw new IllegalArgumentException("HTTP parameters may not be null");
>         }
> >>>>    Socket sock = socket != null ? socket : new Socket(); <<<<
> 
> Shouldn't this be
>         Socket sock = socket != null ? socket : 
> socketfactory.createSocket();
> 

Yes, this is obviously conceptually wrong. Fixed in SVN trunk.

Oleg

> Later in the code, it then checks the Socket type, and since it will not be an SSL socket, it will then call:
>         this.socketfactory.createSocket(sock, hostname, port, true);
> 
> This seemed an odd pattern to me.  I can see a potential reason for 
> it, but wasn't sure about it and was not sure if this would be a possible point of failure in my situation.
>
> Thanks,
> Mark
> 
> -----Original Message-----
> From: Mark Claassen [mailto:mac01@donnell.com]
> Sent: Wednesday, April 04, 2012 5:01 PM
> To: httpclient-users@hc.apache.org
> Subject: Access to "system" SSL socket factory.
> 
> We are still using HttpClient 4.01 and were considering upgrading to 
> 4.1, but I see a feature we were using is gone.  In 4.01, there was a 
> DEFAULT_FACTORY which was the defined from 
> HttpsURLConnection.getDefaultSSLSocketFactory();
> 
> This was very useful to us.  The reason for this was because our app 
> is launched by Java Webstart.  When using the default socket factory, we can benefit from Webstart handling the prompting for things like host name verification.
> 
> More importantly, however, was webstart's ability to interface with 
> the Window's keystore.  We have a client that uses certificated based 
> authentication for their SSL connections.  Using the default socket 
> factory makes everything just work.  The users would get prompted for 
> a certificate and then they could activate it off their hardware 
> devices.  (Presumably, then, the SSL encryption is handled by the 
> device.  I have no idea how I would do this without webstart.)
> 
> I guess I would like to know what is my best path to take to get this 
> working.  Could I just subclass it and then override the
> connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...
> 
> Thanks,
> Mark
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 



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


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


RE: Access to "system" SSL socket factory.

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Mon, 2012-04-09 at 15:18 -0400, Mark Claassen wrote:
> I have had some success wrapping the socket factory in HTTP Client (v4.1.3) and getting that to work. :) However, I have a few
> questions:
> 
> First, how do you feel about having a constructor that would set the final variables directly:
> - javax.net.ssl.SSLSocketFactory
> - HostNameResolver
> - X509HostnameVerifier
> Having this would have made what I needed to do very straight-forward and simple since I could have just passed in the socket
> factory I wanted to use.
> 

Hi Mark

HostNameResolver has been deprecated in 4.2 because it does not support
multi-home hostnames. Moreover, the DNS resolution logic has been moved
from scheme socket factory level to the connection operator level.

There is a SSLSocketFactory(SSLContext, X509HostnameVerifier)
constructor which is effectively equivalent to
SSLSocketFactory(javax.net.ssl.SSLSocketFactory X509HostnameVerifier) as
far as I can tell. But by all of means feel free to submit a patch.

> Second, in this class there is a Socket created not through the SocketFactory in one place, and I was wondering why.  Here is what
> it looks like in org.apache.http.conn.ssl.SSLSocketFactory
> 
>     public Socket connectSocket(
>             final Socket socket,
>             final InetSocketAddress remoteAddress,
>             final InetSocketAddress localAddress,
>             final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
>         if (remoteAddress == null) {
>             throw new IllegalArgumentException("Remote address may not be null");
>         }
>         if (params == null) {
>             throw new IllegalArgumentException("HTTP parameters may not be null");
>         }
> >>>>    Socket sock = socket != null ? socket : new Socket(); <<<<
> 
> Shouldn't this be
>         Socket sock = socket != null ? socket : socketfactory.createSocket();
> 

Yes, this is obviously conceptually wrong. Fixed in SVN trunk.

Oleg

> Later in the code, it then checks the Socket type, and since it will not be an SSL socket, it will then call:
>         this.socketfactory.createSocket(sock, hostname, port, true);
> 
> This seemed an odd pattern to me.  I can see a potential reason for it, but wasn't sure about it and was not sure if this would be a
> possible point of failure in my situation.
>
> Thanks,
> Mark
> 
> -----Original Message-----
> From: Mark Claassen [mailto:mac01@donnell.com] 
> Sent: Wednesday, April 04, 2012 5:01 PM
> To: httpclient-users@hc.apache.org
> Subject: Access to "system" SSL socket factory.
> 
> We are still using HttpClient 4.01 and were considering upgrading to 4.1, but I see a feature we were using is gone.  In 4.01, there
> was a DEFAULT_FACTORY which was the defined from HttpsURLConnection.getDefaultSSLSocketFactory();
> 
> This was very useful to us.  The reason for this was because our app is launched by Java Webstart.  When using the default socket
> factory, we can benefit from Webstart handling the prompting for things like host name verification.
> 
> More importantly, however, was webstart's ability to interface with the Window's keystore.  We have a client that uses certificated
> based authentication for their SSL connections.  Using the default socket factory makes everything just work.  The users would get
> prompted for a certificate and then they could activate it off their hardware devices.  (Presumably, then, the SSL encryption is
> handled by the device.  I have no idea how I would do this without webstart.)
> 
> I guess I would like to know what is my best path to take to get this working.  Could I just subclass it and then override the
> connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...
> 
> Thanks,
> Mark
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
> For additional commands, e-mail: httpclient-users-help@hc.apache.org
> 



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


RE: Access to "system" SSL socket factory.

Posted by Mark Claassen <ma...@donnell.com>.
I have had some success wrapping the socket factory in HTTP Client (v4.1.3) and getting that to work. :) However, I have a few
questions:

First, how do you feel about having a constructor that would set the final variables directly:
- javax.net.ssl.SSLSocketFactory
- HostNameResolver
- X509HostnameVerifier
Having this would have made what I needed to do very straight-forward and simple since I could have just passed in the socket
factory I wanted to use.

Second, in this class there is a Socket created not through the SocketFactory in one place, and I was wondering why.  Here is what
it looks like in org.apache.http.conn.ssl.SSLSocketFactory

    public Socket connectSocket(
            final Socket socket,
            final InetSocketAddress remoteAddress,
            final InetSocketAddress localAddress,
            final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
        if (remoteAddress == null) {
            throw new IllegalArgumentException("Remote address may not be null");
        }
        if (params == null) {
            throw new IllegalArgumentException("HTTP parameters may not be null");
        }
>>>>    Socket sock = socket != null ? socket : new Socket(); <<<<

Shouldn't this be
        Socket sock = socket != null ? socket : socketfactory.createSocket();

Later in the code, it then checks the Socket type, and since it will not be an SSL socket, it will then call:
        this.socketfactory.createSocket(sock, hostname, port, true);

This seemed an odd pattern to me.  I can see a potential reason for it, but wasn't sure about it and was not sure if this would be a
possible point of failure in my situation.

Thanks,
Mark

-----Original Message-----
From: Mark Claassen [mailto:mac01@donnell.com] 
Sent: Wednesday, April 04, 2012 5:01 PM
To: httpclient-users@hc.apache.org
Subject: Access to "system" SSL socket factory.

We are still using HttpClient 4.01 and were considering upgrading to 4.1, but I see a feature we were using is gone.  In 4.01, there
was a DEFAULT_FACTORY which was the defined from HttpsURLConnection.getDefaultSSLSocketFactory();

This was very useful to us.  The reason for this was because our app is launched by Java Webstart.  When using the default socket
factory, we can benefit from Webstart handling the prompting for things like host name verification.

More importantly, however, was webstart's ability to interface with the Window's keystore.  We have a client that uses certificated
based authentication for their SSL connections.  Using the default socket factory makes everything just work.  The users would get
prompted for a certificate and then they could activate it off their hardware devices.  (Presumably, then, the SSL encryption is
handled by the device.  I have no idea how I would do this without webstart.)

I guess I would like to know what is my best path to take to get this working.  Could I just subclass it and then override the
connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...

Thanks,
Mark




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


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


RE: Access to "system" SSL socket factory.

Posted by Mark Claassen <ma...@donnell.com>.
Thanks for the reply.  I think that addresses my questions.  I will check out the 4.2 source code and see if that is what I had in mind.

Mark


-----Original Message-----
From: Oleg Kalnichevski [mailto:olegk@apache.org] 
Sent: Monday, April 09, 2012 3:55 PM
To: HttpClient User Discussion
Subject: Re: Access to "system" SSL socket factory.

On Wed, 2012-04-04 at 17:01 -0400, Mark Claassen wrote:
> We are still using HttpClient 4.01 and were considering upgrading to 
> 4.1, but I see a feature we were using is gone.  In 4.01, there was a 
> DEFAULT_FACTORY which was the defined from 
> HttpsURLConnection.getDefaultSSLSocketFactory();
> 
> This was very useful to us.  The reason for this was because our app 
> is launched by Java Webstart.  When using the default socket factory, we can benefit from Webstart handling the prompting for things like host name verification.
> 
> More importantly, however, was webstart's ability to interface with 
> the Window's keystore.  We have a client that uses certificated based 
> authentication for their SSL connections.  Using the default socket 
> factory makes everything just work.  The users would get prompted for 
> a certificate and then they could activate it off their hardware 
> devices.  (Presumably, then, the SSL encryption is handled by the 
> device.  I have no idea how I would do this without webstart.)
> 
> I guess I would like to know what is my best path to take to get this 
> working.  Could I just subclass it and then override the
> connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...
> 
> Thanks,
> Mark
> 

Hi Mark

I am sorry I could not respond sooner. Yes, indeed, I felt HttpClient should not have had a direct dependency on HttpsURLConnection class.

You have two options: 
(1) create a custom SSL socket factory that makes use of
HttpsURLConnection#getDefaultSSLSocketFactory()

(2) Upgrade to 4.2 and use SSLSocketFactory#getSystemSocketFactory().
This method creates an instance of SSLSocketFactory class using standard JSSE system properties similar to HttpsURLConnection

Oleg


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


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


Re: Access to "system" SSL socket factory.

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Wed, 2012-04-04 at 17:01 -0400, Mark Claassen wrote:
> We are still using HttpClient 4.01 and were considering upgrading to 4.1, but I see a feature we were using is gone.  In 4.01, there
> was a DEFAULT_FACTORY which was the defined from HttpsURLConnection.getDefaultSSLSocketFactory();
> 
> This was very useful to us.  The reason for this was because our app is launched by Java Webstart.  When using the default socket
> factory, we can benefit from Webstart handling the prompting for things like host name verification.
> 
> More importantly, however, was webstart's ability to interface with the Window's keystore.  We have a client that uses certificated
> based authentication for their SSL connections.  Using the default socket factory makes everything just work.  The users would get
> prompted for a certificate and then they could activate it off their hardware devices.  (Presumably, then, the SSL encryption is
> handled by the device.  I have no idea how I would do this without webstart.)
> 
> I guess I would like to know what is my best path to take to get this working.  Could I just subclass it and then override the
> connectSocket() methods?  I noticed that the javax SSLSocketFactory has similar createSocket() methods...
> 
> Thanks,
> Mark
> 

Hi Mark

I am sorry I could not respond sooner. Yes, indeed, I felt HttpClient
should not have had a direct dependency on HttpsURLConnection class.

You have two options: 
(1) create a custom SSL socket factory that makes use of
HttpsURLConnection#getDefaultSSLSocketFactory()

(2) Upgrade to 4.2 and use SSLSocketFactory#getSystemSocketFactory().
This method creates an instance of SSLSocketFactory class using standard
JSSE system properties similar to HttpsURLConnection

Oleg


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