/** * 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 java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.io.InputStream; import java.security.KeyFactory; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; 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 org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.content.SharedPreferences; import android.util.Base64; /** * Stores constants, and implements auxiliary methods used across all LEAP Android classes. * * @author parmegv * @author MeanderingCode * */ public class ConfigHelper { public static SharedPreferences shared_preferences; private static KeyStore keystore_trusted; final public static String NG_1024 = "eeaf0ab9adb38dd69c33f80afa8fc5e86072618775ff3c0b9ea2314c9c256576d674df7496ea81d3383b4813d692c6e0e0d5d8e250b98be48e495c1d6089dad15dc7d7b46154d6b6ce8ef4ad69b15d4982559b297bcf1885c529f566660e57ec68edbc3c05726cc02fd4cbf4976eaa9afd5138fe8376435b9fc61d2fc0eb06e3"; final public static BigInteger G = new BigInteger("2"); private static boolean checkSharedPrefs() { try { shared_preferences = Dashboard.getAppContext().getSharedPreferences(Dashboard.SHARED_PREFERENCES,Context.MODE_PRIVATE); } catch (Exception e) { return false; } return true; } /** * Saves a JSON object into class scope Shared Preferences * @param shared_preferences_key * @param content */ public static void saveSharedPref(String shared_preferences_key, JSONObject content) { SharedPreferences.Editor shared_preferences_editor = shared_preferences .edit(); shared_preferences_editor.putString(shared_preferences_key, content.toString()); shared_preferences_editor.commit(); } /** * Saves a String object into class scope Shared Preferences * @param shared_preferences_key * @param content */ public static void saveSharedPref(String shared_preferences_key, String content) { SharedPreferences.Editor shared_preferences_editor = shared_preferences .edit(); shared_preferences_editor.putString(shared_preferences_key, content); shared_preferences_editor.commit(); } /** * Saves a boolean object into class scope Shared Preferences * @param shared_preferences_key * @param content */ public static void saveSharedPref(String shared_preferences_key, boolean content) { SharedPreferences.Editor shared_preferences_editor = shared_preferences .edit(); shared_preferences_editor.putBoolean(shared_preferences_key, content); shared_preferences_editor.commit(); } /** * Saves an int into class scope Shared Preferences * * @param shared_preferences_key * @param value */ protected static void saveSharedPref(String shared_preferences_key, int value) { SharedPreferences.Editor shared_preferences_editor = shared_preferences.edit(); shared_preferences_editor.putInt(shared_preferences_key, value).commit(); } /** * Gets String object from class scope Shared Preferences * @param shared_preferences_key * @return the string correspondent to the key parameter */ public static String getStringFromSharedPref(String shared_preferences_key) { String content = null; content = shared_preferences.getString(shared_preferences_key, ""); return content; } /** * Gets JSON object from class scope Shared Preferences * @param shared_preferences_key * @return the JSON object correspondent to the key parameter */ public static JSONObject getJsonFromSharedPref(String shared_preferences_key) throws JSONException { JSONObject content = null; if ( checkSharedPrefs() ) { String json_string = shared_preferences.getString(shared_preferences_key, ""); content = new JSONObject(json_string); } return content; } /* * This method defaults to false. * If you use this method, be sure to fail-closed on false! * TODO This is obviously less than ideal...solve it! */ public static boolean getBoolFromSharedPref(String shared_preferences_key) { boolean value = false; if ( checkSharedPrefs() ) { value = shared_preferences.getBoolean(shared_preferences_key, false); } return value; } /** * Get an int from SharedPreferences * * @param shared_preferences_key Key to retrieve * @return The value for the key or 0 */ protected static int getIntFromSharedPref(String shared_preferences_key) { return shared_preferences.getInt(shared_preferences_key, 0); } /* * This method defaults to false. * If you use this method, be sure to fail-closed on false! * TODO This is obviously less than ideal...solve it! */ public static boolean removeFromSharedPref(String shared_preferences_key) { SharedPreferences.Editor shared_preferences_editor = shared_preferences .edit(); shared_preferences_editor.remove(shared_preferences_key); return shared_preferences_editor.commit(); } /** * 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; } /** * Sets class scope Shared Preferences * @param shared_preferences */ public static void setSharedPreferences( SharedPreferences shared_preferences) { ConfigHelper.shared_preferences = shared_preferences; } public static X509Certificate parseX509CertificateFromString(String certificate_string) { java.security.cert.Certificate certificate = null; CertificateFactory cf; try { cf = CertificateFactory.getInstance("X.509"); certificate_string = certificate_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(certificate_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); try { certificate = cf.generateCertificate(caInput); System.out.println("ca=" + ((X509Certificate) certificate).getSubjectDN()); } finally { caInput.close(); } } catch (CertificateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { return null; } return (X509Certificate) certificate; } protected static RSAPrivateKey parseRsaKeyFromString(String RsaKeyString) { RSAPrivateKey key = null; 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, Base64.DEFAULT) ); 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; } return key; } /** * 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; } }