CombiningTrustManager.java

 1package eu.siacs.conversations.crypto;
 2
 3import android.annotation.SuppressLint;
 4import android.util.Log;
 5import com.google.common.collect.ImmutableList;
 6import eu.siacs.conversations.Config;
 7import java.security.KeyStoreException;
 8import java.security.NoSuchAlgorithmException;
 9import java.security.cert.CertificateException;
10import java.security.cert.X509Certificate;
11import java.util.Arrays;
12import java.util.Iterator;
13import java.util.List;
14import javax.net.ssl.X509TrustManager;
15
16@SuppressLint("CustomX509TrustManager")
17public final class CombiningTrustManager implements X509TrustManager {
18
19    private final List<X509TrustManager> trustManagers;
20
21    private CombiningTrustManager(final List<X509TrustManager> trustManagers) {
22        this.trustManagers = trustManagers;
23    }
24
25    @Override
26    public void checkClientTrusted(final X509Certificate[] chain, final String authType)
27            throws CertificateException {
28        for (final Iterator<X509TrustManager> iterator = this.trustManagers.iterator();
29                iterator.hasNext(); ) {
30            final X509TrustManager trustManager = iterator.next();
31            try {
32                trustManager.checkClientTrusted(chain, authType);
33                return;
34            } catch (final CertificateException certificateException) {
35                if (iterator.hasNext()) {
36                    continue;
37                }
38                throw certificateException;
39            }
40        }
41        throw new CertificateException("No trust managers configured");
42    }
43
44    @Override
45    public void checkServerTrusted(final X509Certificate[] chain, final String authType)
46            throws CertificateException {
47        Log.d(
48                Config.LOGTAG,
49                CombiningTrustManager.class.getSimpleName()
50                        + " is configured with "
51                        + this.trustManagers.size()
52                        + " TrustManagers");
53        for (final Iterator<X509TrustManager> iterator = this.trustManagers.iterator();
54                iterator.hasNext(); ) {
55            final X509TrustManager trustManager = iterator.next();
56            try {
57                trustManager.checkServerTrusted(chain, authType);
58                return;
59            } catch (final CertificateException certificateException) {
60                if (iterator.hasNext()) {
61                    continue;
62                }
63                throw certificateException;
64            }
65        }
66        throw new CertificateException("No trust managers configured");
67    }
68
69    @Override
70    public X509Certificate[] getAcceptedIssuers() {
71        final ImmutableList.Builder<X509Certificate> certificates = ImmutableList.builder();
72        for (final X509TrustManager trustManager : this.trustManagers) {
73            for (final X509Certificate certificate : trustManager.getAcceptedIssuers()) {
74                certificates.add(certificate);
75            }
76        }
77        return certificates.build().toArray(new X509Certificate[0]);
78    }
79
80    public static X509TrustManager combineWithDefault(final X509TrustManager... trustManagers)
81            throws NoSuchAlgorithmException, KeyStoreException {
82        final ImmutableList.Builder<X509TrustManager> builder = ImmutableList.builder();
83        builder.addAll(Arrays.asList(trustManagers));
84        builder.add(TrustManagers.createDefaultTrustManager());
85        return new CombiningTrustManager(builder.build());
86    }
87}