Understanding the SSL Trust Strategy
Asked Answered
L

1

12

I am trying to understand what TrustStrategy is to adopt for the method loadTrustMaterial.

 public SSLContextBuilder loadTrustMaterial(KeyStore truststore,
                                  TrustStrategy trustStrategy)
                                    throws NoSuchAlgorithmException,
                                           KeyStoreException

I found four different examples and I am very curious to know the difference between these four as the description is too little to understand the differences/usages/advantages/disadvantages.

Here are the four different code examples:

TrustStrategy: This seems like here we are overriding the standard JSSE certificate verification process but it always returning true so does it trust invalid certificates too?

TrustStrategy trustStrategy = new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
        return true;
    }
    };
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
    .loadTrustMaterial(trustStore, trustStrategy);

NULL: We are NOT giving any Strategy so what it will do?

SSLContextBuilder sslContextBuilder = SSLContexts.custom()
                            .loadTrustMaterial(trustStore, null);

TrustAllStrategy: It will trust all singed certificate so is that secure though?

SSLContextBuilder sslContextBuilder = SSLContexts.custom()
                            .loadTrustMaterial(trustStore, new TrustAllStrategy());

TrustSelfSignedStrategy: What is the difference between this and TrustAllStrategy?

SSLContextBuilder sslContextBuilder = SSLContexts.custom()
                            .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());

Help me to understand the difference between these four versions of the example, please? Thanks in Advance.

Luciferase answered 6/4, 2020 at 8:58 Comment(0)
W
8

First of all, trusting all certificates is highly discouraged. Rather add the certificates to the truststore.

The TrustStategy is an interface, implemented by some types.

All these methods here are from the apache httpclient - the first one (overriding the isTrusted method) is more or less equal to the TrustAllStrategy and just creating a custom instance of a TrustStrategy where you could define your own way to determine whether a certificate is trusted or not.

See the sourcecode of the TrustAllStrategy here:

public class TrustAllStrategy implements TrustStrategy {

    public static final TrustAllStrategy INSTANCE = new TrustAllStrategy();

    @Override
    public boolean isTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
        return true;
    }

Setting the TrustStrategy to null will result in not having any TrustManager:

   public SSLContextBuilder loadTrustMaterial(
            final KeyStore truststore,
            final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
        final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
                trustManagerFactoryAlgorithm == null ? TrustManagerFactory.getDefaultAlgorithm()
                        : trustManagerFactoryAlgorithm);
        tmfactory.init(truststore);
        final TrustManager[] tms = tmfactory.getTrustManagers();
        if (tms != null) {
            if (trustStrategy != null) {
                for (int i = 0; i < tms.length; i++) {
                    final TrustManager tm = tms[i];
                    if (tm instanceof X509TrustManager) {
                        tms[i] = new TrustManagerDelegate(
                                (X509TrustManager) tm, trustStrategy);
                    }
                }
            }
            for (final TrustManager tm : tms) {
                this.trustManagers.add(tm);
            }
        }
        return this;
    }

The TrustSelfSignedStrategy works as follows:

@Override
public boolean isTrusted(
        final X509Certificate[] chain, final String authType) throws CertificateException {
    return chain.length == 1;
}

A self singed certificate is issued by the target of the certificate. It's generated by default in many applications and often used for intranet purposes.

Warfourd answered 6/4, 2020 at 9:21 Comment(2)
When passing null we do have TrustManager since "final TrustManager[] tms" is not an empty array. The question is "is it safer" to pass null in the strategy than passing a "TrustSelfSignedStrategy"? should we use "TrustSelfSignedStrategy" only for testing?Decarbonate
Sorry for the rather late reply: It really depends on your environment. But since the emerge of Let's Encrypt I am not really certain whether that's a great idea. On the other hand: In a closed and protected hosting environment where a man-in-the-middle attack can be ruled out, there is in my opinion no real need for an externally singed certificate. However, if certain attack vectors cannot be ruled out, I wouldn't rely on self-singed certificates only - and when end users are involved, you'd generally avoid it unless you have your own CA (commonly seen on domain controllers).Warfourd

© 2022 - 2024 — McMap. All rights reserved.