Disabling SSL on for Junit test cases [duplicate] - java

I have a Java program that connects to a webserver using SSL/TLS, and sends various HTTP requests over that connection. The server is localhost and is using a self-signed cert, but my code is using custom TrustManagers, and ignores invalid certificates. It has worked perfectly until now.
The only difference on the server is that it used to run jboss 6 and is now running jboss 7. I'm not sure if this is a configuration issue, or whether there is a problem with my code, but I get the same errors if I try to connect using other Java-based programs like WebScarab or ZAP.
In any case, is there anything I can do to my code to get around this problem? Here is the error in full:
Received fatal alert: handshake_failure
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(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.https.HttpsURLConnectionImpl.connect(Unknown Source)
Here are the debug messages before the failure:
main, WRITE: TLSv1 Handshake, length = 75
main, WRITE: SSLv2 client hello message, length = 101
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT: fatal, handshake_failure

So I found the problem. There might be a bug in Java, but the client seems to initiate a TLSv1 Handshake, but then sends an SSLv2 client hello message, at which point the server rejects the connection.
This happens even if you create your SSLContext with an instance of TLS:
SSLContext sslContext = SSLContext.getInstance("TLS");
The solution is to set a system property before any connection attempts are made:
System.setProperty("https.protocols", "TLSv1");
There are probably other solutions to it, but this one worked for me.

The info you provide is very little as well as your stack trace.
I'll take a guess here.
What I suspect is that in the new server the protocol is TLSv1 while your clients try to connect with SSLv3 (or less) and as a result the handshake fails.
Change you clients to use higher version of TLS
or
Make your webserver support SSLv3 as well. I know how to do this in Tomcat but not in JBoss.
If this doesn't work update the post with more info (and a full stack trace).
You should enable ssl debug info -Djavax.net.debug=ssl

Was this ever resolved?
I had the exact same problem, essentially I was receiving a handshake exception immediately following the clientHello. So The chain of events was
I would present my certificate to the server
Server would imediately respond with a handshake failure. (I would not even get a Server Hello back).
Eventually I found that the server was requiring a stronger encryption/decryption algorithm than what I Was supplying in the initial handshake phase (Ie. Client and Server could not agree on a mutual encryption algorithm to use for the ssl communication).
I need to install the Unlimited Java JCE (Java Cryptography Extension Policy). There are export rules on using this, so if you ship your code overseas that may have implications..however this is what solved my problem.
This link explains how to install the updated policies
http://suhothayan.blogspot.com/2012/05/how-to-install-java-cryptography.html
This was also a great link that helped me understand exactly what was going on
https://support.f5.com/kb/en-us/solutions/public/15000/200/sol15292.html#id
This may or may not be the issue, but when the handshake fails immediately after the client Hello, it looks like the client and the server can not agree on something (in many cases its the encryption algorithms that they will mutually need to communicate).

You are seeing this error most probably because the keystore that your JBoss 6 had access to is not accessible to your JBoss 7 instance.
What I would recommend is the following.
Your self-signed server certificate must be imported into a truststore
keytool -import -alias gridserver -file server.crt -storepass $YOUR_PASSWORD_HERE -keystore server.keystore
Add the following properties to your run.conf
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.keyStore=clientcertificate.p12
-Djavax.net.ssl.trustStore=server.keystore
-Djavax.net.debug=ssl # very verbose debug. Turn this off after everything looks good.
-Djavax.net.ssl.keyStorePassword=$YOUR_PASSWORD_HERE
-Djavax.net.ssl.trustStorePassword=$YOUR_PASSWORD_HERE

The stack trace is from you client code and your client 'Received [a] fatal alert'. In other words, the SSL error happened in Jboss, not your client.
Your client side custom TrustManagers have therefore nothing to do with it. My wild guess is that your new Jboss 7 is configured to require client certificate and your client did not present any.
To debug your SSL connection, use openssl and try this:
openssl s_client -connect jboss.server.com:443
or is it is an SSLV3 server
openssl s_client -connect jboss.server.com:443 -ssl3
This should print a lot of interesting information.

I think this is related to a Java 7 bug. It is hard to be sure without more details.

For me solution was : System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");

Related

handshake_failure in Jmeter4

Tried many ways, still got handshake_failure in JMeter.
Get cer file from Chrome with different type cer and p7b(used OpenSSL to read out 4 parts certificate and save in 4 pem files)
Import in Keystore
Set SSL manager in Jmeter
error still show handshake_failure
If you run your JMeter test in command-line non-GUI mode the SSL Manager will not work, you will need to set javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword system properties, see How to Set Your JMeter Load Test to Use Client Side Certificates article for more information.
Also "from Chrome" you're getting server certificate, for two-way SSL handshake you need to get the client certificate.
If this doesn't help, handshake failure may have different causes, for example:
Incorrect certificate, i.e. you're sending certificates in wrong order
You're using incompatible SSL version, check https.default.protocol property
You're using incompatible SSL protocol, checkhttps.socket.protocols property
You're using incompatible SSL Cipher Suite, check your Java version against Default Enabled Cipher Suites table
You can enable SSL debugging by adding the next line to system.properties file:
javax.net.debug=ssl
and compare the handshake with the OpenSSL tool output

Received fatal alert: handshake_failure after upgrade to TLSv1.2

I am working on a Java 1.7 application on a Linux Centos server that connects to a third party using SOAP. Everything was working until the third party upgraded their SSL from TLSv1.1 to TLSv1.2. Now when we try to call their service, we get:
javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://webservices.abc.company.com: Received fatal alert: handshake_failure
We also have another Linux Centos server, that uses the exact same code base, but it can call the SOAP service with no errors. So I have tried to compare to find any differences. The differences I can find is that some of the directory structures are different, but the files I think are applicable are the same. For example,
/etc/httpd/conf.d/ssl.conf
Are both in the same place, and both have the same ciphers:
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
#SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLHonorCipherOrder on
They both have the same certificate issued by the third party company.
/etc/httpd/ssl/abc.crt
I have stopped the firewall.
sudo systemctl stop firewalld
Question
Do you know where else I can look, and what I can try?

Error in Java 8: 'javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: Certificate chaining error'

I try a tls1.2 connection to a local Webserver (IIS) over Apache HTTPS client, via CloseableHTTPClient. I use a local cacert-file (jks-File) that contains the root, the intermediate and even the servers certificates. The certs themselves look fine when checked manually and are accepted by all browsers.
Error:
%% Invalidated: [Session-2, SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
main, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
main, WRITE: TLSv1.2 Alert, length = 2
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: Certificate chaining error
javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: Certificate chaining error
at com.ibm.jsse2.k.a(k.java:6)
at com.ibm.jsse2.at.a(at.java:572)
at com.ibm.jsse2.D.a(D.java:11)
at com.ibm.jsse2.D.a(D.java:74)
at com.ibm.jsse2.E.a(E.java:307)
at com.ibm.jsse2.E.a(E.java:121)
at com.ibm.jsse2.D.r(D.java:223)
at com.ibm.jsse2.D.a(D.java:198)
at com.ibm.jsse2.at.a(at.java:649)
at com.ibm.jsse2.at.i(at.java:627)
at com.ibm.jsse2.at.a(at.java:689)
at com.ibm.jsse2.at.startHandshake(at.java:432)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:404)
and so forth...
This code worked so far, until the certs got changed (they got invalid).
After that, the code crashed with the above message. The new root certificate is SHA1-signed, not SHA256. I cannot see if this is the problem, changing this might be a problem (i consume the cert, i donĀ“t manage it).
EDIT:
The root ca used is the "Digicert Global Root CA".
I have got something similar one of certificates in chain was expired.
Could you recheck yor logs ?
Maybe one of certs in chain is invalid ?
https://www.ibm.com/support/pages/certificate-chaining-errors-httprequest-node
A 'certificate chaining error' occurs when the provided chain of
certificates cannot be validated. Here, one of the certificates is
"not trusted".
In may case one of cert in chain was expired.

bad_certificate when attempting SSL connect through Tomcat but connects successfully through java Main test app

I have a java test app that makes a Restful SSL connection/call to a remote server but same code run from servlet under Tomcat returns Bad_Certificate error.
Test app version successfully connects to remote after referencing my keyStore and trustStore that I specify through System.setProperty("javax.net.ssl....? statements for file locations and passwords. This test program is a stand-alone simple class with a main method that successfully establishes connection and gets a response. However, if I move this same code to my servlet that runs on Tomcat I get a "SSLHandshakeException" Bad_Certificate error. And ssl:all:verbose debug trace doesn't provide any help because it appears that it's not getting to the handshake stage. I can recreate this error on my test app only if I don't set the System Properties pointing to the certificates. It appears that setting System.setProperty is being overridden when running from Tomcat. I also tried putting locations in web.xml but that didn't have any affect either.
My code is not readily available because it is exists behind a firewall that won't allow me to copy anything. But I'll fat-finger anything in that you want to verify.
OS: Redhat 7.4
Tomcat: 7.0.76
Java: JDK 10.0.2
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java 198)
java.base/sun.security.ssl.Alerts.getSSLException(Alerts.java 159)
java.base/sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2046)
java.base/sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1207)
java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074)
java.base/sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)
java.base/sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402)
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429)
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1581)
java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1509)
java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:329)
Since adding debug to JAVA_OPTS in Tomcat configuration file, I'm getting more detail. Prior to the stacktrace that I provided yesterday I'm seeing the handshake now. And the last part of the handshake looks as follows:
update handshake state: finished
upcoming handshake states: server change_cipher_spec[-1]
upcoming handshake states: server finished [20]
ajp-bio-8009-exec-1, WRITE TLSv1.2 Handshake, length = 32
ajp-bio-8009-exec-1, READ TLSv1.2 Alert, length = 2
ajp-bio-8009-exec-1, RECV TLSv1.2 ALERT: fatal, bad certificate
%%invalidated: [Session-3 TLS_RSA_WITH_AES_128_CBC_SHA]
ajp-bio-8009-exec-1, call closeSocket()
But I'm not sure what to do about this.

Securing a Thrift server aginst the POODLE SSL vulnerability

In order to secure my Thrift server against the recently discovered SSLv3 vulnerability, I explicitly stated which protocols should be enabled for the server socket:
TServerSocket socket = TSSLTransportFactory.getServerSocket(...);
SSLServerSocket sslServerSocket = (SSLServerSocket) socket.getServerSocket;
sslServerSocket.setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
However, even though a check using the TestSSLServer lists only TLSv1.1 and TLSv1.2, I'm still able to connect with OpenSSL using SSLv3:
openssl s_client -connect localhost:1111 -ssl3
How can I entirely disable SSLv3 on Thrift, so it fails during the SSL handshake already?
It seems I misinterpreted the openssl client output. Even though there is CONNECTED(00000003) on the first line, the error message follows:
140535757866656:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:337:
It is, therefore, not possible to connect to the server; the code snippet presented in the question works fine.

Categories