SSL Certificates, Debian, and Java

Recently, I tried to run a Java application on my Debian workstation that needed to establish SSL / HTTPs connections.

But... as soon as a connection was attempted, the application failed with an ugly stack trace:

ValidatorException: No trusted certificate found
sun.security.validator.ValidatorException: No trusted certificate found
        at net.filebot.web.WebRequest.fetch(WebRequest.java:123)
          at net.filebot.web.WebRequest.fetchIfModified(WebRequest.java:101)
          at net.filebot.web.CachedResource.fetchData(CachedResource.java:28)
          at net.filebot.web.CachedResource.fetchData(CachedResource.java:11)
          at net.filebot.web.AbstractCachedResource.fetch(AbstractCachedResource.java:137)
          at net.filebot.web.AbstractCachedResource.get(AbstractCachedResource.java:82)
          at net.filebot.cli.ArgumentProcessor$DefaultScriptProvider.fetchScript(ArgumentProcessor.java:210)
          at net.filebot.cli.ScriptShell.runScript(ScriptShell.java:82)
          at net.filebot.cli.ArgumentProcessor.process(ArgumentProcessor.java:116)
          at net.filebot.Main.main(Main.java:169)
Failure (<C2><B0>_<C2><B0>)

First attempts at solving the problem were trivial: install all trusted SSL certificates on the Debian box.

apt-get install ca-certificates-java
apt-get install ca-certificates

This did not help, though: turns out that ca-certificates-java installs a script /etc/ca-certificates/update.d/jks-keystore that whenever ca-certificates is updated, re-generates the java certificates. Given that ca-certificates was already installed on my system, the newly installed script was not invoked (or it did not work properly? See below). Fail. A simple apt-get install --reinstall ca-certificates seemed to run the script, and create the file.

However, the stack trace did not go away: the application kept failing. As I know nothing about how java certs are handled in debian, I run a simple strace of the java interpreter running my application. A long shot, but grepping for open in the strace.log file and looking for files that seemed relevant, showed that java was looking (among many other files) for /etc/ssl/certs/java/cacerts, which contained very little (and was non existant before installing ca-certificates-java).

By quickly poking at /etc/ca-certificates/update.d/jks-keystore, a few things looked fishy, but did not spend time debugging it.

Rather, I tried to add the certificate manually as a first step to see if it would fix things.

Went to chromium, went to the https site the Java app was trying to access, looked at the root authority, looked for the corresponding file in /etc/ssl/certs/ (a simple ls |grep -i authorityname), and then run the commands:

# cd /etc/ssl/certs
# openssl x509 -outform der -in DigiCert_High_Assurance_EV_Root_CA.pem -out /tmp/certificate.der
# keytool -import -alias DigiCert -keystore ./java/cacerts -file /tmp/certificate.der

when prompted for a password, turns out there is a default signing password of changeit, which also works on Debian.

Once this was done, the stack trace disappeared. Rather than debug jks-keystore, the fastest way to get the java app to run was to (sigh, sigh, sigh :-() add all root certificates to the java/cacerts file.

A simple for loop helped:

# cd /etc/ssl/certs
# for file in *.pem; do openssl x509 -outform der -in "$file" -out /tmp/certificate.der; keytool -import -alias "$file" -keystore ./java/cacerts -file /tmp/certificate.der -deststorepass changeit -noprompt; done;

which solved the problem. Now to file bugs...


Other posts

Technology/Security