0

I am trying to setup ssl/tls between the app and the cloud following this https://cloud.ibm.com/docs/mqcloud?topic=mqcloud-mqoc_jms_tls.

When the sslauth is set to optional on the cloud mq app channel CLOUD.APP.SVRCONN I am able to send and receive message.

Ii downloaded the certificate and added it to a trust store using the following command.

keytool -importcert -alias DigiCertRootCA -file qmgrcert.pem -keystore truststore.jks

I am passing this to the connection factory through sslcontext. (note that this whole setup worked with docker instance of ibmmq)

The code i am trying this with is the following..

            // Load in the keystore for SSL certificates
            FileInputStream keyStoreInputStream = new FileInputStream("/other/dev/MQ/keystore.jks");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(keyStoreInputStream, ("changeit").toCharArray());

            keyStoreInputStream.close();

            // Create a keyManager that can select the certificate with the correct alias
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, ("changeit").toCharArray());
            // final X509KeyManager defaultKm = (X509KeyManager)keyManagerFactory.getKeyManagers()[0];
            // X509KeyManager aliasKeyManager = new AliasKeyManagerWrapper(defaultKm, "server-certificate");

            // Create an SSLSocketFactory
            FileInputStream myKeys = new FileInputStream("truststore.jks");

            // Do the same with your trust store this time
            // Adapt how you load the keystore to your needs
            KeyStore myTrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            myTrustStore.load(myKeys, "changeit".toCharArray());

            myKeys.close();
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(myTrustStore);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

            // Get an SSLSocketFactory to pass to WMQ
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            MQConnectionFactory cf = new MQConnectionFactory();
            // set "client" connection mode for remote queue manager, as opposed to attempting to connect to a local queue manager
            cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);

            cf.setSSLSocketFactory(sslSocketFactory);

I get the following error:

yatish.kadam@YKADAM-LT01:/other/dev/MQ$ java -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -cp ./com.ibm.mq.allclient-9.1.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet
com.ibm.msg.client.jms.DetailedIllegalStateRuntimeException: JMSWMQ0018: Failed to connect to queue manager 'removed' with connection mode 'Client' and host name 'host name removed(31201)'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.

I use oracle java.. 1.8 .. ibmmq version9...

The command i use to run the program...

java -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -cp ./com.ibm.mq.allclient-9.1.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet

error on the ibmmq

----- amqrmrsa.c : 961 --------------------------------------------------------
05/31/20 18:57:58 - Process(984.8768) User(mqm) Program(amqrmppa)
                    Host() Installation(Installation1)
                    VRMF(9.1.5.0) QMgr()
                    Time(2020-05-31T18:57:58.942Z)
                    RemoteHost()
                    ArithInsert1(414)
                    CommentInsert1(????)
                    CommentInsert2(????)
                    CommentInsert3()

AMQ9633E: Bad SSL certificate for channel '????'.
EXPLANATION:
A certificate encountered during SSL handshaking is regarded as bad for one of
the following reasons: 
(a) it was formatted incorrectly and could not be validated 
(b) it was formatted correctly but failed validation against the Certification
  Authority (CA) root and other certificates held on the local system 
(c) it was found in a Certification Revocation List (CRL) on an LDAP server 
(d) a CRL was specified but the CRL could not be found on the LDAP server 
(e) an OCSP responder has indicated that it is revoked 
The channel is '????'; in some cases its name cannot be determined and so is
shown as '????'. The remote host is ''. The channel did not start. 
The details of the certificate which could not be validated are '????'. 
The certificate validation error was 0.
ACTION:
Check which of the possible causes applies on your system. Correct the error,
and restart the channel. 
This error might indicate that the remote end of the channel is configured to
send the wrong certificate. Check the certificate label configuration at the
remote end of the channel and ensure that the local key repository contains all
of the necessary CA certificates.
----- amqccisa.c : 8421 ---------------------------

The key store contents:

Keystore type: jks
Keystore provider: SUN

Your keystore contains 3 entries

