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