Will the cross root cover trust by the default list in the JDK/JRE?


#21

Which certificate store does Java use? Does it use the system one? Really don’t see any issue here on Linux with Java. Which domain did you test?


#22

It works on OpenJDK on Ubuntu. But Oracle Java does not accept it; not even on Ubuntu.

Since there is no OpenJDK für Microsoft Windows, I assume that is broken for all java based Feed readers on Windows.


#23

Did you try the oracle java with the openJDK’s keystore? It could simply be that the openJDK one’s been updated to include the relevant root certs


#24

OpenJDK on ubuntu definitely uses a different keystore. You can look at the contents with:

keytool -keystore /etc/ssl/certs/java/cacerts -storepass changeit -list

Similar command for the Oracle JRE/JDK keystore


#25

This is the root that allows it to trust LE:

debian:dst_root_ca_x3.pem, Nov 9, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13


#26

Sorry, if this has been posted or answered already, but it may help some people until an official support is made available. Though JAVA may not support the CA out-of-the-box, the CA can be added during runtime of a java program by this simple code.

public static void addRootCA() throws Exception {
InputStream fis = new BufferedInputStream(new FileInputStream(“target/classes/dst_root_ca_x3.pem”));
Certificate ca = CertificateFactory.getInstance(“X.509”).generateCertificate(fis);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setCertificateEntry(Integer.toString(1), ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance(“TLS”);
ctx.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
}

So, calling this function inside URLConnectionReader.java from Firefishy should do the job. I prefer this rather than disabling certificate path checking completely in java by creating a dummy trust manager.


#27

It’s pretty trivial to add the CA to the trust list for any standard JDK with the keytool command. Point is - if you have to add the CA it’s not much different than you adding your own local CA — it’s not something you can expect an end-user to do.


#28

If you use services with certificates issued by LE, just load the CA dynamically. The end user doesn’t have anything to do with it then and you’re fine.


#29

Can someone give me instructions for adding to the JRE:s truststore that a retard like me understands?

~/dev/projects/kostbevakningen $ java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)


sudo keytool -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -file ~/Downloads/isrgrootx1.pem

Still get errors:

[error] Server access Error: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target url…

#30

I’m struggling. I have exactly the same use case (nexus and sbt/ivy) but JDK build 1.8.0_65-b17 (the latest for OS X it seems).

I’ve run:

sudo keytool -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -file ~/Downloads/isrgrootx1.pem

but it doesn’t help. I guess I need the full chain. Individually adding the three pem:s from here doesn’t work: https://letsencrypt.org/certificates/. I get errors:

keytool error: java.lang.Exception: Certificate not imported, alias <mykey> already exists

on the two later and on second runnings of the first.


#31

You need to use a different alias for each imported cert.

i.e. if It’s a chain of “root”, “intermediate1”, “intermediate2” - specify “-alias leroot”, “-alias leint1”, “-alias leint2” for example when doing the imports.

You should also validate that your server is returning the intermediates/chain.


#32

Found out the pem-file didn’t work for me here: https://letsencrypt.org/certs/letsencryptauthorityx1.pem.

`keytool error: java.lang.Exception: Input not an X.509 certificate``

But the .der file worked fine. So for me:

wget https://letsencrypt.org/certs/isrgrootx1.pem
wget https://letsencrypt.org/certs/letsencryptauthorityx1.der

sudo keytool -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias isrgrootx1 -file ~/Downloads/isrgrootx1.pem
sudo keytool -trustcacerts -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/security/cacerts -storepass changeit -noprompt -importcert -alias letsencryptauthorityx1 -file ~/Downloads/letsencryptauthorityx1.der


#33

Hi, this is the output of keytool -list

lets-encrypt-x2, 20/01/2016, trustedCertEntry, 
Huella Digital de Certificado (SHA1): 02:00:7A:05:CE:D3:68:99:AA:8A:03:A2:CF:30:7F:1C:04:49:FC:31
lets-encrypt-x1, 20/01/2016, trustedCertEntry, 
Huella Digital de Certificado (SHA1): 3E:AE:91:93:7E:C8:5D:74:48:3F:F4:B7:7B:07:B4:3E:2A:F3:6B:F4
isrgrootx1, 20/01/2016, trustedCertEntry, 
Huella Digital de Certificado (SHA1): CA:BD:2A:79:A1:07:6A:31:F2:1D:25:36:35:CB:03:9D:43:29:A5:E8
signfiles, 20/01/2016, PrivateKeyEntry, 
Huella Digital de Certificado (SHA1): 38:11:0A:E1:0C:00:31:6C:AF:84:9A:DA:98:B9:10:F1:DA:EA:9A:86
letsencryptauthorityx1, 20/01/2016, trustedCertEntry, 
Huella Digital de Certificado (SHA1): E0:45:A5:A9:59:F4:27:80:FA:5B:D7:62:35:12:AF:27:6C:F4:2F:20

My program is still returning:
```sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target````

