Tech ramblings by Marcin

JCE keystore and untrusted sites

2011-05-02 15:03

Recently at work I was in need of connecting to a web service exposed via HTTPS. I've been doing this from inside Servicemix 3.3.1, which may seem a bit inhibiting, but that was a requirement. Nevertheless I've been trying my luck with the included servicemix-http-2008.01 component. I've created a simple Service Unit using that component and made connection attempt. Unfortunately I've encountered issues with the SSL conversation negotiation. I had to dig deeper into the servicemix-http code to find out these had something to do with my JCE keystore. Read more to find out what happened!

Ok, so I had my xbean.xml for http component looking like this:

As you can see this is a proxy adapter to some outside service exposed via secured HTTP protocol. Since it's HTTPS I've specified some SSL parameters. It was sufficient in my case to just pass the keystore file and it's password.

I've created my keystore.jks file in smx_home/conf with password servicemix in the following manner:

You can see what's in this file with this command:

At this point I thought, that having a configured keystore and my component would suffice. Wrong! As soon as I've tried to connect to the external service I got an exception:

Hmmm.. this looks pretty nasty, but it's not that bad. As one can read here, it's associated with the other site's having an untrusted (unsigned) certificate. Assuming you actually trust the other end of the communication and this situation is ok for you, you should add the servers certificate to your keystore. The previously mentioned link contained a little java class that would do just that. You can find it here (original code) InstallCert.java or you can look into my slightly changed version here at github.

You should call it as follows, assuming that file keystore.jks is in the current directory:

What you'll probably see, when you execute this app is this:

Please note that there is a prompt (Enter certificate to add to trusted keystore...) in which you can enter the certificate number you wish to add to your keystore.

After all those steps my request got through and I could happily query HTTPS service as long as I wanted to! Great!

Possible problems

In my search for this problem's solution I've encountered this kind of exception:

A little googling led me to this StackOverflow question.

It seems that you cannot have multiple keys with different passwords in the same keystore and use KeyManagerFactory class. Oh well...

.

Ending

To sum up, the solution given works, but in my opinion using the InstallCert.java app is rather dirty. I've been wondering, do you know other ways of doing that thing?