Jun 29

This is a follow-up on my previous post on creating certificates for WebSphere MQ.

In one of my customers environment we began having troubles connecting to SSL secured WMQ channels as we upgraded the WebSphere Message Broker Toolkit to version 6.1. After opening a ticket with IBM and getting quite a few groups within Big Blue involved, it turned out that starting with the IBM Java 1.5 JRE, they have added a validation on Basic Constraints for CA certificates. WMB 6.1 ships with Java 1.5. The scripts I published in my last post does not set this attribute. As far as I’ve been able to find, there is no workaround besides recreating your CA certificate, which means re-signing all your keys. This annoys me, but given that the requirement for setting the Basic Constraints has been in the RFC since before dawn, the blame is pretty much my own.

4.2.1.10  Basic Constraints                                            
                                                                       
   The basic constraints extension identifies whether the subject of the
   certificate is a CA and the maximum depth of valid certification    
   paths that include this certificate.                                
                                                                       
The cA boolean indicates whether the certified public key belongs to   
   a CA.  If the cA boolean is not asserted, then the keyCertSign bit in
   the key usage extension MUST NOT be asserted.                       
                                                                       
This extension MUST appear as a critical extension in all CA           
   certificates that contain public keys used to validate digital      
   signatures on certificates. 

Anyways, the script is now updated. The required change is to add the argument “-ca true” when creating the CA certificate.
If you have any further suggestions to improve the scripts, please contact me and I’ll make sure to upgrade them.

May 31
Custom SSL factory
icon1 Niklas | icon2 Tags: , , , . | icon4 05 31st, 2008| icon3No Comments »

I’ve been having this code around for a long time but never seemed to get the time to publish it. Some time ago one of my colleagues asked for a similar solution which finally got me cleaning up the code and publishing it.

Lets have a look at the problem at hand. Using SSL sockets with most Java APIs means setting a bunch of system properties, javax.net.ssl.keyStore and friends. Here be dragons. Using the system properties are in most cases a horrible idea. First of all, the JRE implementation is completely silent on any issues found when it tries to use these system properties, for example due to the key store file path being incorrect. Instead, the SSL handshake will fail in wondrous ways. This will in no way tell you what the real problem is unless you dive into the SSL trace logs. And that’s not an exercise I would recommend for anyone that doesn’t enjoy tedious log files and SSL internals.

In addition, using system properties means the same keystore and truststore must be used for the entire JVM, at least if your application is multithreaded. Want to use different keys for different connections. No can do.

However, some cases the API will allow for providing a custom SSL socket factory. WebSphere MQ is an example of such an API. As described in this post by Peter Broadhurst, you can quite easily provide such a custom socket factory with the benefit of getting much improved exceptions if anything goes wrong.

So, I took some code I had since before, merged it with Peters code and got the following. You use it like this.


        MQQueueConnectionFactory qcf = new MQQueueConnectionFactory();
        qcf.setQueueManager("MYQM");
        qcf.setHostName("localhost");
        qcf.setChannel("SYSTEM.ADMIN.SVRCONN");
        qcf.setSSLCipherSuite(CipherSuite.NULL_SHA);
        qcf.setTransportType(1);

        File ks = new File("mykeystore.jks");

        // create our factory
        PojoSslSocketFactoryFactory sf = new PojoSslSocketFactoryFactory();
        // setting only the key store means that
        // it will also be used as the truststore
        sf.setKeyStore(ks);
        sf.setKeyStorePassword("secret");

	  // create the socket factory
        qcf.setSSLSocketFactory(sf.createSocketFactory());

        Connection conn = qcf.createConnection();

Pretty damn easy. And a huge improvement for those who like getting told what’s wrong with ones configuration. Using the code above, you can also use different key stores within the same JVM.

The code is available as part of the wmq-util project, however it is generic and could be used in most applications using SSL sockets where you would normally used the system properties.

Now we can only hope that, for example, IBM starts using something similar in the WMQ Explorer and WMB Toolkit to make SSL issues easier to debug.

If anyone is interested, I also got the code to make it possible to have multiple keys in the same key store and configure the one needed for each connection. I haven’t yet integrated it with the above code but if there is any interest I’ll do that as well.