diff options
| -rw-r--r-- | .classpath | 2 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | assets/urls/bitmask.url | 2 | ||||
| -rw-r--r-- | libs/bcprov-ext-jdk15on-146.jar | bin | 0 -> 1825975 bytes | |||
| -rw-r--r-- | project.properties | 2 | ||||
| -rw-r--r-- | res/raw/leapkeystore.bks | bin | 1487 -> 1437 bytes | |||
| -rw-r--r-- | res/raw/leapkeystore_bc147.bks | bin | 0 -> 2871 bytes | |||
| -rw-r--r-- | src/se/leap/leapclient/ConfigHelper.java | 72 | ||||
| -rw-r--r-- | src/se/leap/leapclient/ConfigurationWizard.java | 47 | ||||
| -rw-r--r-- | src/se/leap/leapclient/LeapHttpClient.java | 15 | ||||
| -rw-r--r-- | src/se/leap/leapclient/NewProviderDialog.java | 2 | ||||
| -rw-r--r-- | src/se/leap/leapclient/ProviderAPI.java | 112 | ||||
| -rw-r--r-- | src/se/leap/leapclient/ProviderListContent.java | 6 | 
13 files changed, 192 insertions, 69 deletions
@@ -2,7 +2,7 @@  <classpath>  	<classpathentry kind="src" path="src"/>  	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> -	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>  	<classpathentry kind="src" path="gen"/> +	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>  	<classpathentry kind="output" path="bin/classes"/>  </classpath> @@ -1,6 +1,5 @@  obj  bin -libs  gen  openvpn/.git  openvpn/autom4te.cache diff --git a/assets/urls/bitmask.url b/assets/urls/bitmask.url index f83ead86..910f0400 100644 --- a/assets/urls/bitmask.url +++ b/assets/urls/bitmask.url @@ -3,5 +3,5 @@  	"assets_json_provider" : "providers/bitmask.net_provider.json",
  	"json_provider" : "https://bitmask.net/provider.json",
  	"cert" : "https://bitmask.net/ca.crt",
 -	"json_eip_service" : "https://api.bitmask.net/1/config/eip-service.json"
 +	"json_eip_service" : "https://api.bitmask.net:4430/1/config/eip-service.json"
  }
