Camel CXF Rest SSL Handshake Error - ssl

We are using Camel CXF API for communicating with a secured server. This is 2-way SSL and we're talking to 3 different systems via Netscaler. 2 systems expose SOAP WS and we're able to establish 2-way SSL and exchange messages. The third system exposes REST APIs and is giving a very wierd problem at the SSL handshake. The error occurs when we Camel CXF in Fuse. A standalone Java Program running in its own JVM is able to successfully talk to the REST service.
We have enabled SSL debug flags and get the following errors in the logs.
Camel thread #0 - timer://foo, WRITE: TLSv1 Change Cipher Spec, length = 1
Camel thread #0 - timer://foo, handling exception: java.net.SocketException: Connection reset
%% Invalidated: [Session-11, SSL_RSA_WITH_RC4_128_MD5]
Camel thread #0 - timer://foo, SEND TLSv1 ALERT: fatal, description = unexpected_message
Camel thread #0 - timer://foo, WRITE: TLSv1 Alert, length = 2
Camel thread #0 - timer://foo, Exception sending alert: java.net.SocketException: Broken pipe
Camel thread #0 - timer://foo, called closeSocket()
Here's the configuration in Camel REST svc.
<!-- Key Manager & Trust Manager -->
<bean id="keyManagersBean"
class="test.IntegrationKeyManagerFactory"
factory-method="getKeyManager">
<argument value="${security.keystorepassword}"/>
<argument value="${security.keystorelocation}"/>
</bean>
<bean id="trustManagersBean"
class="test.IntegrationKeyManagerFactory"
factory-method="getTrustManager">
<argument value="${security.keystorepassword}"/>
<argument value="${security.keystorelocation}"/>
</bean>
<!-- ==================== security configuration =================== -->
<http:conduit name="*.http-conduit">
<http:tlsClientParameters>
<sec:keyManagers ref="keyManagersBean"/>
<sec:trustManagers ref="trustManagersBean"/>
</http:tlsClientParameters>
</http:conduit>
<!-- ====================== Camel Context & Routes ====================== -->
<camel:camelContext id="camel.test.context">
<camel:route id="testRoute">
<camel:from uri="timer://foo?fixedRate=true&period=30s" />
<camel:transform>
<camel:constant>""</camel:constant>
</camel:transform>
<camel:removeHeaders pattern="CamelCxfMessage" />
<camel:setHeader headerName="Exchange.HTTP_METHOD">
<camel:constant>GET</camel:constant>
</camel:setHeader>
<camel:to uri="cxfrs:{{protocol}}://{{host}}:{{port}}/{{context}}/getList" />
<camel:log message="${body}"/>
</camel:route>
</camel:camelContext>
Does anyone know what could be the problem ? The exact same configuration works for communicating with SOAP WS via netscaler but not with REST WS via netscaler.

I was able to fix the issue by switching over from camel cxf rsClient to using plain camel-http call. But think there's some issue with using HttpConduit with cxfrsClient.

Related

SSL Error coneecting from Sprint Client code to Websphere MQ server

We are using below setup
1) Java code using client mode connection to Websphere MQ
<bean id="murexJmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="hostName" value="${mx.mq.hostName}" />
<property name="port" value="${mx.mq.port}" />
<property name="queueManager" value="${mx.mq.queueManager}" />
<property name="channel" value="${mx.mq.channel}" />
<property name="SSLCipherSuite" value="${mx.mq.cipher.suite}"/>
<property name="transportType">
<util:constant static-field="com.ibm.mq.jms.JMSC.MQJMS_TP_CLIENT_MQ_TCPIP"/>
</property>
</bean>
2) Open JDK 1.7 is installed in Linux Server
3) Websphere MQ Version - MQ 7.0.1.13
4) We have configured SSL certificates for connection.
We are getting below exception
retrying in 5000 ms. Cause: JMSWMQ0018: Failed to connect to queue manager 'Q3TEST' with connection mode 'Client' and host name 'myhost'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR').
com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0018: Failed to connect to queue manager 'Q3TEST' with connection mode 'Client' and host name 'myhost'. 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.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:608)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:236)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:421)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6807)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6204)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:278)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6155)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:115)
at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:198)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:184)
at org.springframework.jms.listener.AbstractJmsListeningContainer.createSharedConnection(AbstractJmsListeningContainer.java:403)
at org.springframework.jms.listener.AbstractJmsListeningContainer.refreshSharedConnection(AbstractJmsListeningContainer.java:388)
at com.abnamro.nl.marrs.utilities.spring.jms.OmDefaultMessageListenerContainer.refreshConnectionUntilSuccessful(OmDefaultMessageListenerContainer.java:1046)
at com.abnamro.nl.marrs.utilities.spring.jms.OmDefaultMessageListenerContainer.recoverAfterListenerSetupFailure(OmDefaultMessageListenerContainer.java:1026)
at com.abnamro.nl.marrs.utilities.spring.jms.OmDefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(OmDefaultMessageListenerContainer.java:1193)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)
... 14 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9204: Connection to host 'myhost(1414)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2397;AMQ9771: SSL handshake failed. [1=javax.net.ssl.SSLHandshakeException[No appropriate protocol (protocol is disabled or cipher suites are inappropriate)],3=myhost/1.1.1.1:1414 (myhost),4=SSLSocket.startHandshake,5=default]],3=myhost(1414),5=RemoteTCPConnection.protocolConnect]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1809)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:336)
... 13 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9771: SSL handshake failed. [1=javax.net.ssl.SSLHandshakeException[No appropriate protocol (protocol is disabled or cipher suites are inappropriate)],3=myhost/1.1.1.1:1414 (myhost),4=SSLSocket.startHandshake,5=default]
at com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:950)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.connect(RemoteConnection.java:1075)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection(RemoteConnectionPool.java:338)
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1488)
... 14 more
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
at sun.security.ssl.Handshaker.activate(Handshaker.java:470)
at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1438)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1308)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
at com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:944)
... 17 more
We are able to solve this issue.
Earlier we were using below client library versions
Removed the following MQ related jars (and their dependencies) from our application:
1) jmqi-7.0.jar
2) mq-7.0.jar
3) mqjms-7.0.jar
4) commonservices-7.0.jar
5) headers-7.0.jar
Which we changed to
Downloaded this MQ client distribution from IBM site: mqc8_8.0.0.4_linuxx86-64.tar.gz
Added 2 jars from this distribution:
1) com.ibm.mq.allclient.jar
2) jms.jar
Added their dependency as follows:
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>allclient</artifactId>
<version>8.0.0.4</version>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>jms</artifactId>
<version>8.0.0.4</version>
</dependency>

