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