Reputation: 6715
My Java program uses GitHub's raw address to access a version file to get the latest version. This address is in the format https://raw.github.com/user/repository/branch/version_file
During testing stages, I had no problems using this with the following code:
currentVersion = new Version(plugin.getDescription().getVersion());
URL url = new URL("https://raw.github.com/zonedabone/CommandSigns/master/VERSION");
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
newestVersion = new Version(in.readLine());
if (currentVersion.compareTo(newestVersion) < 0)
newAvailable = true;
However, some users have complained of the following error:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Java is complaining that it can't validate the SSL certificate. GitHub's certificate is verified by DigiCert, but apparently some Java builds won't identify this.
I have read there are two ways to overcome this: adding the certificate to the TrustStore and disabling the validation altogether.
The answers suggested on StackOverflow either make use of an allow-all TrustStore, which would be a really bad idea considering it's not within bounds of a 'test environment', or if they show how to add the certificate, they usually link to a broken web page.
Can somebody provide new information?
Upvotes: 1
Views: 3598
Reputation: 122669
First the theory... As the JSSE Reference Guide says:
IMPORTANT NOTE: The JDK ships with a limited number of trusted root certificates in the /lib/security/cacerts file. As documented in keytool, it is your responsibility to maintain (that is, add/remove) the certificates contained in this file if you use this file as a truststore.
Depending on the certificate configuration of the servers you contact, you may need to add additional root certificate(s). Obtain the needed specific root certificate(s) from the appropriate vendor.
Users should maintain the list of CA certificates themselves. A number of people won't know how to do it, unfortunately. They could use another JRE's cacerts
file (more recent) into their own installation.
You could use a trust manager that trusts any certificate and use it specifically for that connection, but that's not a good idea, since it opens the connection to potential MITM attacks. There are enough examples of code for this insecure solution around.
The best solution, if you want to trust a specific certificate, is to load it correctly using a specific truststore, as described in this answer. You could even load this trust store from an InputStream
from the classloader if you want to bundle it with your application.
Alternatively, where possible, you could use the OS trust store directly. On Windows, you can load the Windows-ROOT
keystore as described in this article. On OSX, you can load a KeychainStore
.
Upvotes: 4
Reputation: 1
You can implement an HttpsUrlConnection with "all"-TrustManager
like http://bitsandcodes.blogspot.de/2010/08/create-trust-manager-that-trust-all-ssl.html
Upvotes: -2