Reputation: 31
I'm having some issues to create a connection to (and reading from) a Tibco EMS JMS queue, using SSL and mutual authentication with certicates. Here is my Spring config:
<!-- TIBCO Connection Factory Bean -->
<bean id="tibcoConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
<constructor-arg value="ssl://mytibco.server.address:30113" />
<property name="userName" value="userName" />
<property name="userPassword" value="${tibcoPwd}" />
<property name="connAttemptCount" value="10" />
<property name="connAttemptDelay" value="100" />
<property name="connAttemptTimeout" value="1000" />
<property name="reconnAttemptCount" value="10" />
<property name="reconnAttemptDelay" value="100" />
<property name="reconnAttemptTimeout" value="1000" />
<property name="SSLVendor" value="j2se" />
<property name="SSLEnableVerifyHost" value="false" />
<property name="SSLEnableVerifyHostName" value="false" />
<property name="SSLTrace" value="true" />
<property name="SSLDebugTrace" value="true" />
<property name="SSLIdentity" value="c:\\cert\\testCert.p12" />
<property name="SSLPassword" value="*******" />
</bean>
<!-- Spring CachingConnectionFactory Bean -->
<bean id="tibcoJmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<constructor-arg ref="tibcoConnectionFactory" />
<property name="reconnectOnException" value="true" />
<property name="sessionCacheSize" value="10" />
</bean>
When I try to put something on the queue, I receive the following stack trace:
[TIBCO EMS]: [J] [SSL] initializing security with vendor 'j2se'
[TIBCO EMS]: [J] [SSL] client version 5.1.0, security version 3.0.0, SSL initialized with vendor 'j2se'
[TIBCO EMS]: [J] [SSL] WARNING: server verification is disabled, will trust any server.
[TIBCO EMS]: [J] [SSL] reading client identity from byte array, format=AUTO
WARN [jmsContainer-1] org.springframework.jms.listener.DefaultMessageListenerContainer - Execution of JMS message listener failed
org.springframework.jms.JmsSecurityException: Error occured while reading identity data: Invalid or not supported identity data; nested exception is javax.jms.JMSSecurityException: Error occured while reading identity data: Invalid or not supported identity data
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:283)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:474)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:436)
...
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:482)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:241)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.jms.JMSSecurityException: Error occured while reading identity data: Invalid or not supported identity data
at com.tibco.tibjms.TibjmsSSL._identityFromStore(TibjmsSSL.java:2670)
at com.tibco.tibjms.TibjmsSSL.createIdentity(TibjmsSSL.java:2575)
at com.tibco.tibjms.TibjmsxLinkSSL._initSSL(TibjmsxLinkSSL.java:309)
at com.tibco.tibjms.TibjmsxLinkSSL.connect(TibjmsxLinkSSL.java:390)
at com.tibco.tibjms.TibjmsConnection._create(TibjmsConnection.java:1288)
at com.tibco.tibjms.TibjmsConnection.<init>(TibjmsConnection.java:4115)
at com.tibco.tibjms.TibjmsxCFImpl._createImpl(TibjmsxCFImpl.java:209)
at com.tibco.tibjms.TibjmsxCFImpl._createConnection(TibjmsxCFImpl.java:253)
at com.tibco.tibjms.TibjmsConnectionFactory.createConnection(TibjmsConnectionFactory.java:36)
at org.springframework.jms.connection.SingleConnectionFactory.doCreateConnection(SingleConnectionFactory.java:343)
at org.springframework.jms.connection.SingleConnectionFactory.initConnection(SingleConnectionFactory.java:290)
at org.springframework.jms.connection.SingleConnectionFactory.createConnection(SingleConnectionFactory.java:227)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.core.JmsTemplate.access$500(JmsTemplate.java:90)
at org.springframework.jms.core.JmsTemplate$JmsTemplateResourceFactory.createConnection(JmsTemplate.java:1028)
at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:298)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:458)
... 12 more
Until now, I can't succeed to resolve the ssl handshake. How to resolve this issue?
Upvotes: 3
Views: 17461
Reputation: 34311
The problem you having is due to a combination of Spring and the fact that com.tibco.tibjms.TibjmsConnectionFactory
overloads the setSSLIdentity
method, allowing either a byte[]
or String
to be passed.
This is confusing Spring which is invoking setSSLIdentity(byte[])
meaning that com.tibco.tibjms.TibjmsConnectionFactory
is treating the bytes of the string c:\\cert\\testCert.p12
as a certificate (which it clearly isn't).
Unfortunately Spring doesn't let you force the type on the property
element (like it does on constructor-arg
, at least at the time of writing), so you'll use the constructor that takes a java.utils.Map
and pass the configuration as properties:
<bean id="tibcoConnectionFactory" class="com.tibco.tibjms.TibjmsConnectionFactory">
<constructor-arg value="ssl://mytibco.server.address:30113" />
<constructor-arg><null/></constructor-arg>
<constructor-arg>
<util:map>
<entry key="com.tibco.tibjms.factory.username" value="userName"/>
<entry key="com.tibco.tibjms.factory.password" value="${tibcoPwd}"/>
<entry key="com.tibco.tibjms.connect.attemptcount" value="10"/>
<entry key="com.tibco.tibjms.connect.attemptdelay" value="100"/>
<entry key="com.tibco.tibjms.connect.attempttimeout" value="1000"/>
<entry key="com.tibco.tibjms.reconnect.attemptcount" value="10"/>
<entry key="com.tibco.tibjms.reconnect.attemptdelay" value="10-"/>
<entry key="com.tibco.tibjms.reconnect.attempttimeout" value="1000" />
<entry key="com.tibco.tibjms.ssl.vendor" value="j2se"/>
<entry key="com.tibco.tibjms.ssl.enable_verify_host" value="false"/>
<entry key="com.tibco.tibjms.ssl.enable_verify_hostname" value="false"/>
<entry key="com.tibco.tibjms.ssl.trace" value="true"/>
<entry key="com.tibco.tibjms.ssl.debug_trace" value="true"/>
<entry key="com.tibco.tibjms.ssl.identity" value="c:/cert/testCert.p12"/>
<entry key="com.tibco.tibjms.ssl.password" value="value="*******"/>
<util:map>
</constructor-arg>
</bean>
For anyone looking for the names for other properties, you can drill into the associated setter and see property name there.
Upvotes: 3
Reputation: 11
The problem is that TibjmsConnectionFactory overloads the setSSLIdentity(..)
setter.
The available setters are:
setSSLIdentity(byte[] identity)
setSSLIdentity(java.lang.String sslIdentity)
This means that Spring doesn't know which setter to call. I haven't researched proof of this, but from a google search I found out that it's up to the JVM implementation to decide which setter will be called and, in my case, it was different with every application restart (Oracle JVM). In fact this is a known issue, see https://github.com/flyway/flyway/issues/890 .
One solution is to call the constructor with a Map
containing your properties:
TibjmsConnectionFactory(java.lang.String serverUrl,
java.lang.String clientId,
java.util.Map properties)
PS: Sorry for resurrecting an old question, but as there is quite a high traffic for this question, this may help others in the future.
Upvotes: 1
Reputation: 1
Enter SSLIdentity
as /c:/cert/testCert.p12
. Then only it will recognize your p12 file, else will treat it as byte array
Upvotes: 0
Reputation: 1
It seems that it's not reading .p12 correctly. It must log something like:
[TIBCO EMS]: [J] [SSL] reading client identity from file 'c:\cert\testCert.p12', format=PKCS12
note the format=...
Upvotes: 0