Secure Sockets Layer (SSL) support

WebSphere MQ base Java client applications and WebSphere MQ JMS connections using TRANSPORT(CLIENT) support Secure Sockets Layer (SSL) encryption. SSL provides communication encryption, authentication, and message integrity. It is typically used to secure communications between any two peers on the Internet or within an intranet.

WebSphere MQ classes for Java uses Java Secure Socket Extension (JSSE) to handle SSL encryption, and so requires a JSSE provider. J2SE v1.4 JVMs have a JSSE provider built in. Details of how to manage and store certificates can vary from provider to provider. For information about this, refer to your JSSE provider's documentation.

This section assumes that your JSSE provider is correctly installed and configured, and that suitable certificates have been installed and made available to your JSSE provider.

If your WebSphere MQ base Java client application uses a client channel definition table to connect to a queue manager, see Using a client channel definition table.

Enabling SSL

SSL is supported only for client connections. To enable SSL, you must specify the CipherSuite to use when communicating with the queue manager, and this must match the CipherSpec set on the target channel. Additionally, the named CipherSuite must be supported by your JSSE provider. However, CipherSuites are distinct from CipherSpecs and so have different names. Appendix D. SSL CipherSpecs and CipherSuites contains a table mapping the CipherSpecs supported by WebSphere(R) MQ to their equivalent CipherSuites as known to JSSE.

To enable SSL, specify the CipherSuite using the sslCipherSuite static member variable of MQEnvironment. The following example attaches to a SVRCONN channel named SECURE.SVRCONN.CHANNEL, which has been set up to require SSL with a CipherSpec of RC4_MD5_EXPORT:

MQEnvironment.hostname       = "your_hostname";
MQEnvironment.channel        = "SECURE.SVRCONN.CHANNEL";
MQEnvironment.sslCipherSuite = "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
MQQueueManager qmgr = new MQQueueManager("your_Q_manager");

Note that, although the channel has a CipherSpec of RC4_MD5_EXPORT, the Java application must specify a CipherSuite of SSL_RSA_EXPORT_WITH_RC4_40_MD5. For more information about CipherSpecs and CipherSuites, see the WebSphere MQ Security book. See Appendix D. SSL CipherSpecs and CipherSuites for a list of mappings between CipherSpecs and CipherSuites.

An application can also specify a CipherSuite by setting the environment property MQC.SSL_CIPHER_SUITE_PROPERTY.

If you require a client connection to use a CipherSuite that is supported by the IBM Java JSSE FIPS provider (IBMJSSEFIPS), an application can set the sslFipsRequired field in the MQEnvironment class to true. Alternatively, the application can set the environment property MQC.SSL_FIPS_REQUIRED_PROPERTY. The default value is false, which means that a client connection can use any CipherSuite that is not supported by IBMJSSEFIPS.

If an application uses more than one client connection, the value of the sslFipsRequired field that is used when the application creates the first client connection determines the value that is used when the application creates any subsequent client connection. This means that, when the application creates a subsequent client connection, the value of the sslFipsRequired field is ignored. You must restart the application if you want to use a different value for the sslFipsRequired field.

To connect successfully using SSL, the JSSE truststore must be set up with Certificate Authority root certificates from which the certificate presented by the queue manager can be authenticated. Similarly, if SSLClientAuth on the SVRCONN channel has been set to MQSSL_CLIENT_AUTH_REQUIRED, the JSSE keystore must contain an identifying certificate that is trusted by the queue manager.

Using the distinguished name of the queue manager

The queue manager identifies itself using an SSL certificate, which contains a Distinguished Name (DN). A WebSphere MQ base Java client application can use this DN to ensure that it is communicating with the correct queue manager. A DN pattern is specified using the sslPeerName variable of MQEnvironment. For example, setting:

  MQEnvironment.sslPeerName = "CN=QMGR.*, OU=IBM, OU=WEBSPHERE";

allows the connection to succeed only if the queue manager presents a certificate with a Common Name beginning QMGR., and at least two Organizational Unit names, the first of which must be IBM and the second WEBSPHERE.

