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?


thanks a lot!

Michelle

Reply via email to