What should I check?


#34

What about getting cross signature from another authority that’s already in java keystore in older versions as well?
The problem is still present with jre 1.8.0_71.


#35

FYI: problem is still here with jdk-8u74.
It seems that, at least under Linux debian/ubuntu/mint/…, OpenJDK installer symlinks $JAVA_HOME/jre/lib/secutity/cacerts to /etc/ssl/certs/java/cacerts in order to have all certifications centralized.
Oracle JDK/JRE rely on it’s own internal cacerts (as expected).
I “solved” the problem doing the same with my hand-installed Oracle JDK:

cd $JAVA_HOME/jre/lib/security/ && mv cacerts cacerts-orig && ln -s /etc/ssl/certs/java/cacerts .

To solve the problem it might be enough to provide a specialized installer for Oracle JDK.


#36

I still get SunCertPathBuilderException even with your code. I’m using Unirest which uses Apache HttpComponents.


#37

Could you give the following a try?
Just change the URL part to your ssl enabled site (which is signed by letsencrypt):

package com.sandbox;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class CheckSSL {

public static void main(String[] args) throws Exception {
	addRootCA();
    URL oracle = new URL("https://yoursslsitewhichissignedbytheca/");
    URLConnection yc = oracle.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(
                                yc.getInputStream()));
    String inputLine;
    while ((inputLine = in.readLine()) != null)
        System.out.println(inputLine);
    in.close();
}

public static void addRootCA() throws Exception {
	InputStream fis = new BufferedInputStream(new FileInputStream("target/classes/dst_root_ca_x3.pem"));
	Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(fis);

	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
	ks.load(null, null);
	ks.setCertificateEntry(Integer.toString(1), ca);

	TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	tmf.init(ks);

	SSLContext ctx = SSLContext.getInstance("TLS");
	ctx.init(null, tmf.getTrustManagers(), null);		
	
	HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
	
}

public static void disableCertificateValidation() {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] { 
      new X509TrustManager() {
        public X509Certificate[] getAcceptedIssuers() { 
          return new X509Certificate[0]; 
        }
        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
    }};

    // Ignore differences between given hostname and certificate hostname
    HostnameVerifier hv = new HostnameVerifier() {
      public boolean verify(String hostname, SSLSession session) { return true; }
    };

    // Install the all-trusting trust manager
    try {
      SSLContext sc = SSLContext.getInstance("SSL");
      sc.init(null, trustAllCerts, new SecureRandom());
      HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
      HttpsURLConnection.setDefaultHostnameVerifier(hv);
    } catch (Exception e) {}
  }

}

And if that doesn’t work, try using the disableCertificateValidation() instead of addRootCA() in the main method


#38

Thanks for offering this fix. I just spent $15 and half an hour to make the problem go away for three years, so I’m not really in a position to test it now.


#39

I see my own reply up above here, but suddenly I have the issue again:

Server access Error: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target url=https://repo.woodenstake.se/content/groups/All/se/hedefalk/lift-utils_2.5_2.11/0.1/lift-utils_2.5_2.11-0.1.pom

Even though I follow my own instructions above of importing isrgrootx1 and letsencryptauthorityx1, the problem persists. The only thing I can think of is that I have gone to using SAN extensions for all my subdomains in one cert. Or that the root cert has changed?


#40

Oh, it’s the later:

The X1 and X2 intermediates were our first generation of intermediates. We’ve replaced them with new intermediates that are more compatible with Windows XP.

https://letsencrypt.org/certificates/