Hi, Michelle,

You might find this library helpful.

http://juliusdavies.ca/commons-ssl/

I originally didn't reply to your note because Commons-SSL is quite young -
"Alpha" quality so to speak.  But maybe it will help.  There's a code sample
here:

http://juliusdavies.ca/commons-ssl/ssl.html

Just replace "SSLClient client = new SSLClient();" from the example with
"HttpSecureProtocol client = new HttpSecureProtocol();"  (HttpSecureProtocol
extends SSLClient, and provides the hook into HttpClient).

Here's an example for working with HTTPClient:

http://juliusdavies.ca/commons-ssl/TrustExample.java.html


One thing that's nice about this library is that it's automatically trusting
anything specified by the user in the "javax.net.ssl.trustStore"
System.property, whereas I think the original AuthSSLProtocolSocketFactory
loses that.  (Thanks to Ole Matzura for asking for that!).

Good luck!  These links are only meant to try and help get you started.  I
don't really know if Commons-SSL helps you in this case, but it might get
you pointed in a good direction.  The code examples are definitely not meant
to be just blindly cut & paste into a production environment.  They are more
meant to give people an idea of how the library works.  "
client.setCheckExpiry( false )" alone is inappropriate for production, but I
put it in every example.

Note:  Commons-SSL includes its own version of AuthSSLProtocolSocketFactory!
So you'll need to ditch the AuthSSLProtocolSocketFactory you've already
added to your classpath if you go with Commons-SSL, or at least rename it.


yours,

Julius



On 11/28/06, Erxiang Liu <[EMAIL PROTECTED]> wrote:

Thanks, Oleg:

Yes, We did use AuthSSLProtocolSocketFactory. and it works fine when
passing a URL for a certain keystore.
but the issue is our https url handler is for the whole platform. Once we
register the AuthSSLProtocolSocketFactory.
every https connection would look for the certificate at the location
specified at that URL.
As a result if  now i want to connect to 
*https://bugs.eclipse.org/bugs/*<https://bugs.eclipse.org/bugs/>
it would not work since the certificate is stored in the
default JRE cacerts, not in the keystore specified by the URL.

Obviously, one solution is have a KeyStore implementation, which returned
certs in the user's storage area (ie: their .keystore) as well as a
shared/replicated/managed storage area (like cacerts).

But is there a better solution because we can not ask every customer to
have a special keystore implementation.

thanks,

Michelle

[image: Inactive hide details for Oleg Kalnichevski <[EMAIL PROTECTED]>]Oleg
Kalnichevski <[EMAIL PROTECTED]>



    *Oleg Kalnichevski <[EMAIL PROTECTED]>*

            11/17/2006 10:10 AM Please respond to
            "HttpClient User Discussion" <
            [email protected]>


To

HttpClient User Discussion <[email protected]>
cc


Subject

Re: How to make SSL working with a certificate imported from a keystore
other than cacerts?

On Fri, 2006-11-17 at 09:27 -0600, Erxiang Liu wrote:
>
> We are using the apache httpclient  code to create a custom https URL
> handler.
> The URL handler is registered with the JRE early in platform startup. so
> when a component in our platform opens a https connection, it is
> calling our https URLhandler instead of the default JRE URL handler.
>
> Our https URL handler works fine for a site with a CA issued
certificate.
> (eg. opening a https client connection  to
https://bugs.eclipse.org/bugs/
> works fine).
>
> But doesn't work if the user wants to create his own keystore and import
> the certificate in that keystore and then initialize the sslContext.
> Here is the user code :
>
>             FileInputStream fis = new FileInputStream(truststore_loc);
>             CertificateFactory cf = CertificateFactory.getInstance("
X.509"
> );
>             java.security.cert.Certificate c = cf.generateCertificate
(fis);
>             KeyStore ks = KeyStore.getInstance("JCEKS");
>             TrustManagerFactory tmf = TrustManagerFactory.getInstance(
> TrustManagerFactory.getDefaultAlgorithm());
>             ks.load(null, null);
>             ks.setCertificateEntry("agentAlias", c);
>             tmf.init(ks);
>
>             SSLContext ctx;
>             ctx = SSLContext.getInstance("SSL");
>             ctx.init(null, tmf.getTrustManagers(), null);
>
>
> This works fine when opening a https connection using JRE default https
URL
> handler.  But when we use our https URL handler, we get the following
> error:
>
> javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: PKIX path
> building failed: java.security.cert.CertPathBuilderException: unable to
> find valid certification path to requested target
>       at com.ibm.jsse2.n.a(n.java:17)
>       at com.ibm.jsse2.jc.a(jc.java:541)
>       at com.ibm.jsse2.db.a(db.java:403)
>       at com.ibm.jsse2.db.a(db.java:278)
>       at com.ibm.jsse2.eb.a(eb.java:137)
>       at com.ibm.jsse2.eb.a(eb.java:157)
>       at com.ibm.jsse2.db.m(db.java:243)
>       at com.ibm.jsse2.db.a(db.java:280)
>       at com.ibm.jsse2.jc.a(jc.java:104)
>       at com.ibm.jsse2.jc.g(jc.java:470)
>       at com.ibm.jsse2.jc.a(jc.java:291)
>       at com.ibm.jsse2.j.write(j.java:21)
>       at java.io.BufferedOutputStream.flushBuffer(
> BufferedOutputStream.java:88)
>       at java.io.BufferedOutputStream.flush(BufferedOutputStream.java
:146)
>       at
> org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(
> HttpConnection.java:827)
>       at org.apache.commons.httpclient.HttpMethodBase.writeRequest(
> HttpMethodBase.java:1975)
>       at org.apache.commons.httpclient.HttpMethodBase.execute(
> HttpMethodBase.java:993)
>       at
org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(
> HttpMethodDirector.java:397)
>       at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(
> HttpMethodDirector.java:170)
>       at org.apache.commons.httpclient.HttpClient.executeMethod(
> HttpClient.java:396)
>       at org.apache.commons.httpclient.HttpClient.executeMethod(
> HttpClient.java:324)
>
>
> I took a look at the apache ssl guide and  it says: The default behavior
of
> HttpClient is suitable for most uses, however there are some aspects
which
> you may want to configure. The most common requirements for customizing
SSL
> are:
>       Ability to accept self-signed or untrusted SSL certificates. This
is
>       highlighted by an SSLException with the message Unrecognized SSL
>       handshake (or similar) being thrown when a connection attempt is
>       made.
>       You want to use a third party SSL library instead of Sun's default
>       implementation.
>
> In our case, we are using IBM JSSE, which is third party SSL lib.   I
tried
> the EasySSLProtocolSocketFactory, but that seems
> accept any certificate. If I try to create other custom
> ProtocolSocketFactory and register the
> protocol(Protocol.registerProtocol("https",
> new Protocol("https", new MySSLSocketFactory(), 443)); it only search
the
> certifcate in the key store URL specified
> in the custom protocolsocketFactory. As a result, connect to
> https://bugs.eclipse.org/bugs/ would not work
> since the certificate is stored in the default cacerts.
>
> Right now, our workaround is to ask the user to import the certifcate
into
> the JRE keystore(cacerts ). Does anyone know how to make the apache http
> client code
> working with a certificate imported from a keystore other than cacerts?
>

Michelle,

Have you looked at the AuthSSLProtocolSocketFactory?


http://svn.apache.org/viewvc/jakarta/commons/proper/httpclient/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java?view=markup

Oleg

>
> thanks a lot!
>
> Michelle


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





--
yours,

Julius Davies
416-652-0183
http://juliusdavies.ca/

Reply via email to