diff --git a/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveOkHttpTlsHelper.java b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveOkHttpTlsHelper.java index 5c95a686c..87e0138ff 100644 --- a/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveOkHttpTlsHelper.java +++ b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveOkHttpTlsHelper.java @@ -1,26 +1,14 @@ package org.schabi.newpipe.util; -import android.content.Context; import android.os.Build; +import android.util.Log; -import org.schabi.newpipe.App; +import org.schabi.newpipe.BraveTag; -import java.io.ByteArrayInputStream; -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.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.util.Arrays; -import java.util.List; 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; @@ -30,6 +18,9 @@ import static org.schabi.newpipe.MainActivity.DEBUG; public final class BraveOkHttpTlsHelper { + private static final String TAG = + new BraveTag().tagShort23(BraveOkHttpTlsHelper.class.getSimpleName()); + private BraveOkHttpTlsHelper() { } @@ -50,105 +41,23 @@ public final class BraveOkHttpTlsHelper { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) { try { - final KeyStore customCAsKeystore = createKeystoreWithCustomCAsAndSystemCAs(); - final TrustManagerFactory trustManagerFactory = - getTrustManagerFactory(customCAsKeystore); + final BraveTLSSocketFactory sslSocketFactory = BraveTLSSocketFactory.getInstance(); + final TrustManagerFactory trustManagerFactory = sslSocketFactory + .getTrustManagerFactory(); + final SSLContext context = SSLContext.getInstance("TLS"); context.init(null, trustManagerFactory.getTrustManagers(), null); - final SSLSocketFactory sslSocketFactory = - new BraveTLSSocketFactory(trustManagerFactory); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagerFactory.getTrustManagers()[0]); - } catch (final KeyManagementException | NoSuchAlgorithmException | KeyStoreException - | IOException | CertificateException e) { + } catch (final KeyManagementException | NoSuchAlgorithmException e) { if (DEBUG) { e.printStackTrace(); + Log.e(TAG, "Unable to insert own {SSLSocket,TrustManager}Factory in OkHttp", e); } } } return builder; } - - public static TrustManagerFactory getTrustManagerFactory( - final KeyStore keyStore) - throws NoSuchAlgorithmException, KeyStoreException { - - final TrustManagerFactory trustManagerFactory = TrustManagerFactory - .getInstance(TrustManagerFactory.getDefaultAlgorithm()); - - // Tell TrustManager to trust the CAs in our KeyStore - trustManagerFactory.init(keyStore); - - // only allow one TrustManager - final TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { - throw new IllegalStateException("Unexpected default trust managers:" - + Arrays.toString(trustManagers)); - } - - return trustManagerFactory; - } - - - /** - * Add our trusted CAs for rumble.com and framatube.org to keystore. - * - * @return custom CA keystore with our added CAs - * @throws KeyStoreException - * @throws CertificateException - * @throws IOException - * @throws NoSuchAlgorithmException - */ - private static KeyStore createKeystoreWithCustomCAsAndSystemCAs() - throws KeyStoreException, CertificateException, - IOException, NoSuchAlgorithmException { - - final List rawCertFiles = Arrays.asList("ca_digicert_global_g2", "ca_lets_encrypt"); - final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - keyStore.load(null, null); - for (final String rawCertFile : rawCertFiles) { - final Certificate cert = readCertificateFromFile(rawCertFile); - keyStore.setCertificateEntry(rawCertFile, cert); - } - - addSystemCAsToKeystore(keyStore); - - return keyStore; - } - - private static void addSystemCAsToKeystore( - final KeyStore keyStore) throws NoSuchAlgorithmException, KeyStoreException { - - // Default TrustManager to get device trusted CA's - final TrustManagerFactory defaultTrustManagerFactory = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - defaultTrustManagerFactory.init((KeyStore) null); - - final X509TrustManager trustManager = - (X509TrustManager) defaultTrustManagerFactory.getTrustManagers()[0]; - int idx = 0; - for (final Certificate cert : trustManager.getAcceptedIssuers()) { - keyStore.setCertificateEntry(Integer.toString(idx), cert); - idx++; - } - } - - private static Certificate readCertificateFromFile( - final String rawFile) - throws IOException, CertificateException { - - final Context context = App.getApp().getApplicationContext(); - final InputStream inputStream = context.getResources().openRawResource( - context.getResources().getIdentifier(rawFile, - "raw", context.getPackageName())); - - final byte[] rawBytes = new byte[inputStream.available()]; - inputStream.read(rawBytes); - inputStream.close(); - - final CertificateFactory cf = CertificateFactory.getInstance("X.509"); - return cf.generateCertificate(new ByteArrayInputStream(rawBytes)); - } } diff --git a/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTLSSocketFactory.java b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTLSSocketFactory.java index 18852f053..edbd94d47 100644 --- a/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTLSSocketFactory.java +++ b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTLSSocketFactory.java @@ -1,5 +1,9 @@ package org.schabi.newpipe.util; +import android.util.Log; + +import org.schabi.newpipe.BraveTag; + import java.io.IOException; import java.net.InetAddress; import java.net.Socket; @@ -12,32 +16,27 @@ import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; -import android.util.Log; - /** - * This is an extension of the SSLSocketFactory which enables TLS 1.2 and 1.1. + * This is an extension of the SSLSocketFactory which enables TLS 1.2 and 1.3. * Created for usage on Android 4.1-4.4 devices, which haven't enabled those by default. */ -public class BraveTLSSocketFactory extends SSLSocketFactory { +public final class BraveTLSSocketFactory extends SSLSocketFactory { - private static final String TAG = "TLSSocketFactoryCom"; + private static final String TAG = + new BraveTag().tagShort23(BraveTLSSocketFactory.class.getSimpleName()); private static BraveTLSSocketFactory instance = null; private final SSLSocketFactory internalSSLSocketFactory; + private final BraveTrustManagerFactoryHelper trustManagerFactoryHelper; - public BraveTLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { - final SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, null, null); - internalSSLSocketFactory = context.getSocketFactory(); - } - - public BraveTLSSocketFactory( - final TrustManagerFactory trustManagerFactory) + private BraveTLSSocketFactory() throws NoSuchAlgorithmException, KeyManagementException { + trustManagerFactoryHelper = new BraveTrustManagerFactoryHelper(); final SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, trustManagerFactory.getTrustManagers(), null); + context.init(null, trustManagerFactoryHelper.getTrustManagerFactory() + .getTrustManagers(), null); internalSSLSocketFactory = context.getSocketFactory(); } @@ -110,4 +109,8 @@ public class BraveTLSSocketFactory extends SSLSocketFactory { } return socket; } + + public TrustManagerFactory getTrustManagerFactory() { + return trustManagerFactoryHelper.getTrustManagerFactory(); + } } diff --git a/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTrustManagerFactoryHelper.java b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTrustManagerFactoryHelper.java new file mode 100644 index 000000000..ebc75dd56 --- /dev/null +++ b/app/src/braveLegacy/java/org/schabi/newpipe/util/BraveTrustManagerFactoryHelper.java @@ -0,0 +1,136 @@ +package org.schabi.newpipe.util; + +import android.content.Context; +import android.util.Log; + +import org.schabi.newpipe.App; +import org.schabi.newpipe.BraveTag; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Arrays; +import java.util.List; + +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import static org.schabi.newpipe.MainActivity.DEBUG; + +/** + * This helper class basically init the TrustManagerFactory with our custom CA's. + *

+ * The CA's are for rumble.com and framatube.org + */ +public class BraveTrustManagerFactoryHelper { + private static final String TAG = + new BraveTag().tagShort23(BraveTrustManagerFactoryHelper.class.getSimpleName()); + TrustManagerFactory trustManagerFactory; + + public BraveTrustManagerFactoryHelper() { + + try { + final KeyStore customCAsKeystore = createKeystoreWithCustomCAsAndSystemCAs(); + trustManagerFactory = + addOurKeystoreToTrustManagerFactory(customCAsKeystore); + } catch (final NoSuchAlgorithmException | KeyStoreException + | IOException | CertificateException e) { + if (DEBUG) { + e.printStackTrace(); + Log.e(TAG, "Unable to create TrustManagerFactory with own CA's", e); + } + } + } + + public TrustManagerFactory getTrustManagerFactory() { + return trustManagerFactory; + } + + private TrustManagerFactory addOurKeystoreToTrustManagerFactory( + final KeyStore keyStore) + throws NoSuchAlgorithmException, KeyStoreException { + + final TrustManagerFactory managerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + + // Tell TrustManager to trust the CAs in our KeyStore + managerFactory.init(keyStore); + + // only allow one TrustManager + final TrustManager[] trustManagers = managerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException("Unexpected default trust managers:" + + Arrays.toString(trustManagers)); + } + + return managerFactory; + } + + /** + * Add our trusted CAs for rumble.com and framatube.org to keystore. + * + * @return custom CA keystore with our added CAs + * @throws KeyStoreException + * @throws CertificateException + * @throws IOException + * @throws NoSuchAlgorithmException + */ + private KeyStore createKeystoreWithCustomCAsAndSystemCAs() + throws KeyStoreException, CertificateException, + IOException, NoSuchAlgorithmException { + + final List rawCertFiles = Arrays.asList("ca_digicert_global_g2", + "ca_lets_encrypt_root" /*, "ca_lets_encrypt"*/); + final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, null); + for (final String rawCertFile : rawCertFiles) { + final Certificate cert = readCertificateFromFile(rawCertFile); + keyStore.setCertificateEntry(rawCertFile, cert); + } + + addSystemCAsToKeystore(keyStore); + + return keyStore; + } + + private void addSystemCAsToKeystore( + final KeyStore keyStore) throws NoSuchAlgorithmException, KeyStoreException { + + // Default TrustManager to get device trusted CA's + final TrustManagerFactory defaultTrustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + defaultTrustManagerFactory.init((KeyStore) null); + + final X509TrustManager trustManager = + (X509TrustManager) defaultTrustManagerFactory.getTrustManagers()[0]; + int idx = 0; + for (final Certificate cert : trustManager.getAcceptedIssuers()) { + keyStore.setCertificateEntry(Integer.toString(idx), cert); + idx++; + } + } + + private Certificate readCertificateFromFile( + final String rawFile) + throws IOException, CertificateException { + + final Context context = App.getApp().getApplicationContext(); + final InputStream inputStream = context.getResources().openRawResource( + context.getResources().getIdentifier(rawFile, + "raw", context.getPackageName())); + + final byte[] rawBytes = new byte[inputStream.available()]; + inputStream.read(rawBytes); + inputStream.close(); + + final CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return cf.generateCertificate(new ByteArrayInputStream(rawBytes)); + } +} diff --git a/app/src/main/java/org/schabi/newpipe/BraveTag.java b/app/src/main/java/org/schabi/newpipe/BraveTag.java new file mode 100644 index 000000000..593781cc0 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/BraveTag.java @@ -0,0 +1,22 @@ +package org.schabi.newpipe; + +public final class BraveTag { + + /** + * This just truncate the string to have 23 chars. + *

+ * This has to be <= 23 chars on devices running Android 7 or lower (API <= 25) + * or it fails with an IllegalArgumentException + * https://stackoverflow.com/a/54744028 + * + * @param longTag the tag you want to shorten + * @return the 23 chars tag string + */ + public String tagShort23(final String longTag) { + if (longTag.length() > 23) { + return longTag.substring(0, 22); + } else { + return longTag; + } + } +}