I have a very weird issue and looking for some tips. I have a certificate sent by client that I need to install so I can access HTTPS webservice. The certifcate has been installed, in both windows and Linux OS. using keytool command
keytool -import -alias ca -file somecert.cer -keystore cacerts –storepass changeit
when i deploy my application in windows tomcat I can communicate with HTTPS web server. However Linux tomcat gives me and error:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target at
sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
at
sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
This means it couldn't find the certifcate. The certifcate is at java security cacerts. I have used keytool -list
command and it is there.
I have no idea why it works in windows and not linux. I have tried setting the paramaters in the My servlet
System.setProperty("javax.net.debug", "all");
System.setProperty("javax.net.ssl.trustStore", "/usr/java/jdk1.5.0_14/jre/lib/security/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
It still doesn't work.
My questions are:
1.Anyone has any idea why this isn't working, I have tired everything?
2.How do you enbale SSL debuging for tomcat.Ss setting System.setProperty("javax.net.debug", "all")
works ? For some reason I don't see any SSL debug Info in Catalina.out. Do I need to change anything else.What kind of debug info should i see.
Any help is greatly appericated I am out of ideas.
To solve this problem you could try the following
Download SSLPoke.java from google
SSLPoke.java
Compile it:
javac SSLPoke.java
Once you compile code call SSLPoke as
java -Djavax.net.debug=all SSLPoke [your https host] 443
In the output you will see where java is looking for cacerts.
Once you know the exact location use keytool to import your file to cacerts
keytool -import -alias [your https host] -keystore [the location returned]/cacerts -file [your.crt]
And that is all, restart tomcat and it must be working right.
Some times when you have lot of java versions on the same Linux machine even adding [your.crt] to the cacerts returned by debug does not work, if this is the case add [your.crt] to all cacerts on the Linux machine you can find them all with:
locate cacert
once the Linux machine return all the locations of cacerts for example:
/home/xuser/NetBeansProjects/porjectx/conf/cacerts
/opt/otherlocation/j2sdkee1.3.1/lib/security/cacerts.jks
/opt/icedtea-bin-6.1.12.7/jre/lib/security/cacerts
/opt/icedtea-bin-6.1.13.5/jre/lib/security/cacerts
/opt/icedtea-bin-7.2.4.1/jre/lib/security/cacerts
/opt/oracle-jdk-bin-1.7.0.76/jre/lib/security/cacerts
/opt/sun-j2ee-1.3.1/lib/security/cacerts.jks
add [your.crt] to all of them with keytool and restart tomcat.
If you dont have the file your.crt you can get it with command
openssl s_client -connect [your https host]:443 < /dev/null
and copy from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----
I hope this help you
Have you inspected the certificate itself to see if there are any root certificates missing in the Certificate Path?
Also, keep in mind that if you're pointing to Java's built-in cacerts and you go to update Java, your cert(s) will get overwritten. I typically use an alternate keystore location for this reason.