Chrome/Firefox and Jetty HTTPS - java

I have an application running on Jetty 6 which is accessed over HTTPS. Connecting with IE 11 works but not Firefox 43 or Google 40.
The SSL trace shows that Jetty and browser fail to find a common cipher:
%% Initialized: [Session-13, SSL_NULL_WITH_NULL_NULL]
%% Invalidated: [Session-13, SSL_NULL_WITH_NULL_NULL]
783842035#qtp-1833323686-4, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
783842035#qtp-1833323686-4, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 28 ......(
783842035#qtp-1833323686-4, called closeSocket()
783842035#qtp-1833323686-4, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
However, when IE 11 is used the selected cipher is TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
%% Initialized: [Session-30, SSL_NULL_WITH_NULL_NULL]
%% Negotiating: [Session-30, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256]
*** ServerHello, TLSv1.2
Since Chrome warns about RC4 ciphers when it fails to connect:
A secure connection cannot be established because this site uses an >>unsupported protocol or cipher suite. This is likely to be caused when the >>server needs RC4, which is no longer considered secure.
I have excluded RC4 in java.security by adding the following property
jdk.tls.disabledAlgorithms=RC4
but to no avail, Chrome and FF still fail to connect.
I've ran out of ideas. Any suggestions? TIA.

Jetty 6 is long ago EOL (End of Life).
If you stick with Jetty 6, know that the level of SSL/TLS tweaking you need is not present in that version of Jetty.
You'll either have to stick with JVM level tweaks, or write a custom SslSelectChannelConnector (sorry, the easier SslContextFactory concepts were introduced in Jetty 7) implementation of your own to accomplish the necessary includes and excludes of ciphers and protocols, along with the new TLS ciphers ordering requirements to pull this off reliably.
Jetty 9.3.7.v20160115 is almost up to date with the recent and upcoming browser changes. The next release, likely 9.3.8, will have the remaining tweaks necessary to support the recent browser changes, but only under Java 8u72 (or newer).
Also of note, since you have SSL/TLS enabled on Jetty, you have to keep your version of Java up to date, if for no other reason then to keep up with the changes in SSL/TLS over the past few years.

Related

.Net Client - Java server Connection problem using tls1.2

