From ac7204c4daa0ae7e68ddfb89845c4f115b8a646c Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sun, 18 Mar 2018 03:37:20 +0100 Subject: refactor ConfigHelper, split into multiple helper classes --- .../java/se/leap/bitmaskclient/ConfigHelper.java | 445 --------------------- 1 file changed, 445 deletions(-) delete mode 100644 app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java (limited to 'app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java') diff --git a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java deleted file mode 100644 index aaff9ebc..00000000 --- a/app/src/main/java/se/leap/bitmaskclient/ConfigHelper.java +++ /dev/null @@ -1,445 +0,0 @@ -/** - * Copyright (c) 2013 LEAP Encryption Access Project and contributers - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package se.leap.bitmaskclient; - -import android.content.Context; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; -import org.spongycastle.util.encoders.Base64; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigInteger; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.KeyStoreException; -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.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static android.R.attr.name; -import static se.leap.bitmaskclient.Constants.ALWAYS_ON_SHOW_DIALOG; -import static se.leap.bitmaskclient.Constants.DEFAULT_SHARED_PREFS_BATTERY_SAVER; -import static se.leap.bitmaskclient.Constants.PREFERENCES_APP_VERSION; -import static se.leap.bitmaskclient.Constants.PROVIDER_CONFIGURED; -import static se.leap.bitmaskclient.Constants.PROVIDER_EIP_DEFINITION; -import static se.leap.bitmaskclient.Constants.PROVIDER_PRIVATE_KEY; -import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE; -import static se.leap.bitmaskclient.Constants.SHARED_PREFERENCES; - -/** - * Stores constants, and implements auxiliary methods used across all Bitmask Android classes. - * - * @author parmegv - * @author MeanderingCode - */ -public class ConfigHelper { - private static final String TAG = ConfigHelper.class.getName(); - private static KeyStore keystore_trusted; - - final public static String NG_1024 = - "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3"; - final public static BigInteger G = new BigInteger("2"); - - public static boolean checkErroneousDownload(String downloadedString) { - try { - if (downloadedString == null || downloadedString.isEmpty() || new JSONObject(downloadedString).has(ProviderAPI.ERRORS) || new JSONObject(downloadedString).has(ProviderAPI.BACKEND_ERROR_KEY)) { - return true; - } else { - return false; - } - } catch (NullPointerException | JSONException e) { - return false; - } - } - - /** - * Treat the input as the MSB representation of a number, - * and lop off leading zero elements. For efficiency, the - * input is simply returned if no leading zeroes are found. - * - * @param in array to be trimmed - */ - public static byte[] trim(byte[] in) { - if (in.length == 0 || in[0] != 0) - return in; - - int len = in.length; - int i = 1; - while (in[i] == 0 && i < len) - ++i; - byte[] ret = new byte[len - i]; - System.arraycopy(in, i, ret, 0, len - i); - return ret; - } - - public static X509Certificate parseX509CertificateFromString(String certificateString) { - java.security.cert.Certificate certificate = null; - CertificateFactory cf; - try { - cf = CertificateFactory.getInstance("X.509"); - - certificateString = certificateString.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); - byte[] cert_bytes = Base64.decode(certificateString); - InputStream caInput = new ByteArrayInputStream(cert_bytes); - try { - certificate = cf.generateCertificate(caInput); - System.out.println("ca=" + ((X509Certificate) certificate).getSubjectDN()); - } finally { - caInput.close(); - } - } catch (NullPointerException | CertificateException | IOException | IllegalArgumentException e) { - return null; - } - return (X509Certificate) certificate; - } - - public static String loadInputStreamAsString(java.io.InputStream is) { - java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); - return s.hasNext() ? s.next() : ""; - } - - //allows us to mock FileInputStream - public static InputStream getInputStreamFrom(String filePath) throws FileNotFoundException { - return new FileInputStream(filePath); - } - - protected static RSAPrivateKey parseRsaKeyFromString(String rsaKeyString) { - RSAPrivateKey key; - try { - KeyFactory kf = KeyFactory.getInstance("RSA", "BC"); - 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 (NoSuchProviderException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } catch (NullPointerException e) { - e.printStackTrace(); - return null; - } - - return key; - } - - private static String byteArrayToHex(byte[] input) { - int readBytes = input.length; - StringBuffer hexData = new StringBuffer(); - int onebyte; - for (int i = 0; i < readBytes; i++) { - onebyte = ((0x000000ff & input[i]) | 0xffffff00); - hexData.append(Integer.toHexString(onebyte).substring(6)); - } - return hexData.toString(); - } - - /** - * Calculates the hexadecimal representation of a sha256/sha1 fingerprint of a certificate - * - * @param certificate - * @param encoding - * @return - * @throws NoSuchAlgorithmException - * @throws CertificateEncodingException - */ - @NonNull - public static String getFingerprintFromCertificate(X509Certificate certificate, String encoding) throws NoSuchAlgorithmException, CertificateEncodingException /*, UnsupportedEncodingException*/ { - byte[] byteArray = MessageDigest.getInstance(encoding).digest(certificate.getEncoded()); - return byteArrayToHex(byteArray); - } - - /** - * Adds a new X509 certificate given its input stream and its provider name - * - * @param provider used to store the certificate in the keystore - * @param inputStream from which X509 certificate must be generated. - */ - public static void addTrustedCertificate(String provider, InputStream inputStream) { - CertificateFactory cf; - try { - cf = CertificateFactory.getInstance("X.509"); - X509Certificate cert = - (X509Certificate) cf.generateCertificate(inputStream); - keystore_trusted.setCertificateEntry(provider, cert); - } catch (CertificateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (KeyStoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * Adds a new X509 certificate given in its string from and using its provider name - * - * @param provider used to store the certificate in the keystore - * @param certificate - */ - public static void addTrustedCertificate(String provider, String certificate) { - - try { - X509Certificate cert = ConfigHelper.parseX509CertificateFromString(certificate); - if (keystore_trusted == null) { - keystore_trusted = KeyStore.getInstance("BKS"); - keystore_trusted.load(null); - } - keystore_trusted.setCertificateEntry(provider, cert); - } catch (KeyStoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (CertificateException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * @return class wide keystore - */ - public static KeyStore getKeystore() { - return keystore_trusted; - } - - - public static boolean providerInSharedPreferences(@NonNull SharedPreferences preferences) { - return preferences.getBoolean(PROVIDER_CONFIGURED, false); - } - - public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) { - Provider provider = new Provider(); - try { - provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); - provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); - provider.setCaCert(preferences.getString(Provider.CA_CERT, "")); - provider.setVpnCertificate(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); - provider.setPrivateKey(preferences.getString(PROVIDER_PRIVATE_KEY, "")); - provider.setEipServiceJson(new JSONObject(preferences.getString(PROVIDER_EIP_DEFINITION, ""))); - } catch (MalformedURLException | JSONException e) { - e.printStackTrace(); - } - - return provider; - } - - public static String getFromPersistedProvider(String toFetch, String providerDomain, SharedPreferences preferences) { - return preferences.getString(toFetch + "." + providerDomain, ""); - } - - public static String getProviderName(String provider) { - return getProviderName(null, provider); - } - - public static String getProviderName(@Nullable SharedPreferences preferences) { - return getProviderName(preferences,null); - } - - public static String getProviderName(@Nullable SharedPreferences preferences, @Nullable String provider) { - if (provider == null && preferences != null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - String lang = Locale.getDefault().getLanguage(); - return providerJson.getJSONObject(Provider.NAME).getString(lang); - } catch (JSONException e) { - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getJSONObject(Provider.NAME).getString("en"); - } catch (JSONException e2) { - return null; - } - } catch (NullPointerException npe) { - return null; - } - } - - public static String getProviderDomain(SharedPreferences preferences) { - return getProviderDomain(preferences, null); - } - - public static String getProviderDomain(String provider) { - return getProviderDomain(null, provider); - } - - public static String getProviderDomain(@Nullable SharedPreferences preferences, @Nullable String provider) { - if (provider == null && preferences != null) { - provider = preferences.getString(Provider.KEY, ""); - } - try { - JSONObject providerJson = new JSONObject(provider); - return providerJson.getString(Provider.DOMAIN); - } catch (JSONException | NullPointerException e) { - return null; - } - } - - public static String getDescription(SharedPreferences preferences) { - try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); - String lang = Locale.getDefault().getLanguage(); - return providerJson.getJSONObject(Provider.DESCRIPTION).getString(lang); - } catch (JSONException e) { - try { - JSONObject providerJson = new JSONObject(preferences.getString(Provider.KEY, "")); - return providerJson.getJSONObject(Provider.DESCRIPTION).getString("en"); - } catch (JSONException e1) { - return null; - } - } - } - - // TODO: replace commit with apply after refactoring EIP - //FIXME: don't save private keys in shared preferences! use the keystore - public static void storeProviderInPreferences(SharedPreferences preferences, Provider provider) { - preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.MAIN_URL, provider.getMainUrlString()). - putString(Provider.KEY, provider.getDefinitionString()). - putString(Provider.CA_CERT, provider.getCaCert()). - putString(PROVIDER_EIP_DEFINITION, provider.getEipServiceJsonString()). - putString(PROVIDER_PRIVATE_KEY, provider.getPrivateKey()). - putString(PROVIDER_VPN_CERTIFICATE, provider.getVpnCertificate()). - commit(); - - String providerDomain = provider.getDomain(); - preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.MAIN_URL + "." + providerDomain, provider.getMainUrlString()). - putString(Provider.KEY + "." + providerDomain, provider.getDefinitionString()). - putString(Provider.CA_CERT + "." + providerDomain, provider.getCaCert()). - putString(PROVIDER_EIP_DEFINITION + "." + providerDomain, provider.getEipServiceJsonString()). - apply(); - } - - - public static void clearDataOfLastProvider(SharedPreferences preferences) { - clearDataOfLastProvider(preferences, false); - } - - @Deprecated - public static void clearDataOfLastProvider(SharedPreferences preferences, boolean commit) { - Map allEntries = preferences.getAll(); - List lastProvidersKeys = new ArrayList<>(); - for (Map.Entry entry : allEntries.entrySet()) { - //sort out all preferences that don't belong to the last provider - if (entry.getKey().startsWith(Provider.KEY + ".") || - entry.getKey().startsWith(Provider.CA_CERT + ".") || - entry.getKey().startsWith(Provider.CA_CERT_FINGERPRINT + "." )|| - entry.getKey().equals(PREFERENCES_APP_VERSION) - ) { - continue; - } - lastProvidersKeys.add(entry.getKey()); - } - - SharedPreferences.Editor preferenceEditor = preferences.edit(); - for (String key : lastProvidersKeys) { - preferenceEditor.remove(key); - } - if (commit) { - preferenceEditor.commit(); - } else { - preferenceEditor.apply(); - } - } - - public static void deleteProviderDetailsFromPreferences(@NonNull SharedPreferences preferences, String providerDomain) { - preferences.edit(). - remove(Provider.KEY + "." + providerDomain). - remove(Provider.CA_CERT + "." + providerDomain). - remove(Provider.CA_CERT_FINGERPRINT + "." + providerDomain). - remove(Provider.MAIN_URL + "." + providerDomain). - remove(Provider.KEY + "." + providerDomain). - remove(Provider.CA_CERT + "." + providerDomain). - remove(PROVIDER_EIP_DEFINITION + "." + providerDomain). - remove(PROVIDER_PRIVATE_KEY + "." + providerDomain). - remove(PROVIDER_VPN_CERTIFICATE + "." + providerDomain). - apply(); - } - - public static void saveBattery(Context context, boolean isEnabled) { - if (context == null) { - return; - } - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - preferences.edit().putBoolean(DEFAULT_SHARED_PREFS_BATTERY_SAVER, isEnabled).apply(); - } - - public static boolean getSaveBattery(Context context) { - if (context == null) { - return false; - } - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - return preferences.getBoolean(DEFAULT_SHARED_PREFS_BATTERY_SAVER, false); - } - - public static void saveShowAlwaysOnDialog(Context context, boolean showAlwaysOnDialog) { - if (context == null) { - return; - } - SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); - preferences.edit().putBoolean(ALWAYS_ON_SHOW_DIALOG, showAlwaysOnDialog).apply(); - } - - public static boolean getShowAlwaysOnDialog(Context context) { - if (context == null) { - return true; - } - SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE); - return preferences.getBoolean(ALWAYS_ON_SHOW_DIALOG, true); - } -} -- cgit v1.2.3