digicertrootca, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): 1F:B8:6B:11:68:EC:74:31:54:06:2E:8C:9C:C5:B1:71:A4:B7:CC:B4
digicertrootca11, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): 26:26:F7:42:08:95:39:27:8D:66:B6:51:49:12:D3:93:CA:2E:E1:9E
digicertrootca3, May 31, 2020, trustedCertEntry, 
Certificate fingerprint (SHA1): A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36
Yatish Kadam
  • 454
  • 2
  • 11
  • Does the pem file contain the private key and singers? What version of client mq jars are you using? Are you using IBM java or something else? Do you pass or set any `com.ibm.*` java system properties? – JoshMc May 31 '20 at 11:06
  • @JoshMc I use oracle java.. 1.8 .. ibmmq version9... the command i use to run the program... java -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -cp ./com.ibm.mq.allclient-9.1.4.0.jar:./javax.jms-api-2.0.1.jar:. com.ibm.mq.samples.jms.JmsPutGet – Yatish Kadam May 31 '20 at 16:25
  • Does the pem file contain the private key and singers? – JoshMc May 31 '20 at 16:32
  • .pem file does yes.. it has 3 certificates when i print it out.. although the truststore has only one for some reason.. – Yatish Kadam May 31 '20 at 16:33
  • @JoshMc what is the equivalent for ikeycmd -cert -add -db trust.jks -file /qmgrcert.pem -label DigiCertRootCA -pw could that be the problem? – Yatish Kadam May 31 '20 at 16:42
  • What about you keyStore? That should have the private key. Also note that you do not have to do all the setup of the trust and keystore, those can be replaced by a few java system properties. See this [answer](https://stackoverflow.com/questions/52775733/problem-connecting-a-java-client-jms-to-a-ibm-mq/52777130#52777130) for details. I don't think that is your problem but wanted to mention it as it can simplify you code. – JoshMc May 31 '20 at 16:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215040/discussion-between-yatish-kadam-and-joshmc). – Yatish Kadam May 31 '20 at 16:58
  • I am not familiar with keytool, but perhaps this [answer](https://serverfault.com/questions/483465/import-of-pem-certificate-chain-and-key-to-java-keystore/745143#745143) will help. I reread and see that you just specify the single jks as both the key and trustSrore, that should not cause a problem. I suspect it is your import command or the pem does not include a private key (for example it could just be the public keys). – JoshMc May 31 '20 at 17:00
  • @JoshMc i did import all the certs into the truststore.. still get the same error.. – Yatish Kadam May 31 '20 at 17:47
  • @JoshMc i added the ibmmq error logs too – Yatish Kadam May 31 '20 at 17:51
  • You previously said "although the truststore has only one for some reason", do you mean you have correct this now? Can you try starting the java process with the following hava system property`javax.net.debug=ssl` and reproduce the problem? The output should go to STDOUT for the java process. Can you also display the cert details for your private key and validate the expiration and signer and if verify the key store for the queue manager includes the same signer. Also ensure you have the full cert chain, Private key, intermediate, root all in your key store. – JoshMc May 31 '20 at 23:03
  • @JoshMc i had to separately export and import the keys into the trust store.. ive added the contents above.. – Yatish Kadam Jun 01 '20 at 15:58
  • Those three entries are all labeled as `trustedCertEntry`, you need a private key to be able to have `SSLCAUTH(REQUIRED)`. – JoshMc Jun 01 '20 at 17:40
  • @JoshMc yes.. i will update the above code to reflect that.. – Yatish Kadam Jun 01 '20 at 18:02
  • Did you update the question with the fixed code? That won't help anyone learn. You should put the fixed code in your answer. – JoshMc Jun 01 '20 at 19:04
  • the fix was still to use the given rsa algorithm while generating the keys.. the updated code was just to include the managers back to the sslcontext.. – Yatish Kadam Jun 01 '20 at 20:24

1 Answers1

0

@joshmc Thanks.. Finally got it working.. The client key that is created needs to be with specific algorithm SHA256withRSA.

the link to the source i found.. Digital certificates and CipherSpec compatibility in IBM MQ

use the following to create a new self signed cert..

keytool -genkey -alias clientcert -keyalg RSA -sigalg SHA256withRSA -keysize 2048 -validity 3650 -keystore keystore.jks
Yatish Kadam
  • 454
  • 2
  • 11
  • Click the chat link in the comments above I think I answered this yesterday but you never responded to my chat reply? I spent much time on this with you and would appreciate the opportunity to write up an answer for you to accept. – JoshMc Jun 01 '20 at 18:52
  • @JoshMc ia m extremely sorry i missed the discussion as you commented outside of it .. i assumed you didnt reply inside the discussion as i didnt get a notification.. you can write up an answer.. ill gladly accept it. – Yatish Kadam Jun 01 '20 at 20:22