\ No newline at end of file diff --git a/libs/bcprov-ext-jdk15on-146.jar b/libs/bcprov-ext-jdk15on-146.jar Binary files differnew file mode 100644 index 00000000..7d8a22e4 --- /dev/null +++ b/libs/bcprov-ext-jdk15on-146.jar diff --git a/project.properties b/project.properties index c4f09d2b..895c9ce2 100644 --- a/project.properties +++ b/project.properties @@ -8,4 +8,4 @@  # project structure.  # Project target. -target=android-17 +target=android-16 diff --git a/res/raw/leapkeystore.bks b/res/raw/leapkeystore.bks Binary files differindex 2e853ac4..b972172c 100644 --- a/res/raw/leapkeystore.bks +++ b/res/raw/leapkeystore.bks diff --git a/res/raw/leapkeystore_bc147.bks b/res/raw/leapkeystore_bc147.bks Binary files differnew file mode 100644 index 00000000..a6eaf30d --- /dev/null +++ b/res/raw/leapkeystore_bc147.bks diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index 52365762..11401df5 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -8,6 +8,13 @@ import java.io.FileNotFoundException;  import java.io.FileWriter;  import java.io.IOException;  import java.math.BigInteger; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate;  import org.json.JSONException;  import org.json.JSONObject; @@ -19,6 +26,7 @@ import android.util.Log;  public class ConfigHelper {      public static SharedPreferences shared_preferences; +    private static KeyStore keystore_trusted;  	final static String downloadJsonFilesBundleExtra = "downloadJSONFiles";  	final static String downloadNewProviderDotJSON = "downloadNewProviderDotJSON"; @@ -104,4 +112,68 @@ public class ConfigHelper {  			SharedPreferences shared_preferences) {  		ConfigHelper.shared_preferences = shared_preferences;  	} + +	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(); +		} +	} + +	public static void addTrustedCertificate(String provider, String certificate) { +		String filename_to_save = provider + "_certificate.cer"; +		saveFile(filename_to_save, certificate); +		CertificateFactory cf; +		try { +			cf = CertificateFactory.getInstance("X.509"); +			X509Certificate cert = +					(X509Certificate)cf.generateCertificate(openFileInputStream(filename_to_save)); +			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(); +		} +	} +	 +	public static KeyStore getKeystore() { +		return keystore_trusted; +	} + +	public static void getNewKeystore(InputStream leap_keystore) { +		try { +			keystore_trusted = KeyStore.getInstance("BKS"); +			try { +				// Initialize the keystore with the provided trusted certificates +				// Also provide the password of the keystore +				keystore_trusted.load(leap_keystore, "uer92jf".toCharArray()); +				//keystore_trusted.load(null, null); +			} finally { +				leap_keystore.close(); +			} +		} 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(); +		} +	}  } diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/leapclient/ConfigurationWizard.java index 33ff31fe..5b93cbbe 100644 --- a/src/se/leap/leapclient/ConfigurationWizard.java +++ b/src/se/leap/leapclient/ConfigurationWizard.java @@ -1,6 +1,7 @@  package se.leap.leapclient;
  import java.io.IOException;
 +import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Iterator;
  import java.util.Scanner;
 @@ -56,9 +57,16 @@ public class ConfigurationWizard extends Activity          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_configuration_wizard);
 -        
 +         +        ConfigHelper.setSharedPreferences(getSharedPreferences(ConfigHelper.PREFERENCES_KEY,MODE_PRIVATE));
 +                  loadPreseededProviders();
 +        if(ConfigHelper.getKeystore() == null) {
 +        	InputStream keystore_input_stream = getResources().openRawResource(R.raw.leapkeystore);
 +        	ConfigHelper.getNewKeystore(keystore_input_stream);
 +        }
 +        
          // Only create our fragments if we're not restoring a saved instance
          if ( savedInstanceState == null ){
          	// TODO Some welcome screen?
 @@ -114,29 +122,26 @@ public class ConfigurationWizard extends Activity          		if(current_provider_item.id.equalsIgnoreCase(id))
          		{
          			try {
 -        				if(!current_provider_item.custom)
 -        					processAssetsFiles(current_provider_item);
 -        				// TODO ask Provider class to save provider.json, setResult(OK), finish() to ConfigurationWizard
 -						downloadJSONFiles(current_provider_item);
 +        				saveProviderJson(current_provider_item);
 +        				downloadJSONFiles(current_provider_item);
  					} catch (IOException e) {
  						// TODO Auto-generated catch block
  						e.printStackTrace();
  					}
          		}
          	}
 -        	
 -            // FIXME!! We're going to have more Fragments and listeners, flow control?
 -        	// TODO There is no testing done to know if we're okay...
 -        	setResult(RESULT_OK);
 -        	finish();
          }
      }
 -	private void processAssetsFiles(ProviderItem current_provider_item) {
 +	private void saveProviderJson(ProviderItem current_provider_item) {
  		AssetManager assets_manager = getAssets();
  		JSONObject provider_json = new JSONObject();
  		try {
 -			String provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_assets))).useDelimiter("\\A").next();
 +			String provider_contents = "";
 +			if(!current_provider_item.custom)
 +				provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_filename))).useDelimiter("\\A").next();
 +			else
 +				provider_contents = new Scanner(ConfigHelper.openFileInputStream(current_provider_item.provider_json_filename)).useDelimiter("\\A").next();
  			provider_json = new JSONObject(provider_contents);
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
 @@ -148,17 +153,21 @@ public class ConfigurationWizard extends Activity  	}
  	private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException {
 +		providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler());
 +		providerAPI_result_receiver.setReceiver(this);
 +		
  		Intent provider_API_command = new Intent(this, ProviderAPI.class);
  		Bundle method_and_parameters = new Bundle();
 +		
 +		method_and_parameters.putString(ConfigHelper.provider_key, current_provider_item.name);
  		method_and_parameters.putString(ConfigHelper.cert_key, current_provider_item.cert_json_url);
  		method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url);
  		provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters);
  		provider_API_command.putExtra("receiver", providerAPI_result_receiver);
 -		
 +  		startService(provider_API_command);
 -		
  	}
  	public void addNewProvider(View view) {
 @@ -198,12 +207,14 @@ public class ConfigurationWizard extends Activity  			fragmentManager.beginTransaction()
  				.replace(R.id.configuration_wizard_layout, providerList, "providerlist")
  				.commit();
 +		} +		else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES) {
 +        	setResult(RESULT_OK);
 +        	finish();
  		}
  		else if(resultCode == ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES) {
 -			// TODO Show error
 -		}
 -		else if(resultCode == ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES) {
 -			// TODO Show nothing? Show success?
 +        	setResult(RESULT_CANCELED);
 +        	finish();  		}
  	}
  }
 diff --git a/src/se/leap/leapclient/LeapHttpClient.java b/src/se/leap/leapclient/LeapHttpClient.java index fd6db745..51b76b2c 100644 --- a/src/se/leap/leapclient/LeapHttpClient.java +++ b/src/se/leap/leapclient/LeapHttpClient.java @@ -35,23 +35,16 @@ public class LeapHttpClient extends DefaultHttpClient {  	  private SSLSocketFactory newSslSocketFactory() {  	      try {  	          // Get an instance of the Bouncy Castle KeyStore format -	          KeyStore trusted = KeyStore.getInstance("BKS"); -	          // Get the raw resource, which contains the keystore with -	          // your trusted certificates (root and any intermediate certs) -	          InputStream in = context.getResources().openRawResource(R.raw.leapkeystore); -	          try { -	              // Initialize the keystore with the provided trusted certificates -	              // Also provide the password of the keystore -	              trusted.load(in, "uer92jf".toCharArray()); -	          } finally { -	              in.close(); -	          } +	          KeyStore trusted = ConfigHelper.getKeystore(); +	            	          // Pass the keystore to the SSLSocketFactory. The factory is responsible  	          // for the verification of the server certificate.  	          SSLSocketFactory sf = new SSLSocketFactory(trusted); +	            	          // Hostname verification from certificate  	          // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506  	          sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); +	            	          return sf;  	      } catch (Exception e) {  	          throw new AssertionError(e); diff --git a/src/se/leap/leapclient/NewProviderDialog.java b/src/se/leap/leapclient/NewProviderDialog.java index 09e7453a..52453485 100644 --- a/src/se/leap/leapclient/NewProviderDialog.java +++ b/src/se/leap/leapclient/NewProviderDialog.java @@ -8,8 +8,6 @@ import android.content.DialogInterface;  import android.os.Bundle;  import android.view.LayoutInflater;  import android.view.View; -import android.view.ViewGroup; -import android.webkit.WebView.FindListener;  import android.widget.EditText;  import android.widget.Toast; diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index ea1410ad..6b09eb9d 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -4,6 +4,8 @@ import java.io.IOException;  import java.math.BigInteger;  import java.security.NoSuchAlgorithmException;  import java.util.List; +import java.net.MalformedURLException; +import java.net.URL;  import java.util.Scanner;  import org.apache.http.HttpEntity; @@ -17,7 +19,6 @@ import org.apache.http.cookie.Cookie;  import org.apache.http.impl.client.DefaultHttpClient;  import org.apache.http.protocol.BasicHttpContext;  import org.apache.http.protocol.HttpContext; -import org.jboss.security.srp.SRPClientSession;  import org.jboss.security.srp.SRPParameters;  import org.json.JSONException;  import org.json.JSONObject; @@ -42,43 +43,15 @@ public class ProviderAPI extends IntentService {  		final ResultReceiver receiver = task_for.getParcelableExtra("receiver");  		Bundle task; -		System.out.println("onHandleIntent called");  		if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) {  			if(!downloadJsonFiles(task))  				receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);  			else  				receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); -		} -		else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { -			boolean custom = true; -			String provider_main_url = (String) task.get(ConfigHelper.provider_key_url); -			String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); -			String provider_json_url = guessURL(provider_main_url); -			try { -				JSONObject provider_json = getJSONFromProvider(provider_json_url); -				String filename = provider_name + "_provider.json".replaceFirst("__", "_"); -				ConfigHelper.saveFile(filename, provider_json.toString()); -        		ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom)); -        		receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); -			} catch (IOException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} catch (JSONException e) { -				// TODO Auto-generated catch block -				e.printStackTrace(); -			} -		} -		else if ((task = task_for.getBundleExtra(ConfigHelper.srpRegister)) != null) { -			if(!registerWithSRP(task)) -				receiver.send(ConfigHelper.SRP_REGISTRATION_FAILED, Bundle.EMPTY); -			else -				receiver.send(ConfigHelper.SRP_REGISTRATION_SUCCESSFUL, Bundle.EMPTY); -		} -		else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { -			if(!authenticateBySRP(task)) -				receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); +			if(downloadJsonFilesBundleExtra(task)) +				receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);  			else -				receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, Bundle.EMPTY); +				receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY);  		}  	} @@ -202,6 +175,81 @@ public class ProviderAPI extends IntentService {  		return json_response.getString("M2").getBytes();  	} +	private boolean downloadNewProviderDotJSON(Bundle task) { +		boolean custom = true; +		String provider_main_url = (String) task.get(ConfigHelper.provider_key_url); +		String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); +		String provider_json_url = guessURL(provider_main_url); +		JSONObject provider_json = null; +		try { +			provider_json = getJSONFromProvider(provider_json_url); +		} catch (IOException e) { +			// It could happen that an https site used a certificate not trusted. +			provider_json = downloadNewProviderDotJsonWithoutCert(provider_json_url); +		} catch (JSONException e) { +			// TODO Auto-generated catch block +			e.printStackTrace(); +			return false; +		} +		 +		if(provider_json == null) { +			return false; +		} else { +			String filename = provider_name + "_provider.json".replaceFirst("__", "_"); +			ConfigHelper.saveFile(filename, provider_json.toString()); + +			ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom)); +			return true; +		} +	} + +	private boolean downloadJsonFilesBundleExtra(Bundle task) { +		String provider_name = (String) task.get(ConfigHelper.provider_key); +		String cert_url = (String) task.get(ConfigHelper.cert_key); +		String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); +		try { +			//JSONObject provider_json = new JSONObject("{ \"provider\" : \"" + provider_name + "\"}"); +			//ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); +			 +			/*String cert_string = getStringFromProvider(cert_url); +			JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); +			ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); +			ConfigHelper.addTrustedCertificate(provider_name, cert_string);*/ +			URL cacert = new URL(cert_url); +			ConfigHelper.addTrustedCertificate(provider_name, cacert.openStream()); +			JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); +			ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); +			return true; +		} catch (IOException e) { +			// It could happen that an https site used a certificate not trusted: solved above using URL +			e.printStackTrace(); +			return false; +		} catch (JSONException e) { +			ConfigHelper.rescueJSONException(e); +			return false; +		} catch(Exception e) { +			e.printStackTrace(); +			return false; +		} +	} + +	private JSONObject downloadNewProviderDotJsonWithoutCert( +			String provider_json_url) { +		JSONObject provider_json = null; +		try { +			URL provider_url = new URL(provider_json_url); +			String provider_json_string = new Scanner(provider_url.openStream()).useDelimiter("\\A").next(); +			provider_json = new JSONObject(provider_json_string); +		} catch (MalformedURLException e1) { +			e1.printStackTrace(); +		} catch (IOException e1) { +			e1.printStackTrace(); +		} catch (JSONException e1) { +			e1.printStackTrace(); +		} +		return provider_json; +	} +  	private String guessURL(String provider_main_url) {  		return provider_main_url + "/provider.json";  	} diff --git a/src/se/leap/leapclient/ProviderListContent.java b/src/se/leap/leapclient/ProviderListContent.java index d475d368..dd227bfd 100644 --- a/src/se/leap/leapclient/ProviderListContent.java +++ b/src/se/leap/leapclient/ProviderListContent.java @@ -41,7 +41,7 @@ public class ProviderListContent {      	public String id;
          public String name;
          public String provider_json_url;
 -        public String provider_json_assets;
 +        public String provider_json_filename;
          public String eip_service_json_url;
          public String cert_json_url;
 @@ -63,7 +63,7 @@ public class ProviderListContent {  				id = name;
  				this.name = name;
  				provider_json_url = (String) file_contents.get("json_provider");
 -				provider_json_assets = (String) file_contents.get("assets_json_provider");
 +				provider_json_filename = (String) file_contents.get("assets_json_provider");
  				eip_service_json_url = (String) file_contents.get("json_eip_service");
  				cert_json_url = (String) file_contents.get("cert");
  				this.custom = custom;
 @@ -88,6 +88,8 @@ public class ProviderListContent {  				eip_service_json_url = (String) file_contents.get("api_uri") + ConfigHelper.eip_service_api_path;
  				cert_json_url = (String) file_contents.get("ca_cert_uri");
  				this.custom = custom;
 +				if(custom)
 +					provider_json_filename = name + "_provider.json".replaceFirst("__", "_");
  			} catch (JSONException e) {
  				// TODO Auto-generated catch block
  				e.printStackTrace();
  | 
