ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Java / JMS » MQ Connection failed with SSL

Post new topic  Reply to topic Goto page 1, 2  Next
 MQ Connection failed with SSL « View previous topic :: View next topic » 
Author Message
francoG
PostPosted: Thu Mar 08, 2012 3:45 am    Post subject: MQ Connection failed with SSL Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

Hello dear friends,
I'm writing a Java application that send message over MQ.
the application is working fine, but now I have to add SSL security.
I followed instruction i found in the WebSphere MQ V6,... redpaper to set up connection on server and client and various certificate and keystore.
I used the amqsputc command in a cmd window and after some initial problem I get a successfull connection.
The only way I get to work is to define a ClientChannel and export the AMQCLCHL.TAB file from Server to client.
The first Question is : is this the only way to connect a client to a SSL MQ server?

Now I try to do the same with Java:
I defined a class for testing connection: here is the code I used in Java
Code:

   public class MyMQSender {
        private MQQueueConnectionFactory qcf =new MQQueueConnectionFactory();
        private MQQueueConnection connection;
        private MQQueueSession session;
        private MQQueue outQueue;
        private MQQueue inQueue;
      private String inQueueName;      
        public boolean startMQConnection(String host, String port, String queueManager, String sendQueue, String receiveQueue, String channelName) {
            try {
               System.out.println("Initial user.name="+System.getProperty("user.name"));
               System.out.println("DBConfig.user.name="+DBConfig.MQ_USERNAME);
               System.setProperty("user.name",DBConfig.MQ_USERNAME);
               System.out.println("Authorisation required user.name="+System.getProperty("user.name"));
               System.out.println("set Host name to "+host);
               
               qcf.setHostName(host);
               System.out.println("set MQ Channel to "+channelName);
               qcf.setChannel(channelName);
         
         
               System.out.println("set Port to "+port);
               qcf.setPort(Integer.parseInt(port));
               System.out.println("set QueueManager to "+queueManager);
               qcf.setQueueManager(queueManager);
               //qcf.setQueueManager("");
               System.out.println("set TransportType to "+JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
               qcf.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
               System.out.println("Use SSL is "+myConfig._UseSSLCert );
               if (myConfig._UseSSLCert){
                  System.out.println("trustStore "+myConfig._truststoragepath);
                  System.setProperty("javax.net.ssl.trustStore", myConfig._truststoragepath);
                  System.out.println("keyStore"+apiaConfig._keystoragepath);
                  System.setProperty("javax.net.ssl.keyStore", myConfig._keystoragepath);
                  System.out.println("keyStorePassword "+myConfig._keystoragepass);
                  System.setProperty("javax.net.ssl.keyStorePassword", myConfig._keystoragepass);
                  System.out.println("SSLCipherSuite "+myConfig._SSLCipherSuite);
                     qcf.setSSLCipherSuite(myConfig._SSLCipherSuite);
                       
               //
               }
               System.out.println("SSLPeerName "+qcf.getSSLPeerName());
                
               System.out.println("Set Transport type to MQJMS_TP_CLIENT_MQ_TCPIP( "+JMSC.MQJMS_TP_CLIENT_MQ_TCPIP+")");
                 //qcf.setTransportType(JMSC.MQJMS_TP_BINDINGS_MQ);
               qcf.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
               System.out.println("setFailIfQuiesce(1)");
               qcf.setFailIfQuiesce(1);

               URL channelTable1 = null;
               try {
                  channelTable1 = new URL("file:"+"C:/MQCLIENT/AMQCLCHL.TAB");
               } catch (MalformedURLException e) {
                  JOptionPane.showMessageDialog(null,   e.getMessage());
                  return false;
               }
               System.out.println("set Channel Table to "+channelTable1.toString());
               
               if (channelTable1 != null) {
                  qcf.setCCDTURL(channelTable1);
               }
               System.out.println("value of CCD "+qcf.getCCDTURL().toString());
               System.out.println("value of CCS "+qcf.getCCSID());
               System.out.println("value of QueueManager "+qcf.getQueueManager());
               
               System.out.println("createQueueConnection()");
                
               connection  = (MQQueueConnection)qcf.createQueueConnection();
               
               System.out.println("Starting MQ connection ");
               connection.start();
               System.out.println("create QueueSession ");
               session  = (MQQueueSession)connection.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
               System.out.println("outPut Queue"+sendQueue);
               outQueue = new MQQueue(qcf.getQueueManager(), sendQueue);
               outQueue.setFailIfQuiesce(1);
               outQueue.setTargetClient(1); //Setta la connessione JMS compliant
               
               System.out.println("input Queue"+receiveQueue);
               
               inQueue = new MQQueue(qcf.getQueueManager(), receiveQueue); //verificare il nome della coda
               inQueue.setFailIfQuiesce(1);
               inQueue.setTargetClient(1); //Setta la connessione JMS compliant
               inQueueName = receiveQueue;
               return true;

            } catch (JMSException e) {
               
               e.printStackTrace();
               System.out.println("errore in startMQConnection",   e.getMessage());

               return false;
            }   

           }

by running this code I get the following prinout:

Initial user.name=fgi
DBConfig.user.name=FGI
Authorisation required user.name=FGI
set Host name to 129.188.20.64
set MQ Channel to M00182S.SZEKWAS.O
set Port to 1416
set QueueManager to SZEKWAS
set TransportType to 1
Use SSL is true
trustStore C:\MQCLIENT\ClientKey.jks
keyStoreC:\MQCLIENT\ClientKey.jks
keyStorePassword franco
SSLCipherSuite SSL_RSA_WITH_AES_128_CBC_SHA
SSLPeerName null
Set Transport type to MQJMS_TP_CLIENT_MQ_TCPIP( 1)
setFailIfQuiesce(1)
set Channel Table to file:C:/MQCLIENT/AMQCLCHL.TAB
value of CCD file:C:/MQCLIENT/AMQCLCHL.TAB
value of CCS 819
value of QueueManager SZEKWAS
createQueueConnection()
javax.jms.JMSException: MQJMS2005: Creazione di MQQueueManager non riuscita per '129.188.20.64:SZEKWAS'
at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:586)
at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2110)
at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:185)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:112)
(... more stack trace)

