1package de.gultsch.common;
2
3import android.content.Context;
4import android.os.Build;
5import androidx.annotation.Nullable;
6import com.google.common.collect.Iterables;
7import eu.siacs.conversations.R;
8import java.io.IOException;
9import java.io.InputStream;
10import java.security.KeyStore;
11import java.security.KeyStoreException;
12import java.security.NoSuchAlgorithmException;
13import java.security.cert.CertificateException;
14import java.util.Arrays;
15import javax.net.ssl.TrustManagerFactory;
16import javax.net.ssl.X509TrustManager;
17
18public final class TrustManagers {
19
20 private static final char[] BUNDLED_KEYSTORE_PASSWORD = "letsencrypt".toCharArray();
21
22 private TrustManagers() {
23 throw new IllegalStateException("Do not instantiate me");
24 }
25
26 public static X509TrustManager createTrustManager(@Nullable final KeyStore keyStore)
27 throws NoSuchAlgorithmException, KeyStoreException {
28 final TrustManagerFactory trustManagerFactory =
29 TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
30 trustManagerFactory.init(keyStore);
31 return Iterables.getOnlyElement(
32 Iterables.filter(
33 Arrays.asList(trustManagerFactory.getTrustManagers()),
34 X509TrustManager.class));
35 }
36
37 public static X509TrustManager createForAndroidVersion(final Context context)
38 throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
39 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
40 return TrustManagers.createDefaultWithBundledLetsEncrypt(context);
41 } else {
42 return TrustManagers.createDefaultTrustManager();
43 }
44 }
45
46 public static X509TrustManager createDefaultTrustManager()
47 throws NoSuchAlgorithmException, KeyStoreException {
48 return createTrustManager(null);
49 }
50
51 private static X509TrustManager createDefaultWithBundledLetsEncrypt(final Context context)
52 throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException {
53 final var bundleTrustManager =
54 createWithKeyStore(context.getResources().openRawResource(R.raw.letsencrypt));
55 return CombiningTrustManager.combineWithDefault(bundleTrustManager);
56 }
57
58 private static X509TrustManager createWithKeyStore(final InputStream inputStream)
59 throws CertificateException, IOException, NoSuchAlgorithmException, KeyStoreException {
60 final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
61 keyStore.load(inputStream, BUNDLED_KEYSTORE_PASSWORD);
62 return TrustManagers.createTrustManager(keyStore);
63 }
64}