12

I've a weird problem - a supplier uses TLS SSLv3 with both a self signed client and server certificate. This hasn't been a problem with Java1.5 and Java1.6 - simply import client certificate and private key into a keystore and the server public certificate into the truststore. Everything works fine. However with Java7 the server certificate fails to be trusted even though the same truststore is being used. I've tried Windows and Red Hat both using Java7 (1.7.03, 04 and 05, x86 and x64 versions) with no success.

I've recreated the keystore/truststore from scratch and they only contain these certificates. The appropriate system properties have been set (javax.net.ssl.keyStore, javax.net.ssl.trustStore) and the key aspect is that the exact same code and configuration runs perfectly in JDK5/6.

I'm at a loss - I can't find any reference to additional checking but I would have thought that the fact the certificate was located in the truststore should mean that it's trusted regardless of being self signed.

Any help appreciated. Ads

Exception trace:

Exception in thread "main" 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
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
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:1338)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
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:998)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at com.alltria.ypsilon.testing.TestSSL.main(TestSSL.java:65)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:350)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:249)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
... 13 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:208)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:279)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:345)
... 19 more
Java Result: 1

The part where the ssl debug fails is trying to validate the server certificate:

***
%% Invalidated:  [Session-1, SSL_RSA_WITH_RC4_128_SHA]
main, SEND SSLv3 ALERT:  fatal, description = certificate_unknown
main, WRITE: SSLv3 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 00 00 02 02 2E                               .......
main, called closeSocket()
main, 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
main, called close()
main, called closeInternal(true)
Adam Green
  • 181
  • 1
  • 1
  • 4
  • Greetings from Ypsilon, we're working on it :) – cat_baxter Jun 22 '12 at 09:31
  • Maybe it is related to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7018897 ?? – Pma Aug 27 '12 at 21:44
  • Can you add `-Djavax.net.debug=all` to your `java` command line and post the full resulting log, especially where the trust store is loaded? – David Grant Oct 03 '12 at 08:02
  • I'm trying to solve this problem now. I investigated the Java bug database and it says this problem is fixed, but I don't see what the solution is. Does anyone know how to get past it? – IcedDante May 21 '14 at 19:30
  • @adam-green, could you figure out how to fix this? We are kinda of in the same boat... – tavlima May 21 '14 at 19:58

3 Answers3

10

I actually had a somewhat similar issue, where a Tomcat application would trust the ca cert in the truststore when using Java 1.6 and reject it with java 1.7. After adding keyUsage to my ca certificate it works (after reading a bug report, JDK-7018897 : CertPath validation cannot handle self-signed cert with bad KeyUsage).

What I have done (Ubuntu 12.04 x64):

  1. Edit /etc/ssl/openssl.cnf and uncomment keyUsage line in v3_ca section.
  2. Generate new ca cert from old one with keyUsage included using the command:

    openssl x509 -in oldca.pem -clrext -signkey oldca.key -extfile /etc/ssl/openssl.cnf -extensions v3_ca -out newca.pem
    
  3. Delete old CA key from truststore and insert the new one.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
Pma
  • 1,063
  • 1
  • 16
  • 30
  • See [RFC 5280](http://tools.ietf.org/html/rfc5280) and [RFC 6125](http://tools.ietf.org/html/rfc6125) for the rules Java uses. – jww May 11 '14 at 05:06
  • 2
    How does this solution work in a Windows environment? I don't have the openssl.cnf file. Looking at the bug report I'm not sure what the fix is. Am I supposed to grab the certificate in Java and modify it there during runtime? Doesn't seem like the right solution... – IcedDante May 21 '14 at 05:34
  • To be more specific... I've installed openSSL, I have downloaded the certificate from the target server. But I'm not sure how I get the oldca.key file. Also, I thought certificates were managed with a "crt" extension. Is there a reason you're using pem? – IcedDante May 21 '14 at 18:59
0

I have also encountered this situation when dealing with JDK 1.7. If req command is invoked with the -x509 option, it's better to uncomment keyUsage line in v3_ca section and generate the CA again with(see http://wwwneu.secit.at/web/documentation/openssl/openssl_cnf.html)

openssl req -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf -extensions v3_ca -batch

And if you use the generated CA certificate to sign other certificate make sure that you also uncomment the item basicConstraints = CA:true and set value to true

  • @IcedDante - See [How do you sign OpenSSL Certificate Signing Requests with your Certification Authority?](https://stackoverflow.com/questions/21297139/how-do-you-sign-openssl-certificate-signing-requests-with-your-certification-aut) on Stack Overflow. – jww Aug 12 '14 at 02:53
0

For some reasons Java 8 doesn't accept self-signed certificate even added to its cacerts store.

My workaround for that is to create a custom keystore :

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj "/C=MA/ST=ByExample/L=Test/O=Chapter3/OU=Org/CN=bip70.com" -nodes

keytool -import -keystore clientkeystore -file cert.der -alias bip70.com -storepass changeit

then using it in My IDE using as jvm argument: -Djavax.net.ssl.trustStore=clientkeystore

Badr Bellaj
  • 11,560
  • 2
  • 43
  • 44