Search code examples
javajavafxtrustmanagerx509trustmanager

Can checkServerTrusted result be cached for X509TrustManager?


In my JavaFX client application, I'm implementing my own TrustManager that relies on Platform TrustManager.

Basically, I'm always calling the Platform trustManager and if the connection is not trusted, I'm able to pop a warning Dialog asking the user if he wants to trust the certificate (just like a browser would do).

I'm facing an issue where a certificate has specified several URL in order to retrieve intermediary certificate using AIA (authority information access) and some of them are not responding. Therefore, each time the checkServerTrusted method is called, the response can be quite long because Java is trying to reach URL that are not reachable. When the timeout happens, Java tries another URL and finally, one of them is finally responding.

During my client session, can I cache the result of a checkServerTrusted given the certificate chain and authType and return the cached value rather that call the TrustManager? Or is it a bad idea or not reliable?


Solution

  • I've ended up by indeed caching the chain certificate during session time in order to respond faster.

       //Cache validated certificate's chain during session
        private final Set<UUID> chainCache;
    
        /*
         * Delegate to the default trust manager.
         */
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            checkTrusted(chain, authType, false);
        }
    
        /*
         * Delegate to the default trust manager.
         */
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            checkTrusted(chain, authType, true);
        }
    
         private void checkTrusted(X509Certificate[] chain, String authType, boolean server) throws CertificateException {
            // Internal class but Arrays.hashcode can be used in the same manner
            Digester digester = new Digester();
            //Digester will run through the array
            digester.digest(chain);
            digester.digest(authType);
            digester.digest(server);
            UUID uuid = digester.getUUID();
            //If the chain has been validated, no need top check again.
            if (chainCache.contains(uuid)) {
                return;
            }
           //Do stuff
         }