more fun with ssl (connecting to an MQ Queue Manager)

Ok, this time I was trying to make a client connection to an MQ server using SSL.

If you google for how to do this, most of the hits will show you how to do it with code similar to this:

System.setProperty("javax.net.ssl.keyStore", "<keystoreFilename>");
System.setProperty("javax.net.ssl.keyStorePassword", "<keystorePassword>");

System.setProperty("javax.net.ssl.trustStore", "<truststoreFilename>");
System.setProperty("javax.net.ssl.trustStorePassword", "<truststorePassword>");

The crux of this is that you specify a specific file for your keyStore and trustStore (they may be the same file). The same effect can be achieved by passing these values in as parameters to the JVM with -Djavax.net.ssl.keyStore=<keystoreFilename>, etc.

The problem here is that when you do this, you are setting these values for the entire JVM.

Moreover, many of the MQ docs you come across will tell you to specify the socket factory (more on the SocketFactory later) for the MQ connection by setting the MQEnvironment.sslSocketFactory static variable. Again, setting a static variable is going to affect all MQ connections you make, and this isn’t always what you want. In fact, I would have thought that most of the time, you wouldn’t want this.

What if you needed to use a specific keyStore/trustStore, and the resulting SSLSocketFactory only for one particular connection/session? The answer is to create the SSLSocketFactory using the keystore/truststore, and then pass it to the MQQueueManager constructor like so:


KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/path/to/keystore"), "password".toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "password".toCharArray());

KeyStore ts = KeyStore.getInstance("JKS");
ts.load(new FileInputStream("/path/to/truststore"), "password".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

tmf.init(ts);

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

Hashtable props = new Hashtable();
props.put(MQConstants.SSL_SOCKET_FACTORY_PROPERTY, sslContext.getSocketFactory());

// ccdt is a java.net.URL that points to a client channel definition table file
MQQueueManager manager = new MQQueueManager(managerName, props, ccdt);

So we create a new SocketFactory, and use it to instantiate an MQQueueManager. Doing it this way doesn’t affect any other code in this JVM that may wish to use the default keyStore/trustStore, or any connections to a different Queue Manager.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s