4
votes

I'm preparing a test environment to connect to Websphere MQ 7.0 through SSL, so I have to configure SSL on Websphere MQ myself before I start configuring the SSL connection from JMS side.

So, I'm trying to create SSL certificates for Websphere MQ, following these steps. But when I attempt to add the signed certificate to the repository using the command gsk7cmd.exe -cert -receive -db key.kdb -pw pass -file QMANAGER_signed.arm I get the error:

An attempt to receive the certificate has failed.
All the signer certificates must exist in the key database.

I even tried the C command gsk7capicmd but it also fails, with the error:

Error: 146

Error id: GSKKM_ERR_INVALID_CERT_CHAIN
Details: QMANAGER_signed.arm

UPDATE 1:

I used the WMQ SSL Wizard to create the proper configuration. The configuration went smoothly, but when I run the JMS sample included with the SSL Wizard I get the error: MQJE001: Completion Code '2', Reason '2397' the SSL logs (using the option -Djavax.net.debug=all) shows the following error:

Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9771: SSL handshake failed. [1=javax.net.ssl.SSLHandshakeExcep
tion[Remote host closed connection during handshake],3=localhost/127.0.0.1:1414 (localhost),4=SSLSocket.startHandshake,5
=default]
        at com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:995)
        at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.connect(RemoteConnection.java:989)
        at com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection(RemoteConnectionPool.java:293)
        at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1371)
        at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:331)
        ... 7 more
Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
        at com.ibm.jsse2.jc.a(jc.java:380)
        at com.ibm.jsse2.jc.g(jc.java:115)
        at com.ibm.jsse2.jc.a(jc.java:240)
        at com.ibm.jsse2.jc.startHandshake(jc.java:54)
        at com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:989)
        ... 11 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
        at com.ibm.jsse2.a.a(a.java:7)
        at com.ibm.jsse2.jc.a(jc.java:493)
        ... 15 more

UPDATE 2:

Using T.Rob's diagnostic technique mentioned in his answer, I'm still stuck at point #3 with the same error as before.

1

1 Answers

4
votes

The error that you are seeing is because your keystore does not have the signing CA's root and/or intermediate signer certificates. When you get a signed certificate back from the Certificate Authority it must be validated before adding it to the keystore. Pretty much anyone could have intercepted your signing request and signed the certificate. The step of validating it when received insures that it was signed by a CA that you actually trust and not some anonymous man-in-the-middle.

The way the cert is validated is by checking the CA signature against the public key of the CA that is in your KDB. For that the CA's certificate must already be in the KDB when you attempt to receive your signed cert. If the CA uses an intermediate signer certificate (and for a variety of reasons any commercial CA will use intermediate certs) then you must also have imported the intermediate cert and the root cert. This forms a certificate chain or certificate path from the CA's root cert through any intermediate certs to your signed certificate. Each thing in the chain is authenticated by the thing above it until you get to the root. Your KDB must have the entire chain and because each cert is validated by the one above it, you must import these beginning with the root and working your way down.

Typically your CA will have posted their signer certs on their web site where you retrieve them using SSL. Fetch those and import them and you will be able to receive your signed cert.

As it happens, The Sphere Online Journal just published an article that walks you through this process using Verisign as an example, and with screen shots of importing the root and intermediate signer certs. The article is about Renewing WebSphere MQ Certificates but the first part of the article creates a kdb file and a signing request, then imports the CA certs and the signed cert.

Let's also get you to the correct Infocenter. Please look at the WMQ v7.0 Infocenter's section on Using CA Signed Certificates. The one you were looking at is for Message Broker and quite frankly the article you linked to is a bit of a mess. I'll see about getting it fixed. For starters, that bit about creating the cert in one kdb, getting it signed, then exporting it, deleting it and importing it to the QMgr's KDB is pure rubbish. Just generate the CSR in the QMgr's own KDB file and receive the signed cert directly to it. This is much easier and is the process illustrated in the article mentioned above.

Finally, if you go to t-rob.net and download the WMQ Security Lab from IMPACT 2011 you will find there a lab guide and some scripts. These use self-signed certificates but the scripts can easily be converted to use CA signed certificates and then tailored for use in your WMQ network.

UPDATE:
Responding to he additional questions in the comments:

I'm actually planning to use a self-signed certificate, so I guess I only need to extract it and adding it to the client's trust store?

Yes, that is correct. But here's a problem in the WMB Infocenter page that was originally linked in that it asks you to create a cert with the label qmgrname instead of ibmwebspheremqqmgrname. The QMgr finds its cert based on the label and so it must match the specified format. So when you create your self-signed cert, mke sure that the label is the literalibmwebspheremq with the QMgr name folded to lower case appended. If you have made a cert with the wrong label, you can always export it to a P12 file and then import it to a new KDB with the right label.

I used the WMQ SSL Wizard mentioned in the WMQ Security Lab to create the proper configuration. The configuration went smoothly, but when I run the JMS sample included with the SSL Wizard I get the error MQJE001: Completion Code '2', Reason '2397', the SSL logs shows the following error main, received EOFException: error main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake main, SEND TLSv1 ALERT: fatal, description = handshake_failure

There are a few reasons why that might occur. Rather than going through all of them, I'll suggest some diagnostic techniques. When I set up SSL channels, I always use the following procedure:

  1. Get the channel running without SSL. This proves that the basic communication path is working (listener running, ports match, channel object definitions match, etc.).
  2. If this is the first time that the QMgr is using SSL, or if the kdb has changed, be sure to issue the REFRESH SECURITY TYPE(SSL) command.
  3. Enable SSL by specifying the same ciphersuite at the QMgr and client but be sure that the QMgr's SVRCONN channel is set to SSLCAUTH(OPTINAL) SSLPEER(). This verifies that the client accepts the QMgr's certificate. Only when this works, go to the next step.
  4. Now change the QMgr's SVRCONN to SSLCAUTH(REQUIRED) SSLPEER(). This causes the QMgr to request the client's certificate.
  5. If using SSLPEER set it to the desired value.

This process isolates the possible problems so that at any point you know where to look. If the process fails in Step #3 then there is either an issue with the SSL configuration of the application, or it cannot validate the QMgr's cert. If the process fails in Step #4 then we know the application's SSL configuration is sound and that it likes the QMgr's cert bu that the QMgr doesn't like the application cert. If we get to Step #5 then it's just a matter of getting the SSLPEER value correct.

Because you got a handshake failure that appears to be due to the QMgr closing the TCP connection, I am assuming that you have SSLCAUTH(REQUIRED) (which is the default, by the way) and that either the QMgr doesn't have the application's certificate or that you were attempting to use an anonymous connection where the client doesn't require a personal cert. If that is the case, setting SSLCAUTH(OPTIONAL) will get you past the point of failure - although possibly to an entirely new point of failure.