summaryrefslogtreecommitdiff
path: root/app/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml5
-rw-r--r--app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl33
-rw-r--r--app/src/main/java/de/blinkt/openvpn/VpnProfile.java206
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java14
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java15
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java6
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java30
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java1
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java14
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java25
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java24
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Provider.java11
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java56
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java89
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java19
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java28
-rwxr-xr-xapp/src/main/res/values/strings-icsopenvpn.xml2
-rw-r--r--app/src/main/res/xml/data_extraction_rules.xml17
33 files changed, 486 insertions, 175 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5d221529..cbc06854 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,7 +33,9 @@
<application
android:name=".base.BitmaskApp"
- android:allowBackup="true"
+ android:allowBackup="false"
+ android:fullBackupContent="false"
+ android:dataExtractionRules="@xml/data_extraction_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:extractNativeLibs="true"
@@ -82,6 +84,7 @@
android:name=".base.StartActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
+ android:taskAffinity=""
android:theme="@style/SplashTheme"
android:exported="true"
>
diff --git a/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl b/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
index c6db965b..1f77b15f 100644
--- a/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
+++ b/app/src/main/aidl/de/blinkt/openvpn/api/ExternalCertificateProvider.aidl
@@ -1,16 +1,16 @@
// ExternalCertificateProvider.aidl
package de.blinkt.openvpn.api;
-
/*
* This is very simple interface that is specialised to have only the minimal set of crypto
* operation that are needed for OpenVPN to authenticate with an external certificate
*/
interface ExternalCertificateProvider {
/**
+ * @deprecated use {@link #getSignedDataWithExtra} instead
* Requests signing the data with RSA/ECB/PKCS1PADDING
* for RSA certficate and with NONEwithECDSA for EC certificates
- * @parm alias the parameter that
+ * @param alias user certificate identifier
*/
byte[] getSignedData(in String alias, in byte[] data);
@@ -36,4 +36,33 @@ interface ExternalCertificateProvider {
*
*/
Bundle getCertificateMetaData(in String alias);
+
+ /**
+ * Requests signing the data with RSA/ECB/nopadding, RSA/ECB/PKCS1PADDING or PKCS1PSSPADDING
+ * for RSA certficate and with NONEwithECDSA for EC certificates
+ * @param alias user certificate identifier
+ * @param data the data to be signed
+ * @param extra additional information.
+ * Should contain the following keys:
+ * <ul>
+ * <li>int key "de.blinkt.openvpn.api.RSA_PADDING_TYPE", may be set as:
+ * <ul>
+ * <li>0 - for RSA/ECB/nopadding
+ * <li>1 - for RSA/ECB/PKCS1PADDING
+ * <li>2 - for PKCS1PSSPADDING
+ * </ul>
+ * <li>string key "de.blinkt.openvpn.api.SALTLEN", may be set as:
+ * <ul>
+ * <li>"digest" - use the same salt size as the hash to sign
+ * <li>"max" - use maximum possible saltlen which is '(nbits-1)/8 - hlen - 2'. Here
+ * 'nbits' is the number of bits in the key modulus and 'hlen' is the size in octets of
+ * the hash. See: RFC 8017 sec 8.1.1 and 9.1.1.
+ * </ul>
+ * <li>boolean key "de.blinkt.openvpn.api.NEEDS_DIGEST", indicating that the data should be
+ * hashed before signing or not
+ * <li>string key "de.blinkt.openvpn.api.DIGEST", the short common digest algorithm name to
+ * use (such as SHA256, SHA224, etc.)
+ * </ul>
+ */
+ byte[] getSignedDataWithExtra(in String alias, in byte[] data, in Bundle extra);
}
diff --git a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
index 9baac195..780ac9d8 100644
--- a/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
+++ b/app/src/main/java/de/blinkt/openvpn/VpnProfile.java
@@ -15,6 +15,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
+import android.os.Bundle;
import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
@@ -37,7 +38,9 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
+import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
@@ -45,6 +48,9 @@ import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
@@ -58,6 +64,7 @@ import javax.crypto.NoSuchPaddingException;
import de.blinkt.openvpn.core.ExtAuthHelper;
import de.blinkt.openvpn.core.NativeUtils;
+import de.blinkt.openvpn.core.OpenVPNManagement;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.OrbotHelper;
import de.blinkt.openvpn.core.PasswordCache;
@@ -69,6 +76,7 @@ import de.blinkt.openvpn.core.connection.Connection;
import de.blinkt.openvpn.core.connection.ConnectionAdapter;
import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.base.models.ProviderObservable;
public class VpnProfile implements Serializable, Cloneable {
// Note that this class cannot be moved to core where it belongs since
@@ -104,6 +112,10 @@ public class VpnProfile implements Serializable, Cloneable {
private static final long serialVersionUID = 7085688938959334563L;
private static final int AUTH_RETRY_NONE_KEEP = 1;
private static final int AUTH_RETRY_INTERACT = 3;
+ private static final String EXTRA_RSA_PADDING_TYPE = "de.blinkt.openvpn.api.RSA_PADDING_TYPE";
+ private static final String EXTRA_SALTLEN = "de.blinkt.openvpn.api.SALTLEN";
+ private static final String EXTRA_NEEDS_DIGEST = "de.blinkt.openvpn.api.NEEDS_DIGEST";
+ private static final String EXTRA_DIGEST = "de.blinkt.openvpn.api.DIGEST";
public static String DEFAULT_DNS1 = "8.8.8.8";
public static String DEFAULT_DNS2 = "8.8.4.4";
// variable named wrong and should haven beeen transient
@@ -431,8 +443,9 @@ public class VpnProfile implements Serializable, Cloneable {
cfg.append(insertFileData("ca", mCaFilename));
// Client Cert + Key
- cfg.append(insertFileData("key", mClientKeyFilename));
cfg.append(insertFileData("cert", mClientCertFilename));
+ mPrivateKey = ProviderObservable.getInstance().getCurrentProvider().getRSAPrivateKey();
+ cfg.append("management-external-key nopadding pkcs1 pss digest\n");
break;
case VpnProfile.TYPE_USERPASS_PKCS12:
@@ -458,7 +471,7 @@ public class VpnProfile implements Serializable, Cloneable {
if (!TextUtils.isEmpty(ks[1]))
cfg.append("<extra-certs>\n").append(ks[1]).append("\n</extra-certs>\n");
cfg.append("<cert>\n").append(ks[2]).append("\n</cert>\n");
- cfg.append("management-external-key nopadding\n");
+ cfg.append("management-external-key nopadding pkcs1 pss digest\n");
} else {
cfg.append(context.getString(R.string.keychain_access)).append("\n");
}
@@ -750,7 +763,7 @@ public class VpnProfile implements Serializable, Cloneable {
public Intent prepareStartService(Context context) {
Intent intent = getStartServiceIntent(context);
- // TODO: Handle this?!
+ // This can remain outcommented for now, Bitmask uses VpnProfile.TYPE_CERTIFICATE
// if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
// if (getKeyStoreCertificates(context) == null)
// return null;
@@ -832,6 +845,14 @@ public class VpnProfile implements Serializable, Cloneable {
return ExtAuthHelper.getCertificateChain(context, mExternalAuthenticator, mAlias);
}
+ /**
+ * returns an array certificates, depending on the profile type either from the keychain or an external cert provider
+ * @param context
+ * @return pem encoded certificates, where:
+ * [0] is the ca cert
+ * [1] is an optional extra cert
+ * [2] is the vpn certificate
+ */
public String[] getExternalCertificates(Context context) {
return getExternalCertificates(context, 5);
}
@@ -966,8 +987,9 @@ public class VpnProfile implements Serializable, Cloneable {
if (mUseTLSAuth && TextUtils.isEmpty(mTLSAuthFilename))
return R.string.missing_tlsauth;
- if ((mAuthenticationType == TYPE_USERPASS_CERTIFICATES || mAuthenticationType == TYPE_CERTIFICATES)
- && (TextUtils.isEmpty(mClientCertFilename) || TextUtils.isEmpty(mClientKeyFilename)))
+ if ((mAuthenticationType == TYPE_USERPASS_CERTIFICATES &&
+ (TextUtils.isEmpty(mClientCertFilename) || (TextUtils.isEmpty(mClientKeyFilename)))) ||
+ mAuthenticationType == TYPE_CERTIFICATES && TextUtils.isEmpty(mClientCertFilename))
return R.string.missing_certificates;
if ((mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES)
@@ -1148,13 +1170,14 @@ public class VpnProfile implements Serializable, Cloneable {
}
@Nullable
- public String getSignedData(Context c, String b64data, boolean pkcs1padding) {
+ public String getSignedData(Context c, String b64data, OpenVPNManagement.SignaturePadding padding, String saltlen, String hashalg, boolean needDigest) {
byte[] data = Base64.decode(b64data, Base64.DEFAULT);
byte[] signed_bytes;
- if (mAuthenticationType == TYPE_EXTERNAL_APP)
- signed_bytes = getExtAppSignedData(c, data);
- else
- signed_bytes = getKeyChainSignedData(data, pkcs1padding);
+ if (mAuthenticationType == TYPE_EXTERNAL_APP) {
+ signed_bytes = getExtAppSignedData(c, data, padding, saltlen, hashalg, needDigest);
+ } else {
+ signed_bytes = getKeyChainSignedData(data, padding, saltlen, hashalg, needDigest);
+ }
if (signed_bytes != null)
return Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
@@ -1162,19 +1185,41 @@ public class VpnProfile implements Serializable, Cloneable {
return null;
}
- private byte[] getExtAppSignedData(Context c, byte[] data) {
+ private byte[] getExtAppSignedData(Context c, byte[] data, OpenVPNManagement.SignaturePadding padding, String saltlen, String hashalg, boolean needDigest)
+ {
+
+ Bundle extra = new Bundle();
+ RsaPaddingType paddingType;
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ paddingType = RsaPaddingType.PKCS1_PADDING;
+ break;
+ case NO_PADDING:
+ paddingType = RsaPaddingType.NO_PADDING;
+ break;
+ case RSA_PKCS1_PSS_PADDING:
+ paddingType = RsaPaddingType.RSAPSS_PADDING;
+ break;
+ default:
+ paddingType = RsaPaddingType.NO_PADDING;
+ }
+
+ extra.putInt(EXTRA_RSA_PADDING_TYPE, paddingType.ordinal());
+ extra.putString(EXTRA_SALTLEN, saltlen);
+ extra.putString(EXTRA_DIGEST, hashalg);
+ extra.putBoolean(EXTRA_NEEDS_DIGEST, needDigest);
+
if (TextUtils.isEmpty(mExternalAuthenticator))
return null;
try {
- return ExtAuthHelper.signData(c, mExternalAuthenticator, mAlias, data);
+ return ExtAuthHelper.signData(c, mExternalAuthenticator, mAlias, data, extra);
} catch (KeyChainException | InterruptedException e) {
VpnStatus.logError(R.string.error_extapp_sign, mExternalAuthenticator, e.getClass().toString(), e.getLocalizedMessage());
return null;
}
}
- private byte[] getKeyChainSignedData(byte[] data, boolean pkcs1padding) {
-
+ private byte[] getKeyChainSignedData(byte[] data, OpenVPNManagement.SignaturePadding padding, String saltlen, String hashalg, boolean needDigest) {
PrivateKey privkey = getKeystoreKey();
try {
@@ -1182,36 +1227,121 @@ public class VpnProfile implements Serializable, Cloneable {
String keyalgorithm = privkey.getAlgorithm();
byte[] signed_bytes;
- if (keyalgorithm.equals("EC")) {
- Signature signer = Signature.getInstance("NONEwithECDSA");
-
- signer.initSign(privkey);
- signer.update(data);
- signed_bytes = signer.sign();
-
+ if (needDigest || keyalgorithm.equals("EC")) {
+ return doDigestSign(privkey, data, padding, hashalg, saltlen);
} else {
- /* ECB is perfectly fine in this special case, since we are using it for
- the public/private part in the TLS exchange
- */
- Cipher signer;
- if (pkcs1padding)
- signer = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
- else
- signer = Cipher.getInstance("RSA/ECB/NoPadding");
-
+ /* ECB is perfectly fine in this special case, since we are using it for
+ the public/private part in the TLS exchange */
+ Cipher signer = null;
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+ signer = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
+ break;
+ case NO_PADDING:
+ signer = Cipher.getInstance("RSA/ECB/NoPadding");
+ break;
+ case RSA_PKCS1_PSS_PADDING:
+ throw new NoSuchPaddingException("Cannot do PKCS1 PSS padding without also doing the digest");
+ }
signer.init(Cipher.ENCRYPT_MODE, privkey);
signed_bytes = signer.doFinal(data);
+
+ return signed_bytes;
}
- return signed_bytes;
- } catch (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException
- | BadPaddingException | NoSuchPaddingException | SignatureException e) {
+ } catch
+ (NoSuchAlgorithmException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchPaddingException | SignatureException | InvalidAlgorithmParameterException
+ e) {
VpnStatus.logError(R.string.error_rsa_sign, e.getClass().toString(), e.getLocalizedMessage());
return null;
}
}
+ private byte[] addPSSPadding(PrivateKey privkey, String digest, byte[] data) throws NoSuchAlgorithmException {
+ /* For < API 23, add padding ourselves */
+ int hashtype = getHashtype(digest);
+
+ MessageDigest msgDigest = MessageDigest.getInstance(digest);
+ byte[] hash = msgDigest.digest(data);
+
+ /* MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; */
+ int numbits = ((RSAPrivateKey) privkey).getModulus().bitLength();
+
+ int MSBits = (numbits - 1) & 0x7;
+
+ return NativeUtils.addRssPssPadding(hashtype, MSBits, numbits/8, hash);
+ }
+
+ private int getHashtype(String digest) throws NoSuchAlgorithmException {
+ int hashtype = 0;
+ switch (digest) {
+ case "SHA1":
+ hashtype = 1;
+ break;
+ case "SHA224":
+ hashtype = 2;
+ break;
+ case "SHA256":
+ hashtype = 3;
+ break;
+ case "SHA384":
+ hashtype = 4;
+ break;
+ case "SHA512":
+ hashtype = 5;
+ break;
+ default:
+ throw new NoSuchAlgorithmException("Unknown digest algorithm: " + digest);
+ }
+ return hashtype;
+ }
+
+ private byte[] doDigestSign(PrivateKey privkey, byte[] data, OpenVPNManagement.SignaturePadding padding, String hashalg, String saltlen) throws SignatureException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException {
+ /* RSA */
+ Signature sig = null;
+
+ if (privkey.getAlgorithm().equals("EC")) {
+ if (hashalg.equals(""))
+ hashalg = "NONE";
+ /* e.g. SHA512withECDSA */
+ hashalg = hashalg + "withECDSA";
+ sig = Signature.getInstance(hashalg.toUpperCase(Locale.ROOT));
+ } else if (padding == OpenVPNManagement.SignaturePadding.RSA_PKCS1_PSS_PADDING) {
+ /* https://developer.android.com/training/articles/keystore#SupportedSignatures */
+ if (!"digest".equals(saltlen))
+ throw new SignatureException("PSS signing requires saltlen=digest");
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ data = addPSSPadding(privkey, hashalg, data);
+ return getKeyChainSignedData(data, OpenVPNManagement.SignaturePadding.NO_PADDING, "none", "none", false);
+ }
+
+ sig = Signature.getInstance(hashalg + "withRSA/PSS");
+
+ PSSParameterSpec pssspec = null;
+ switch (hashalg) {
+ case "SHA256":
+ pssspec = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
+ break;
+ case "SHA512":
+ pssspec = new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 64, 1);
+ break;
+ case "SHA384":
+ pssspec = new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384, 48, 1);
+ break;
+ }
+ sig.setParameter(pssspec);
+ } else if (padding == OpenVPNManagement.SignaturePadding.RSA_PKCS1_PADDING) {
+ sig = Signature.getInstance(hashalg + "withRSA");
+ }
+
+ sig.initSign(privkey);
+ sig.update(data);
+ return sig.sign();
+ }
+
+
private boolean usesExtraProxyOptions() {
if (mUseCustomConfig && mCustomConfigOptions != null && mCustomConfigOptions.contains("http-proxy-option "))
return true;
@@ -1222,6 +1352,16 @@ public class VpnProfile implements Serializable, Cloneable {
return false;
}
+ /**
+ * The order of elements is important!
+ */
+ private enum RsaPaddingType {
+ NO_PADDING,
+ PKCS1_PADDING,
+ RSAPSS_PADDING
+ }
+
+
class NoCertReturnedException extends Exception {
public NoCertReturnedException(String msg) {
super(msg);
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
index e8d333e3..ff27a5a2 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ConfigParser.java
@@ -70,9 +70,7 @@ public class ConfigParser {
"management",
"management-client",
"management-query-remote",
- "management-query-passwords",
"management-query-proxy",
- "management-external-key",
"management-forget-disconnect",
"management-signal",
"management-log-cache",
diff --git a/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java b/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
index a62a4c62..d102dce2 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/ExtAuthHelper.java
@@ -108,15 +108,23 @@ public class ExtAuthHelper {
public static byte[] signData(@NonNull Context context,
@NonNull String extAuthPackageName,
@NonNull String alias,
- @NonNull byte[] data
+ @NonNull byte[] data,
+ @NonNull Bundle extra
) throws KeyChainException, InterruptedException
{
- try (ExternalAuthProviderConnection authProviderConnection = bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
+ try (ExternalAuthProviderConnection authProviderConnection =
+ bindToExtAuthProvider(context.getApplicationContext(), extAuthPackageName)) {
ExternalCertificateProvider externalAuthProvider = authProviderConnection.getService();
- return externalAuthProvider.getSignedData(alias, data);
+
+ byte[] result = externalAuthProvider.getSignedDataWithExtra(alias, data, extra);
+ // When the desired method is not implemented, a default implementation is called, returning null
+ if (result == null)
+ result = externalAuthProvider.getSignedData(alias, data);
+
+ return result;
} catch (RemoteException e) {
throw new KeyChainException(e);
diff --git a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
index f769b38e..818564c7 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/NativeUtils.java
@@ -29,6 +29,21 @@ public class NativeUtils {
private static native String getJNIAPI();
+ static boolean rsspssloaded = false;
+
+ public static byte[] addRssPssPadding(int hashtype, int MSBits, int rsa_size, byte[] from)
+ {
+ if (!rsspssloaded) {
+ rsspssloaded = true;
+ System.loadLibrary("rsapss");
+ }
+
+ return rsapss(hashtype, MSBits, rsa_size, from);
+ }
+
+ private static native byte[] rsapss(int hashtype, int MSBits, int rsa_size, byte[] from);
+
+
public final static int[] openSSLlengths = {
16, 64, 256, 1024, 8 * 1024, 16 * 1024
};
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
index ef17e98b..02e4eca9 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
@@ -16,6 +16,12 @@ public interface OpenVPNManagement {
screenOff,
}
+ enum SignaturePadding {
+ RSA_PKCS1_PSS_PADDING,
+ RSA_PKCS1_PADDING,
+ NO_PADDING
+ }
+
int mBytecountInterval = 2;
void reconnect();
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index a02e7e27..88b933eb 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -194,7 +194,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
// Closing one of the two sockets also closes the other
//mServerSocketLocal.close();
- managmentCommand("version 2\n");
+ managmentCommand("version 3\n");
while (true) {
@@ -730,9 +730,33 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
releaseHold();
}
- private void processSignCommand(String b64data) {
+ private void processSignCommand(String argument) {
- String signed_string = mProfile.getSignedData(mOpenVPNService, b64data, false);
+ String[] arguments = argument.split(",");
+
+ // NC9t8IkYrjAQcCzc85zN0H5TvwfAUDwYkR4j2ga6fGw=,RSA_PKCS1_PSS_PADDING,hashalg=SHA256,saltlen=digest
+
+
+ SignaturePadding padding = SignaturePadding.NO_PADDING;
+ String saltlen="";
+ String hashalg="";
+ boolean needsDigest = false;
+
+ for (int i=1;i < arguments.length;i++) {
+ String arg = arguments[i];
+ if(arg.equals("RSA_PKCS1_PADDING"))
+ padding = SignaturePadding.RSA_PKCS1_PADDING;
+ else if (arg.equals("RSA_PKCS1_PSS_PADDING"))
+ padding = SignaturePadding.RSA_PKCS1_PSS_PADDING;
+ else if (arg.startsWith("saltlen="))
+ saltlen= arg.substring(8);
+ else if (arg.startsWith("hashalg="))
+ hashalg = arg.substring(8);
+ else if (arg.equals("data=message"))
+ needsDigest = true;
+ }
+
+ String signed_string = mProfile.getSignedData(mOpenVPNService, arguments[0], padding, saltlen, hashalg, needsDigest);
if (signed_string == null) {
managmentCommand("pk-sig\n");
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
index 80427a03..67636762 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
@@ -5,7 +5,6 @@
package de.blinkt.openvpn.core;
-import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index f28651f3..8115548f 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -5,6 +5,8 @@
package de.blinkt.openvpn.core;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
+
import android.content.Context;
import android.os.Build;
import android.os.HandlerThread;
@@ -23,8 +25,6 @@ import de.blinkt.openvpn.VpnProfile;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
-import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
-
public class VpnStatus {
@@ -485,10 +485,6 @@ public class VpnStatus {
mLogFileHandler.sendMessage(mLogFileHandler.obtainMessage(LogFileHandler.TRIM_LOG_FILE));
}
- //if (BuildConfig.DEBUG && !cachedLine && !BuildConfig.FLAVOR.equals("test"))
- // Log.d("OpenVPN", logItem.getString(null));
-
-
for (LogListener ll : logListener) {
ll.newLog(logItem);
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java
index 0ccef0ae..74b789a9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java
@@ -22,11 +22,9 @@ import static se.leap.bitmaskclient.appUpdate.DownloadBroadcastReceiver.ACTION_D
import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.CHECK_VERSION_FILE;
import static se.leap.bitmaskclient.appUpdate.DownloadServiceCommand.DOWNLOAD_UPDATE;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_DOWNLOAD_SERVICE_EVENT;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.isCalyxOSWithTetheringSupport;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSavedProviderFromSharedPreferences;
-import android.content.Context;
import android.content.IntentFilter;
import android.content.SharedPreferences;
@@ -42,6 +40,7 @@ import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.appUpdate.DownloadBroadcastReceiver;
import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.PRNGFixes;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.eip.EipSetupObserver;
import se.leap.bitmaskclient.tethering.TetheringStateManager;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -64,7 +63,7 @@ public class BitmaskApp extends MultiDexApplication {
// Normal app init code...*/
PRNGFixes.apply();
Security.insertProviderAt(Conscrypt.newProvider(), 1);
- SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = PreferenceHelper.getSharedPreferences(this);
providerObservable = ProviderObservable.getInstance();
providerObservable.updateProvider(getSavedProviderFromSharedPreferences(preferences));
torStatusObservable = TorStatusObservable.getInstance();
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
index 9225755e..248d96c7 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
@@ -33,7 +33,6 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE;
@@ -113,7 +112,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
navigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
- preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(this);
provider = ProviderObservable.getInstance().getCurrentProvider();
EipSetupObserver.addListener(this);
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java
index 3b534a7d..a508329c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java
@@ -1,5 +1,10 @@
package se.leap.bitmaskclient.base;
+import static android.content.Intent.ACTION_BOOT_COMPLETED;
+import static se.leap.bitmaskclient.base.models.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT;
+import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -8,12 +13,7 @@ import android.os.Build;
import android.util.Log;
import de.blinkt.openvpn.core.VpnStatus;
-
-import static android.content.Intent.ACTION_BOOT_COMPLETED;
-import static se.leap.bitmaskclient.base.models.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT;
-import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
public class OnBootReceiver extends BroadcastReceiver {
@@ -26,7 +26,7 @@ public class OnBootReceiver extends BroadcastReceiver {
if (intent == null || !ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
return;
}
- preferences = context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(context);
boolean providerConfigured = !preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty();
boolean startOnBoot = preferences.getBoolean(EIP_RESTART_ON_BOOT, false) && Build.VERSION.SDK_INT < Build.VERSION_CODES.O;
boolean isAlwaysOnConfigured = VpnStatus.isAlwaysOn();
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
index 58b057b7..94000a0f 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java
@@ -25,7 +25,6 @@ import static se.leap.bitmaskclient.base.models.Constants.PREFERENCES_APP_VERSIO
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_EIP_DEFINITION;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences;
@@ -81,7 +80,7 @@ public class StartActivity extends Activity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(this);
Log.d(TAG, "Started");
@@ -103,10 +102,27 @@ public class StartActivity extends Activity{
// initialize app necessities
VpnStatus.initLogCache(getApplicationContext().getCacheDir());
+ sanitizeStartIntent();
prepareEIP();
}
+ private void sanitizeStartIntent() {
+ Intent intent = new Intent();
+ try {
+ if (getIntent().hasExtra(EIP_RESTART_ON_BOOT)) {
+ intent.putExtra(EIP_RESTART_ON_BOOT, getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false));
+ }
+ if (getIntent().hasExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE)) {
+ intent.putExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE, false);
+ }
+ } catch (RuntimeException e) {
+
+ }
+ this.setIntent(intent);
+ }
+
+
/**
* check if normal start, first run, up or downgrade
* @return @StartupMode
@@ -180,6 +196,11 @@ public class StartActivity extends Activity{
}
}
+ if (hasNewFeature(FeatureVersionCode.ENCRYPTED_SHARED_PREFS)) {
+ PreferenceHelper.migrateToEncryptedPrefs(this);
+ preferences = PreferenceHelper.getSharedPreferences(this);
+ }
+
// always check if manual gateway selection feature switch has been disabled
if (!BuildConfig.allow_manual_gateway_selection && PreferenceHelper.getPreferredCity(this) != null) {
PreferenceHelper.setPreferredCity(this, null);
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
index a2fb2683..a8d11869 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
@@ -25,7 +25,6 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
import static se.leap.bitmaskclient.eip.EipSetupObserver.reconnectingWithDifferentGateway;
@@ -159,7 +158,7 @@ public class EipFragment extends Fragment implements Observer {
torStatusObservable = TorStatusObservable.getInstance();
Activity activity = getActivity();
if (activity != null) {
- preferences = getActivity().getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(activity);
} else {
Log.e(TAG, "activity is null in onCreate - no preferences set!");
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java
index 749ffd9f..793c6407 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java
@@ -16,6 +16,16 @@
*/
package se.leap.bitmaskclient.base.fragments;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
+import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
+import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
+import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges;
+import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle;
+
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -49,18 +59,6 @@ import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.eip.GatewaysManager;
-import static android.content.Context.MODE_PRIVATE;
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
-import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
-import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
-import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges;
-import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle;
-
interface LocationListSelectionListener {
void onLocationManuallySelected(Location location);
}
@@ -89,7 +87,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca
super.onCreate(savedInstanceState);
gatewaysManager = new GatewaysManager(getContext());
eipStatus = EipStatus.getInstance();
- preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(getContext());
}
@Override
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java
index aa894cca..f51fd342 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java
@@ -25,7 +25,6 @@ import static se.leap.bitmaskclient.base.models.Constants.ENABLE_DONATION;
import static se.leap.bitmaskclient.base.models.Constants.PREFERRED_CITY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSaveBattery;
@@ -63,6 +62,7 @@ import se.leap.bitmaskclient.base.FragmentManagerEnhanced;
import se.leap.bitmaskclient.base.MainActivity;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.models.ProviderObservable;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.base.views.IconSwitchEntry;
import se.leap.bitmaskclient.base.views.IconTextEntry;
import se.leap.bitmaskclient.eip.EipStatus;
@@ -110,7 +110,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen
super.onCreate(savedInstanceState);
// Reads in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
- preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(getContext());
preferences.registerOnSharedPreferenceChangeListener(this);
}
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 40bc256c..f36b17ad 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
@@ -1,12 +1,10 @@
package se.leap.bitmaskclient.base.fragments;
-import static android.content.Context.MODE_PRIVATE;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static se.leap.bitmaskclient.R.string.advanced_settings;
import static se.leap.bitmaskclient.base.models.Constants.GATEWAY_PINNING;
import static se.leap.bitmaskclient.base.models.Constants.PREFER_UDP;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
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;
@@ -71,7 +69,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(getContext());
preferences.registerOnSharedPreferenceChangeListener(this);
firewallManager = new FirewallManager(getContext().getApplicationContext(), false);
}
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 57467974..70bf3943 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
@@ -27,6 +27,7 @@ public interface Constants {
/////////////////////////////////////////////
String SHARED_PREFERENCES = "LEAPPreferences";
+ String SHARED_ENCRYPTED_PREFERENCES = "LEAPEncryptedPreferences";
String PREFERENCES_APP_VERSION = "bitmask version";
String ALWAYS_ON_SHOW_DIALOG = "DIALOG.ALWAYS_ON_SHOW_DIALOG";
String CLEARLOG = "clearlogconnect";
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java b/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
index f7251acb..c2eb9694 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/FeatureVersionCode.java
@@ -5,4 +5,6 @@ public interface FeatureVersionCode {
int GEOIP_SERVICE = 148;
int CALYX_PROVIDER_LILYPAD_UPDATE = 165000;
int RISEUP_PROVIDER_LILYPAD_UPDATE = 165000;
+
+ int ENCRYPTED_SHARED_PREFS = 170000;
}
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 08e13cf6..14c78cc3 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
@@ -29,6 +29,7 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_ALLOW_ANONYMO
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.providersetup.ProviderAPI.ERRORS;
import android.os.Parcel;
@@ -44,6 +45,7 @@ import org.json.JSONObject;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.interfaces.RSAPrivateKey;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Locale;
@@ -79,6 +81,8 @@ public final class Provider implements Parcelable {
private String caCert = "";
private String apiVersion = "";
private String privateKey = "";
+
+ private transient RSAPrivateKey rsaPrivateKey = null;
private String vpnCertificate = "";
private long lastEipServiceUpdate = 0L;
private long lastGeoIpUpdate = 0L;
@@ -701,6 +705,13 @@ public final class Provider implements Parcelable {
return privateKey;
}
+ public RSAPrivateKey getRSAPrivateKey() {
+ if (rsaPrivateKey == null) {
+ rsaPrivateKey = parseRsaKeyFromString(privateKey);
+ }
+ return rsaPrivateKey;
+ }
+
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
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 2412efdd..9289738a 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
@@ -131,35 +131,37 @@ public class ConfigHelper {
return null;
}
- 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");
+ 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;
}
- 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;
+ return key;
+ }
}
private static String byteArrayToHex(byte[] input) {
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 9cba221a..12196aee 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
@@ -27,6 +27,7 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_MOTD_LAST_UPD
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.base.models.Constants.RESTART_ON_UPDATE;
+import static se.leap.bitmaskclient.base.models.Constants.SHARED_ENCRYPTED_PREFERENCES;
import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.models.Constants.SHOW_EXPERIMENTAL;
import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES;
@@ -37,16 +38,22 @@ import static se.leap.bitmaskclient.base.models.Constants.USE_SNOWFLAKE;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
+import androidx.security.crypto.EncryptedSharedPreferences;
+import androidx.security.crypto.MasterKey;
import org.json.JSONException;
import org.json.JSONObject;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.GeneralSecurityException;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import de.blinkt.openvpn.VpnProfile;
@@ -60,6 +67,26 @@ import se.leap.bitmaskclient.tor.TorStatusObservable;
public class PreferenceHelper {
+ private static final String TAG = PreferenceHelper.class.getSimpleName();
+
+ public static SharedPreferences getSharedPreferences(Context context) {
+ try {
+ MasterKey masterKey = new MasterKey.Builder(context)
+ .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
+ .build();
+
+ return EncryptedSharedPreferences.create(
+ context,
+ SHARED_ENCRYPTED_PREFERENCES,
+ masterKey,
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM);
+ } catch (GeneralSecurityException | IOException e) {
+ e.printStackTrace();
+ }
+ return context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ }
+
public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) {
Provider provider = new Provider();
try {
@@ -97,7 +124,7 @@ public class PreferenceHelper {
}
public static void persistProviderAsync(Context context, Provider provider) {
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
storeProviderInPreferences(preferences, provider, true);
}
@@ -151,7 +178,7 @@ public class PreferenceHelper {
* Sets the profile that is connected (to connect if the service restarts)
*/
public static void setLastUsedVpnProfile(Context context, VpnProfile connectedProfile) {
- SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences prefs = getSharedPreferences(context);
SharedPreferences.Editor prefsedit = prefs.edit();
prefsedit.putString(LAST_USED_PROFILE, connectedProfile.toJson());
prefsedit.apply();
@@ -161,7 +188,7 @@ public class PreferenceHelper {
* Returns the profile that was last connected (to connect if the service restarts)
*/
public static VpnProfile getLastConnectedVpnProfile(Context context) {
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
String lastConnectedProfileJson = preferences.getString(LAST_USED_PROFILE, null);
return VpnProfile.fromJson(lastConnectedProfileJson);
}
@@ -204,6 +231,8 @@ public class PreferenceHelper {
apply();
}
+ // used in fatweb flavor
+ @SuppressWarnings("unused")
public static void setLastAppUpdateCheck(Context context) {
putLong(context, LAST_UPDATE_CHECK, System.currentTimeMillis());
}
@@ -419,7 +448,7 @@ public class PreferenceHelper {
if (context == null) {
return null;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
return preferences.getStringSet(EXCLUDED_APPS, new HashSet<>());
}
@@ -427,7 +456,7 @@ public class PreferenceHelper {
if (context == null) {
return defValue;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
return preferences.getLong(key, defValue);
}
@@ -435,7 +464,7 @@ public class PreferenceHelper {
if (context == null) {
return;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
preferences.edit().putLong(key, value).apply();
}
@@ -443,7 +472,7 @@ public class PreferenceHelper {
if (context == null) {
return defValue;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
return preferences.getString(key, defValue);
}
@@ -452,7 +481,7 @@ public class PreferenceHelper {
if (context == null) {
return;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
preferences.edit().putString(key, value).commit();
}
@@ -460,7 +489,7 @@ public class PreferenceHelper {
if (context == null) {
return;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
preferences.edit().putString(key, value).apply();
}
@@ -468,7 +497,7 @@ public class PreferenceHelper {
if (context == null) {
return;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
preferences.edit().putStringSet(key, value).apply();
}
@@ -477,7 +506,7 @@ public class PreferenceHelper {
return false;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
return preferences.getBoolean(key, defValue);
}
@@ -486,7 +515,7 @@ public class PreferenceHelper {
return;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
preferences.edit().putBoolean(key, value).apply();
}
@@ -495,7 +524,41 @@ public class PreferenceHelper {
return false;
}
- SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = getSharedPreferences(context);
return preferences.contains(key);
}
+
+ public static void migrateToEncryptedPrefs(Context context) {
+ SharedPreferences encryptedPrefs = getSharedPreferences(context);
+ if (!(encryptedPrefs instanceof EncryptedSharedPreferences)) {
+ Log.e(TAG, "Failed to migrate shared preferences");
+ return;
+ }
+ SharedPreferences.Editor encryptedEditor = encryptedPrefs.edit();
+ SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ Map<String,?> keys = preferences.getAll();
+
+ for(Map.Entry<String,?> entry : keys.entrySet()){
+ try {
+ Object value = entry.getValue();
+ if (value instanceof String) {
+ encryptedEditor.putString(entry.getKey(), (String) value);
+ } else if (value instanceof Boolean) {
+ encryptedEditor.putBoolean(entry.getKey(), (Boolean) value);
+ } else if (value instanceof Integer) {
+ encryptedEditor.putInt(entry.getKey(), (Integer) value);
+ } else if (value instanceof Set<?>) {
+ encryptedEditor.putStringSet(entry.getKey(), (Set<String>) value);
+ } else if (value instanceof Long) {
+ encryptedEditor.putLong(entry.getKey(), (Long) value);
+ } else if (value instanceof Float) {
+ encryptedEditor.putFloat(entry.getKey(), (Float) value);
+ }
+ } catch (ClassCastException e) {
+ e.printStackTrace();
+ }
+ }
+ encryptedEditor.commit();
+ preferences.edit().clear().apply();
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index 5b082448..29714670 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -37,7 +37,6 @@ import static se.leap.bitmaskclient.base.models.Constants.EIP_RECEIVER;
import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_PROFILE;
@@ -84,11 +83,9 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.Preferences;
import de.blinkt.openvpn.core.VpnStatus;
-import de.blinkt.openvpn.core.connection.Connection;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.OnBootReceiver;
import se.leap.bitmaskclient.base.models.Provider;
-import se.leap.bitmaskclient.base.models.Pair;
import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.eip.GatewaysManager.GatewayOptions;
@@ -147,7 +144,7 @@ public final class EIP extends JobIntentService implements Observer {
super.onCreate();
eipStatus = EipStatus.getInstance();
eipStatus.addObserver(this);
- preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(this);
}
@Override
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
index 85cdb06c..bb05810c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
@@ -73,6 +73,7 @@ import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.ConnectionStatus;
import de.blinkt.openvpn.core.LogItem;
import de.blinkt.openvpn.core.VpnStatus;
+import se.leap.bitmaskclient.BuildConfig;
import se.leap.bitmaskclient.appUpdate.DownloadServiceCommand;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.models.ProviderObservable;
@@ -433,6 +434,9 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta
@Override
public void newLog(LogItem logItem) {
if (logItem.getLogLevel() == VpnStatus.LogLevel.ERROR) {
+ if (BuildConfig.DEBUG) {
+ Log.e("ERROR", logItem.getString(appContext));
+ }
switch (logItem.getErrorType()) {
case SHAPESHIFTER:
VpnProfile profile = VpnStatus.getLastConnectedVpnProfile();
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
index d114665b..5e05b7c1 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java
@@ -22,7 +22,6 @@ import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN
import static de.blinkt.openvpn.core.connection.Connection.TransportType.PT;
import static se.leap.bitmaskclient.base.models.Constants.GATEWAYS;
import static se.leap.bitmaskclient.base.models.Constants.HOST;
-import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.base.models.Constants.SORTED_GATEWAYS;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPinningCert;
@@ -124,6 +123,7 @@ public class GatewaysManager {
GatewaySelector gatewaySelector;
+
public GatewaysManager(Context context) {
this.context = context;
configureFromCurrentProvider();
@@ -392,7 +392,6 @@ public class GatewaysManager {
try {
JSONObject eipDefinition = provider.getEipServiceJson();
JSONObject secrets = secretsConfigurationFromCurrentProvider();
-
JSONArray gatewaysDefined = new JSONArray();
try {
gatewaysDefined = eipDefinition.getJSONArray(GATEWAYS);
@@ -488,10 +487,8 @@ public class GatewaysManager {
private JSONObject secretsConfigurationFromCurrentProvider() {
JSONObject result = new JSONObject();
Provider provider = ProviderObservable.getInstance().getCurrentProvider();
-
try {
result.put(Provider.CA_CERT, provider.getCaCert());
- result.put(PROVIDER_PRIVATE_KEY, provider.getPrivateKey());
result.put(PROVIDER_VPN_CERTIFICATE, provider.getVpnCertificate());
} catch (JSONException e) {
e.printStackTrace();
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
index 79876d50..d9da622c 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
@@ -16,7 +16,12 @@
*/
package se.leap.bitmaskclient.eip;
-import android.annotation.TargetApi;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_BLOCKING_VPN;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_IS_ALWAYS_ON;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
+
import android.app.Notification;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -35,13 +40,7 @@ import java.util.Observer;
import de.blinkt.openvpn.core.ConnectionStatus;
import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.R;
-
-import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_BLOCKING_VPN;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_IS_ALWAYS_ON;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
-import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
public class VoidVpnService extends VpnService implements Observer, VpnNotificationManager.VpnServiceCallback {
@@ -85,7 +84,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat
thread = new Thread(new Runnable() {
public void run() {
establishBlockingVpn();
- SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = PreferenceHelper.getSharedPreferences(VoidVpnService.this.getApplicationContext());
preferences.edit().putBoolean(EIP_IS_ALWAYS_ON, false).commit();
Log.d(TAG, "start blocking vpn profile - always on = false");
}
@@ -97,7 +96,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat
thread = new Thread(new Runnable() {
public void run() {
establishBlockingVpn();
- SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ SharedPreferences preferences = PreferenceHelper.getSharedPreferences(VoidVpnService.this.getApplicationContext());
preferences.edit().putBoolean(EIP_IS_ALWAYS_ON, true).commit();
requestVpnWithLastSelectedProfile();
Log.d(TAG, "start blocking vpn profile - always on = true");
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 2c22d4f7..fa2ab352 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java
@@ -490,13 +490,6 @@ public class VpnConfigGenerator {
+ newLine
+ "</ca>";
- String key =
- "<key>"
- + newLine
- + secrets.getString(PROVIDER_PRIVATE_KEY)
- + newLine
- + "</key>";
-
String openvpnCert =
"<cert>"
+ newLine
@@ -504,7 +497,7 @@ public class VpnConfigGenerator {
+ newLine
+ "</cert>";
- return ca + newLine + key + newLine + openvpnCert;
+ return ca + newLine + openvpnCert;
} catch (JSONException e) {
e.printStackTrace();
return "";
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
index 86ce577b..0e7e1f4a 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java
@@ -19,7 +19,6 @@ package se.leap.bitmaskclient.providersetup;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
@@ -31,11 +30,9 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.util.concurrent.TimeoutException;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator;
import se.leap.bitmaskclient.tor.TorServiceCommand;
-import se.leap.bitmaskclient.tor.TorServiceConnection;
-
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
/**
* Implements HTTP api methods (encapsulated in {{@link ProviderApiManager}})
@@ -180,9 +177,8 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB
private ProviderApiManager initApiManager() {
- SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(getResources());
- return new ProviderApiManager(preferences, getResources(), clientGenerator, this);
+ return new ProviderApiManager(PreferenceHelper.getSharedPreferences(this), getResources(), clientGenerator, this);
}
}
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 14308875..fdaef28b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
@@ -43,13 +43,12 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
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.MOTD_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.ConfigHelper.getDomainFromMainURL;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getFingerprintFromCertificate;
import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString;
-import static se.leap.bitmaskclient.base.utils.ConfigHelper.parseRsaKeyFromString;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.deleteProviderDetailsFromPreferences;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getFromPersistedProvider;
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getLongFromPersistedProvider;
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
index 5cfefb2e..caba1436 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java
@@ -1,7 +1,17 @@
package se.leap.bitmaskclient.providersetup.activities;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
+import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getBootstrapProgress;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastLogs;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog;
+import static se.leap.bitmaskclient.tor.TorStatusObservable.getStringForCurrentStatus;
+
import android.content.SharedPreferences;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
@@ -20,7 +30,6 @@ import androidx.annotation.StringRes;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Guideline;
-import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -31,21 +40,10 @@ import java.util.Observer;
import butterknife.BindView;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.models.Provider;
+import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.base.views.ProviderHeaderView;
import se.leap.bitmaskclient.tor.TorStatusObservable;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
-import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY;
-import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getBootstrapProgress;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastLogs;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getStringForCurrentStatus;
-
/**
* Base Activity for configuration wizard activities
*
@@ -135,7 +133,7 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
+ preferences = PreferenceHelper.getSharedPreferences(this);
provider = getIntent().getParcelableExtra(PROVIDER_KEY);
}
diff --git a/app/src/main/res/values/strings-icsopenvpn.xml b/app/src/main/res/values/strings-icsopenvpn.xml
index dee6a42f..eab5e0c9 100755
--- a/app/src/main/res/values/strings-icsopenvpn.xml
+++ b/app/src/main/res/values/strings-icsopenvpn.xml
@@ -399,7 +399,7 @@
<string name="menu_use_inline_data">Use inline data</string>
<string name="export_config_chooser_title">Export configuration file</string>
<string name="missing_tlsauth">tls-auth file is missing</string>
- <string name="missing_certificates">Missing user certificate or user certifcate key file</string>
+ <string name="missing_certificates">Missing user certificate or user certificate key file</string>
<string name="missing_ca_certificate">Missing CA certificate</string>
<string name="crl_title">Certifcate Revoke List (optional)</string>
<string name="reread_log">Reread (%d) log items from log cache file</string>
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 00000000..fe61eb71
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<data-extraction-rules>
+ <cloud-backup>
+ <exclude domain="root" />
+ <exclude domain="file" />
+ <exclude domain="database" />
+ <exclude domain="sharedpref" />
+ <exclude domain="external" />
+ </cloud-backup>
+ <device-transfer>
+ <exclude domain="root" />
+ <exclude domain="file" />
+ <exclude domain="database" />
+ <exclude domain="sharedpref" />
+ <exclude domain="external" />
+ </device-transfer>
+</data-extraction-rules>