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.
openssl s_client -connect <server>:<port>
. – Messier