Skip to content

Commit

Permalink
move enableModernTLS() method and KitKat check to helper class
Browse files Browse the repository at this point in the history
evermind-zz moved the DownloaderImpl enableModernTLS() method to a helper class and reuse that code to configure the OkHttpClient.Builder() instance in the same way

Co-Authored-By: evermind-zz <[email protected]>
  • Loading branch information
ShareASmile and evermind-zz committed Jun 24, 2024
1 parent c69c6ff commit 13791ea
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 67 deletions.
69 changes: 2 additions & 67 deletions app/src/main/java/org/schabi/newpipelegacy/DownloaderImpl.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.schabi.newpipelegacy;

import android.content.Context;
import android.os.Build;
import android.preference.PreferenceManager;

import androidx.annotation.NonNull;
Expand All @@ -13,33 +12,20 @@
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipelegacy.util.CookieUtils;
import org.schabi.newpipelegacy.util.InfoCache;
import org.schabi.newpipelegacy.util.TLSSocketFactoryCompat;
import org.schabi.newpipelegacy.util.OkHttpTlsHelper;

import java.io.IOException;
import java.io.InputStream;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

import static org.schabi.newpipelegacy.MainActivity.DEBUG;

public final class DownloaderImpl extends Downloader {
public static final String USER_AGENT
Expand All @@ -54,9 +40,7 @@ public final class DownloaderImpl extends Downloader {
private OkHttpClient client;

private DownloaderImpl(final OkHttpClient.Builder builder) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
enableModernTLS(builder);
}
OkHttpTlsHelper.enableModernTLS(builder);
this.client = builder
.readTimeout(30, TimeUnit.SECONDS)
// .cache(new Cache(new File(context.getExternalCacheDir(), "okhttp"),
Expand All @@ -81,55 +65,6 @@ public static DownloaderImpl getInstance() {
return instance;
}

/**
* Enable TLS 1.2 and 1.1 on Android Kitkat. This function is mostly taken
* from the documentation of OkHttpClient.Builder.sslSocketFactory(_,_).
* <p>
* If there is an error, the function will safely fall back to doing nothing
* and printing the error to the console.
* </p>
*
* @param builder The HTTPClient Builder on which TLS is enabled on (will be modified in-place)
*/
private static void enableModernTLS(final OkHttpClient.Builder builder) {
try {
// get the default TrustManager
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];

// insert our own TLSSocketFactory
SSLSocketFactory sslSocketFactory = TLSSocketFactoryCompat.getInstance();

builder.sslSocketFactory(sslSocketFactory, trustManager);

// This will try to enable all modern CipherSuites(+2 more)
// that are supported on the device.
// Necessary because some servers (e.g. Framatube.org)
// don't support the old cipher suites.
// https://github.com/square/okhttp/issues/4053#issuecomment-402579554
List<CipherSuite> cipherSuites = new ArrayList<>();
cipherSuites.addAll(ConnectionSpec.MODERN_TLS.cipherSuites());
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
ConnectionSpec legacyTLS = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(cipherSuites.toArray(new CipherSuite[0]))
.build();

builder.connectionSpecs(Arrays.asList(legacyTLS, ConnectionSpec.CLEARTEXT));
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
if (DEBUG) {
e.printStackTrace();
}
}
}

public String getCookies(final String url) {
List<String> resultCookies = new ArrayList<>();
if (url.contains(YOUTUBE_DOMAIN)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.schabi.newpipelegacy.util;

import android.os.Build;

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 javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;

import static org.schabi.newpipelegacy.MainActivity.DEBUG;

public final class OkHttpTlsHelper {

private OkHttpTlsHelper() {
}

/**
* Enable TLS 1.2 and 1.1 on Android Kitkat. This function is mostly taken
* from the documentation of OkHttpClient.Builder.sslSocketFactory(_,_).
* <p>
* If there is an error, the function will safely fall back to doing nothing
* and printing the error to the console.
* </p>
*
* @param builder The HTTPClient Builder on which TLS is enabled on (will be modified in-place)
*/
public static void enableModernTLS(final OkHttpClient.Builder builder) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
try {
// get the default TrustManager
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
final TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
final X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

// insert our own TLSSocketFactory
final SSLSocketFactory sslSocketFactory = TLSSocketFactoryCompat.getInstance();

builder.sslSocketFactory(sslSocketFactory, trustManager);

// This will try to enable all modern CipherSuites(+2 more)
// that are supported on the device.
// Necessary because some servers (e.g. Framatube.org)
// don't support the old cipher suites.
// https://github.com/square/okhttp/issues/4053#issuecomment-402579554
final List<CipherSuite> cipherSuites =
new ArrayList<>(ConnectionSpec.MODERN_TLS.cipherSuites());
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
cipherSuites.add(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
final ConnectionSpec legacyTLS =
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.cipherSuites(cipherSuites.toArray(new CipherSuite[0]))
.build();

builder.connectionSpecs(Arrays.asList(legacyTLS, ConnectionSpec.CLEARTEXT));
} catch (final KeyManagementException | NoSuchAlgorithmException
| KeyStoreException e) {
if (DEBUG) {
e.printStackTrace();
}
}
}
}
}

0 comments on commit 13791ea

Please sign in to comment.