javatomcatsslcertificatessl-certificate

Tomcat server AND HTTP Client accepting expired self-signed certificate


I'm writing a rest client and server with mutual authentication. The keystore on the client side acts as both keystore and truststore. The keystore on server side acts as both the keystore and truststore.

The server is an embedded Tomcat server started by Spring boot.

I am writing two tests, one of which verifies that the server rejects client connections with expired certificates and the other verifies the client does not connect to the server with expired certificates.

I have a truststore and keystore that I created using java keytool. They each contain a respective self-signed cert and associated key.

Test 1

The client has the expired key (in client keystore) associated with the expired certificate (in server's keystore).

When my client makes a request to the server, the server handles the request successfully instead of rejecting the request. The server should reject the request.

I am using these properties to configure tomcat's trust store. Am I missing something?

server.ssl.trust-store={truststore location}
server.ssl.trust-store-password={password}
server.ssl.trust-alias={trust alias}
server.ssl.client_auth=NEED

Test 2

The server has the expired key (in server keystore) associated with the expired certificate (in client's keystore).

When my client (Apache HTTP Client) makes a request to the server, the request is successful. This is the wrong behavior. My fix was to create a new TrustStrategy for the SSL context which fixed the issue.

    return new TrustStrategy() {

        /**
         * Checks to see if certificate has not expired yet.
         * 
         * Always returns false so the trust manager is consulted.
         */
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException
        {
            for (X509Certificate certificate : chain)
            {
                certificate.checkValidity();
            }

            return false;
        }

    };

Shouldn't the default behavior be to reject expired certificates? What is the certificate trust manager on Embedded Tomcat and how do I modify it to reject expired certificates?

Thanks!

Using spring-boot 1.4.0, Embedded tomcat 7.0.70, Apache HTTP Client 4.3.6


Solution

  • I figured out the problem.

    The reason behind the observed behavior is that the X509TrustManager uses PKIXValidator to validate client and server certificates. If the certificate that the validator wants to validate already exists in the truststore, then it automatically trusts it without doing any validation.

    I was able to enable expiry validation by wrapping the TrustManagers with my own that checks for the expiry manually.