From 0e9f4e5265e61796cbad7f6e91a8690bf3f43bca Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 3 Apr 2024 08:33:21 +0200 Subject: [PATCH] Channel discovery service / okttp needs bundled letsencrypt too --- .../conversations/crypto/TrustManagers.java | 17 ++++++ .../services/ChannelDiscoveryService.java | 52 +++++++++++++++---- .../services/MemorizingTrustManager.java | 13 +---- 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/TrustManagers.java b/src/main/java/eu/siacs/conversations/crypto/TrustManagers.java index 11fe182dde8449364c371b5005933f6a8e4d0d33..4fc11eecf349979d57a77b61c73a5015fcff7e18 100644 --- a/src/main/java/eu/siacs/conversations/crypto/TrustManagers.java +++ b/src/main/java/eu/siacs/conversations/crypto/TrustManagers.java @@ -1,17 +1,23 @@ package eu.siacs.conversations.crypto; +import android.content.Context; + import androidx.annotation.Nullable; import com.google.common.collect.Iterables; +import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.util.Arrays; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; +import eu.siacs.conversations.R; + public final class TrustManagers { private TrustManagers() { @@ -34,5 +40,16 @@ public final class TrustManagers { return createTrustManager(null); } + public static X509TrustManager defaultWithBundledLetsEncrypt(final Context context) + throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + final BundledTrustManager bundleTrustManager = + BundledTrustManager.builder() + .loadKeyStore( + context.getResources().openRawResource(R.raw.letsencrypt), + "letsencrypt") + .build(); + return CombiningTrustManager.combineWithDefault(bundleTrustManager); + } + } diff --git a/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java b/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java index 2f9553bfce714bda47f3e438da7fa96c76e65ebf..3ca6bfde4cfecd9f76eebb2e6d13f055c7b7f418 100644 --- a/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java +++ b/src/main/java/eu/siacs/conversations/services/ChannelDiscoveryService.java @@ -1,5 +1,8 @@ package eu.siacs.conversations.services; +import static eu.siacs.conversations.utils.Random.SECURE_RANDOM; + +import android.os.Build; import android.util.Log; import androidx.annotation.NonNull; @@ -8,34 +11,45 @@ import com.google.common.base.Strings; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.TrustManagers; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Room; import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.http.services.MuclumbusService; import eu.siacs.conversations.parser.IqParser; +import eu.siacs.conversations.utils.TLSSocketFactory; import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.stanzas.IqPacket; + import okhttp3.OkHttpClient; import okhttp3.ResponseBody; + import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; + public class ChannelDiscoveryService { private final XmppConnectionService service; @@ -55,6 +69,24 @@ public class ChannelDiscoveryService { return; } final OkHttpClient.Builder builder = HttpConnectionManager.OK_HTTP_CLIENT.newBuilder(); + try { + final X509TrustManager trustManager; + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { + trustManager = TrustManagers.defaultWithBundledLetsEncrypt(service); + } else { + trustManager = TrustManagers.createDefaultTrustManager(); + } + final SSLSocketFactory socketFactory = + new TLSSocketFactory(new X509TrustManager[] {trustManager}, SECURE_RANDOM); + builder.sslSocketFactory(socketFactory, trustManager); + } catch (final IOException + | KeyManagementException + | NoSuchAlgorithmException + | KeyStoreException + | CertificateException e) { + Log.d(Config.LOGTAG, "not reconfiguring service to work with bundled LetsEncrypt"); + throw new RuntimeException(e); + } if (service.useTorToConnect()) { builder.proxy(HttpConnectionManager.getProxy()); } diff --git a/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java b/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java index 81cfb951fb279f5940f4cdd2a4931a10fad422a6..d05fa4ac3dfe2b98d3d61f99427a12eea60a4f08 100644 --- a/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java +++ b/src/main/java/eu/siacs/conversations/services/MemorizingTrustManager.java @@ -176,7 +176,7 @@ public class MemorizingTrustManager { this.appTrustManager = getTrustManager(appKeyStore); try { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { - this.defaultTrustManager = defaultWithBundledLetsEncrypt(context); + this.defaultTrustManager = TrustManagers.defaultWithBundledLetsEncrypt(context); } else { this.defaultTrustManager = TrustManagers.createDefaultTrustManager(); } @@ -188,17 +188,6 @@ public class MemorizingTrustManager { } } - private static X509TrustManager defaultWithBundledLetsEncrypt(final Context context) - throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { - final BundledTrustManager bundleTrustManager = - BundledTrustManager.builder() - .loadKeyStore( - context.getResources().openRawResource(R.raw.letsencrypt), - "letsencrypt") - .build(); - return CombiningTrustManager.combineWithDefault(bundleTrustManager); - } - private static boolean isIp(final String server) { return server != null && (PATTERN_IPV4.matcher(server).matches()