Listing certificates in JVM trust store

Carlos picture Carlos · Jan 16, 2012 · Viewed 8.8k times · Source

I've defined a custom truststore via system properties:

System.setProperty("javax.net.ssl.trustStore", ...);
System.setProperty("javax.net.ssl.trustStorePassword", ...);

Given that the VM already takes care of loading the file, I'd like to list those certificates that were loaded. I don't want to once again load the truststore into a stream and obtain the certificates from there, but rather I want to see those that the VM already loaded by itself. Also, I want to see them from within my own application, not using a separate tool. I've done some googling, but so far I've been unable to find this.

Answer

Bruno picture Bruno · Jan 16, 2012

When they're used, JSSE uses these settings to build its default X509TrustManager (overriding the JRE default). However, there's nothing in the JSSE API to gain access to the keystore with which the default trust manager was build since, in the JSSE architecture, the default trust manager needs not be built from a keystore in principle.

If you want to read the content of the trust store passed via the javax.net.ssl.trustStore* properties, you will have to open the file yourself.

The closest thing you can get hold of will be the default X509TrustManager using the default TrustManagerFactory.

EDIT:

For more details, you can look at the implementation in the OpenJDK.

The logic in sun.security.ssl.DefaultSSLContextImpl (not part of the public API) is to initialise the TrustManagerFactory with a KeyStore obtained from the TrustManagerFactoryImpl (which is not part for the public API either):

KeyStore ks = TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);

This is consistent with the behaviour of TrustManagerFactory with tmf.init(null). This would also have relied on the default keystore, but that's documented in the public API. Indeed, the implementation (with tmf.init(null)) ends up doing the same, as shown in TrustManagerFactoryImpl (engineInit also calls getCacertsKeyStore when the keystore parameter is null).

In both cases, the KeyStore variable is not stored in a class member, it's just a local variable that is not accessible after using these initialisation methods.

The resulting X509TrustManagerImpl does indeed contain the list of trusted certificates, but (a) trustedCerts is a private member and (b) none of this is part of the public API of the JSSE.

EDIT 2:

If you want something that is likely work most of the time, but is not guaranteed to work, this answer should help. Be aware that the default trust store isn't necessarily cacerts.