errore in startMQConnection on Queue =MALL.ONLINE.SZEKWASMQJMS2005: Creazione di MQQueueManager non riuscita per '129.188.20.64:SZEKWAS'

here some Parameters:
QueueManager name :SZEKWAS
IP Adress :129.18.8.20.64
Listening port :1416
Server connection channel :M00182S.SZEKWAS.O
local queue :M00182S.ONLINE.SZEKWAS
client connection channel :M00182S.SZEKWAS.O
client side"service directory": C:\MQCLIENT
Directory of c:\MQCLIENT
08.03.2012 10:40 <DIR> .
08.03.2012 10:40 <DIR> ..
08.03.2012 10:28 10'008 AMQCLCHL.TAB
08.03.2012 10:40 21'171 ClientKey.jks
08.03.2012 10:07 80 key.crl
08.03.2012 10:07 110'080 key.kdb
08.03.2012 10:07 80 key.rdb
08.03.2012 10:08 129 key.sth
6 File(s) 141'548 bytes


Can anybody help me?
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Mar 08, 2012 3:50 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

You can set the CCDTURL property of the QCF to indicate the location of the client channel table.

The use of a client channel table is not strictly necessary to configure and use an SSL connection with MQ, it's just the easiest way to do so.

You can, even in C, configure it manually. In C this is done using the MQCONNX call. In Java this is done by setting the necessary pieces of MQEnvironment.

You're not using straight Java, however, you're using JMS. This is a different beast, and does not allow an individual programmer to have actual direct access to the low level connection objects, because JMS is supposed to make things *easier* by *abstracting* the messaging layer.

So please look into using CCDTURL on your connection factory.
Back to top
View user's profile Send private message
zpat
PostPosted: Thu Mar 08, 2012 5:00 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5866
Location: UK

Two excellent IBM articles

http://www.ibm.com/developerworks/websphere/library/techarticles/0510_fehners/0510_fehners.html

http://www.ibm.com/developerworks/websphere/library/techarticles/0506_barrago/0506_barrago.html
Back to top
View user's profile Send private message
francoG
PostPosted: Thu Mar 08, 2012 5:12 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

hi mqjeff,
in the Java code that I've attached you can see I've set the CCDTOURL .

see the line ->qcf.setCCDTURL(channelTable1);

I once try to connect even without using CCDTOURL but I get always the same error.
I even enabled the -Djavax.net.debug=all switch to see the SSL debug informations, but it seems it crash before starting SSL handshake.
Franco
Back to top
View user's profile Send private message
francoG
PostPosted: Thu Mar 08, 2012 5:26 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

Hi zpat ,


Quote:
Posted: Thu Mar 08, 2012 2:00 pm Post subject:

Two excellent IBM articles

http://www.ibm.com/developerworks/websphere/library/techarticles/0510_fehners/0510_fehners.html

http://www.ibm.com/developerworks/websphere/library/techarticles/0506_barrago/0506_barrago.html



I 've already read the both documents: the first ends with this quote:
Quote:
If you are using the MQ JMS client, you can set the CipherSuite on the connection factory using the setSSLCipherSuite() method:


MQConnectionFactory factory = new MQConnectionFactory();
factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
factory.setQueueManager("MyQMgr");
factory.setSSLCipherSuite("SSL_RSA_WITH_NULL_MD5");
factory.setPort(1414);
factory.setHostName("127.0.0.1");
MQConnection connection = factory.createConnection();


that is my case:
I started developing with the code fragment in example.
I then read the second document ( and more others in the last two weeks ) but I think I'm lost.
Back to top
View user's profile Send private message
francoG
PostPosted: Thu Mar 08, 2012 6:50 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

I try again WITHOUT using setCCDTURL
the result is only little different: the
ssl log is now showing the first stage of negotiation...


    createQueueConnection()
    keyStore is : C:\MQCLIENT\key.jks
    keyStore type is : jks
    keyStore provider is :
    init keystore
    init keymanager of type SunX509
    trustStore is: C:\MQCLIENT\key.jks
    trustStore type is : jks
    trustStore provider is :
    init truststore
    adding as trusted cert:
    Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
    Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3, OU="(c) 1999 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
    Algorithm: RSA; Serial number: 0xeca0a78b6e756a01cfc47ccc2f945ed7
    Valid from Fri Oct 01 02:00:00 CEST 1999 until Thu Jul 17 01:59:59 CEST 2036

    adding as trusted cert:
    ....
    here is the long list of all certificate found in the keystore


then continue with start connection....


    trigger seeding of SecureRandom
    done seeding SecureRandom
    Allow unsafe renegotiation: false
    Allow legacy hello messages: true
    Is initial handshake: true
    Is secure renegotiation: false
    javax.jms.JMSException: MQJMS2005: Creazione di MQQueueManager non riuscita per '129.188.20.64:SZEKWAS'
    at com.ibm.mq.jms.services.ConfigEnvironment.newException(ConfigEnvironment.java:586)
    at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2110)
    at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
    at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:185)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:112)



so the MQ CLient Software is able to read the keystore:
what I miss?
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Mar 08, 2012 6:58 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

francoG wrote:
I try again WITHOUT using setCCDTURL


Right, so I didn't see the setCCDTURL because you were also calling a bunch of other things to set up the connection.

If you're using the CCDT, you only need to provide the queue manager name, so that it uses the right channel in the CCDT, and then the keystore/truststore information.

You also need to print the LinkedException from the JMSException.

This will give you the MQRC that tells you why the SSL is failing.
Back to top
View user's profile Send private message
francoG
PostPosted: Thu Mar 08, 2012 7:30 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

hi mqjeff
Quote:
you were also calling a bunch of other things to set up the connection.


you're right btw it's alway difficult to give the right amount of information....

I changed a little my program, so when I use the CCDT I set only the MQserverName and the Truststore path.

I then add the stacktracePrintout of the lined exception....thank you!

here is the list...MQJE001 : code 2, cause 2009.....mhmm did you know what does it means?

    com.ibm.mq.MQException: MQJE001: Codice completamento 2, Causa 2009
    at com.ibm.mq.MQQueueManager.sequentialConstruct(MQQueueManager.java:978)
    at com.ibm.mq.MQQueueManager.<init>(MQQueueManager.java:865)
    at com.ibm.mq.MQSPIQueueManager.<init>(MQSPIQueueManager.java:83)
    at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2037)
    at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
    at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
    at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:60)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:171)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:112)

Back to top
View user's profile Send private message
Vitor
PostPosted: Thu Mar 08, 2012 7:57 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

francoG wrote:
here is the list...MQJE001 : code 2, cause 2009.....mhmm did you know what does it means?


Yes.

If you look it up, you'll know too.

If you search for it in this forum, you'll find a wealth of useful discussion.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Mar 08, 2012 8:04 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

francoG wrote:
hi mqjeff
Quote:
you were also calling a bunch of other things to set up the connection.


you're right btw it's alway difficult to give the right amount of information....

I changed a little my program, so when I use the CCDT I set only the MQserverName and the Truststore path.


Let me be a bit more clear about what I mean.

Code:
System.out.println("set QueueManager to "+queueManager);
               qcf.setQueueManager(queueManager);
               URL channelTable1 = null;
               try {
                  channelTable1 = new URL("file:"+"C:/MQCLIENT/AMQCLCHL.TAB");
               } catch (MalformedURLException e) {
                  JOptionPane.showMessageDialog(null,   e.getMessage());
                  return false;
               }
               System.out.println("set Channel Table to "+channelTable1.toString());
               
               if (channelTable1 != null) {
                  qcf.setCCDTURL(channelTable1);
               }

                  System.out.println("trustStore "+myConfig._truststoragepath);
                  System.setProperty("javax.net.ssl.trustStore", myConfig._truststoragepath);
                  System.out.println("keyStore"+apiaConfig._keystoragepath);
                  System.setProperty("javax.net.ssl.keyStore", myConfig._keystoragepath);
                  System.out.println("keyStorePassword "+myConfig._keystoragepass);
                  System.setProperty("javax.net.ssl.keyStorePassword", myConfig._keystoragepass);
                  System.out.println("SSLCipherSuite "+myConfig._SSLCipherSuite);
                     qcf.setSSLCipherSuite(myConfig._SSLCipherSuite);


Should be all you need.

The name of the *queue manager*, the *location of the CCDT* and the *locations* of the keystore/trust stores.
Back to top
View user's profile Send private message
francoG
PostPosted: Sun Mar 11, 2012 1:33 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

i'm Sorry for long delay in reply, I was cut off from log-in due a problem with my account.

thank you mqjeff, for your reply
indeed what you wrote is exactly what i done in the code: probably there is still a stupid error that crash everything.

what It should be right:
1 Keystores in client and server side.
2 key exchange
3 channel definition.
4accessibility of CCDT file
5 accessibility of server ( no firewall)
this becase ( as I wrote ) I could connect by using command line amqxxx commands.
Ok, in the next days, as soon I will be back in office, I will perform more test on this side.
On the other side, the fact I used CCDT, was only because I found only this as method to connect via SSL using Command line.

My final task is to connect using the java program.
Now I'm only in Testing phase, I use a testing MQ server on a VM on my computer, so ther's no problem for me to change any configuration I want and copy the CCDT table.
But I'm quite sure the owner of the productione MQ server I will have connect to, will not sent me the CCDT table. I suppose I should connect using another solution.

In another post of this forum I see the following code ( do you think it could work or there are other way?):



Code:
SSLContext ctx;
KeyManagerFactory kmf;
TrustManagerFactory tmf;
File keystoreFile;
KeyStore ks;
char[] passphrase = "xxxxxxx".toCharArray();

ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
ks = KeyStore.getInstance("JKS");



kmf.init(ks, passphrase);
tmf.init(ks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

factory = ctx.getSocketFactory();

MQEnvironment.sslCipherSuite = "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
MQEnvironment.sslSocketFactory = factory;

Back to top
View user's profile Send private message
fjb_saper
PostPosted: Sun Mar 11, 2012 2:13 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

No you don't need all that.

What you did not tell us is the CipherSpec of the SVRCONN channel on the qmgr. This will determine whether or not you need to set SSLFIPS to true...

O.K. so when you specify the CCDT URL you MUST have host, channel and port as blank/empty strings. Best would be to not set them at all...

Also keep in mind if you need a CipherSuite that is SSLFIPS your keysize needs to be at least 2048...

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
francoG
PostPosted: Wed Mar 14, 2012 10:15 am    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

After several test I finally get the connection with SSL without using the CCDT Table.
The only problem is that not all ciphersuite are working.
some ciphersuite returns this error
MQJE001: Si è verificata una MQException: Codice completamento 2, Causa 2400
MQJE011: Il tentativo di connessione socket è stato rifiutato

I see that 2400 is the code for "unsupported Ciphersuite".
typically do not work the TLS_RSA_*
the other with *DES* or even the NULL_MD5 and NULL_SHA works fine.

is there something different I have to specify when I use different cipher?
is there problem ith JVM or something like that?
thank you
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Mar 14, 2012 8:24 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

francoG wrote:
After several test I finally get the connection with SSL without using the CCDT Table.
The only problem is that not all ciphersuite are working.
some ciphersuite returns this error
MQJE001: Si è verificata una MQException: Codice completamento 2, Causa 2400
MQJE011: Il tentativo di connessione socket è stato rifiutato

I see that 2400 is the code for "unsupported Ciphersuite".
typically do not work the TLS_RSA_*
the other with *DES* or even the NULL_MD5 and NULL_SHA works fine.

is there something different I have to specify when I use different cipher?
is there problem ith JVM or something like that?
thank you



Yes typically the "TLS_RSA*" Ciphersuites will require you to set the SSLFIPS flag on the connection factory to true, and also have a keysize of 2048 or bigger (need to specify when you create your cert request).

You also need to look into the SSLPEER setup. Depending on endianness of the platform, multiple entries of OU may need to appear in the inverse order from what you would expect....

There should be a nice set up on SSL on www.nynjmq.org
See if http://www.nynjmq.org/WMB%20V7%20administration%20with%20SSL.zip will help you any...

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
francoG
PostPosted: Wed Mar 14, 2012 11:51 pm    Post subject: Reply with quote

Novice

Joined: 18 Aug 2011
Posts: 23

hello fjb_saper,
thank you for reply.
This means that my program works in the right direction, but I only need to add a parametrization switch in my program's configuration panel to set the SSLFIPS.
At present I do not set SSLPEER; btw the meaning of SSLPEER is not totally clear to me.

Beyond mutual autentication....
I actually use ony the server autentication, by specifying "SSL Client Aut" to "Optional" in the SSL parametrisation of the server channel.

Will I need to specify something more in the client softtware if I want to switch "SSL Client Aut" to "Required" ?
How the client software will decide what certificate will be presented to the server? it use the SSLPEER name or what?
thank you
franco
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ Java / JMS » MQ Connection failed with SSL
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.