diff options
author | cyBerta <cyberta@riseup.net> | 2024-01-25 02:32:55 +0100 |
---|---|---|
committer | cyBerta <cyberta@riseup.net> | 2024-01-25 02:32:55 +0100 |
commit | 23278cefe308043228c9da9b4937d27888146206 (patch) | |
tree | f851b9e9bad156a00b694ade42eb9c2a2be3b6c2 /app/src/main/java/se/leap | |
parent | ed8a28962675b540389fc9280ab1122613230fa8 (diff) |
fix VpnConfigGenerator Test, move RSAHelper and ObfsVpnHelper out of ConfigHelper, use injection pattern for these helpers
Diffstat (limited to 'app/src/main/java/se/leap')
10 files changed, 171 insertions, 74 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java index 948d764f..635af701 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java @@ -15,7 +15,7 @@ import androidx.appcompat.app.AppCompatDialogFragment; import androidx.appcompat.widget.AppCompatButton; import androidx.appcompat.widget.AppCompatEditText; -import se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper; +import se.leap.bitmaskclient.base.utils.ObfsVpnHelper; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.base.views.IconSwitchEntry; import se.leap.bitmaskclient.databinding.DObfuscationProxyBinding; diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java index c8c994a5..77becc80 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java @@ -8,7 +8,7 @@ import static se.leap.bitmaskclient.base.models.Constants.PREFER_UDP; import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; import static se.leap.bitmaskclient.base.models.Constants.USE_IPv6_FIREWALL; import static se.leap.bitmaskclient.base.models.Constants.USE_OBFUSCATION_PINNING; -import static se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper.useObfsVpn; +import static se.leap.bitmaskclient.base.utils.ObfsVpnHelper.useObfsVpn; import static se.leap.bitmaskclient.base.utils.ConfigHelper.isCalyxOSWithTetheringSupport; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.allowExperimentalTransports; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getExcludedApps; diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java index 70bf3943..18590f0b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java @@ -52,6 +52,7 @@ public interface Constants { String OBFUSCATION_PINNING_CERT = "obfuscation_pinning_cert"; String OBFUSCATION_PINNING_KCP = "obfuscation_pinning_udp"; String OBFUSCATION_PINNING_LOCATION = "obfuscation_pinning_location"; + String USE_SYSTEM_PROXY = "usesystemproxy"; ////////////////////////////////////////////// diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java index 14c78cc3..af9122de 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java @@ -28,8 +28,8 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_ALLOWED_REGIS import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_ALLOW_ANONYMOUS; import static se.leap.bitmaskclient.base.models.Constants.TRANSPORT; import static se.leap.bitmaskclient.base.models.Constants.TYPE; -import static se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper.useObfsVpn; -import static se.leap.bitmaskclient.base.utils.ConfigHelper.RSAHelper.parseRsaKeyFromString; +import static se.leap.bitmaskclient.base.utils.ObfsVpnHelper.useObfsVpn; +import static se.leap.bitmaskclient.base.utils.RSAHelper.parseRsaKeyFromString; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; import android.os.Parcel; diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java index d416a1ab..a06d85be 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java @@ -36,17 +36,12 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; -import java.security.KeyFactory; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.security.interfaces.RSAPrivateKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -130,39 +125,6 @@ public class ConfigHelper { return null; } - public static class RSAHelper { - public static RSAPrivateKey parseRsaKeyFromString(String rsaKeyString) { - RSAPrivateKey key; - try { - KeyFactory kf; - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { - kf = KeyFactory.getInstance("RSA", "BC"); - } else { - kf = KeyFactory.getInstance("RSA"); - } - rsaKeyString = rsaKeyString.replaceFirst("-----BEGIN RSA PRIVATE KEY-----", "").replaceFirst("-----END RSA PRIVATE KEY-----", ""); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(rsaKeyString)); - key = (RSAPrivateKey) kf.generatePrivate(keySpec); - } catch (InvalidKeySpecException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } catch (NullPointerException e) { - e.printStackTrace(); - return null; - } catch (NoSuchProviderException e) { - e.printStackTrace(); - return null; - } - - return key; - } - } - private static String byteArrayToHex(byte[] input) { int readBytes = input.length; StringBuffer hexData = new StringBuffer(); @@ -273,35 +235,6 @@ public class ConfigHelper { Build.VERSION.SDK_INT >= Build.VERSION_CODES.R; } - // ObfsVpnHelper class allows us to mock BuildConfig.use_obfsvpn while - // not mocking the whole ConfigHelper class - public static class ObfsVpnHelper { - public static boolean useObfsVpn() { - return BuildConfig.use_obfsvpn; - } - - public static boolean hasObfuscationPinningDefaults() { - return BuildConfig.obfsvpn_ip != null && - BuildConfig.obfsvpn_port != null && - BuildConfig.obfsvpn_cert != null && - !BuildConfig.obfsvpn_ip.isEmpty() && - !BuildConfig.obfsvpn_port.isEmpty() && - !BuildConfig.obfsvpn_cert.isEmpty(); - } - public static String obfsvpnIP() { - return BuildConfig.obfsvpn_ip; - } - public static String obfsvpnPort() { - return BuildConfig.obfsvpn_port; - } - public static String obfsvpnCert() { - return BuildConfig.obfsvpn_cert; - } - public static boolean useKcp() { - return BuildConfig.obfsvpn_use_kcp; - } - } - public static int getPendingIntentFlags() { int flags = PendingIntent.FLAG_CANCEL_CURRENT; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ObfsVpnHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ObfsVpnHelper.java new file mode 100644 index 00000000..054c85b3 --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ObfsVpnHelper.java @@ -0,0 +1,86 @@ +package se.leap.bitmaskclient.base.utils; + +import androidx.annotation.VisibleForTesting; + +import de.blinkt.openvpn.core.NativeUtils; +import se.leap.bitmaskclient.BuildConfig; + +// ObfsVpnHelper class allows us to mock BuildConfig fields related to the pre-shipped circumvention settings +public class ObfsVpnHelper { + + public interface ObfsVpnHelperInterface { + boolean useObfsVpn(); + boolean hasObfuscationPinningDefaults(); + String obfsvpnIP(); + String obfsvpnPort(); + String obfsvpnCert(); + boolean useKcp(); + } + + public static class DefaultObfsVpnHelper implements ObfsVpnHelperInterface { + @Override + public boolean useObfsVpn() { + return BuildConfig.use_obfsvpn; + } + + @Override + public boolean hasObfuscationPinningDefaults() { + return BuildConfig.obfsvpn_ip != null && + BuildConfig.obfsvpn_port != null && + BuildConfig.obfsvpn_cert != null && + !BuildConfig.obfsvpn_ip.isEmpty() && + !BuildConfig.obfsvpn_port.isEmpty() && + !BuildConfig.obfsvpn_cert.isEmpty(); + } + + @Override + public String obfsvpnIP() { + return BuildConfig.obfsvpn_ip; + } + + @Override + public String obfsvpnPort() { + return BuildConfig.obfsvpn_port; + } + + @Override + public String obfsvpnCert() { + return BuildConfig.obfsvpn_cert; + } + + @Override + public boolean useKcp() { + return BuildConfig.obfsvpn_use_kcp; + } + } + + private static ObfsVpnHelperInterface instance = new DefaultObfsVpnHelper(); + + @VisibleForTesting + public ObfsVpnHelper(ObfsVpnHelperInterface helperInterface) { + if (!NativeUtils.isUnitTest()) { + throw new IllegalStateException("ObfsVpnHelper injected with ObfsVpnHelperInterface outside of an unit test"); + } + instance = helperInterface; + } + + public static boolean useObfsVpn() { + return instance.useObfsVpn(); + } + + public static boolean hasObfuscationPinningDefaults() { + return instance.hasObfuscationPinningDefaults(); + } + public static String obfsvpnIP() { + return instance.obfsvpnIP(); + } + public static String obfsvpnPort() { + return instance.obfsvpnPort(); + } + public static String obfsvpnCert() { + return instance.obfsvpnCert(); + } + public static boolean useKcp() { + return instance.useKcp(); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java index b35a04cd..a04c3686 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java @@ -40,6 +40,7 @@ import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; import static se.leap.bitmaskclient.base.models.Constants.USE_IPv6_FIREWALL; import static se.leap.bitmaskclient.base.models.Constants.USE_OBFUSCATION_PINNING; import static se.leap.bitmaskclient.base.models.Constants.USE_SNOWFLAKE; +import static se.leap.bitmaskclient.base.models.Constants.USE_SYSTEM_PROXY; import android.content.Context; import android.content.SharedPreferences; @@ -460,12 +461,16 @@ public class PreferenceHelper { return getBoolean(ALLOW_EXPERIMENTAL_TRANSPORTS, false); } + public static boolean useSystemProxy() { + return getBoolean(USE_SYSTEM_PROXY, true); + } + public static void setUseObfuscationPinning(Boolean pinning) { putBoolean(USE_OBFUSCATION_PINNING, pinning); } public static boolean useObfuscationPinning() { - return ConfigHelper.ObfsVpnHelper.useObfsVpn() && + return ObfsVpnHelper.useObfsVpn() && getUseBridges() && getBoolean(USE_OBFUSCATION_PINNING, false) && !TextUtils.isEmpty(getObfuscationPinningIP()) && diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/RSAHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/RSAHelper.java new file mode 100644 index 00000000..2872139a --- /dev/null +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/RSAHelper.java @@ -0,0 +1,72 @@ +package se.leap.bitmaskclient.base.utils; + +import android.os.Build; + +import androidx.annotation.VisibleForTesting; + +import org.spongycastle.util.encoders.Base64; + +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; + +import de.blinkt.openvpn.core.NativeUtils; + +public class RSAHelper { + + public interface RSAHelperInterface { + RSAPrivateKey parseRsaKeyFromString(String rsaKeyString); + } + + public static class DefaultRSAHelper implements RSAHelperInterface { + + @Override + public RSAPrivateKey parseRsaKeyFromString(String rsaKeyString) { + RSAPrivateKey key; + try { + KeyFactory kf; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + kf = KeyFactory.getInstance("RSA", "BC"); + } else { + kf = KeyFactory.getInstance("RSA"); + } + rsaKeyString = rsaKeyString.replaceFirst("-----BEGIN RSA PRIVATE KEY-----", "").replaceFirst("-----END RSA PRIVATE KEY-----", ""); + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decode(rsaKeyString)); + key = (RSAPrivateKey) kf.generatePrivate(keySpec); + } catch (InvalidKeySpecException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } catch (NoSuchProviderException e) { + e.printStackTrace(); + return null; + } + + return key; + } + } + + private static RSAHelperInterface instance = new DefaultRSAHelper(); + + @VisibleForTesting + public RSAHelper(RSAHelperInterface helperInterface) { + if (!NativeUtils.isUnitTest()) { + throw new IllegalStateException("RSAHelper injected with RSAHelperInterface outside of an unit test"); + } + instance = helperInterface; + } + + public static RSAPrivateKey parseRsaKeyFromString(String rsaKeyString) { + return instance.parseRsaKeyFromString(rsaKeyString); + } +} diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index 6d5a406e..d21b6078 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -30,7 +30,7 @@ import static se.leap.bitmaskclient.base.models.Constants.REMOTE; import static se.leap.bitmaskclient.base.models.Constants.TCP; import static se.leap.bitmaskclient.base.models.Constants.TRANSPORT; import static se.leap.bitmaskclient.base.models.Constants.UDP; -import static se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper.useObfsVpn; +import static se.leap.bitmaskclient.base.utils.ObfsVpnHelper.useObfsVpn; import static se.leap.bitmaskclient.pluggableTransports.ShapeshifterClient.DISPATCHER_IP; import static se.leap.bitmaskclient.pluggableTransports.ShapeshifterClient.DISPATCHER_PORT; diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 93648bb0..08067d38 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -45,7 +45,7 @@ import static se.leap.bitmaskclient.base.models.Provider.CA_CERT; import static se.leap.bitmaskclient.base.models.Provider.GEOIP_URL; import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_API_IP; import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_IP; -import static se.leap.bitmaskclient.base.utils.ConfigHelper.RSAHelper.parseRsaKeyFromString; +import static se.leap.bitmaskclient.base.utils.RSAHelper.parseRsaKeyFromString; import static se.leap.bitmaskclient.base.utils.ConfigHelper.getDomainFromMainURL; import static se.leap.bitmaskclient.base.utils.ConfigHelper.getFingerprintFromCertificate; import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString; |