tESBConsumer with mutual SSL (client authentication)

One Star

tESBConsumer with mutual SSL (client authentication)

Dear sirs,
we decided to apply stronger security measures
- services inside ESB should be accessed by mutual SSL
- services accessible from outside must have WS-S enabled

enabling mutual SSL for T-ESB it was easy
in the container /etc/org.ops4j.pax.web.cfg we set:
org.osgi.service.http.port.secure=9001
org.osgi.service.http.secure.enabled=true
org.ops4j.pax.web.ssl.keystore = /var/lib/midoffice/midoffice.jks
org.ops4j.pax.web.ssl.password = xxxxx
org.ops4j.pax.web.ssl.keypassword = xxxxx
org.ops4j.pax.web.ssl.clientauthneeded true

on other side - to reach such secured web services from T-ESB we have an issue. From the tWebservice component it works with help of the tSetKeystore component (img1), but when using tESBConsumer (as it was adviced that's the better approach), we got following exception:
rg.talend.ws.helper.ServiceInvokerHelper.invoke(ServiceInvokerHelper.java:167)
at demo1.callvkbotest3_0_1.CallVkboTest3.tFixedFlowInput_1Process(CallVkboTest3.java:3850)
at demo1.callvkbotest3_0_1.CallVkboTest3.tSetKeystore_1Process(CallVkboTest3.java:1259)
at demo1.callvkbotest3_0_1.CallVkboTest3.runJobInTOS(CallVkboTest3.java:5439)
at demo1.callvkbotest3_0_1.CallVkboTest3.main(CallVkboTest3.java:5170)
Caused by: java.net.SocketException: SocketException invoking https://localhost:9001/services/VkboProxy: Software caused connection abort: recv failed
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1431)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1416)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:649)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 14 more
Caused by: java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(Unknown Source)
at com.sun.net.ssl.internal.ssl.InputRecord.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.waitForClose(Unknown Source)
at com.sun.net.ssl.internal.ssl.HandshakeOutStream.flush(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.sendChangeCipherSpec(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.sendChangeCipherAndFinish(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1368)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1310)
at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42)
at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1388)
... 17 more
error calling vkbo

It seems the tESBConsumer ignores properties set by tSetKeystore artefact. Is it a bug or I forgot anything? I'd like to keep using the tESBConsumer.
Kind regards
Gabriel
One Star

Re: tESBConsumer with mutual SSL (client authentication)

Dear gusto2!
I can reproduce the error. I have exactly the same configuration of a job example. I want to implement a consumer job with mutual authentication. I debugged the job and tried to change from JKS to P12 client/keystore certificate. The funniest thing is, that the webservice's returned message is already decrypthed successfully (I see this in the SSL debug log, after sending client cert etc). I also see, that the framework does the SSL handshake twice. That is strange.
Can somebody answer, why the framework is doing SSL handshake twice?
I wish you merry christmas! Enjoy!
Kind regards,
Peter
PS: Accessing the webservice configured in the ESB consumer item is working properly via internet browser (IE), with server certificate and client certificate! That's great!
One Star

Re: tESBConsumer with mutual SSL (client authentication)

Hi Peter,
seems you put extra effort in the case (debugging SSL). So far seems we can use server side SSL with client's UsenameToken authentication (even it's more persormance expensive) until the bug is fixed (if Talend consider this as a bug)
Gabriel
Four Stars

Re: tESBConsumer with mutual SSL (client authentication)

Hi guys,
I know the issue is quite old but we are having quite similar problems with mutual authentication on the client side (server side is already in place). We are still wondering about following questions:
- is it possible to implement TLS 1.2 connection (mutual authentication) with just tESBConsumer or should we use it in combination with tSetKeyStore?
- how does Talend (cxf) knows which certificate to send from the keystore if there exists many of them
- how do you debug webservices in Talend? In the previous post you mentioned ssl logs but I could not find any of them in the workspace.
- how do you debug errors as "tls handshake error"? Would you suggest to use any sniffing tool as a proxy?
Thank you
One Star

Re: tESBConsumer with mutual SSL (client authentication)

hi

- is it possible to implement TLS 1.2 connection (mutual authentication) with just tESBConsumer or should we use it in combination with tSetKeyStore?

Apparently we always need to specify a keystore with the client certificates. So without the keystore loaded the runtime woudn't have idea where to look for client's keypair and certificate.


- how does Talend (cxf) knows which certificate to send from the keystore if there exists many of them

How it works on the TLS/SSLSocket level: During SSL handshake the server sends a flag that client authentication is required and  a list of trusted CA records. The client will search all loaded keystores for keypairs with certificates matching the provided CA list. The first found is provided. That's why we suggest to have a keystore only with single valid key and its certificate chain.

- how do you debug webservices in Talend? In the previous post you mentioned ssl logs but I could not find any of them in the workspace.
- how do you debug errors as "tls handshake error"? Would you suggest to use any sniffing tool as a proxy?

On Java runtime you can set env property: -Djavax.net.debug=all , on Talend Runtime or SoapUI. Be prepared for A LOT of logs and VERY SLOW responses. See http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug
Have fun
Four Stars

Re: tESBConsumer with mutual SSL (client authentication)

Perfect, thank you gusto for the clarifications!
Four Stars

Re: tESBConsumer with mutual SSL (client authentication)

Gabriel just another question regarding securing the keystore and private key. Each of them uses a different password but Talend lets you insert just the password for the keystore. If the password for the keystore is the same as the password for deciphering the private key then the connection is establish without any problem. Do you know what steps should we take where those are different? Does that imply that those two password should always be equal?
One Star

Re: tESBConsumer with mutual SSL (client authentication)

 Do you know what steps should we take where those are different? Does that imply that those two password should always be equal?

I don't recall the component configuration after long time, but if there's only a single password field, we can assume Talend took a shortcut and they simplified things for themselves reusing the same field for the keystore and key password.
If it works for you with the same password, let it be. Having two password won't increase security in this case.
Four Stars

Re: tESBConsumer with mutual SSL (client authentication)

You are right, we will use same..
The remaining thing that I am struggling with is how to sign those messages. Probably it should be done separately (eg. in a tJavaRow) and then composing them together? Have you used any different approach?
One Star

Re: tESBConsumer with mutual SSL (client authentication)

if you set 'authentication', the tESBComponent should use the UsernameToken profile (username, password in the WS-Security header). No other profiles (security measures) are supported. If you want something more (message signing, message encryption, RM, ..) I suggest you use CXF (e.g. via Camel routes). You can build camel routes in TOS (route perspective) with some limitations or build your own OSGi bundles from scratch. However - this approach requires some skillset outside this scope (OSGi, CXf, Camel).