How to configure the sslContextParameters in the camel spring xml

<camel:sslContextParameters id="sslContextParameters">
<camel:keyManagers keyPassword="changeit">
<camel:keyStore type="JKS" resource="C:\keystore.jks"
password="changeit" />
</camel:keyManagers>
<camel:trustManagers>
<camel:keyStore type="JKS" resource="C:\keystore.jks"
password="changeit" />
</camel:trustManagers>
</camel:sslContextParameters>
When I tried too load the resource like in the above xml , I still get SSL handshake exception. Please help me out the same how to set the camel http connection with the SSL parameters reference added to it , so that I can hit any secured link without any SSL handshake exceptions
From the docs, you apply the SSL context parameters against an option for the http4 component.
<to uri="https4://127.0.0.1/mail/?sslContextParametersRef=sslContextParameters"/>

RabbitMQ SSL Connection with Apring AMQP 1.4.3

I am trying to connect to RabbitMQ over SSL. I have followed the RabbitMQ SSL documentation linked [here}(https://www.rabbitmq.com/ssl.html).
As per RabbitMQ SSL documentation connecting using SSLv3 and TLSv1 is not recommeded due to known vulnerabilities. Due to this I have disabled these protocols on RabbitMQ as per instructions.
I am using Spring AMQP 1.4.3 to connect to RabbitMQ.
ApplicationContext context = new GenericXmlApplicationContext("classpath:/testConfig/testrabbit-context.xml");
RabbitTemplate template = context.getBean(RabbitTemplate.class);
MessageProperties messageProperties = new MessageProperties();
org.springframework.amqp.core.Message amqpMessage = new org.springframework.amqp.core.Message("Test".getBytes(), messageProperties);
String routingKey = "TEST.businessevent.route";
template.send(routingKey, amqpMessage);
My config:
<rabbit:connection-factory id="rabbitConnectionFactory"
connection-factory="clientConnectionFactory"
host="localhost"
port="5671"
username="username"
password="password"
virtual-host="test_host" />
<rabbit:admin connection-factory="rabbitConnectionFactory" />
<rabbit:template id="rabbitTemplate"
connection-factory="rabbitConnectionFactory" exchange="test_topic" />
<rabbit:topic-exchange name="test_topic" durable="true" />
<bean id="clientConnectionFactory" class="org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean">
<property name="useSSL" value="true" />
<property name="sslPropertiesLocation" value="/testconfig/rabbitSSL.properties"/>
</bean>
rabbitSSL.properties:
keyStore=file:/client/keycert.p12
trustStore=file:/lib/security/rabbitStore
keyStore.passPhrase=testpassword
trustStore.passPhrase=testpassword
However when I use the above code and config to connect to RabbitMQ over SSL I am getting a fatal alert: protocol_version.
When I looked at the org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean class that Spring is using to connect to RabbitMQ, I can see that the protocol appears to be hard coded to SSLv3.
SSLContext context = SSLContext.getInstance("SSLv3");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
this.connectionFactory.useSslProtocol(context);
This code works fine if I do not disable SSLv3 on RabbitMQ. However I need to connect to RabbitMQ using Tlsv1.2. Can I do that using Spring AMQP 1.4.3 or do I need to use another version.
Thanks for any help you can provide me with this issue.
While searching for RabbitMQ remote access I came across the below Spring application.properties configuration settings that can be done in Spring to configure the RabbitMQ connections.
https://www.oodlestechnologies.com/blogs/Connect-to-SSL-enabled-RabbitMQ-server-Springboot/
spring.rabbitmq.host=hostURL
spring.rabbitmq.port = hostPort
spring.rabbitmq.username = username
spring.rabbitmq.password = password
spring.rabbitmq.virtual-host=virtualHost
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.2
https://www.baeldung.com/spring-remoting-amqp#2-configuration
I have opened a JIRA Issue for this.
In the meantime, the RabbitConnectionFactoryBean is just a convenience class to make configuring an underlying connection factory more "Spring friendly" with defaults.
Instead, you can perform this initialization in your own code (perhaps using a #Bean declaration using Java Configuration).
Okay, I was trying to connect by Spring Boot application(2.1.4.RELEASE) that uses spring-boot-starter-amqp (2.1.4.RELEASE) to an AWS Managed instance of RabbitMQ aka Amazon MQ and it would fail with a similar error. What worked for me was setting these properties.
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.3
Setting these properties explicitly was not required in an application that was using Spring Boot and spring-boot-starter-amqp (2.7.8) and they worked out of the box. Here's a mention of the same in Spring AMQP Documentation.
https://docs.spring.io/spring-amqp/reference/html/#rabbitconnectionfactorybean-configuring-ssl

Repeated log : Warn Transport Connection to tcp:<ip> failed: java.net.SocketException: Connection reset

I am running ActiveMQ 5.9.0 release on my local machine for dev purposes (Windows 7). I am using AMQP as the protocol and Apache qpid as the client to consume messages (publish subscribe) from activeMQ broker (AMQP 1.0 protocol).
Although I have commented out all the protocols except amqp in activemq.xml, still periodically I am seeing the below message in broker log (standard out):
WARN: Transport Connect to tcp://<ip> failed: java.net.SocketException: Connection reset
I did try to "uncomment" the openwire protocl definition in activemq.xml and append transport.useInactivityMonitor=false (based on googling around):
I still cannot get warning messages to disappear.
I haven't used it myself. But the amqp protocol is using the tcp transport under the covers. Use of the protocol is documented here. You can configure it to use nio as well. It is hardcoded to have useInactivityMonitor=false. You can modify the transport options on the amqp transport by setting those options in the connect uri. For example:
<transportConnectors>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?transport.keepAlive=true"/>
</transportConnectors>
The tcp transport options are documented here.

CXF Client With SSL Throws SSLHandshakeException

I am facing getting SSLhandshakeException while I try to consume a CXF webservice using a CXF client over HTTPS connection.
The web service requires SSL connection therefore I have PKCS 12 key store which is referenced in the java code directly with the password as below.
System property configuration in java code:
System.setProperty("javax.net.ssl.keyStore", "/home/user/test-client.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "AbcgfhYgb");
System.setProperty("javax.net.debug", "ssl, handshake");
CXF client configuration in cxf.xml
<jaxws:client id="CService" serviceClass="com..cws.CService"
address="https://developer.webservice.com/test" />
<http-conf:conduit name="*.http-conduit">
<http-conf:tlsClientParameters disableCNCheck="true">
</http-conf:tlsClientParameters>
</http-conf:conduit>
Exception Thrown on executing the client
Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://developer.webservice.com/test: Received fatal alert: handshake_failure
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:534)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1338)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1322)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:50)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:223)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:622)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:133)
... 53 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1748)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:991)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1175)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1202)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1186)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:440)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:979)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:168)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1282)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1233)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:195)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1295)
... 65 more
Can anyone suggest solution for accessing the web service using CXF client with SSL.
Reference the JDK cacerts as a trustore manager which consist of the CA certificate for the SSL certificate. Also, add the keystore which consist of the SSL certifcate as below.
<http-conf:conduit name="*.http-conduit">
<http-conf:tlsClientParameters>
<sec:keyManagers keyPassword="testkey">
<sec:keyStore type="JKS" password="changeit"
file="<keystore path>" />
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="changeit"
file="<cacert path>" />
</sec:trustManagers>
</http-conf:tlsClientParameters>
<http-conf:client AutoRedirect="true" Connection="Keep-Alive" />
</http-conf:conduit>
Below configuration will enable CXF client to consume JAXWS service over SSL ( https):
<http-conf:conduit name="*.http-conduit" >
<http-conf:tlsClientParameters
useHttpsURLConnectionDefaultSslSocketFactory="true"
/>
</http-conf:conduit>
Check:
1. That certificate has been impoprted in the consumer for producer
2. Additionlay if you have a problem where there is a mismatch between hostname and the one in certificate you can use disableCNCheck="true". However this flag is not recomended for Producation