diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/HttpClientFactory.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/HttpClientFactory.kt index 4ba993bb5..74eb06138 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/HttpClientFactory.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/HttpClientFactory.kt @@ -7,7 +7,6 @@ import android.os.Build import android.util.Base64 import android.util.Log import okhttp3.* -import okhttp3.internal.platform.Platform import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.toIntOr import org.mariotaku.restfu.http.RestHttpClient @@ -15,7 +14,6 @@ import org.mariotaku.restfu.okhttp3.OkHttpRestClient import org.mariotaku.twidere.constant.SharedPreferenceConstants.* import org.mariotaku.twidere.constant.cacheSizeLimitKey import org.mariotaku.twidere.util.dagger.DependencyHolder -import org.mariotaku.twidere.util.net.TLSSocketFactory import java.io.IOException import java.net.InetSocketAddress import java.net.Proxy @@ -31,7 +29,6 @@ import javax.net.ssl.X509TrustManager * Created by mariotaku on 16/1/27. */ object HttpClientFactory { - fun createRestHttpClient(conf: HttpClientConfiguration, dns: Dns, connectionPool: ConnectionPool, cache: Cache): RestHttpClient { val builder = OkHttpClient.Builder() @@ -42,25 +39,14 @@ object HttpClientFactory { fun initOkHttpClient(conf: HttpClientConfiguration, builder: OkHttpClient.Builder, dns: Dns, connectionPool: ConnectionPool, cache: Cache) { updateHttpClientConfiguration(builder, conf, dns, connectionPool, cache) - if (Build.VERSION.SDK_INT in Build.VERSION_CODES.JELLY_BEAN until Build.VERSION_CODES.LOLLIPOP) { - val tlsContext = SSLContext.getInstance("TLS") - val trustManager = getPlatformTrustManager() - val tlsSocketFactory = tlsContext.apply { - init(null, arrayOf(trustManager), null) - }.socketFactory - builder.sslSocketFactory(tlsSocketFactory, trustManager) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + val tlsTocketFactory = TLSSocketFactory() + builder.sslSocketFactory(tlsTocketFactory, tlsTocketFactory.trustManager); } updateTLSConnectionSpecs(builder) DebugModeUtils.initForOkHttpClient(builder) } - fun getPlatformTrustManager(): X509TrustManager { - val factory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()) - factory.init(null as KeyStore?) - return factory.trustManagers!![0] as X509TrustManager - } - fun reloadConnectivitySettings(context: Context) { val holder = DependencyHolder.get(context) val client = holder.restHttpClient as? OkHttpRestClient ?: return diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/TLSSocketFactory.java b/twidere/src/main/kotlin/org/mariotaku/twidere/util/TLSSocketFactory.java new file mode 100644 index 000000000..c9602de5c --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/TLSSocketFactory.java @@ -0,0 +1,98 @@ +package org.mariotaku.twidere.util; + +import androidx.annotation.Nullable; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +public class TLSSocketFactory extends SSLSocketFactory { + + private final SSLSocketFactory delegate; + private TrustManager[] trustManagers; + + public TLSSocketFactory() throws KeyStoreException, KeyManagementException, NoSuchAlgorithmException { + generateTrustManagers(); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, trustManagers, null); + delegate = context.getSocketFactory(); + } + + private void generateTrustManagers() throws KeyStoreException, NoSuchAlgorithmException { + 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)); + } + + this.trustManagers = trustManagers; + } + + @Override + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket() throws IOException { + return enableTLSOnSocket(delegate.createSocket()); + } + + @Override + public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose)); + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + return enableTLSOnSocket(delegate.createSocket(host, port)); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { + return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort)); + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + return enableTLSOnSocket(delegate.createSocket(host, port)); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort)); + } + + private Socket enableTLSOnSocket(Socket socket) { + if (socket instanceof SSLSocket) { + ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"}); + } + return socket; + } + + @Nullable + public X509TrustManager getTrustManager() { + return (X509TrustManager) trustManagers[0]; + } +}