upgrade OkHttp, add Conscrypt (#1083)
* upgrade OkHttp, add Conscrypt * fix tests
This commit is contained in:
parent
a9524508e6
commit
2b490dd4f3
@ -94,8 +94,9 @@ dependencies {
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
|
||||
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
|
||||
implementation 'com.squareup.picasso:picasso:2.5.2'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.13.1'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.13.1'
|
||||
implementation "org.conscrypt:conscrypt-android:2.0.0"
|
||||
implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
|
||||
implementation 'com.github.connyduck:sparkbutton:2.0.0'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
|
@ -32,6 +32,10 @@ import com.keylesspalace.tusky.util.EmojiCompatFont;
|
||||
import com.keylesspalace.tusky.util.NotificationPullJobCreator;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import org.conscrypt.Conscrypt;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
@ -62,6 +66,8 @@ public class TuskyApplication extends Application implements HasActivityInjector
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
initSecurityProvider();
|
||||
|
||||
appDatabase = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "tuskyDB")
|
||||
.allowMainThreadQueries()
|
||||
.addMigrations(AppDatabase.MIGRATION_2_3, AppDatabase.MIGRATION_3_4, AppDatabase.MIGRATION_4_5,
|
||||
@ -93,6 +99,10 @@ public class TuskyApplication extends Application implements HasActivityInjector
|
||||
|
||||
}
|
||||
|
||||
protected void initSecurityProvider() {
|
||||
Security.insertProviderAt(Conscrypt.newProvider(), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will load the EmojiCompat font which has been selected.
|
||||
* If this font does not work or if the user hasn't selected one (yet), it will use a
|
||||
|
@ -19,49 +19,21 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.keylesspalace.tusky.BuildConfig;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.ConnectionSpec;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
|
||||
public class OkHttpUtils {
|
||||
private static final String TAG = "OkHttpUtils"; // logging tag
|
||||
|
||||
/**
|
||||
* Makes a Builder with the maximum range of TLS versions and cipher suites enabled.
|
||||
* <p>
|
||||
* It first tries the "approved" list of cipher suites given in OkHttp (the default in
|
||||
* ConnectionSpec.MODERN_TLS) and if that doesn't work falls back to the set of ALL enabled,
|
||||
* then falls back to plain http.
|
||||
* <p>
|
||||
* API level 24 has a regression in elliptic curves where it only supports secp256r1, so this
|
||||
* first tries a fallback without elliptic curves at all, and then tries them after.
|
||||
* <p>
|
||||
* TLS 1.1 and 1.2 have to be manually enabled on API levels 16-20.
|
||||
*/
|
||||
@NonNull
|
||||
public static OkHttpClient.Builder getCompatibleClientBuilder(@NonNull Context context) {
|
||||
|
||||
@ -77,25 +49,13 @@ public class OkHttpUtils {
|
||||
httpPort = -1;
|
||||
}
|
||||
|
||||
ConnectionSpec fallback = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||
.allEnabledCipherSuites()
|
||||
.supportsTlsExtensions(true)
|
||||
.build();
|
||||
|
||||
List<ConnectionSpec> specList = new ArrayList<>();
|
||||
specList.add(ConnectionSpec.MODERN_TLS);
|
||||
addNougatFixConnectionSpec(specList);
|
||||
specList.add(fallback);
|
||||
specList.add(ConnectionSpec.CLEARTEXT);
|
||||
|
||||
int cacheSize = 25*1024*1024; // 25 MiB
|
||||
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.addInterceptor(getUserAgentInterceptor())
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.cache(new Cache(context.getCacheDir(), cacheSize))
|
||||
.connectionSpecs(specList);
|
||||
.cache(new Cache(context.getCacheDir(), cacheSize));
|
||||
|
||||
if (httpProxyEnabled && !httpServer.isEmpty() && (httpPort > 0) && (httpPort < 65535)) {
|
||||
InetSocketAddress address = InetSocketAddress.createUnresolved(httpServer, httpPort);
|
||||
@ -121,47 +81,6 @@ public class OkHttpUtils {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Android version Nougat has a regression where elliptic curve cipher suites are supported, but
|
||||
* only the curve secp256r1 is allowed. So, first it's best to just disable all elliptic
|
||||
* ciphers, try the connection, and fall back to the all cipher suites enabled list after.
|
||||
*/
|
||||
private static void addNougatFixConnectionSpec(List<ConnectionSpec> specList) {
|
||||
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.N) {
|
||||
return;
|
||||
}
|
||||
SSLSocketFactory socketFactory;
|
||||
try {
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
|
||||
TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init((KeyStore) null);
|
||||
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
|
||||
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
|
||||
throw new IllegalStateException("Unexpected default trust managers:"
|
||||
+ Arrays.toString(trustManagers));
|
||||
}
|
||||
|
||||
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(null, new TrustManager[] { trustManager }, null);
|
||||
socketFactory = sslContext.getSocketFactory();
|
||||
} catch (NoSuchAlgorithmException|KeyStoreException|KeyManagementException e) {
|
||||
Log.e(TAG, "Failed obtaining the SSL socket factory.");
|
||||
return;
|
||||
}
|
||||
String[] cipherSuites = socketFactory.getDefaultCipherSuites();
|
||||
ArrayList<String> allowedList = new ArrayList<>();
|
||||
for (String suite : cipherSuites) {
|
||||
if (!suite.contains("ECDH")) {
|
||||
allowedList.add(suite);
|
||||
}
|
||||
}
|
||||
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||
.cipherSuites(allowedList.toArray(new String[0]))
|
||||
.supportsTlsExtensions(true)
|
||||
.build();
|
||||
specList.add(spec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,10 @@ class FakeTuskyApplication : TuskyApplication() {
|
||||
|
||||
lateinit var locator: ServiceLocator
|
||||
|
||||
override fun initSecurityProvider() {
|
||||
// No-op
|
||||
}
|
||||
|
||||
override fun initAppInjector() {
|
||||
// No-op
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user