mirror of
https://github.com/MaintainTeam/LastPipeBender.git
synced 2025-03-01 05:48:22 +03:00
BraveNewPipeLegacy: move custom TrustManagerFactory creation into BraveTLSSocketFactory
As the custom TrustManagerFactory was only set correctly in BraveOkHttpTlsHelper but not if setting the default SSLSocketFactory for HttpsURLConnection. So the whole code for adding own CA's was moved into BraveTrustManagerFactoryHelper and the BraveTLSSocketFactory handles now its usage internally and not via constructor.
This commit is contained in:
parent
837ae586f2
commit
3df1047d91
4 changed files with 186 additions and 116 deletions
|
@ -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<String> 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
* <p>
|
||||
* 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<String> 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));
|
||||
}
|
||||
}
|
22
app/src/main/java/org/schabi/newpipe/BraveTag.java
Normal file
22
app/src/main/java/org/schabi/newpipe/BraveTag.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package org.schabi.newpipe;
|
||||
|
||||
public final class BraveTag {
|
||||
|
||||
/**
|
||||
* This just truncate the string to have 23 chars.
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue