Author |
Message
|
GaryGWood |
Posted: Wed Oct 15, 2003 1:07 pm Post subject: SSL access from Java |
|
|
Apprentice
Joined: 14 Oct 2003 Posts: 48 Location: Austin, TX
|
I'm pretty new to MQ so please bare with me...
I have read through the forum (especially TonyD's posts) and Kevin Tobin's tutorial on SSL - great stuff. However, none seem to address accessing from Java code only.
I do have the CA and keyrings setup (I think) correctly. I have defined a server connection channel with SSL. The java code I'm using is:
MQEnvironment.hostname = "server.mycompany.com";
MQEnvironment.channel = "QM1Channel";
MQEnvironment.sslCipherSuite = "SSL_RSA_WITH_ RC4_128_MD5";
MQEnvironment.port = 1414;
SourceQMgr = new MQQueueManager("QM1");
I am getting the following error(s):
MQJE001: An MQException occurred: Completion Code 2, Reason 2059
MQJE013: Error accessing socket streams
MQJE001: Completion Code 2, Reason 2059
Any ideas or pointers will be greatly appreciated.
Last edited by GaryGWood on Thu Oct 16, 2003 5:38 am; edited 1 time in total |
|
Back to top |
|
 |
xxx |
Posted: Thu Oct 16, 2003 12:05 am Post subject: |
|
|
Centurion
Joined: 13 Oct 2003 Posts: 137
|
Ensure that the queue manager has been started. If the connection is from a client application, check the channel definitions.
2059 ? is the qmanager running |
|
Back to top |
|
 |
harwinderr |
Posted: Thu Oct 16, 2003 3:50 am Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
Mostly, you get a 2059 if the queue manager (or its listener) is not running or your application has not set the MQ environment correctly.
From the code snippet what you have posted, it seems that the latter is not the case, so just ensure that you have the listener running on the server side.
I have successfully tested SSL connection through a Java client (on Win2K) to a WMQ server (on Linux) without any problem. Which platforms are you using??
Hope it helps  |
|
Back to top |
|
 |
GaryGWood |
Posted: Thu Oct 16, 2003 5:31 am Post subject: |
|
|
Apprentice
Joined: 14 Oct 2003 Posts: 48 Location: Austin, TX
|
Thanks for the input. This is on Windows XP. I believe everything is running (listener, queue manager, etc.) since I can turn SSL off on the channel and remove the line of code setting the cipher suite and succesfully put a message. I turn SSL back on and get the error. |
|
Back to top |
|
 |
harwinderr |
Posted: Thu Oct 16, 2003 9:58 pm Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
hmm, well thats quite strange. I believe running on Windows XP should not make any difference what so ever.
Are you running the WMQ server too on XP??
I will just list down the steps which I carried out on the Linux and W2K boxes. This might help you to troubleshoot.
1. After creating the queue manager, create the channel, a local queue and make sure the key database file is in the default location.
runmqsc hsr1
def chl(chan1) chltype(svrconn) trptype(tcp) mcauser(' ') sslciph('RC4_MD5_US') sslcauth(optional)
def ql(q1)
alter qmgr sslkeyr('/var/mqm/qmgrs/hsr1/ssl/key')
2. Create a self signed certificate for the queue manager and label it "ibmwebspheremqhsr1" using iKeyman.
3. Make sure that you have proper access permissions for the key database file. Use the following commands
chmod g+r /var/mqm/qmgrs/QM1/ssl/key.kdb
chmod g+r /var/mqm/qmgrs/QM1/ssl/key.sth
4. Start the listener
$ runmqlsr -m hsr1 -t TCP -p 3333 &
That completes our setup on the server side. Now extract the queue manager certificate and FTP it to the Windows box. You can choose to extract it in either Base64-encoded ASCII data or DER data.
On Windows, you have to add this certificate to the trusted store. I recommend using the latest version of JDK 1.4 because it has JSSE integrated with it. Otherwise you have to download the JSSE separately from SUN's web site.
Now use the "keytool" utility to add the certificate
F:\WMQ>keytool -import -alias wmq -keystore keyStore -file cert.der
This wil create a trusted store called keyStore in the current directory and add cert.der as a trusted certificate. You can verify this by
F:\WMQ>keytool -list -v -file keyStore
Use the below listed Java code to get messages from the queue Q1. Make sure you have put test messages on the queue before using amqsput.
Java code
Code: |
import com.ibm.mq.*;
import java.io.IOException;
import java.util.Hashtable;
import java.io.*;
public class MQRead
{
private MQQueueManager _queueManager = null;
private Hashtable params = null;
public int port = 1414;
public String hostname = "127.0.0.1";
public String channel = "CLIENT.TO.MQA1";
public String qManager = "MQA1";
public String inputQName = "SYSTEM.DEFAULT.LOCAL.QUEUE";
public MQRead()
{
super();
}
private boolean allParamsPresent()
{
boolean b = params.containsKey("-h") &&
params.containsKey("-p") &&
params.containsKey("-c") &&
params.containsKey("-m") &&
params.containsKey("-q");
if (b)
{
try
{
port = Integer.parseInt((String) params.get("-p"));
}
catch (NumberFormatException e)
{
b = false;
}
// Set up MQ environment
hostname = (String) params.get("-h");
channel = (String) params.get("-c");
qManager = (String) params.get("-m");
inputQName = (String) params.get("-q");
}
return b;
}
private void init(String[] args) throws IllegalArgumentException
{
params = new Hashtable(5);
if (args.length > 0 && (args.length % 2) == 0)
{
for (int i = 0; i < args.length; i+=2)
{
params.put(args[i], args[i+1]);
}
}
else
{
throw new IllegalArgumentException();
}
if (allParamsPresent())
{
// Set up MQ environment
MQEnvironment.hostname = hostname;
MQEnvironment.channel = channel;
MQEnvironment.port = port;
MQEnvironment.sslCipherSuite = "SSL_RSA_WITH_RC4_128_MD5";
}
else
{
throw new IllegalArgumentException();
}
}
public static void main(String[] args)
{
MQRead readQ = new MQRead();
try
{
readQ.init(args);
readQ.selectQMgr();
readQ.read();
}
catch (IllegalArgumentException e)
{
System.out.println("Usage: java MQRead <-h host> <-p port> <-c channel> <-m QueueManagerName> <-q QueueName>");
System.exit(1);
}
catch (MQException e)
{
System.out.println(e);
System.exit(1);
}
}
private void read() throws MQException
{
int openOptions = MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING + MQC.MQOO_INPUT_SHARED;
MQQueue queue = _queueManager.accessQueue( inputQName,
openOptions,
null, // default q manager
null, // no dynamic q name
null ); // no alternate user id
System.out.println("MQRead v1.0 connected.\n");
int depth = queue.getCurrentDepth();
System.out.println("Current depth: " + depth + "\n");
if (depth == 0)
{
return;
}
MQGetMessageOptions getOptions = new MQGetMessageOptions();
getOptions.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQGMO_CONVERT;
while(true)
{
MQMessage message = new MQMessage();
try
{
queue.get(message, getOptions);
byte[] b = new byte[message.getMessageLength()];
message.readFully(b);
System.out.println(new String(b));
message.clearMessage();
}
catch (IOException e)
{
System.out.println("IOException during GET: " + e.getMessage());
break;
}
catch (MQException e)
{
if (e.completionCode == 2 && e.reasonCode == MQException.MQRC_NO_MSG_AVAILABLE) {
if (depth > 0)
{
System.out.println("All messages read.");
}
}
else
{
System.out.println("GET Exception: " + e);
}
break;
}
}
queue.close();
_queueManager.disconnect();
}
private void selectQMgr() throws MQException
{
System.setProperty("javax.net.ssl.trustStore", "F:\\WMQ\\keyStore"); //Path to trusted keyStore
System.setProperty("javax.net.ssl.trustStorePassword", "Welcome123"); //Password
try
{
_queueManager = new MQQueueManager(qManager);
}catch(MQException mq)
{
System.out.println("Exception : " + mq.getCause());
}
System.out.println("QM created");
}
}
|
Hope that helps  |
|
Back to top |
|
 |
GaryGWood |
Posted: Fri Oct 17, 2003 8:29 am Post subject: Sounds easy but ... |
|
|
Apprentice
Joined: 14 Oct 2003 Posts: 48 Location: Austin, TX
|
HR - thanks for the great input!
I have followed your example and have a few questions and will post some more detail of my environment.
I am on a WinXP client accessing MQ on a Win2K server. I have also tried this accessing MQ installed locally on my XP system with the same results.
Step 1
I have created the queue manger, channel, a local queue and a listener. They are all working since I can put a message on the queue when SSL is disabled. The queue manager key file is in the default location of "C:\Program Files\IBM\WebSphere MQ\qmgrs\QM1\ssl\key".
Step 2
I did not create a self signed certificate for the server but got one from a certification authority. I have a self signed certificate I use for the client (now that I type that statment, it sounds like I'm doing something a little goofy... am I?)
Step 3
I don't believe this is an issue on the Windows boxes is it?
Step 4
The listener is running. I exported the certificate I got from the CA as DER data
On my local XP machine I did the following:
Used the keytool to import the certificate into my keystore (named keyStore). I used the command just as you listed it. In my attempt to verify the certificate was added, I could not use the command you listed. It reported, "Keystore file does not exist: C:\Documents and Settings\Adminstrator\.keystore". If I use the command "keytool -list -v -keystore keyStore", I do see the contents of the keystore and that I do have the certificate in the store.
On step 2, you created the certificate for the queue manager. Do you also need to assign this certificate to the queue manager? I guess I'm a little fuzzy on how SSL works regarding MQ. I thought I needed a certificate assigned to the queue manager and another one for the client so they could verify each other's identity. I am using a self signed certificate for the client and the CA issued certificate for the server. Both are listed in the keystore for the queue manager (public key only for the client certificate). The local keystore on my XP client contains the public/private keys for the client as well as the certificate for the server.
I made a few code changes, here's the current snapshot:
Code: |
System.setProperty("javax.net.ssl.trustStore","C:\\ssl\\keyStore");
System.setProperty("javax.net.ssl.trustStorePassword", "password");
MQEnvironment.hostname = "myserver.com";
MQEnvironment.channel = "QM1.SSL";
MQEnvironment.sslCipherSuite = "SSL_RSA_WITH_ RC4_128_MD5";
MQEnvironment.port = 1414;
SourceQMgr = new MQQueueManager("QM1"); |
I still get the error:
MQJE001: An MQException occurred: Completion Code 2, Reason 2059
MQJE013: Error accessing socket streams
MQJE001: Completion Code 2, Reason 2059
Somehow I am not making the socket connection - I know the queue manager and listener is running. I think the 2059 error is coming up because the SSL connection is never made.
I appreciate all your help! |
|
Back to top |
|
 |
harwinderr |
Posted: Mon Oct 20, 2003 4:35 am Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
Quote: |
I did not create a self signed certificate for the server but got one from a certification authority. I have a self signed certificate I use for the client (now that I type that statment, it sounds like I'm doing something a little goofy... am I?) |
No, this is a valid scenario. Normally, we use a self signed certificate for testing purposes but they are no different from the certificates you get from the CA. I would suggest you first test without the client authorization. That would mean to turn the SSLCAUTH parameter to "OPTIONAL" in your channel definition.
Quote: |
On step 2, you created the certificate for the queue manager. Do you also need to assign this certificate to the queue manager? |
Yes, you do neet to assign this certificate to the queue manager. For details refer to the "Security Guide" and read the "Working with the Secure Sockets Layer (SSL) on Windows systems". This will tell you how to assign your certificate to the queue manager.
Unfortunately, I dont have a Windows XP box to run the tests, otherwise I could have tried to reproduce the problem. Moreover I suggest applying all the patches to your Windows boxes (all the latest service packs and critical updates) and also use the latest WMQ version which is WMQ53 (with CSD4).
Hope it helps Do let me know if it solves your problem. |
|
Back to top |
|
 |
GaryGWood |
Posted: Mon Oct 20, 2003 11:26 am Post subject: Solution |
|
|
Apprentice
Joined: 14 Oct 2003 Posts: 48 Location: Austin, TX
|
Okay, I'm going to admit it. I installed version 1.4 of the JVM but I did not set it up to work with my Java IDE. How embarrassing.
Once I realized that, I changed the IDE to work with 1.4 and it all began to happen.
The only question I have left now is how to specify the id of the program running. (I'll risk more embarrassment here…)
The only tool I have to create certificates is keytool. If I create a client certificate with that, it stores it in a truststore that I can’t use to assign to the MQ client. MQ clients on Windows need the file in the .sto format. With keytool I cannot export the private key with the public key for import so I’m limited there.
I thought about using makecert (from the MS SDK for Java) but I can’t seem to find anywhere to download that anymore.
Any ideas on this part? |
|
Back to top |
|
 |
harwinderr |
Posted: Tue Oct 21, 2003 4:59 am Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
Quote: |
The only tool I have to create certificates is keytool. If I create a client certificate with that, it stores it in a truststore that I can’t use to assign to the MQ client. MQ clients on Windows need the file in the .sto format. |
AFAIK, the .sto format is needed only for the C client. In case of Java clients, you have to specify the certificate in the keystore.
Quote: |
With keytool I cannot export the private key with the public key for import so I’m limited there. |
Thats a limitation. Unless, someone else has find a way to export the private key as well using keytool.
I dont know how makecert will help you there. You can get the files (makecert.exe and signer.dll) from Office 2000 installation CDs.
Another option will be to make use of openSSL to generate the test certificate and import it in the keystore of the client and also making it a trusted certificate on the server. |
|
Back to top |
|
 |
GaryGWood |
Posted: Tue Oct 21, 2003 10:35 am Post subject: SSL access from Java with client authentication |
|
|
Apprentice
Joined: 14 Oct 2003 Posts: 48 Location: Austin, TX
|
Follow instructions for obtaining or generating a digital certificate and setting up the server found at http://www7b.software.ibm.com/wsdd/techjournal/0211_yusuf/yusuf.html
In the section on configuring the Java application, I did not use the default the default keystore, JAVA_HOME\jre\lib\security\cacerts. Instead I setup a truststore (information on that in step 2 on Kareem’s page).
Once you have imported the certificates into the truststore, we veer away from Kareem’s JMS Client instructions. In your Java application you will need to add the following lines:
Code: |
System.setProperty("javax.net.ssl.trustStore","C:\\ssl\\jmskeystore"); //Path to trustStore
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); //keyStore password
System.setProperty("javax.net.ssl.keyStore","C:\\ssl\\jmskeystore"); //Path to keyStore
System.setProperty("javax.net.ssl.keyStorePassword", "changeit"); //keyStore password |
Notice that I have set my truststore and keystore to be the same file. I figured it would be easier to manage but it’s not necessary. You are now setup for SSL communication with client authentication. |
|
Back to top |
|
 |
harwinderr |
Posted: Wed Oct 22, 2003 10:52 pm Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
Thanks for the pointer. Could see what I was doing wrong.
I successfully tested the client authorization to a QMgr running on a Linux box. |
|
Back to top |
|
 |
techno |
Posted: Thu May 20, 2004 9:48 am Post subject: |
|
|
Chevalier
Joined: 22 Jan 2003 Posts: 429
|
Code: |
That completes our setup on the server side. Now extract the queue manager certificate and FTP it to the Windows box. You can choose to extract it in either Base64-encoded ASCII data or DER data. |
Harvinder.. Could you tell me here what do you mean by extracting the qmgr certificate? How do you extract it? When certificate is created, it is added to keys db on server side. Do you have to take the same certificate and put it on client side? Or you need to create a new one?
Thanks |
|
Back to top |
|
 |
harwinderr |
Posted: Thu May 20, 2004 8:02 pm Post subject: |
|
|
 Voyager
Joined: 29 Jan 2002 Posts: 90
|
Yes, when the certificate is created it is added to the keys db on the server side. For a certificate to be authenticated when it is received on another system, the receiving system must have a copy of the CA certificate for the CA that issued the certificate. That certificate can be a self-signed certificate.
To extract the certificate, you can use the gsk6ikm tool, which comes along with WMQ53. Select the certificate and click on "Extract Certificate..." You should then FTP this extracted certificate to the other system. The FTP should be done in the correct format only.
More information on this is available in Security Guide.
hope this helps  |
|
Back to top |
|
 |
techno |
Posted: Fri May 21, 2004 7:26 am Post subject: |
|
|
Chevalier
Joined: 22 Jan 2003 Posts: 429
|
I am confused here. May be I am not clear exactly. Please help me understanding it. SelfSigned Certificate that gets created by gsk6cmd- Is ita CA certificate? Then where are the public and private keys? There has to be some key with qmgr, right! I am sure I am missing something.
Thanks
Edit:
Do I have to create personal certificate which has to be on qmgr? |
|
Back to top |
|
 |
techno |
Posted: Fri May 21, 2004 10:22 am Post subject: |
|
|
Chevalier
Joined: 22 Jan 2003 Posts: 429
|
Okay, I think I have understood it to some extent.
This is what I have done.
On HP-UX:
export JAVA_HOME=/opt/mqm/ssl
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=/opt/ibm/gsk6/classes/cfwk.zip:$CLASSPATH
export CLASSPATH=/opt/ibm/gsk6/classes/gsk6cls.jar:$CLASSPATH
On HP-UX:
// Creating KeyStore
gsk6cmd -cert -create -db /var/mqm/qmgrs/QMGR/ssl/key.kdb -pw password -label MYCA -size 512 -dn "CN=SH,O=OSH,C=CSH"
On HP-UX:
// Creating CA Certificate
gsk6cmd -cert -create -db /var/mqm/qmgrs/QMGR/ssl/key.kdb -pw password -label MYCA -size 512 -dn "CN=SH,O=OSH,C=CSH"
On HP-UX:
// Extracting the certificate to transfer it to Windows
gsk6cmd -cert -extract -db /var/mqm/qmgrs/QMGR/ssl/key.kdb -label MYCA -pw password -target MYCA.arm -format ascii
FTPed to Windows
On Windows:
// Creating KeyStore and adding CA certificate to the store
keytool -import -alias wmq -keystore KeyStore -file MYCA.arm
On HP-UX
// Creating Personal Certificate
gsk6cmd -certreq -create -db /var/mqm/qmgrs/DHOCLM2/ssl/key.kdb -pw password -label PersCert -dn "CN=SH,O=OSH,C=CSH" -size 512 -file MyPersCert
On HP-UX
// Adding Personal Certificate to KeyStore
gsk6cmd -cert -receive -file MyPersCert -db /var/mqm/qmgrs/QMGR/ssl/key.kdb
Above step isgiving error: An error occurred while processing X509 certificates.
Also, How is CA linked to above personal certificate? Personal Certificate shold be signed by CA? (MYCA)(so that client will assume that server is valid)
Pls help me.... |
|
Back to top |
|
 |
|