Channel discovery service / okttp needs bundled letsencrypt too

This commit is contained in:
Daniel Gultsch 2024-04-03 08:33:21 +02:00
parent 2fa541f2dc
commit 0e9f4e5265
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
3 changed files with 67 additions and 29 deletions

View file

@ -1,17 +1,23 @@
package eu.siacs.conversations.crypto; package eu.siacs.conversations.crypto;
import android.content.Context;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import java.io.IOException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Arrays; import java.util.Arrays;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.R;
public final class TrustManagers { public final class TrustManagers {
private TrustManagers() { private TrustManagers() {
@ -34,5 +40,16 @@ public final class TrustManagers {
return createTrustManager(null); 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);
}
} }

View file

@ -1,5 +1,8 @@
package eu.siacs.conversations.services; package eu.siacs.conversations.services;
import static eu.siacs.conversations.utils.Random.SECURE_RANDOM;
import android.os.Build;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -8,7 +11,33 @@ import com.google.common.base.Strings;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
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.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.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -18,23 +47,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import eu.siacs.conversations.Config; import javax.net.ssl.SSLSocketFactory;
import eu.siacs.conversations.entities.Account; import javax.net.ssl.X509TrustManager;
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.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;
public class ChannelDiscoveryService { public class ChannelDiscoveryService {
@ -55,6 +69,24 @@ public class ChannelDiscoveryService {
return; return;
} }
final OkHttpClient.Builder builder = HttpConnectionManager.OK_HTTP_CLIENT.newBuilder(); 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()) { if (service.useTorToConnect()) {
builder.proxy(HttpConnectionManager.getProxy()); builder.proxy(HttpConnectionManager.getProxy());
} }

View file

@ -176,7 +176,7 @@ public class MemorizingTrustManager {
this.appTrustManager = getTrustManager(appKeyStore); this.appTrustManager = getTrustManager(appKeyStore);
try { try {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
this.defaultTrustManager = defaultWithBundledLetsEncrypt(context); this.defaultTrustManager = TrustManagers.defaultWithBundledLetsEncrypt(context);
} else { } else {
this.defaultTrustManager = TrustManagers.createDefaultTrustManager(); 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) { private static boolean isIp(final String server) {
return server != null return server != null
&& (PATTERN_IPV4.matcher(server).matches() && (PATTERN_IPV4.matcher(server).matches()