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/
