First of all, I'll explain the scenario.
I have a WSO2 ESB-4.6.0 (that uses Apache's HttpClient) running with jdk1.7.0_79
, and my goal is to call an external secure service that only accepts TLSv1.2
protocol, without to update the Java to the version 8.
The external server directives are:
Supported versions: TLSv1.2
Deflate compression: no
Supported cipher suites (ORDER IS NOT SIGNIFICANT):
TLSv1.2
RSA_WITH_3DES_EDE_CBC_SHA
DHE_RSA_WITH_3DES_EDE_CBC_SHA
RSA_WITH_AES_128_CBC_SHA
DHE_RSA_WITH_AES_128_CBC_SHA
RSA_WITH_AES_256_CBC_SHA
DHE_RSA_WITH_AES_256_CBC_SHA
RSA_WITH_AES_128_CBC_SHA256
RSA_WITH_AES_256_CBC_SHA256
RSA_WITH_CAMELLIA_128_CBC_SHA
DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
DHE_RSA_WITH_AES_128_CBC_SHA256
DHE_RSA_WITH_AES_256_CBC_SHA256
RSA_WITH_CAMELLIA_256_CBC_SHA
DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
----------------------
Minimal encryption strength: strong encryption (96-bit or more)
Achievable encryption strength: strong encryption (96-bit or more)
BEAST status: protected
CRIME status: protected
So, building and calling a simple proxy, which have an endpoint poiting to this service, results in:
Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
HTTPS-Sender I/O dispatcher-1, fatal error: 40: Couldn't kickstart handshaking
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
HTTPS-Sender I/O dispatcher-1, SEND TLSv1 ALERT: fatal, description = handshake_failure
HTTPS-Sender I/O dispatcher-1, WRITE: TLSv1 Alert, length = 2
[2016-02-25 22:15:12,689] ERROR - TargetHandler I/O error: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
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.SSLEngineImpl.kickstartHandshake(SSLEngineImpl.java:714)
at sun.security.ssl.SSLEngineImpl.beginHandshake(SSLEngineImpl.java:740)
at org.apache.http.impl.nio.reactor.SSLIOSession.bind(SSLIOSession.java:141)
at org.apache.http.impl.nio.ssl.SSLClientIOEventDispatch.connected(SSLClientIOEventDispatch.java:205)
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionCreated(BaseIOReactor.java:250)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processNewChannels(AbstractIOReactor.java:425)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:289)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
at java.lang.Thread.run(Thread.java:745)
At this point, my first thought was to find a way to "configure" the Java 7 to work with this. So, I did build a simple webservice client class with Eclipse (using javax.xml.soap.SOAPConnectionFactory
) and run it with the same JVM that the ESB uses. As expected, same error!
However, I edited the jre/lib/security/java.security
file and found this parameters that makes the call work:
java MyClientClass -Dhttps.protocols=TLSv1.2 -Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
After all this, I thought the same parameters applied to the ESB should work. But the two parameters above and the others below, in many different combinations, not make it happen, having the same exception as before.
./wso2server.sh -Ddeployment.security.SSLv3=false \
-Ddeployment.security.TLSv1=false \
-Ddeployment.security.TLSv1.1=false \
-Ddeployment.security.TLSv1.2=true \
-Dhttps.protocols=TLSv1.2 \
-Dhttps.cipherSuites=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Why the ESB, with the same JVM and the same arguments does not works, and MyClientClass
do? The problem is in Apache's http-core implementation (as stack trace points)? I made some mistake or this parameters are simply ignored?
The HttpCore version is 4.1.3.