If sslPeerName is set, connections succeed only if it is set to a valid pattern and the queue manager presents a matching certificate.

An application can also specify the distinguished name of the queue manager by setting the environment property MQC.SSL_PEER_NAME_PROPERTY. For more information about distinguished names, see WebSphere MQ Security.

Using certificate revocation lists

A certificate revocation list (CRL) is a set of certificates that have been revoked, either by the issuing Certificate Authority or by the local organization. CRLs are typically hosted on LDAP servers. With Java 2 v1.4, a CRL server can be specified at connect-time and the certificate presented by the queue manager is checked against the CRL before the connection is allowed. For more information about certificate revocation lists and WebSphere MQ, see WebSphere MQ Security.

Note:
To use a CertStore successfully with a CRL hosted on an LDAP server, make sure that your Java Software Development Kit (SDK) is compatible with the CRL. Some SDKs require that the CRL conforms to RFC 2587, which defines a schema for LDAP v2. Most LDAP v3 servers use RFC 2256 instead.

The CRLs to use are specified through the java.security.cert.CertStore class. Refer to documentation on this class for full details of how to obtain instances of CertStore. To create a CertStore based on an LDAP server, first create an LDAPCertStoreParameters instance, initialized with the server and port settings to use. For example:

import java.security.cert.*;
CertStoreParameters csp = new LDAPCertStoreParameters("crl_server", 389);

Having created a CertStoreParameters instance, use the static constructor on CertStore to create a CertStore of type LDAP:

CertStore cs = CertStore.getInstance("LDAP", csp);

Other CertStore types (for example, Collection) are also supported. Commonly there are several CRL servers set up with identical CRL information to give redundancy. Once you have a CertStore object for each of these CRL servers, place them all in a suitable Collection. The following example shows the CertStore objects placed in an ArrayList:

import java.util.ArrayList;
Collection crls = new ArrayList();
crls.add(cs);

This Collection can be set into the MQEnvironment static variable, sslCertStores, before connecting to enable CRL checking:

MQEnvironment.sslCertStores = crls;

The certificate presented by the queue manager when a connection is being set up is validated as follows:

  1. The first CertStore object in the Collection identified by sslCertStores is used to identify a CRL server.
  2. An attempt is made to contact the CRL server.
  3. If the attempt is successful, the server is searched for a match for the certificate.
    1. If the certificate is found to be revoked, the search process is over and the connection request fails with reason code MQRC_SSL_CERTIFICATE_REVOKED.
    2. If the certificate is not found, the search process is over and the connection is allowed to proceed.
  4. If the attempt to contact the server is unsuccessful, the next CertStore object is used to identify a CRL server and the process repeats from step 2.

    If this was the last CertStore in the Collection, or if the Collection contains no CertStore objects, the search process has failed and the connection request fails with reason code MQRC_SSL_CERT_STORE_ERROR.

The Collection object determines the order in which CertStores are used.

The Collection of CertStores can also be set using the MQC.SSL_CERT_STORE_PROPERTY. As a convenience, this property also allows a single CertStore to be specified without needing to be a member of a Collection.

If sslCertStores is set to null, no CRL checking is performed. This property is ignored if sslCipherSuite is not set.

Renegotiating the secret key used for encryption

A WebSphere MQ base Java client application can control when the secret key that is used for encryption on a client connection is renegotiated. The application can do this in any of the following ways:

If the application uses more than one of these ways, the usual precedence rules apply. See MQEnvironment for the precedence rules.

The value of the sslResetCount field or environment property MQC.SSL_RESET_COUNT_PROPERTY represents the total number of bytes sent and received by the WebSphere MQ base Java client code before the secret key is renegotiated. The number of bytes sent is the number before encryption, and the number of bytes received is the number after decryption. The number of bytes also includes control information sent and received by the WebSphere MQ base Java client.

If the reset count is zero, which is the default value, the secret key is never renegotiated. The reset count is ignored if no CipherSuite is specified.