I have a problem connecting from my .Net client to Java server, both were changed from TLS1 to TLS1.2.
Both client and server in the same machine, Windows10 64bits.
.Net client created under .Net Framework 4.5, using HttpWebRequest.
Previous the request call I set
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
.Net Error "The request was aborted: Could not create SSL/TLS secure channel."
Java using jdk1.8.0_25
Java Error log:
P-86, received EOFException: error
P-86, handling exception: javax.net.ssl.SSLHandshakeException: Remote host
closed connection during handshake
%% Invalidated: [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA256]
P-86, SEND TLSv1.2 ALERT: fatal, description = handshake_failure
P-86, WRITE: TLSv1.2 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 03 00 02 02 28 ......(
P-86, called closeSocket()
P-86, called close()
P-86, called closeInternal(true)
I have changed to different ciphers with no success. Any suggestion to follow ?
thanks
My problem was the certificate.I was using a very old one, I changed it and It works. I'm not clear why, I'm investigating.
Thanks to all.

Log displays TLSv1 instead of SSLv3

I have enabled logs in my application using -Djavax.net.debug=all option. Code that have written is supposed to use SSLv3 protocol, but in logs when I am checking it is displaying as ::
*** ClientHello, TLSv1
*** ServerHello, TLSv1
As far as I understand from reading is, Client and Server using TLSv1 for handshake, but as I have used SSLv3 in my code while initiating socket, ideally it should print SSLv3 instead TLSv1.
Below is the code snippet I have used :
SSLContextBuilder builder = new SSLContextBuilder();
builder.useProtocol("SSLv3");
SSLContext sslContext = builder.build();
Can someone please clarify the reason for the same, or is there something else I have missed out. Just to add on I am on Java 7.
Most probably SSLv3 is just not supported by server (which is recommended configuration nowadays because of security), so the lib uses least supported TLS version.
UPD: seems that hello format says nothing about what protocol will be used in fact. There's something from Java docs:
Currently, the SSLv3, TLSv1, and TLSv1.1 protocols allow you to send SSLv3, TLSv1, and TLSv1.1 hellos encapsulated in an SSLv2 format hello. For more details on the reasons for allowing this compatibility in these protocols, see Appendix E in the appropriate RFCs (previously listed).
Note that some SSL/TLS servers do not support the v2 hello format and require that client hellos conform to the SSLv3 or TLSv1 client hello formats.
The SSLv2Hello option controls the SSLv2 encapsulation. If SSLv2Hello is disabled on the client, then all outgoing messages will conform to the SSLv3/TLSv1 client hello format. If SSLv2Hello is disabled on the server, then all incoming messages must conform to the SSLv3/TLSv1 client hello format.

SQL Server JDBC Error on Java 8: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption

I am getting the following error when connecting to a SQL Server database using version the Microsoft JDBC Driver:
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:98d0b6f4-f3ca-4683-939e-7c0a0fca5931".
We recently upgraded our applications from Java 6 & Java 7 to Java 8. All systems running Java are running SUSE Linux Enterprise Server 11 (x86_64), VERSION = 11, PATCHLEVEL = 3.
Here are the facts I have collected with a Java program that I wrote which simply sequentially opens and closes 1,000 database connections.
Connections are dropped with this error about 5%-10% of the time. The error DOES NOT occur on every connection.
The problem ONLY occurs with Java 8. I ran the same program on Java 7 and the problem is not reproducible. This is consistent with our experience in production prior to upgrading. We've had zero problems running under Java 7 in production.
The problem DOES NOT occur on all of our Linux servers running Java 8, it only occurs on some of them. This is perplexing to me, but when I run the same test program on the same version of the Linux JVM (1.8.0_60, 64 bit) on different Linux instances, the problem does not occur on one of the Linux instances, but the problem does occur on others. The Linux instances are running the same version of SUSE and they are at the same patch level.
The problem occurs when connecting to BOTH SQL Server 2008 and SQL Server 2014 servers/databases.
The problem occurs regardless if I am using the 4.0 version of the SQL Server JDBC driver or the newer 4.1 version of the driver.
The thing that makes my observations unique on this compared to others on the web is that although the problem happens ONLY on Java 8, I cannot get the problem to occur on one of the seemingly identical Linux servers that is running the same Java 8 JVM. Other folks have seen this problem on earlier versions of Java as well, but that has not been our experience.
Any input, suggestions, or observations you may have are appreciated.
Your url should be like below and add sql sqljdbc42.jar. This will resolve your issue
url = "jdbc:sqlserver://" +serverName + ":1433;DatabaseName=" + dbName + ";encrypt=true;trustServerCertificate=true;
I turned on SSL logging in the Java 8 JVM on a Linux instance which reproduces the problem. SSL logging is turned on using -Djavax.net.debug=ssl:handshake:verbose. This revealed some useful information.
The workaround that we are using in production and has proven to work for us is to set this parameter on the JVM:
-Djdk.tls.client.protocols=TLSv1
If you want more details, please read on.
On a server where the problem can be reproduced (again, only 5-10% of the time), I observed the following:
*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 195
main, READ: TLSv1.2 Handshake, length = 1130
*** ServerHello, TLSv1.2
--- 8<-- SNIP -----
%% Initialized: [Session-79, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
*** Diffie-Hellman ServerKeyExchange
--- 8<-- SNIP -----
*** ServerHelloDone
*** ClientKeyExchange, DH
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 133
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Change Cipher Spec, length = 1
*** Finished
verify_data: { 108, 116, 29, 115, 13, 26, 154, 198, 17, 125, 114, 166 }
***
main, WRITE: TLSv1.2 Handshake, length = 40
main, called close()
main, called closeInternal(true)
main, SEND TLSv1.2 ALERT: warning, description = close_notify
main, WRITE: TLSv1.2 Alert, length = 26
main, called closeSocket(true)
main, waiting for close_notify or alert: state 5
main, received EOFException: ignored
main, called closeInternal(false)
main, close invoked again; state = 5
main, handling exception: java.io.IOException: SQL Server returned an incomplete response. The connection has been closed. ClientConnectionId:12a722b3-d61d-4ce4-8319-af049a0a4415
Notice that TLSv1.2 is selected by the database server and used in this exchange. I've observed that, when connections fail from the problematic linux service, TLSv1.2 is ALWAYS the level which was selected. However, connections do not ALWAYS fail when TLSv1.2 is used. They only fail 5-10% of the time.
Now here is an exchange from a server that does NOT have the problem. Everything else is equal. I.e., connecting to the same database, same version of the JVM (Java 1.8.0_60), same JDBC driver, etc. Notice that, here, TLSv1 is selected by the database server instead of TLSv1.2 as in the faulty server's case.
*** ClientHello, TLSv1.2
--- 8<-- SNIP -----
main, WRITE: TLSv1.2 Handshake, length = 207
main, READ: TLSv1 Handshake, length = 604
*** ServerHello, TLSv1
--- 8<-- SNIP -----
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
%% Initialized: [Session-79, TLS_RSA_WITH_AES_128_CBC_SHA]
** TLS_RSA_WITH_AES_128_CBC_SHA
--- 8<-- SNIP -----
Algorithm: [SHA1withRSA]
--- 8<-- SNIP -----
***
*** ServerHelloDone
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
--- 8<-- SNIP -----
main, WRITE: TLSv1 Handshake, length = 134
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data: { 26, 155, 166, 89, 229, 193, 126, 39, 103, 206, 126, 21 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, READ: TLSv1 Change Cipher Spec, length = 1
main, READ: TLSv1 Handshake, length = 48
*** Finished
So, when TLSv1 is negotiated between the Linux JVM and the SQL Server, connections are ALWAYS successful. When TLSv1.2 is negotiated, we get sporadic connection failures.
(Note: Java 7 (1.7.0_51) always negotiates TLSv1, which is why the problem never occurred for us with a Java 7 JVM.)
The open questions we still have are:
WHY is that the same Java 8 JVM run from 2 different Linux servers will always negotiate TLSv1, but when connecting from another Linux server it always negotiates TLSv1.2.
And also why are TLSv1.2 negotiated connections successful most, but not all, of the time on that server?
Update 6/10/2017:
This posting from Microsoft describes the problem and their proposed solution.
Resources:
http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html
http://www.infoworld.com/article/2849292/operating-systems/more-patch-problems-reported-with-the-ms14-066-kb-2992611-winshock-mess.html
http://blogs.msdn.com/b/jdbcteam/archive/2008/09/09/the-driver-could-not-establish-a-secure-connection-to-sql-server-by-using-secure-sockets-layer-ssl-encryption.aspx
Java 8 , JCE Unlimited Strength Policy and SSL Handshake over TLS
http://blogs.msdn.com/b/saponsqlserver/archive/2013/05/10/analyzing-jdbc-connection-issues.aspx
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#descPhase2
https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls
In case someone arrives here looking for a solution to connect to a database from PhpStorm, just add the following after the port in the URL:
;encrypt=true;trustServerCertificate=true;
I got the solution from this comment: SQL Server JDBC Error on Java 8: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption
Thank you so much! Can confirm it's working on PhpStorm 2022.1.1.
Using openjdk 11 it's possible to add the following properties to the connection URL in order to force the use of SSL
;integratedSecurity=false;encrypt=false;trustServerCertificate=true;
Before you upgrade SQL JDBC Driver, check the compatibility first:
Sqljdbc.jar requires a JRE of 5 and supports the JDBC 3.0 API
Sqljdbc4.jar requires a JRE of 6 and supports the JDBC 4.0 API
Sqljdbc41.jar requires a JRE of 7 and supports the JDBC 4.1 API
Sqljdbc42.jar requires a JRE of 8 and supports the JDBC 4.2 API
Source: https://www.microsoft.com/en-us/download/details.aspx?id=11774
This appears to have been fixed in version 4.2 of the MS SQL JDBC driver. I created a program where I connected to the server 1000 times, pausing 100ms between each attempt. With version 4.1 I was able to reproduce the problem every time, although it happened only sporadically. With version 4.2 I was unable to reproduce the problem.
Add ;encrypt=true;trustServerCertificate=true into connection.url. Example
jdbc:sqlserver://localhost\SQLEXPRESS:1433;databaseName=testdb;encrypt=true;trustServerCertificate=true
And check Compatible compiler version java in pom file with version jre of mssql-jdbc of maven. Like this
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
And
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>11.2.1.jre8</version>
</dependency>
compiler 1.8 and jre8
Issue got resolved for me when I changed the sqljdbc-4.2.0 jar with mssql-jdbc-8.4.1 jar
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.4.1.jre8</version>
</dependency>
In my case i had a sql server using the 3DES_EDE_CBC algorithm, this is disabled by default on jdk 1.8 , so checking the
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/security/java.security
And eliminating the algorithm from:
jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize <
1024, \
EC keySize < 224, 3DES_EDE_CBC, anon, NULL
Worked for me.
Like #2Aguy wrote, you can change the JVM parameter.
In my case I couldn't change it, and used the connection string "sslProtocol" parameter, lowering the connection to TLSV1.
Connection String:
jdbc:sqlserver://<HOST>:<PORT>;encrypt=true;trustServerCertificate=true;sslProtocol=TLSv1;database=<DB NAME>
application.properties:
spring.datasource.url=jdbc:sqlserver://YourServerName:1433;database=<YourDatabaseName>;encrypt=true;trustServerCertificate=true;
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql=true
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.jpa.hibernate.ddl-auto = create-drop
Microsoft Recently open sourced their driver. One can see mssql-jdbc driver activity on GitHub. I guess latest preview version is 6.1.5.
Also you can find all preview versions on maven too. Supporting both JDK7 & JDK 8.
I've also hit this issue on Windows Server 2012 R2, using JDBC driver 4.0 & 4.1 with Java 7. This Microsoft article pins the blame on DHE ciphersuites, and recommends disabling them or reducing their priority if you cannot upgrade to JDBC driver 4.2
In my case, the issue was because the app was set to use spring-boot-ext-security-starter-credhub-credential and there were some issues with that setup.
So I removed credhub from the manifest file and pom and fetched credentials in a different way; then the error was gone.
If the server name in the connection string does not match the server name in the SQL Server SSL certificate, the following error will be issued: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.security.cert.CertificateException: Failed to validate the server name in a certificate during Secure Sockets Layer (SSL) initialization."
This helped me resolve the issue. Was using the localhost in servername, finally changing in jdbc connection string to the same name as the CN was able to connect.
Refer: https://wiki.deepnetsecurity.com/pages/viewpage.action?pageId=1410867 for more info
I have fixed the issue on my local enviroment, it mainly contains two steps below.
Switch the JDBC Driver dependency like below if your project is built by maven:
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
2.Replace the Driver Class Name additionally:
ru.yandex.clickhouse.ClickHouseDriver
3.Modify the JDBC URL like this:
jdbc:jtds:sqlserver://xxxx:1433;databaseName=xxx
Thanks to #Sunil Kumar and #Joce.
I used the jar and below syntax:
String myDriver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
String myURL = "jdbc:sqlserver://DB_ipaddress\DB_instance;databaseName=DB_name;user=myusername; password=mypass;encrypt=true;trustServerCertificate=true;"; /==> here the semicolon will be twice like shown/
Connection con = DriverManager.getConnection(myURL);
I had this issue recently after doing a yum update in a client's server running RedHat 7. Since the above thread did not help me resolve my issue, I am posting this answer.
Issue:-
Yum update in RedHat automatically reinstalls OpenJDK , my applications use oracle JDK.
Verifying Default JDK:
java version
Switch the default version:
update-alternatives --config java
There are 2 programs which provide 'java'.
Selection Command
1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.302.b08-0.el7_9.x86_64/jre/bin/java)
2 /usr/java/jdk1.8.0_181-amd64/jre/bin/java
Enter to keep the current selection[+], or type selection number:
Enter the number alongside the appropriate version you want to us and hit enter.
I have also faced same issue while creating connection to the database with below connection string.
DriverManager.getConnection("jdbc:sqlserver://" + host + ":" + port + ";databaseName=" + dbName + ";user=" + userName + ";password=" + password);
After updating connection string as below, it worked.
Connection con = DriverManager.getConnection("jdbc:sqlserver://" + host + ":" + port + ";databaseName=" + dbName + ";encrypt=true;trustServerCertificate=true;user=" + userName + ";password=" + password);
here i have added encrypt=true;trustServerCertificate=true after the database name.
For me I add to add Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
between the two lines
DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
Connection con = DriverManager.getConnection(connectionUrl);
So the final code for the connection would be:
DriverManager.registerDriver(new com.microsoft.sqlserver.jdbc.SQLServerDriver());
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection(connectionUrl);
If you came here for Ignition 8.1+ error, and you're using MSSQL express on your local host, at your "Connect URL" put this: jdbc:sqlserver://localhost\SQLEXPRESS; encrypt=true;trustServerCertificate=true;
URL settings
Valid connection
setTrustServerCertificate(true); worked for me.

JAVA TLS 1.2 downgrade to TLS 1.0 sometimes error

I have TLS client writen in JAVA. When i set
sslContext = TLS1.2
and enabled protocols to SSLv3 TLSv1 TLSv1.1 TLS1.2
it works fine with almost all servers. Client start handshake with TLSv1.2. If server can only TLSv1, connection downgrades to TLSv1 during handshake.
But! We use about 15 such TLSv1 services and 4 of them fails to downgrade. Servers are all different:
Microsoft-IIS/7.5, nginx, IBM_HTTP_SERVER, SQLAnywhere.
Errors like this:
SEND TLSv1 ALERT: fatal, description = unexpected_message X2
handling exception: javax.net.ssl.SSLException: Invalid Padding length: 139
javaException : Received fatal alert: unexpected_message
If i set enabled protocols to TLSv1, that servers works fine. But i want set sslContext and enabled protocols to be compatible with all services and preferably work with TLSv1.2
Any suggestions will be appreciated!
But i want set sslContext and enabled protocols to be compatible with all services and preferably work with TLSv1.2
First, there are enough servers out there which don't do TLS 1.2 but the best they can do is TLS 1.0 (and some even only SSL 3.0). A proper implementation of the TLS stack would in this case simply send a TLS 1.0 reply and thus enforcing the connection to be TLS 1.0 which is supported in your client. Forcing these servers to TLS 1.2 will not work because they don't implement it. All you could do is replace the servers with newer implementations.
And then there are several implementations out there which incorrectly implement the protocol. Some of these simply close the connection if you send a TLS 1.2 ClientHello or use some TLS extensions they never heard of. If you can not replace these servers you have to communicate with them in a way they will understand, like speaking only TLS 1.0 etc. Browsers already deal with this rotten servers by slowly downgrading the connection, i.e. if TLS 1.2 causes a handshake failure they will try again with TLS 1.0 etc. Often browsers even have hard coded a list of servers which are too rotten to even play nice after trying simple downgrads and which need to have special ciphers or something like this.

Java 7 (acting as client) SSL handshake failure with keystore and truststore that worked in Java 6

I'm doing a JBoss AS 5.1 to 7.4, and Java 6 to 7 migration, and get a handshake failure.
The keystore and truststore are the ones we have been using successfully for ages with Java 6.
I've written some tests to narrow the problem down, it's definitely not JBoss but rather Java 7.
With SSL logging turned on, I get this:
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) %% Invalidated: [Session-2, SSL_RSA_WITH_RC4_128_SHA]
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, SEND TLSv1 ALERT: fatal, description = certificate_unknown
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, WRITE: TLSv1 Alert, length = 2
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called closeSocket()
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
17:44:30,041 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called close()
17:44:30,042 INFO [stdout] (http-/192.168.147.20:8080-120) http-/192.168.147.20:8080-120, called closeInternal(true)
There are some threads touching upon this (or a similar) problem, where people are suggesting to recreate certs or truststores with different params. I'd rather not go down this route, since I've recently without success tried to create more such keystores and truststores for different accounts of the same webservice.
Since we have been using these old (keystore and truststore) in production with Java 6, I'd like to keep them if at all possible.
It appears the problem may be caused by Java 7 being more tight regarding the checking of truststore certificate chain?
Is it possible to set some flags to relax the checking, make it behave like Java 6?
A thing I'm not 100% sure about is how to interpret the failure message: I think it's telling me that it's my machine (not the remove server), which isn't satisfied that the remote machine is safe. Is that correct?
Any help/ideas appreciated!
==========================================================
As suggested, have added PEM (with chain), exported from firefox when accessing the WS URL, to the truststore. This doesn't make it handshake, but slightly changes the failure.
***
%% Invalidated: [Session-1, SSL_RSA_WITH_RC4_128_SHA]
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown
main, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 2E .......
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
==============================================================
Also, as suggested in other threads, I've written another test that uses a TrustManager that does not validate certificate chains, and ran this with my original truststore.
This test is able to connect, and thus shows that my machine's validating of the remote machine is the only problem, and that my keystore is fine.
However, I can't use this approach for our actual webservice client, since that uses the Sun RPC lib, and connecting happens somewhere deep inside their code, so I can't touch it.
First, yes, the exception says the Java SSL module in your machine doesn't trust the proof of identity (certificate) received from the server.
Yes, Java 7 does stricter checking. There may be more, but the one I'm sure of is that it doesn't allow the validity period of a child cert to end after the parent/CA cert (or begin before, but in practice that doesn't happen). See PKIX Path does not chain with any of the trust anchors error in Windows Environment which says it is a bug and will be fixed.
To check: if the server is a webserver, you could access any (harmless) page with a browser and use that to look at the cert chain. Otherwise, run openssl s_client -connect $host:443 -showcerts and once it connects enter EOF (Unix ^D, Windows ^Z), then put each ----BEGIN CERT... to -----END CERT... block in a different file and run openssl x509 -noout -subject -issuer -startdate -enddate on each in order.
To fix: if this is the problem, there doesn't seem to be any way to turn it off directly, except by turning off all cert checking (and thus losing some of the security of SSL), but adding the server entity cert to your truststore should work because then Java doesn't verify the chain. (You don't need to remove what's already there, just use an alias that isn't already in use.) Good luck.

Categories

Resources