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 Oleg Kalnichevski <ol...@apache.org> on 2006/11/28 17:45:05 UTC
Re: How to make SSL working with a certificate imported from
a keystore other than cacerts?
On Tue, 2006-11-28 at 09:42 -0600, Erxiang Liu 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/ 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
Michelle,
Simply instantiate multiple protocol objects, one per keystore
ProtocolSocketFactory socketfactory1 = new
AuthSSLProtocolSocketFactory(...);
Protocol myhttps1 = new Protocol("https", socketfactory1, 443);
Protocol.registerProtocol("myhttps1", myhttps1);
ProtocolSocketFactory socketfactory2 = new
AuthSSLProtocolSocketFactory(...);
Protocol myhttps2 = new Protocol("https", socketfactory2, 443);
Protocol.registerProtocol("myhttps2", myhttps1);
You can use those custom protocol schemes in the request URIs
GetMethod get1 = new GetMethod("myhttps1://targethost1/stuff");
httpclient.executeMethod(get1);
Or employ them using a custom HostConfiguration on a per request basis
HostConfiguration hostconf = new HostConfiguration();
hostconf.setHost("targethost2", -1, myhttps2);
GetMethod get2 = new GetMethod("/stuff");
httpclient.executeMethod(hostconf2, get2);
In the latter case it is not necessary to register custom protocols with
the Protocol class. Just make sure you use _relative_ URIs when passing
a custom HostConfiguration instance to httpclient#executeMethod
Hope this helps
Oleg
>
> Inactive hide details for Oleg Kalnichevski <ol...@apache.org>Oleg
> Kalnichevski <ol...@apache.org>
>
>
> Oleg Kalnichevski <ol...@apache.org>
>
> 11/17/2006 10:10 AM
> Please respond to
> "HttpClient User Discussion" <ht...@jakarta.apache.org>
>
>
> To
>
> HttpClient User
> Discussion
> <ht...@jakarta.apache.org>
>
> 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: httpclient-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> httpclient-user-help@jakarta.apache.org
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpclient-user-help@jakarta.apache.org