If you are using an HP or Sun Java 2 Software Development Kit (SDK) or Java Runtime Environment (JRE), do not set the reset count to a value other than zero. If you do set the reset count to a value other than zero, a client connection fails when it attempts to renegotiate the secret key.

For more information about the secret key that is used for encryption on an SSL enabled channel, see WebSphere MQ Security.

Supplying a customized SSLSocketFactory

Different JSSE implementations can provide different features. For example, a specialized JSSE implementation could allow configuration of a particular model of encryption hardware. Additionally, some JSSE providers allow customization of keystores and truststores by program, or allow the choice of identity certificate from the keystore to be altered. In JSSE, all these customizations are abstracted into a factory class, javax.net.ssl.SSLSocketFactory.

Refer to your JSSE documentation for details of how to create a customized SSLSocketFactory implementation. The details vary from provider to provider, but a typical sequence of steps might be:

  1. Create an SSLContext object using a static method on SSLContext
  2. Initialize this SSLContext with appropriate KeyManager and TrustManager implementations (created from their own factory classes)
  3. Create an SSLSocketFactory from the SSLContext

When you have an SSLSocketFactory object, set the MQEnvironment.sslSocketFactory to the customized factory object. For example:

javax.net.ssl.SSLSocketFactory sf = sslContext.getSocketFactory();
MQEnvironment.sslSocketFactory = sf;

WebSphere MQ classes for Java then use this SSLSocketFactory to connect to the WebSphere MQ queue manager. This property can also be set using the MQC.SSL_SOCKET_FACTORY_PROPERTY. If sslSocketFactory is set to null, the JVM's default SSLSocketFactory is used. This property is ignored if sslCipherSuite is not set.

Making changes to the JSSE keystore or truststore

If you change the contents of the JSSE keystore or truststore, or change the location of the keystore or truststore file, WebSphere MQ base Java applications that are running at the time do not automatically pick up the changes. For the changes to take effect, the following actions must be performed:

After these actions have been performed, the applications can then recreate their connections.

Depending on how you design your applications, and on the function provided by your JSSE provider, it might be possible to perform these actions without stopping and restarting your applications. However, stopping and restarting the applications might be the simplest solution.

Error handling when using SSL

The following reason codes can be issued by WebSphere MQ classes for Java when connecting to a queue manager using SSL:

MQRC_SSL_NOT_ALLOWED
The sslCipherSuite property was set, but bindings connect was used. Only client connect supports SSL.
MQRC_JSSE_ERROR
The JSSE provider reported an error that could not be handled by WebSphere MQ. This could be caused by a configuration problem with JSSE, or because the certificate presented by the queue manager could not be validated. The exception produced by JSSE can be retrieved using the getCause() method on MQException.
MQRC_SSL_PEER_NAME_MISMATCH
The DN pattern specified in the sslPeerName property did not match the DN presented by the queue manager.
MQRC_SSL_PEER_NAME_ERROR
The DN pattern specified in the sslPeerName property was not valid.
MQRC_UNSUPPORTED_CIPHER_SUITE
The CipherSuite named in sslCipherSuite was not recognized by the JSSE provider. A full list of CipherSuites supported by the JSSE provider can be obtained by a program using the SSLSocketFactory.getSupportedCipherSuites() method. A list of CipherSuites that can be used to communicate with WebSphere MQ can be found in Appendix D. SSL CipherSpecs and CipherSuites.
MQRC_SSL_CERTIFICATE_REVOKED
The certificate presented by the queue manager was found in a CRL specified with the sslCertStores property. Update the queue manager to use trusted certificates.
MQRC_SSL_CERT_STORE_ERROR
None of the supplied CertStores could be searched for the certificate presented by the queue manager. The MQException.getCause() method returns the error that occurred while searching the first CertStore attempted. If the causal exception is NoSuchElementException, ClassCastException, or NullPointerException, check that the Collection specified on the sslCertStores property contains at least one valid CertStore object.