From 92c32b0b96938009af55ed28920472f22a4614ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 31 Jan 2013 22:12:21 +0100 Subject: Problems with downloaded file, the emulator cannot find the file downloaded. Seen http://code.google.com/p/android/issues/detail?id=18462 and decided to look for another solution. First solution thought (and going to be the next test): HTTP Get request :) --- src/se/leap/leapclient/ProviderAPI.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/se/leap/leapclient/ProviderAPI.java (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java new file mode 100644 index 00000000..6d52e44f --- /dev/null +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -0,0 +1,15 @@ +package se.leap.leapclient; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class ProviderAPI extends Service { + + @Override + public IBinder onBind(Intent arg0) { + // TODO Auto-generated method stub + return null; + } + +} -- cgit v1.2.3 From 7b9e22e765a1e5eda05ad121684e63c20ff5f049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 1 Feb 2013 00:13:09 +0100 Subject: I have a handshake failing within an HTTP connection in order to get the eip-service.json file. provider.json downloads and parses itself OK to SharedPreferences. It also does not link OK to the Dashboard, I do not know how to do it properly and I'm so tired (eyes hurting). Beginning with security things :) Happy to have gotten around DownloadManager problem with a simple HTTP connection. --- src/se/leap/leapclient/ProviderAPI.java | 64 +++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 6d52e44f..aefb87fc 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,15 +1,67 @@ package se.leap.leapclient; -import android.app.Service; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Scanner; + +import android.app.IntentService; import android.content.Intent; -import android.os.IBinder; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; + +public class ProviderAPI extends IntentService { -public class ProviderAPI extends Service { + public ProviderAPI() { + super("ProviderAPI"); + Log.v("ClassName", "Provider API"); + // TODO Auto-generated constructor stub + } @Override - public IBinder onBind(Intent arg0) { - // TODO Auto-generated method stub - return null; + protected void onHandleIntent(Intent task_for) { + Bundle task ; + System.out.println("onHandleIntent called"); + if(!(task = task_for.getBundleExtra("downloadJSONFiles")).isEmpty()) + { + String provider_key = "provider"; + String eip_service_key = "eip"; + String provider_json_url = (String) task.get(provider_key); + String eip_service_json_url = (String) task.get(eip_service_key); + try { + getAndParseSharedPref(provider_key, provider_json_url); + getAndParseSharedPref(eip_service_key, eip_service_json_url); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + private void getAndParseSharedPref(String shared_preferences_key, + String json_url) throws IOException { + URL url = new URL(json_url); + HttpURLConnection urlConnection = (HttpURLConnection) url + .openConnection(); + try { + InputStream in = new BufferedInputStream( + urlConnection.getInputStream()); + String json_file_content = new Scanner(in).useDelimiter("\\A") + .next(); + + SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences + .edit(); + shared_preferences_editor.putString(shared_preferences_key, + json_file_content); + shared_preferences_editor.commit(); + System.out.println("Shared preferences updated: " + ProviderListActivity.shared_preferences.getString(shared_preferences_key, "Default")); + } finally { + urlConnection.disconnect(); + } + } } -- cgit v1.2.3 From d2bd18ef560d95974117604af899b3a9fcc16dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 4 Feb 2013 16:35:28 +0100 Subject: Created ConfigHelper with static information such as sharedprefs keys, the saveSharedPrefs method and an unimplemented rescueFromJSONException. Next step: managing HttpsURLConnection for the CertPathValidatorException. --- src/se/leap/leapclient/ProviderAPI.java | 55 ++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index aefb87fc..40638180 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,11 +5,16 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.net.URLConnection; import java.util.Scanner; +import javax.net.ssl.HttpsURLConnection; + +import org.json.JSONException; +import org.json.JSONObject; + import android.app.IntentService; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; @@ -23,45 +28,45 @@ public class ProviderAPI extends IntentService { @Override protected void onHandleIntent(Intent task_for) { - Bundle task ; + Bundle task; System.out.println("onHandleIntent called"); - if(!(task = task_for.getBundleExtra("downloadJSONFiles")).isEmpty()) - { - String provider_key = "provider"; - String eip_service_key = "eip"; - String provider_json_url = (String) task.get(provider_key); - String eip_service_json_url = (String) task.get(eip_service_key); + if (!(task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)).isEmpty()) { + String provider_json_url = (String) task.get(ConfigHelper.provider_key); + String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); try { - getAndParseSharedPref(provider_key, provider_json_url); - getAndParseSharedPref(eip_service_key, eip_service_json_url); + JSONObject provider_json = getFromProvider(provider_json_url); + ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + JSONObject eip_service_json = getFromProvider(eip_service_json_url); + ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (JSONException e) { + ConfigHelper.rescueJSONException(e); } } } - private void getAndParseSharedPref(String shared_preferences_key, - String json_url) throws IOException { + private JSONObject getFromProvider(String json_url) throws IOException, JSONException { URL url = new URL(json_url); - HttpURLConnection urlConnection = (HttpURLConnection) url - .openConnection(); + String json_file_content = ""; + URLConnection urlConnection = null; + + if (url.getProtocol().equalsIgnoreCase("https")) { + urlConnection = (HttpsURLConnection) url.openConnection(); + } else if (url.getProtocol().equalsIgnoreCase("http")) { + urlConnection = (HttpURLConnection) url.openConnection(); + } + try { InputStream in = new BufferedInputStream( urlConnection.getInputStream()); - String json_file_content = new Scanner(in).useDelimiter("\\A") - .next(); - - SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences - .edit(); - shared_preferences_editor.putString(shared_preferences_key, - json_file_content); - shared_preferences_editor.commit(); - System.out.println("Shared preferences updated: " + ProviderListActivity.shared_preferences.getString(shared_preferences_key, "Default")); + json_file_content = new Scanner(in).useDelimiter("\\A").next(); } finally { - urlConnection.disconnect(); + ((HttpURLConnection) urlConnection).disconnect(); } - + + return new JSONObject(json_file_content); } } -- cgit v1.2.3 From 8ab36864e2a393df077073f8618a4fc55c307522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 4 Feb 2013 18:44:38 +0100 Subject: Secure HTTP working with certificates downloaded from api.bitmask.net and bitmask.net. Both prefs are downloaded and parsed to SharedPreferences. --- src/se/leap/leapclient/ProviderAPI.java | 35 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 40638180..d487ebe3 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,15 +1,12 @@ package se.leap.leapclient; -import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; import java.util.Scanner; -import javax.net.ssl.HttpsURLConnection; - +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; @@ -48,23 +45,17 @@ public class ProviderAPI extends IntentService { } private JSONObject getFromProvider(String json_url) throws IOException, JSONException { - URL url = new URL(json_url); + String json_file_content = ""; - URLConnection urlConnection = null; - if (url.getProtocol().equalsIgnoreCase("https")) { - urlConnection = (HttpsURLConnection) url.openConnection(); - } else if (url.getProtocol().equalsIgnoreCase("http")) { - urlConnection = (HttpURLConnection) url.openConnection(); - } - - try { - InputStream in = new BufferedInputStream( - urlConnection.getInputStream()); - json_file_content = new Scanner(in).useDelimiter("\\A").next(); - } finally { - ((HttpURLConnection) urlConnection).disconnect(); - } + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + HttpGet get = new HttpGet(json_url); + // Execute the GET call and obtain the response + HttpResponse getResponse = client.execute(get); + HttpEntity responseEntity = getResponse.getEntity(); + + json_file_content = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + return new JSONObject(json_file_content); } -- cgit v1.2.3 From 1d5f1c320ee67cfadd62aeef056a043bee75096d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 5 Feb 2013 20:46:33 +0100 Subject: Simplified certificates and urls: only 1 certificate, and no :443 port in eip. Downloads certificate and eip from web, and loads provider from assets. KeyStore not created with latest version of BouncyCastle. Looking forward to file a bug and look for a solution. --- src/se/leap/leapclient/ProviderAPI.java | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index d487ebe3..33f7fd74 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,6 +5,7 @@ import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; @@ -28,35 +29,41 @@ public class ProviderAPI extends IntentService { Bundle task; System.out.println("onHandleIntent called"); if (!(task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)).isEmpty()) { - String provider_json_url = (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 = getFromProvider(provider_json_url); - ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - JSONObject eip_service_json = getFromProvider(eip_service_json_url); + String cert_string = getStringFromProvider(cert_url); + JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); + ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { ConfigHelper.rescueJSONException(e); + } catch(Exception e) { + e.printStackTrace(); } } } - private JSONObject getFromProvider(String json_url) throws IOException, JSONException { + private String getStringFromProvider(String string_url) throws IOException { String json_file_content = ""; DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - HttpGet get = new HttpGet(json_url); + HttpGet get = new HttpGet(string_url); // Execute the GET call and obtain the response HttpResponse getResponse = client.execute(get); HttpEntity responseEntity = getResponse.getEntity(); json_file_content = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - + return json_file_content; + } + private JSONObject getJSONFromProvider(String json_url) throws IOException, JSONException { + String json_file_content = getStringFromProvider(json_url); return new JSONObject(json_file_content); } -- cgit v1.2.3 From 72fd6621a988fcc25d1fa93b977cb7d0a88c96d6 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 17:51:24 -0700 Subject: Clean up unused imports --- src/se/leap/leapclient/ProviderAPI.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 33f7fd74..5a8f9572 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,7 +5,6 @@ import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; -- cgit v1.2.3 From 162afa5bfa6485f3aacb3f60e9c92fa0c3bfa7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 11 Feb 2013 20:28:59 +0100 Subject: Gets provider.json from custom url (assuming the file is at the root of the website, just as bitmask.net/provider.json), and writes it to a file in ~/leap_android. Next steps: parse that file and download eip-service and cert. --- src/se/leap/leapclient/ProviderAPI.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 5a8f9572..c21e17a4 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -27,7 +27,7 @@ public class ProviderAPI extends IntentService { protected void onHandleIntent(Intent task_for) { Bundle task; System.out.println("onHandleIntent called"); - if (!(task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)).isEmpty()) { + if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { String cert_url = (String) task.get(ConfigHelper.cert_key); String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); try { @@ -45,6 +45,25 @@ public class ProviderAPI extends IntentService { e.printStackTrace(); } } + else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { + String provider_main_url = (String) task.get(ConfigHelper.provider_key_url); + String provider_json_url = guessURL(provider_main_url); + try { + JSONObject provider_json = getJSONFromProvider(provider_json_url); + String filename = provider_json_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_") + "_provider.json".replaceFirst("__", "_"); + ConfigHelper.saveFile(filename, provider_json.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + private String guessURL(String provider_main_url) { + return provider_main_url + "/provider.json"; } private String getStringFromProvider(String string_url) throws IOException { -- cgit v1.2.3 From c01aa98a1d43ae0d6b56f0d13a8782dbb6a3e35e Mon Sep 17 00:00:00 2001 From: parmegv Date: Tue, 12 Feb 2013 19:33:19 +0100 Subject: New custom provider dialog effectively adds the new provider to the ProviderListFragment, and then the user can choose it. --- src/se/leap/leapclient/ProviderAPI.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index c21e17a4..583eea06 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -10,13 +10,16 @@ import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; +import se.leap.leapclient.ProviderListContent.ProviderItem; + import android.app.IntentService; import android.content.Intent; import android.os.Bundle; +import android.os.ResultReceiver; import android.util.Log; public class ProviderAPI extends IntentService { - + public ProviderAPI() { super("ProviderAPI"); Log.v("ClassName", "Provider API"); @@ -25,6 +28,7 @@ public class ProviderAPI extends IntentService { @Override protected void onHandleIntent(Intent task_for) { + final ResultReceiver receiver = task_for.getParcelableExtra("receiver"); Bundle task; System.out.println("onHandleIntent called"); if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { @@ -46,12 +50,16 @@ public class ProviderAPI extends IntentService { } } 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_json_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_") + "_provider.json".replaceFirst("__", "_"); + 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(); @@ -84,5 +92,4 @@ public class ProviderAPI extends IntentService { String json_file_content = getStringFromProvider(json_url); return new JSONObject(json_file_content); } - } -- cgit v1.2.3 From 1868e180e8f56c310a52f4ed399dc9e34284957e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 21 Feb 2013 18:49:59 +0100 Subject: Started SRP authentication. Using NG_1024 with g = 2, and SHA256 digest. Next steps: Implement async communication with the server to receive salt, send A and receive B. --- src/se/leap/leapclient/ProviderAPI.java | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 583eea06..e83e9e6e 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,8 +1,13 @@ package se.leap.leapclient; import java.io.IOException; +import java.math.BigInteger; +import java.security.SecureRandom; import java.util.Scanner; +import org.bouncycastle.crypto.agreement.srp.SRP6Client; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.jcajce.provider.digest.Whirlpool.Digest; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -68,6 +73,25 @@ public class ProviderAPI extends IntentService { e.printStackTrace(); } } + else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { + String username = (String) task.get(ConfigHelper.username_key); + String password = (String) task.get(ConfigHelper.password_key); + SRP6Client srp_client = new SRP6Client(); + srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); + // Receive salt from server + String salt = getSaltFromSRPServer(); + BigInteger A = srp_client.generateClientCredentials(salt.getBytes(), username.getBytes(), password.getBytes()); + //Send A to the server. Doing a http response with cookies? + //Receive server generated serverB + //S = calculateSecret(BigInteger serverB) + //K = H(S) + //Now the two parties have a shared, strong session key K. To complete authentication, they need to prove to each other that their keys match. + } + } + + private String getSaltFromSRPServer() { + // TODO Auto-generated method stub + return null; } private String guessURL(String provider_main_url) { -- cgit v1.2.3 From 5964b1ffec270b99cdbc962cd0c4aefa2c5fcb4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 25 Feb 2013 21:30:42 +0100 Subject: Finished first implementation of SRP. Next step: get cookies understood, how do I get server's sent parameters? --- src/se/leap/leapclient/ProviderAPI.java | 154 ++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 8 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index e83e9e6e..39bb50ec 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -2,15 +2,25 @@ package se.leap.leapclient; import java.io.IOException; import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; +import java.util.List; +import java.util.Random; import java.util.Scanner; +import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.agreement.srp.SRP6Client; import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.prng.RandomGenerator; import org.bouncycastle.jcajce.provider.digest.Whirlpool.Digest; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; @@ -76,22 +86,150 @@ public class ProviderAPI extends IntentService { else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); + String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); SRP6Client srp_client = new SRP6Client(); srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); // Receive salt from server - String salt = getSaltFromSRPServer(); - BigInteger A = srp_client.generateClientCredentials(salt.getBytes(), username.getBytes(), password.getBytes()); + Random random_number_generator = new Random(); + int salt = random_number_generator.nextInt(Integer.valueOf(ConfigHelper.NG_1024)); + byte[] salt_in_bytes = ByteBuffer.allocate(4).putInt(salt).array(); + BigInteger clientA = srp_client.generateClientCredentials(salt_in_bytes, username.getBytes(), password.getBytes()); //Send A to the server. Doing a http response with cookies? //Receive server generated serverB - //S = calculateSecret(BigInteger serverB) - //K = H(S) - //Now the two parties have a shared, strong session key K. To complete authentication, they need to prove to each other that their keys match. + try { + BigInteger serverB = sendParameterToSRPServer(authentication_server, "A", clientA); + BigInteger s = srp_client.calculateSecret(serverB); + MessageDigest digest_of_S = MessageDigest.getInstance("SHA-256"); + digest_of_S.update(s.toByteArray(), 0, s.toByteArray().length); + BigInteger k = new BigInteger(digest_of_S.digest()); + BigInteger m1 = generateM1(k, clientA, serverB, salt, username); + BigInteger m2 = sendParameterToSRPServer(authentication_server, "M1", m1); + sendM1(m2, k, clientA, serverB, salt, username); + boolean verified = verifyM2(m2, k, clientA, serverB, salt, username); + if(!verified) { + + } + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + // From sendAToSRPServer or from sendM1ToSRPServer + e.printStackTrace(); + } catch (CryptoException e) { + // TODO Auto-generated catch block + // From calculateSecret + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + // From MessageDigest.getInstance + e.printStackTrace(); + } } } + + private void sendM1(BigInteger m2, BigInteger k, BigInteger clientA, + BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { + BigInteger M1 = generateM1(k, clientA, serverB, salt, username); + + } - private String getSaltFromSRPServer() { - // TODO Auto-generated method stub - return null; + private BigInteger generateM1(BigInteger K, BigInteger clientA, BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { + /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js + var hashN = SHA256(hex2a(N.toString(16))) + var hashG = SHA256(hex2a(g.toString(16))) + var hexString = hexXor(hashN, hashG); + hexString += SHA256(I); + hexString += salt; + hexString += Astr; + hexString += Bstr; + hexString += K + M = SHA256(hex2a(hexString)); + //M2 = H(A, M, K) + M2 = SHA256(hex2a(Astr + M + K)); + */ + MessageDigest digest_of_N = MessageDigest.getInstance("SHA-256"); + digest_of_N.update(ConfigHelper.NG_1024.getBytes()); + String digest_of_N_as_string = new String(digest_of_N.digest()); + + MessageDigest digest_of_G = MessageDigest.getInstance("SHA-256"); + digest_of_G.update(ConfigHelper.g.toByteArray()); + String digest_of_G_as_string = new String(digest_of_G.digest()); + + String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); + + MessageDigest digest_of_username = MessageDigest.getInstance("SHA-256"); + digest_of_username.update(username.getBytes()); + String digest_of_username_as_string = new String(digest_of_username.digest()); + + MessageDigest my_M1 = MessageDigest.getInstance("SHA-256"); + String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString() + serverB.toString() + K.toString(); + + my_M1.update(m1_source_string.getBytes()); + + return new BigInteger(my_M1.digest()); + } + + private boolean verifyM2(BigInteger M2, BigInteger K, BigInteger clientA, BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { + /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js + var hashN = SHA256(hex2a(N.toString(16))) + var hashG = SHA256(hex2a(g.toString(16))) + var hexString = hexXor(hashN, hashG); + hexString += SHA256(I); + hexString += salt; + hexString += Astr; + hexString += Bstr; + hexString += K + M = SHA256(hex2a(hexString)); + //M2 = H(A, M, K) + M2 = SHA256(hex2a(Astr + M + K)); + */ + MessageDigest digest_of_N = MessageDigest.getInstance("SHA-256"); + digest_of_N.update(ConfigHelper.NG_1024.getBytes()); + String digest_of_N_as_string = new String(digest_of_N.digest()); + + MessageDigest digest_of_G = MessageDigest.getInstance("SHA-256"); + digest_of_G.update(ConfigHelper.g.toByteArray()); + String digest_of_G_as_string = new String(digest_of_G.digest()); + + String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); + + MessageDigest digest_of_username = MessageDigest.getInstance("SHA-256"); + digest_of_username.update(username.getBytes()); + String digest_of_username_as_string = new String(digest_of_username.digest()); + + MessageDigest my_M1 = MessageDigest.getInstance("SHA-256"); + String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString() + serverB.toString() + K.toString(); + my_M1.update(m1_source_string.getBytes()); + + MessageDigest my_own_M2 = MessageDigest.getInstance("SHA-256"); + String m2_source_string = clientA.toString() + new String(my_M1.digest()) + K.toString(); + + my_own_M2.update(m2_source_string.getBytes()); + + return M2 == new BigInteger(my_own_M2.digest()); + } + + + private String hexXor(String a, String b) { + String str = ""; + for (int i = 0; i < a.length(); i += 2) { + int xor = Integer.parseInt(a.substring(i, 2), 16) ^ Integer.parseInt(b.substring(i, 2), 16); + String xor_string = String.valueOf(Integer.valueOf(String.valueOf(xor), 16)); + str += (xor_string.length() == 1) ? ("0" + xor) : xor_string; + } + return str; + } + + private BigInteger sendParameterToSRPServer(String server_url, String parameter_name, BigInteger parameter) throws ClientProtocolException, IOException { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = parameter_name + "=" + parameter.toString(); + HttpPost post = new HttpPost(server_url + "?" + parameter_chain); + // TODO Look for how our srp server sends the serverB (as a cookie?) and how to fetch it from response. + HttpResponse getResponse = client.execute(post); + HttpEntity responseEntity = getResponse.getEntity(); + List cookies = client.getCookieStore().getCookies(); + return BigInteger.valueOf((Long.valueOf(cookies.get(0).getValue()))); } private String guessURL(String provider_main_url) { -- cgit v1.2.3 From 36a185ef45678ce2a897d7dda1392b0e147ae336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 27 Feb 2013 17:31:26 +0100 Subject: Added bouncycastle lib with libs folder. --- src/se/leap/leapclient/ProviderAPI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 39bb50ec..96544159 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -84,9 +84,9 @@ public class ProviderAPI extends IntentService { } } else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { - String username = (String) task.get(ConfigHelper.username_key); - String password = (String) task.get(ConfigHelper.password_key); - String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + String username = "username";//(String) task.get(ConfigHelper.username_key); + String password = "password";//(String) task.get(ConfigHelper.password_key); + String authentication_server = "localhost:3000";//(String) task.get(ConfigHelper.srp_server_url_key); SRP6Client srp_client = new SRP6Client(); srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); // Receive salt from server -- cgit v1.2.3 From 018eb179f820b09d2e65c5ede1d4a867957bbce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 28 Feb 2013 16:56:51 +0100 Subject: Now, ProviderAPI sends result to ConfigurationWizard. Refactored downloadJsonFiles in ProviderAPI, new method from block in the intent identification. --- src/se/leap/leapclient/ProviderAPI.java | 44 +++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 16 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 96544159..19404c2b 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -44,25 +44,14 @@ public class ProviderAPI extends IntentService { @Override protected void onHandleIntent(Intent task_for) { final ResultReceiver receiver = task_for.getParcelableExtra("receiver"); + Bundle task; System.out.println("onHandleIntent called"); if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { - String cert_url = (String) task.get(ConfigHelper.cert_key); - String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); - try { - String cert_string = getStringFromProvider(cert_url); - JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); - ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); - JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); - ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JSONException e) { - ConfigHelper.rescueJSONException(e); - } catch(Exception e) { - e.printStackTrace(); - } + 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; @@ -128,6 +117,29 @@ public class ProviderAPI extends IntentService { } } + private boolean downloadJsonFiles(Bundle task) { + String cert_url = (String) task.get(ConfigHelper.cert_key); + String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); + try { + String cert_string = getStringFromProvider(cert_url); + JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); + ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); + ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); + return true; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (JSONException e) { + ConfigHelper.rescueJSONException(e); + return false; + } catch(Exception e) { + e.printStackTrace(); + return false; + } + } + private void sendM1(BigInteger m2, BigInteger k, BigInteger clientA, BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { BigInteger M1 = generateM1(k, clientA, serverB, salt, username); -- cgit v1.2.3 From 5b9e20dca5f70289a2fcdfaa9f45fabd28887726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 5 Mar 2013 21:13:27 +0100 Subject: Registering method from ProviderAPI implemented and tested. M1 is not OK, because errors (with null description, awkward) are received from posting M1 to the server instead of M2. Next step: purge user database from leap_webapp and start testing again. --- src/se/leap/leapclient/ProviderAPI.java | 261 +++++++++++++++++++++++--------- 1 file changed, 187 insertions(+), 74 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 19404c2b..41612d16 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -12,6 +12,7 @@ import java.util.Scanner; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.agreement.srp.SRP6Client; +import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.prng.RandomGenerator; import org.bouncycastle.jcajce.provider.digest.Whirlpool.Digest; @@ -29,6 +30,7 @@ import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.IntentService; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; @@ -38,7 +40,6 @@ public class ProviderAPI extends IntentService { public ProviderAPI() { super("ProviderAPI"); Log.v("ClassName", "Provider API"); - // TODO Auto-generated constructor stub } @Override @@ -72,51 +73,20 @@ public class ProviderAPI extends IntentService { 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) { - String username = "username";//(String) task.get(ConfigHelper.username_key); - String password = "password";//(String) task.get(ConfigHelper.password_key); - String authentication_server = "localhost:3000";//(String) task.get(ConfigHelper.srp_server_url_key); - SRP6Client srp_client = new SRP6Client(); - srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); - // Receive salt from server - Random random_number_generator = new Random(); - int salt = random_number_generator.nextInt(Integer.valueOf(ConfigHelper.NG_1024)); - byte[] salt_in_bytes = ByteBuffer.allocate(4).putInt(salt).array(); - BigInteger clientA = srp_client.generateClientCredentials(salt_in_bytes, username.getBytes(), password.getBytes()); - //Send A to the server. Doing a http response with cookies? - //Receive server generated serverB - try { - BigInteger serverB = sendParameterToSRPServer(authentication_server, "A", clientA); - BigInteger s = srp_client.calculateSecret(serverB); - MessageDigest digest_of_S = MessageDigest.getInstance("SHA-256"); - digest_of_S.update(s.toByteArray(), 0, s.toByteArray().length); - BigInteger k = new BigInteger(digest_of_S.digest()); - BigInteger m1 = generateM1(k, clientA, serverB, salt, username); - BigInteger m2 = sendParameterToSRPServer(authentication_server, "M1", m1); - sendM1(m2, k, clientA, serverB, salt, username); - boolean verified = verifyM2(m2, k, clientA, serverB, salt, username); - if(!verified) { - - } - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - // From sendAToSRPServer or from sendM1ToSRPServer - e.printStackTrace(); - } catch (CryptoException e) { - // TODO Auto-generated catch block - // From calculateSecret - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - // From MessageDigest.getInstance - e.printStackTrace(); - } + if(!authenticateBySRP(task)) + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + else + receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, Bundle.EMPTY); } } - + private boolean downloadJsonFiles(Bundle task) { String cert_url = (String) task.get(ConfigHelper.cert_key); String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); @@ -140,13 +110,115 @@ public class ProviderAPI extends IntentService { } } - private void sendM1(BigInteger m2, BigInteger k, BigInteger clientA, - BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { - BigInteger M1 = generateM1(k, clientA, serverB, salt, username); + private boolean registerWithSRP(Bundle task) { + String username = (String) task.get(ConfigHelper.username_key); + String password = (String) task.get(ConfigHelper.password_key); + String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + + BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); + BigInteger salt = ng_1024.probablePrime(1024, null); + byte[] salt_in_bytes = salt.toByteArray(); + SRP6VerifierGenerator verifier_generator = new SRP6VerifierGenerator(); + verifier_generator.init(ng_1024, ConfigHelper.g, new SHA256Digest()); + BigInteger verifier = verifier_generator.generateVerifier(salt_in_bytes, username.getBytes(), password.getBytes()); + + return sendRegisterMessage(authentication_server, salt.toString(16), verifier.toString(), username); } + + private boolean sendRegisterMessage(String server_url, String password_salt, String password_verifier, String login) { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = "user[password_salt]" + "=" + password_salt + "&" + "user[password_verifier]" + "=" + password_verifier + "&" + "user[login]" + "=" + login; + HttpPost post = new HttpPost(server_url + "/users.json" + "?" + parameter_chain); - private BigInteger generateM1(BigInteger K, BigInteger clientA, BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { + HttpResponse getResponse; + try { + getResponse = client.execute(post); + HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.getString("errors").isEmpty()) { + return false; + } + else if(json_response.getString("password_salt").equalsIgnoreCase(password_salt) && json_response.getString("login").equalsIgnoreCase(login)) + return true; + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + + return false; + } + + private boolean authenticateBySRP(Bundle task) { + String username = (String) task.get(ConfigHelper.username_key); + String password = (String) task.get(ConfigHelper.password_key); + String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + SRP6Client srp_client = new SRP6Client(); + srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); + // Receive salt from server + Random random_number_generator = new Random(); + BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); + byte[] salt_in_bytes = ng_1024.probablePrime(1024, null).toByteArray(); + //int salt = random_number_generator.nextInt(Integer.parseInt(ConfigHelper.NG_1024, 16)); + //byte[] salt_in_bytes = ByteBuffer.allocate(4).putInt(salt).array(); + BigInteger clientA = srp_client.generateClientCredentials(salt_in_bytes, username.getBytes(), password.getBytes()); + //Send A to the server. Doing a http response with cookies? + //Receive server generated serverB + try { + BigInteger serverB = sendAToSRPServer(authentication_server, username, clientA); + if(serverB == BigInteger.ZERO) + return false; // TODO Show error: error trying to start authentication with provider + BigInteger s = srp_client.calculateSecret(serverB); + MessageDigest digest_of_S = MessageDigest.getInstance("SHA-256"); + digest_of_S.update(s.toByteArray(), 0, s.toByteArray().length); + BigInteger k = new BigInteger(digest_of_S.digest()); + BigInteger m1 = generateM1(k, clientA, serverB, username); + BigInteger m2 = sendM1ToSRPServer(authentication_server, "M1", m1); + if(m2 == BigInteger.ZERO) + return false; // TODO Show error: error in M1 + boolean verified = verifyM2(m2, k, clientA, serverB, username); + return verified; // TODO If false, Username or password are not correct -> Show a warning and get back to login fragment + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (IOException e) { + // TODO Auto-generated catch block + // From sendAToSRPServer or from sendM1ToSRPServer + e.printStackTrace(); + return false; + } catch (CryptoException e) { + // TODO Auto-generated catch block + // From calculateSecret + e.printStackTrace(); + return false; + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + // From MessageDigest.getInstance + e.printStackTrace(); + return false; + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + } + + private BigInteger generateM1(BigInteger K, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js var hashN = SHA256(hex2a(N.toString(16))) var hashG = SHA256(hex2a(g.toString(16))) @@ -160,29 +232,21 @@ public class ProviderAPI extends IntentService { //M2 = H(A, M, K) M2 = SHA256(hex2a(Astr + M + K)); */ - MessageDigest digest_of_N = MessageDigest.getInstance("SHA-256"); - digest_of_N.update(ConfigHelper.NG_1024.getBytes()); - String digest_of_N_as_string = new String(digest_of_N.digest()); + String digest_of_N_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(ConfigHelper.NG_1024.getBytes())).toString(16); - MessageDigest digest_of_G = MessageDigest.getInstance("SHA-256"); - digest_of_G.update(ConfigHelper.g.toByteArray()); - String digest_of_G_as_string = new String(digest_of_G.digest()); + String digest_of_G_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toString(16).getBytes())).toString(16); + //String digest_of_G_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toByteArray())).toString(16); String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); - MessageDigest digest_of_username = MessageDigest.getInstance("SHA-256"); - digest_of_username.update(username.getBytes()); - String digest_of_username_as_string = new String(digest_of_username.digest()); + String digest_of_username_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(username.getBytes())).toString(16); - MessageDigest my_M1 = MessageDigest.getInstance("SHA-256"); - String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString() + serverB.toString() + K.toString(); + String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString(16) + serverB.toString(16) + K.toString(16); - my_M1.update(m1_source_string.getBytes()); - - return new BigInteger(my_M1.digest()); + return new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(m1_source_string.getBytes())); } - private boolean verifyM2(BigInteger M2, BigInteger K, BigInteger clientA, BigInteger serverB, int salt, String username) throws NoSuchAlgorithmException { + private boolean verifyM2(BigInteger M2, BigInteger K, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js var hashN = SHA256(hex2a(N.toString(16))) var hashG = SHA256(hex2a(g.toString(16))) @@ -198,50 +262,99 @@ public class ProviderAPI extends IntentService { */ MessageDigest digest_of_N = MessageDigest.getInstance("SHA-256"); digest_of_N.update(ConfigHelper.NG_1024.getBytes()); - String digest_of_N_as_string = new String(digest_of_N.digest()); + String digest_of_N_as_string = new BigInteger(digest_of_N.digest()).toString(); MessageDigest digest_of_G = MessageDigest.getInstance("SHA-256"); digest_of_G.update(ConfigHelper.g.toByteArray()); - String digest_of_G_as_string = new String(digest_of_G.digest()); + String digest_of_G_as_string = new BigInteger(digest_of_G.digest()).toString(); String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); MessageDigest digest_of_username = MessageDigest.getInstance("SHA-256"); digest_of_username.update(username.getBytes()); - String digest_of_username_as_string = new String(digest_of_username.digest()); + String digest_of_username_as_string = new BigInteger(digest_of_username.digest()).toString(); MessageDigest my_M1 = MessageDigest.getInstance("SHA-256"); String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString() + serverB.toString() + K.toString(); my_M1.update(m1_source_string.getBytes()); MessageDigest my_own_M2 = MessageDigest.getInstance("SHA-256"); - String m2_source_string = clientA.toString() + new String(my_M1.digest()) + K.toString(); + String m2_source_string = clientA.toString() + new BigInteger(my_M1.digest()).toString() + K.toString(); my_own_M2.update(m2_source_string.getBytes()); return M2 == new BigInteger(my_own_M2.digest()); } - - private String hexXor(String a, String b) { + private String hexXor(String a, String b) { String str = ""; for (int i = 0; i < a.length(); i += 2) { - int xor = Integer.parseInt(a.substring(i, 2), 16) ^ Integer.parseInt(b.substring(i, 2), 16); + int xor = Integer.parseInt(a.substring(i, 2 + i), 16) ^ Integer.parseInt(b.substring(i, 2 + i), 16); String xor_string = String.valueOf(Integer.valueOf(String.valueOf(xor), 16)); str += (xor_string.length() == 1) ? ("0" + xor) : xor_string; } - return str; + return stringToHex(str); } + + private String stringToHex(String base) + { + StringBuffer buffer = new StringBuffer(); + int intValue; + for(int x = 0; x < base.length(); x++) + { + int cursor = 0; + intValue = base.charAt(x); + String binaryChar = new String(Integer.toBinaryString(base.charAt(x))); + for(int i = 0; i < binaryChar.length(); i++) + { + if(binaryChar.charAt(i) == '1') + { + cursor += 1; + } + } + if((cursor % 2) > 0) + { + intValue += 128; + } + buffer.append(Integer.toHexString(intValue) + ""); + } + return buffer.toString().toUpperCase(); +} - private BigInteger sendParameterToSRPServer(String server_url, String parameter_name, BigInteger parameter) throws ClientProtocolException, IOException { + private BigInteger sendAToSRPServer(String server_url, String username, BigInteger clientA) throws ClientProtocolException, IOException, NumberFormatException, JSONException { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = "A" + "=" + clientA.toString() + "&" + "login" + "=" + username; + HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); + + HttpResponse getResponse = client.execute(post); + HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.isNull("errors")) { + return BigInteger.ZERO; + } + List cookies = client.getCookieStore().getCookies(); + if(!cookies.isEmpty()) { + String session_id = cookies.get(0).getValue(); + } + return new BigInteger(json_response.getString("B"), 16); + } + private BigInteger sendM1ToSRPServer(String server_url, String parameter_name, BigInteger parameter) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); String parameter_chain = parameter_name + "=" + parameter.toString(); - HttpPost post = new HttpPost(server_url + "?" + parameter_chain); - // TODO Look for how our srp server sends the serverB (as a cookie?) and how to fetch it from response. + HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); + HttpResponse getResponse = client.execute(post); HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.isNull("errors") || json_response.has("errors")) { + return BigInteger.ZERO; + } + List cookies = client.getCookieStore().getCookies(); - return BigInteger.valueOf((Long.valueOf(cookies.get(0).getValue()))); + String session_id = cookies.get(0).getValue(); + return new BigInteger(json_response.getString("M2"), 16); } private String guessURL(String provider_main_url) { -- cgit v1.2.3 From 34400de64dcf68a451b5a1bf1dbea52a49bb24eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 7 Mar 2013 19:56:23 +0100 Subject: Changed POST by PUT in the sendM1 method. Cleaned some code, pending the M2 one (testing with M1). --- src/se/leap/leapclient/ProviderAPI.java | 110 +++++++++++++++----------------- 1 file changed, 50 insertions(+), 60 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 41612d16..e2af08e3 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -21,6 +21,7 @@ import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; @@ -123,7 +124,7 @@ public class ProviderAPI extends IntentService { verifier_generator.init(ng_1024, ConfigHelper.g, new SHA256Digest()); BigInteger verifier = verifier_generator.generateVerifier(salt_in_bytes, username.getBytes(), password.getBytes()); - return sendRegisterMessage(authentication_server, salt.toString(16), verifier.toString(), username); + return sendRegisterMessage(authentication_server, salt.toString(16), verifier.toString(16), username); } private boolean sendRegisterMessage(String server_url, String password_salt, String password_verifier, String login) { @@ -137,10 +138,11 @@ public class ProviderAPI extends IntentService { HttpEntity responseEntity = getResponse.getEntity(); String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); - if(!json_response.getString("errors").isEmpty()) { + if(!json_response.isNull("errors") || json_response.has("errors")) { return false; } - else if(json_response.getString("password_salt").equalsIgnoreCase(password_salt) && json_response.getString("login").equalsIgnoreCase(login)) + //else if(json_response.getString("password_salt").equalsIgnoreCase(password_salt) && json_response.getString("login").equalsIgnoreCase(login)) + else if(json_response.getBoolean("ok") && json_response.getString("login").equalsIgnoreCase(login)) return true; } catch (ClientProtocolException e) { // TODO Auto-generated catch block @@ -163,30 +165,31 @@ public class ProviderAPI extends IntentService { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + SRP6Client srp_client = new SRP6Client(); - srp_client.init(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g, new SHA256Digest(), new SecureRandom()); - // Receive salt from server - Random random_number_generator = new Random(); - BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); - byte[] salt_in_bytes = ng_1024.probablePrime(1024, null).toByteArray(); - //int salt = random_number_generator.nextInt(Integer.parseInt(ConfigHelper.NG_1024, 16)); - //byte[] salt_in_bytes = ByteBuffer.allocate(4).putInt(salt).array(); - BigInteger clientA = srp_client.generateClientCredentials(salt_in_bytes, username.getBytes(), password.getBytes()); - //Send A to the server. Doing a http response with cookies? - //Receive server generated serverB + BigInteger n = new BigInteger(ConfigHelper.NG_1024, 16); + srp_client.init(n, ConfigHelper.g, new SHA256Digest(), new SecureRandom()); + + BigInteger salt = BigInteger.probablePrime(1024, null); + BigInteger clientA = srp_client.generateClientCredentials(salt.toByteArray(), username.getBytes(), password.getBytes()); try { BigInteger serverB = sendAToSRPServer(authentication_server, username, clientA); if(serverB == BigInteger.ZERO) return false; // TODO Show error: error trying to start authentication with provider + BigInteger s = srp_client.calculateSecret(serverB); - MessageDigest digest_of_S = MessageDigest.getInstance("SHA-256"); - digest_of_S.update(s.toByteArray(), 0, s.toByteArray().length); - BigInteger k = new BigInteger(digest_of_S.digest()); - BigInteger m1 = generateM1(k, clientA, serverB, username); - BigInteger m2 = sendM1ToSRPServer(authentication_server, "M1", m1); + + BigInteger k = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(s.toByteArray())); + + BigInteger m1 = generateM1(k, salt, clientA, serverB, username); + + BigInteger m2 = sendM1ToSRPServer(authentication_server, username, m1); + if(m2 == BigInteger.ZERO) return false; // TODO Show error: error in M1 + boolean verified = verifyM2(m2, k, clientA, serverB, username); + return verified; // TODO If false, Username or password are not correct -> Show a warning and get back to login fragment } catch (ClientProtocolException e) { // TODO Auto-generated catch block @@ -218,30 +221,35 @@ public class ProviderAPI extends IntentService { } } - private BigInteger generateM1(BigInteger K, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { - /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js - var hashN = SHA256(hex2a(N.toString(16))) - var hashG = SHA256(hex2a(g.toString(16))) - var hexString = hexXor(hashN, hashG); - hexString += SHA256(I); - hexString += salt; - hexString += Astr; - hexString += Bstr; - hexString += K - M = SHA256(hex2a(hexString)); - //M2 = H(A, M, K) - M2 = SHA256(hex2a(Astr + M + K)); - */ + private BigInteger sendAToSRPServer(String server_url, String username, BigInteger clientA) throws ClientProtocolException, IOException, NumberFormatException, JSONException { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = "A" + "=" + clientA.toString(16) + "&" + "login" + "=" + username; + HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); + + HttpResponse getResponse = client.execute(post); + HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.isNull("errors") || json_response.has("errors")) { + return BigInteger.ZERO; + } + List cookies = client.getCookieStore().getCookies(); + if(!cookies.isEmpty()) { + String session_id = cookies.get(0).getValue(); + } + return new BigInteger(json_response.getString("B"), 16); + } + + public BigInteger generateM1(BigInteger K, BigInteger salt, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { String digest_of_N_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(ConfigHelper.NG_1024.getBytes())).toString(16); - + String digest_of_G_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toString(16).getBytes())).toString(16); - //String digest_of_G_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toByteArray())).toString(16); - + String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); - + String digest_of_username_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(username.getBytes())).toString(16); - String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString(16) + serverB.toString(16) + K.toString(16); + String m1_source_string = xor_n_and_g + digest_of_username_as_string + salt.toString(16) + clientA.toString(16) + serverB.toString(16) + K.toString(16); return new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(m1_source_string.getBytes())); } @@ -318,33 +326,15 @@ public class ProviderAPI extends IntentService { } buffer.append(Integer.toHexString(intValue) + ""); } - return buffer.toString().toUpperCase(); + return buffer.toString(); } - private BigInteger sendAToSRPServer(String server_url, String username, BigInteger clientA) throws ClientProtocolException, IOException, NumberFormatException, JSONException { + private BigInteger sendM1ToSRPServer(String server_url, String username, BigInteger m1) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "A" + "=" + clientA.toString() + "&" + "login" + "=" + username; - HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); - - HttpResponse getResponse = client.execute(post); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors")) { - return BigInteger.ZERO; - } - List cookies = client.getCookieStore().getCookies(); - if(!cookies.isEmpty()) { - String session_id = cookies.get(0).getValue(); - } - return new BigInteger(json_response.getString("B"), 16); - } - private BigInteger sendM1ToSRPServer(String server_url, String parameter_name, BigInteger parameter) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = parameter_name + "=" + parameter.toString(); - HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); + String parameter_chain = "client_auth" + "=" + m1.toString(16); + HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); - HttpResponse getResponse = client.execute(post); + HttpResponse getResponse = client.execute(put); HttpEntity responseEntity = getResponse.getEntity(); String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); -- cgit v1.2.3 From 86856f497377aa0c9b39551a2df013b915be21ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 12 Mar 2013 18:23:11 +0100 Subject: Gonna try jboss srp implementation, because if I implement myself one we will have to audit it. --- src/se/leap/leapclient/ProviderAPI.java | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index e2af08e3..591bdc9f 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -171,9 +171,12 @@ public class ProviderAPI extends IntentService { srp_client.init(n, ConfigHelper.g, new SHA256Digest(), new SecureRandom()); BigInteger salt = BigInteger.probablePrime(1024, null); - BigInteger clientA = srp_client.generateClientCredentials(salt.toByteArray(), username.getBytes(), password.getBytes()); + + BigInteger clientA = srp_client.generateClientCredentials(salt.toString(16).getBytes(), username.getBytes(), password.getBytes()); + try { BigInteger serverB = sendAToSRPServer(authentication_server, username, clientA); + if(serverB == BigInteger.ZERO) return false; // TODO Show error: error trying to start authentication with provider @@ -241,7 +244,7 @@ public class ProviderAPI extends IntentService { } public BigInteger generateM1(BigInteger K, BigInteger salt, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { - String digest_of_N_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(ConfigHelper.NG_1024.getBytes())).toString(16); + String digest_of_N_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(hex2ascii(ConfigHelper.NG_1024).getBytes())).toString(16); String digest_of_G_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toString(16).getBytes())).toString(16); @@ -297,7 +300,11 @@ public class ProviderAPI extends IntentService { private String hexXor(String a, String b) { String str = ""; for (int i = 0; i < a.length(); i += 2) { - int xor = Integer.parseInt(a.substring(i, 2 + i), 16) ^ Integer.parseInt(b.substring(i, 2 + i), 16); + int xor = 0; + if(a.length() > i + 2) + xor = Integer.parseInt(a.substring(i, 2 + i), 16) ^ Integer.parseInt(b.substring(i, 2 + i), 16); + else + xor = Integer.parseInt(a.substring(i, 1 + i), 16) ^ Integer.parseInt(b.substring(i, 1 + i), 16); String xor_string = String.valueOf(Integer.valueOf(String.valueOf(xor), 16)); str += (xor_string.length() == 1) ? ("0" + xor) : xor_string; } @@ -328,6 +335,16 @@ public class ProviderAPI extends IntentService { } return buffer.toString(); } + + private String hex2ascii(String hex) { + StringBuilder output = new StringBuilder(); + for (int i = 0; i < hex.length(); i+=2) { + String str = hex.substring(i, i+2); + output.append((char)Integer.parseInt(str, 16)); + } + String debug = output.toString(); + return output.toString(); + } private BigInteger sendM1ToSRPServer(String server_url, String username, BigInteger m1) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); -- cgit v1.2.3 From 49747e858649fa7ed68e4a038d5602ec2bae6df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 12 Mar 2013 19:14:10 +0100 Subject: Error using CryptoUtil.calculatePasswordHash. Going to hit some bugs before continuing with this work. --- src/se/leap/leapclient/ProviderAPI.java | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 591bdc9f..b20e30b1 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -24,6 +24,9 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; +import org.jboss.security.srp.SRPClientSession; +import org.jboss.security.srp.SRPConf.SRPParams; +import org.jboss.security.srp.SRPParameters; import org.json.JSONException; import org.json.JSONObject; @@ -166,6 +169,30 @@ public class ProviderAPI extends IntentService { String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + SRPParameters params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), null); + SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); + byte[] A = client.exponential(); + try { + byte[] B = sendAToSRPServer(authentication_server, username, A); + byte[] M1 = client.response(B); + byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); + if( client.verify(M2) == false ) + throw new SecurityException("Failed to validate server reply"); + return true; + } catch (ClientProtocolException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (JSONException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + SRP6Client srp_client = new SRP6Client(); BigInteger n = new BigInteger(ConfigHelper.NG_1024, 16); srp_client.init(n, ConfigHelper.g, new SHA256Digest(), new SecureRandom()); @@ -242,6 +269,25 @@ public class ProviderAPI extends IntentService { } return new BigInteger(json_response.getString("B"), 16); } + + private byte[] sendAToSRPServer(String server_url, String username, byte[] clientA) throws ClientProtocolException, IOException, JSONException { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = "A" + "=" + new String(clientA) + "&" + "login" + "=" + username; + HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); + + HttpResponse getResponse = client.execute(post); + HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.isNull("errors") || json_response.has("errors")) { + return new byte[0]; + } + List cookies = client.getCookieStore().getCookies(); + if(!cookies.isEmpty()) { + String session_id = cookies.get(0).getValue(); + } + return json_response.getString("B").getBytes(); + } public BigInteger generateM1(BigInteger K, BigInteger salt, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { String digest_of_N_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(hex2ascii(ConfigHelper.NG_1024).getBytes())).toString(16); @@ -364,6 +410,25 @@ public class ProviderAPI extends IntentService { return new BigInteger(json_response.getString("M2"), 16); } + private byte[] sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + String parameter_chain = "client_auth" + "=" + new String(m1); + HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); + + HttpResponse getResponse = client.execute(put); + HttpEntity responseEntity = getResponse.getEntity(); + String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + JSONObject json_response = new JSONObject(plain_response); + if(!json_response.isNull("errors") || json_response.has("errors")) { + return new byte[0]; + } + + List cookies = client.getCookieStore().getCookies(); + String session_id = cookies.get(0).getValue(); + + return json_response.getString("M2").getBytes(); + } + private String guessURL(String provider_main_url) { return provider_main_url + "/provider.json"; } -- cgit v1.2.3 From 929fa9a3b7621e0a956ed8d7beffb87ed7f16249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 13 Mar 2013 21:01:53 +0100 Subject: ConfigurationWizard sets provider.json correctly for Dashboard once a custom provider is selected. Tested using https://bitmask.net as url for custom provider. --- src/se/leap/leapclient/ProviderAPI.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 583eea06..1dc7c9f6 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -32,21 +32,28 @@ public class ProviderAPI extends IntentService { Bundle task; System.out.println("onHandleIntent called"); if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { + 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); JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); + receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } catch (JSONException e) { ConfigHelper.rescueJSONException(e); + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } catch(Exception e) { e.printStackTrace(); + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } } else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { @@ -58,6 +65,7 @@ public class ProviderAPI extends IntentService { 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) { -- cgit v1.2.3 From 203c8caca5a305b90fd0e69c965e503afe979354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 14 Mar 2013 19:53:31 +0100 Subject: After downloading provider.json successfully, ConfigurationWizard now can download eip-service.json and ca.crt without having the latter as a predefined trusted certificate. It does not ask anything about trusting the new certificate as far as selecting a custom provider means that the user trusts that url. Next step: make provider.json also downloadable from https address using ca.cert not trusted. --- src/se/leap/leapclient/ProviderAPI.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 1dc7c9f6..01cbd01c 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,6 +1,9 @@ package se.leap.leapclient; import java.io.IOException; +import java.net.URL; +import java.security.Provider; +import java.security.Security; import java.util.Scanner; import org.apache.http.HttpEntity; @@ -38,14 +41,18 @@ public class ProviderAPI extends IntentService { try { JSONObject provider_json = new JSONObject("{ \"provider\" : \"" + provider_name + "\"}"); ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - String cert_string = getStringFromProvider(cert_url); + + /*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); receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } catch (IOException e) { - // TODO Auto-generated catch block + // TODO It could happen that an https site used a certificate not trusted. e.printStackTrace(); receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } catch (JSONException e) { @@ -69,7 +76,7 @@ public class ProviderAPI extends IntentService { 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 + // TODO It could happen that an https site used a certificate not trusted. e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block -- cgit v1.2.3 From f4f454d53b881563d82f392545fb17ef9283c5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 18 Mar 2013 11:13:54 +0100 Subject: If ca.crt from new provider is not trusted, we can download it without problems assuming user wanted to trust it since s/he entered by him/herself the URL. Next step: refactor a bit, to make code more beautiful. --- src/se/leap/leapclient/ProviderAPI.java | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 01cbd01c..db5301e9 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,6 +1,7 @@ package se.leap.leapclient; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.security.Provider; import java.security.Security; @@ -68,20 +69,36 @@ public class ProviderAPI extends IntentService { 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 { - 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); + provider_json = getJSONFromProvider(provider_json_url); } catch (IOException e) { // TODO It could happen that an https site used a certificate not trusted. + 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) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (JSONException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + e.printStackTrace(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } + 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); } } -- cgit v1.2.3 From 1fcb255170a2be35eecc5645a7b1757101b844f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 18 Mar 2013 12:00:47 +0100 Subject: Refactored ProviderAPI code. ConfigurationWizard works without problem for both new and preseeded providers. I've added flow control for the activity to finish when all files have been downloaded, managing errors with setResult(RESULT_CANCELED). --- src/se/leap/leapclient/ProviderAPI.java | 135 ++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 57 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index db5301e9..afbf1c01 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -34,72 +34,93 @@ public class ProviderAPI extends IntentService { protected void onHandleIntent(Intent task_for) { final ResultReceiver receiver = task_for.getParcelableExtra("receiver"); Bundle task; - System.out.println("onHandleIntent called"); if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { - 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); + if(downloadJsonFilesBundleExtra(task)) receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } catch (IOException e) { - // TODO It could happen that an https site used a certificate not trusted. - e.printStackTrace(); + else receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } catch (JSONException e) { - ConfigHelper.rescueJSONException(e); - receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - } catch(Exception e) { - e.printStackTrace(); - receiver.send(ConfigHelper.INCORRECTLY_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); - JSONObject provider_json = null; - try { - provider_json = getJSONFromProvider(provider_json_url); - } catch (IOException e) { - // TODO It could happen that an https site used a certificate not trusted. - 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) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - - e.printStackTrace(); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + if(downloadNewProviderDotJSON(task)) + receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); + else + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } + } + + 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); - ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom)); - receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); + /*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) { -- cgit v1.2.3 From 57ab546646e3e2814be547dd4666ca2de4548597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 19 Mar 2013 16:29:09 +0100 Subject: Trying to find a jar from JBoss to use their SRP implementation. Imports errors because of classes not yet found. --- src/se/leap/leapclient/ProviderAPI.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index b20e30b1..eb3afcfa 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -24,9 +24,6 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; -import org.jboss.security.srp.SRPClientSession; -import org.jboss.security.srp.SRPConf.SRPParams; -import org.jboss.security.srp.SRPParameters; import org.json.JSONException; import org.json.JSONObject; -- cgit v1.2.3 From 54ad71d09d6cb61fad62d1376cd7b3bf237e16f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 29 Mar 2013 16:30:39 +0100 Subject: Tried to implement SRP with JBoss: discarded because it needs RMI to get the salt, and because of our messageflow I cannot obtain it before starting Authentication. That's why on line 132 from ProviderAPI I tried to get a new SRPClientSession using the newly obtained salt, but of course it fails since A cannot be restored from previous initialization. Next step: try with srpforjava. Next next step: if srpforjava does not work for us, use lower level methods to implement our own http srp flow. --- src/se/leap/leapclient/ProviderAPI.java | 270 +++++--------------------------- 1 file changed, 35 insertions(+), 235 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index eb3afcfa..aa1ce305 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -2,20 +2,11 @@ package se.leap.leapclient; import java.io.IOException; import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; +import java.util.ArrayList; import java.util.List; -import java.util.Random; import java.util.Scanner; -import org.bouncycastle.crypto.CryptoException; -import org.bouncycastle.crypto.agreement.srp.SRP6Client; -import org.bouncycastle.crypto.agreement.srp.SRP6VerifierGenerator; -import org.bouncycastle.crypto.digests.SHA256Digest; -import org.bouncycastle.crypto.prng.RandomGenerator; -import org.bouncycastle.jcajce.provider.digest.Whirlpool.Digest; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; @@ -24,6 +15,9 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; +import org.jboss.security.srp.SRPClientSession; +import org.jboss.security.srp.SRPParameters; +import org.jboss.security.srp.SRPServerInterface; import org.json.JSONException; import org.json.JSONObject; @@ -31,7 +25,6 @@ import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.IntentService; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.os.ResultReceiver; import android.util.Log; @@ -120,44 +113,6 @@ public class ProviderAPI extends IntentService { BigInteger salt = ng_1024.probablePrime(1024, null); byte[] salt_in_bytes = salt.toByteArray(); - SRP6VerifierGenerator verifier_generator = new SRP6VerifierGenerator(); - verifier_generator.init(ng_1024, ConfigHelper.g, new SHA256Digest()); - BigInteger verifier = verifier_generator.generateVerifier(salt_in_bytes, username.getBytes(), password.getBytes()); - - return sendRegisterMessage(authentication_server, salt.toString(16), verifier.toString(16), username); - } - - private boolean sendRegisterMessage(String server_url, String password_salt, String password_verifier, String login) { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "user[password_salt]" + "=" + password_salt + "&" + "user[password_verifier]" + "=" + password_verifier + "&" + "user[login]" + "=" + login; - HttpPost post = new HttpPost(server_url + "/users.json" + "?" + parameter_chain); - - HttpResponse getResponse; - try { - getResponse = client.execute(post); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors") || json_response.has("errors")) { - return false; - } - //else if(json_response.getString("password_salt").equalsIgnoreCase(password_salt) && json_response.getString("login").equalsIgnoreCase(login)) - else if(json_response.getBoolean("ok") && json_response.getString("login").equalsIgnoreCase(login)) - return true; - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } - return false; } @@ -165,12 +120,17 @@ public class ProviderAPI extends IntentService { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); - - SRPParameters params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), null); + + SRPParameters params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), "salt".getBytes(), "SHA-256"); SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); byte[] A = client.exponential(); try { - byte[] B = sendAToSRPServer(authentication_server, username, A); + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, getHexString(A)); + byte[] B = saltAndB.getString("B").getBytes(); + String salt = saltAndB.getString("salt"); + params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), salt.getBytes(), "SHA-256"); + client = new SRPClientSession(username, password.toCharArray(), params); + client.exponential(); byte[] M1 = client.response(B); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify(M2) == false ) @@ -179,78 +139,39 @@ public class ProviderAPI extends IntentService { } catch (ClientProtocolException e1) { // TODO Auto-generated catch block e1.printStackTrace(); + return false; } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); + return false; } catch (JSONException e1) { // TODO Auto-generated catch block e1.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - SRP6Client srp_client = new SRP6Client(); - BigInteger n = new BigInteger(ConfigHelper.NG_1024, 16); - srp_client.init(n, ConfigHelper.g, new SHA256Digest(), new SecureRandom()); - - BigInteger salt = BigInteger.probablePrime(1024, null); - - BigInteger clientA = srp_client.generateClientCredentials(salt.toString(16).getBytes(), username.getBytes(), password.getBytes()); - - try { - BigInteger serverB = sendAToSRPServer(authentication_server, username, clientA); - - if(serverB == BigInteger.ZERO) - return false; // TODO Show error: error trying to start authentication with provider - - BigInteger s = srp_client.calculateSecret(serverB); - - BigInteger k = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(s.toByteArray())); - - BigInteger m1 = generateM1(k, salt, clientA, serverB, username); - - BigInteger m2 = sendM1ToSRPServer(authentication_server, username, m1); - - if(m2 == BigInteger.ZERO) - return false; // TODO Show error: error in M1 - - boolean verified = verifyM2(m2, k, clientA, serverB, username); - - return verified; // TODO If false, Username or password are not correct -> Show a warning and get back to login fragment - } catch (ClientProtocolException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (IOException e) { - // TODO Auto-generated catch block - // From sendAToSRPServer or from sendM1ToSRPServer - e.printStackTrace(); - return false; - } catch (CryptoException e) { - // TODO Auto-generated catch block - // From calculateSecret - e.printStackTrace(); return false; } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - // From MessageDigest.getInstance - e.printStackTrace(); - return false; - } catch (NumberFormatException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; - } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } } + + public static String getHexString(byte[] b) { + String result = ""; + StringBuffer sb = new StringBuffer(); + for (byte tmp : b) { + sb.append(Integer.toHexString((int) (tmp & 0xff))); + } + return sb.toString(); +// for (int i=0; i < b.length; i++) { +// result += +// Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); +// } +// return result; + } - private BigInteger sendAToSRPServer(String server_url, String username, BigInteger clientA) throws ClientProtocolException, IOException, NumberFormatException, JSONException { + private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "A" + "=" + clientA.toString(16) + "&" + "login" + "=" + username; + String parameter_chain = "A" + "=" + clientA + "&" + "login" + "=" + username; HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); HttpResponse getResponse = client.execute(post); @@ -258,18 +179,18 @@ public class ProviderAPI extends IntentService { String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); if(!json_response.isNull("errors") || json_response.has("errors")) { - return BigInteger.ZERO; + return new JSONObject(); } List cookies = client.getCookieStore().getCookies(); if(!cookies.isEmpty()) { String session_id = cookies.get(0).getValue(); } - return new BigInteger(json_response.getString("B"), 16); + return json_response; } - + private byte[] sendAToSRPServer(String server_url, String username, byte[] clientA) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "A" + "=" + new String(clientA) + "&" + "login" + "=" + username; + String parameter_chain = "A" + "=" + getHexString(clientA) + "&" + "login" + "=" + username; HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); HttpResponse getResponse = client.execute(post); @@ -286,130 +207,9 @@ public class ProviderAPI extends IntentService { return json_response.getString("B").getBytes(); } - public BigInteger generateM1(BigInteger K, BigInteger salt, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { - String digest_of_N_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(hex2ascii(ConfigHelper.NG_1024).getBytes())).toString(16); - - String digest_of_G_as_string = new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(ConfigHelper.g.toString(16).getBytes())).toString(16); - - String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); - - String digest_of_username_as_string = new BigInteger(MessageDigest.getInstance("SHA-256").digest(username.getBytes())).toString(16); - - String m1_source_string = xor_n_and_g + digest_of_username_as_string + salt.toString(16) + clientA.toString(16) + serverB.toString(16) + K.toString(16); - - return new BigInteger(1, MessageDigest.getInstance("SHA-256").digest(m1_source_string.getBytes())); - } - - private boolean verifyM2(BigInteger M2, BigInteger K, BigInteger clientA, BigInteger serverB, String username) throws NoSuchAlgorithmException { - /* https://github.com/leapcode/srp_js/blob/master/src/srp_session.js - var hashN = SHA256(hex2a(N.toString(16))) - var hashG = SHA256(hex2a(g.toString(16))) - var hexString = hexXor(hashN, hashG); - hexString += SHA256(I); - hexString += salt; - hexString += Astr; - hexString += Bstr; - hexString += K - M = SHA256(hex2a(hexString)); - //M2 = H(A, M, K) - M2 = SHA256(hex2a(Astr + M + K)); - */ - MessageDigest digest_of_N = MessageDigest.getInstance("SHA-256"); - digest_of_N.update(ConfigHelper.NG_1024.getBytes()); - String digest_of_N_as_string = new BigInteger(digest_of_N.digest()).toString(); - - MessageDigest digest_of_G = MessageDigest.getInstance("SHA-256"); - digest_of_G.update(ConfigHelper.g.toByteArray()); - String digest_of_G_as_string = new BigInteger(digest_of_G.digest()).toString(); - - String xor_n_and_g = hexXor(digest_of_N_as_string, digest_of_G_as_string); - - MessageDigest digest_of_username = MessageDigest.getInstance("SHA-256"); - digest_of_username.update(username.getBytes()); - String digest_of_username_as_string = new BigInteger(digest_of_username.digest()).toString(); - - MessageDigest my_M1 = MessageDigest.getInstance("SHA-256"); - String m1_source_string = xor_n_and_g + digest_of_username_as_string + clientA.toString() + serverB.toString() + K.toString(); - my_M1.update(m1_source_string.getBytes()); - - MessageDigest my_own_M2 = MessageDigest.getInstance("SHA-256"); - String m2_source_string = clientA.toString() + new BigInteger(my_M1.digest()).toString() + K.toString(); - - my_own_M2.update(m2_source_string.getBytes()); - - return M2 == new BigInteger(my_own_M2.digest()); - } - - private String hexXor(String a, String b) { - String str = ""; - for (int i = 0; i < a.length(); i += 2) { - int xor = 0; - if(a.length() > i + 2) - xor = Integer.parseInt(a.substring(i, 2 + i), 16) ^ Integer.parseInt(b.substring(i, 2 + i), 16); - else - xor = Integer.parseInt(a.substring(i, 1 + i), 16) ^ Integer.parseInt(b.substring(i, 1 + i), 16); - String xor_string = String.valueOf(Integer.valueOf(String.valueOf(xor), 16)); - str += (xor_string.length() == 1) ? ("0" + xor) : xor_string; - } - return stringToHex(str); - } - - private String stringToHex(String base) - { - StringBuffer buffer = new StringBuffer(); - int intValue; - for(int x = 0; x < base.length(); x++) - { - int cursor = 0; - intValue = base.charAt(x); - String binaryChar = new String(Integer.toBinaryString(base.charAt(x))); - for(int i = 0; i < binaryChar.length(); i++) - { - if(binaryChar.charAt(i) == '1') - { - cursor += 1; - } - } - if((cursor % 2) > 0) - { - intValue += 128; - } - buffer.append(Integer.toHexString(intValue) + ""); - } - return buffer.toString(); -} - - private String hex2ascii(String hex) { - StringBuilder output = new StringBuilder(); - for (int i = 0; i < hex.length(); i+=2) { - String str = hex.substring(i, i+2); - output.append((char)Integer.parseInt(str, 16)); - } - String debug = output.toString(); - return output.toString(); - } - - private BigInteger sendM1ToSRPServer(String server_url, String username, BigInteger m1) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "client_auth" + "=" + m1.toString(16); - HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); - - HttpResponse getResponse = client.execute(put); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors") || json_response.has("errors")) { - return BigInteger.ZERO; - } - - List cookies = client.getCookieStore().getCookies(); - String session_id = cookies.get(0).getValue(); - return new BigInteger(json_response.getString("M2"), 16); - } - private byte[] sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "client_auth" + "=" + new String(m1); + String parameter_chain = "client_auth" + "=" + getHexString(m1); HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); HttpResponse getResponse = client.execute(put); -- cgit v1.2.3 From 7af9519591ea481718b4f903b97463250cc5f116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 30 Mar 2013 11:20:07 +0100 Subject: Trial for srpforjava: it does not work since it implements SRP-6, and not SRP-6a. That means, for example, that M1 is calculated differently from what we need. --- src/se/leap/leapclient/ProviderAPI.java | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index aa1ce305..b8d6a765 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -15,12 +15,13 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; -import org.jboss.security.srp.SRPClientSession; -import org.jboss.security.srp.SRPParameters; -import org.jboss.security.srp.SRPServerInterface; import org.json.JSONException; import org.json.JSONObject; +import com.jordanzimmerman.SRPClientSession; +import com.jordanzimmerman.SRPConstants; +import com.jordanzimmerman.SRPFactory; + import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.IntentService; @@ -121,20 +122,20 @@ public class ProviderAPI extends IntentService { String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); - SRPParameters params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), "salt".getBytes(), "SHA-256"); - SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); - byte[] A = client.exponential(); + SRPConstants constants = new SRPConstants(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g); + SRPFactory factory = SRPFactory.getInstance(constants); + SRPClientSession session = factory.newClientSession(password.getBytes()); + session.setSalt_s(new BigInteger("1")); + byte[] A = session.getPublicKey_A().toString(16).getBytes(); try { JSONObject saltAndB = sendAToSRPServer(authentication_server, username, getHexString(A)); - byte[] B = saltAndB.getString("B").getBytes(); + String B = saltAndB.getString("B"); String salt = saltAndB.getString("salt"); - params = new SRPParameters(ConfigHelper.NG_1024.getBytes(), "2".getBytes(), salt.getBytes(), "SHA-256"); - client = new SRPClientSession(username, password.toCharArray(), params); - client.exponential(); - byte[] M1 = client.response(B); + session.setSalt_s(new BigInteger(salt, 16)); + session.setServerPublicKey_B(new BigInteger(B, 16)); + byte[] M1 = session.getEvidenceValue_M1().toString(16).getBytes(); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); - if( client.verify(M2) == false ) - throw new SecurityException("Failed to validate server reply"); + session.validateServerEvidenceValue_M2(new BigInteger(getHexString(M2), 16)); return true; } catch (ClientProtocolException e1) { // TODO Auto-generated catch block @@ -148,10 +149,6 @@ public class ProviderAPI extends IntentService { // TODO Auto-generated catch block e1.printStackTrace(); return false; - } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; } } -- cgit v1.2.3 From 3e9a68fcc6c16be69abfa27d5fd3a2cbfc620bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 3 Apr 2013 19:34:40 +0200 Subject: Fixed bug #2146 => A calculation is now fine. Next step: fix M1 calculation, since right now (using tests) response() method is not doing OK. Added new SRPSession modifying response() method from JBoss SRP implementation. Added hosts-for-android-emulator. Use with the following commands to be able to test on api.lvh.me: adb shell mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system adb push ~/workspace/leap_android/hosts-for-android-emulator /system/etc/hosts --- src/se/leap/leapclient/ProviderAPI.java | 99 +++++++++++++-------------------- 1 file changed, 39 insertions(+), 60 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index b8d6a765..ea1410ad 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -3,7 +3,6 @@ package se.leap.leapclient; import java.io.IOException; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; import java.util.List; import java.util.Scanner; @@ -13,15 +12,16 @@ import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.protocol.ClientContext; 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; -import com.jordanzimmerman.SRPClientSession; -import com.jordanzimmerman.SRPConstants; -import com.jordanzimmerman.SRPFactory; - import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.IntentService; @@ -121,22 +121,31 @@ public class ProviderAPI extends IntentService { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + + String salt = "abcd"; - SRPConstants constants = new SRPConstants(new BigInteger(ConfigHelper.NG_1024, 16), ConfigHelper.g); - SRPFactory factory = SRPFactory.getInstance(constants); - SRPClientSession session = factory.newClientSession(password.getBytes()); - session.setSalt_s(new BigInteger("1")); - byte[] A = session.getPublicKey_A().toString(16).getBytes(); + SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); + //SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); + LeapSRPSession client = new LeapSRPSession(username, password.toCharArray(), params); + byte[] A = client.exponential(); try { - JSONObject saltAndB = sendAToSRPServer(authentication_server, username, getHexString(A)); - String B = saltAndB.getString("B"); - String salt = saltAndB.getString("salt"); - session.setSalt_s(new BigInteger(salt, 16)); - session.setServerPublicKey_B(new BigInteger(B, 16)); - byte[] M1 = session.getEvidenceValue_M1().toString(16).getBytes(); - byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); - session.validateServerEvidenceValue_M2(new BigInteger(getHexString(M2), 16)); - return true; + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(A).toString(16)); + if(saltAndB.length() > 0) { + byte[] B = saltAndB.getString("B").getBytes(); + salt = saltAndB.getString("salt"); + params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); + //client = new SRPClientSession(username, password.toCharArray(), params); + client = new LeapSRPSession(username, password.toCharArray(), params); + A = client.exponential(); + saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(A).toString(16)); + String Bhex = saltAndB.getString("B"); + byte[] M1 = client.response(new BigInteger(Bhex, 16).toByteArray()); + byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); + if( client.verify(M2) == false ) + throw new SecurityException("Failed to validate server reply"); + return true; + } + else return false; } catch (ClientProtocolException e1) { // TODO Auto-generated catch block e1.printStackTrace(); @@ -149,25 +158,15 @@ public class ProviderAPI extends IntentService { // TODO Auto-generated catch block e1.printStackTrace(); return false; + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; } } - - public static String getHexString(byte[] b) { - String result = ""; - StringBuffer sb = new StringBuffer(); - for (byte tmp : b) { - sb.append(Integer.toHexString((int) (tmp & 0xff))); - } - return sb.toString(); -// for (int i=0; i < b.length; i++) { -// result += -// Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); -// } -// return result; - } private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); String parameter_chain = "A" + "=" + clientA + "&" + "login" + "=" + username; HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); @@ -185,31 +184,14 @@ public class ProviderAPI extends IntentService { return json_response; } - private byte[] sendAToSRPServer(String server_url, String username, byte[] clientA) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "A" + "=" + getHexString(clientA) + "&" + "login" + "=" + username; - HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); - - HttpResponse getResponse = client.execute(post); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors") || json_response.has("errors")) { - return new byte[0]; - } - List cookies = client.getCookieStore().getCookies(); - if(!cookies.isEmpty()) { - String session_id = cookies.get(0).getValue(); - } - return json_response.getString("B").getBytes(); - } - private byte[] sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - String parameter_chain = "client_auth" + "=" + getHexString(m1); + DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); + String parameter_chain = "client_auth" + "=" + new BigInteger(m1).toString(16); HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); + HttpContext localContext = new BasicHttpContext(); + localContext.setAttribute(ClientContext.COOKIE_STORE, client.getCookieStore()); - HttpResponse getResponse = client.execute(put); + HttpResponse getResponse = client.execute(put, localContext); HttpEntity responseEntity = getResponse.getEntity(); String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); @@ -217,9 +199,6 @@ public class ProviderAPI extends IntentService { return new byte[0]; } - List cookies = client.getCookieStore().getCookies(); - String session_id = cookies.get(0).getValue(); - return json_response.getString("M2").getBytes(); } @@ -231,7 +210,7 @@ public class ProviderAPI extends IntentService { String json_file_content = ""; - DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); HttpGet get = new HttpGet(string_url); // Execute the GET call and obtain the response HttpResponse getResponse = client.execute(get); -- cgit v1.2.3 From c3d73145c746419d23ec1a337b62506c4ef70fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 15 Apr 2013 17:52:19 +0200 Subject: Added one "else if" that I missed during merge. Next step: understand why ca.cert from bitmask is not being downloaded correctly. --- src/se/leap/leapclient/ProviderAPI.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 6b09eb9d..ec131aaa 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -48,6 +48,8 @@ public class ProviderAPI extends IntentService { 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) { if(downloadJsonFilesBundleExtra(task)) receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); else -- cgit v1.2.3 From 418264e2a78371d133b510122f5ac3c9bd940764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 15 Apr 2013 20:20:58 +0200 Subject: Fixed bug 2231. New provider dialog works OK. --- src/se/leap/leapclient/ProviderAPI.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index ec131aaa..07452a44 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -50,7 +50,7 @@ public class ProviderAPI extends IntentService { receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { - if(downloadJsonFilesBundleExtra(task)) + if(downloadNewProviderDotJSON(task)) receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); else receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); @@ -179,7 +179,7 @@ public class ProviderAPI extends IntentService { private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; - String provider_main_url = (String) task.get(ConfigHelper.provider_key_url); + String provider_main_url = (String) task.get(ConfigHelper.provider_main_url); String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); String provider_json_url = guessURL(provider_main_url); JSONObject provider_json = null; @@ -199,6 +199,7 @@ public class ProviderAPI extends IntentService { } else { String filename = provider_name + "_provider.json".replaceFirst("__", "_"); ConfigHelper.saveFile(filename, provider_json.toString()); + ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom)); return true; @@ -206,7 +207,9 @@ public class ProviderAPI extends IntentService { } private boolean downloadJsonFilesBundleExtra(Bundle task) { - String provider_name = (String) task.get(ConfigHelper.provider_key); + //TODO task only contains provider main url -> we need to infer cert_url, provider_name and eip_service_json_url from that. + String provider_main_url = (String) task.get(ConfigHelper.provider_main_url); + String provider_name = ConfigHelper.extractProviderName(provider_main_url); String cert_url = (String) task.get(ConfigHelper.cert_key); String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); try { @@ -223,7 +226,7 @@ public class ProviderAPI extends IntentService { 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 + //TODO It could happen when the url is not valid. e.printStackTrace(); return false; } catch (JSONException e) { -- cgit v1.2.3 From fbfdf86a1df28ccf8f1854c2e2a4c7b3135d50ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 16 Apr 2013 18:14:47 +0200 Subject: Fixed bug #2225 (https://leap.se/code/issues/2225) --- src/se/leap/leapclient/ProviderAPI.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 07452a44..4ffd2762 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -6,6 +6,7 @@ import java.security.NoSuchAlgorithmException; import java.util.List; import java.net.MalformedURLException; import java.net.URL; +import java.net.UnknownHostException; import java.util.Scanner; import org.apache.http.HttpEntity; @@ -247,6 +248,8 @@ public class ProviderAPI extends IntentService { provider_json = new JSONObject(provider_json_string); } catch (MalformedURLException e1) { e1.printStackTrace(); + } catch (UnknownHostException e1) { + e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } catch (JSONException e1) { -- cgit v1.2.3 From 8e47afc7f4f85b80d59d253378681cb85ec54d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 16 Apr 2013 20:12:13 +0200 Subject: Made SRP working with ProviderAPI methods more frequently than not in localhost, but I cannot succeed in api.bitmask.net with my personal account. Next step: add tests from api.bitmask.net. --- src/se/leap/leapclient/ProviderAPI.java | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 4ffd2762..5113ebc1 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -20,6 +20,7 @@ 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.Util; import org.jboss.security.srp.SRPParameters; import org.json.JSONException; import org.json.JSONObject; @@ -56,6 +57,12 @@ public class ProviderAPI extends IntentService { else receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } + else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { + if(authenticateBySRP(task)) + receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, Bundle.EMPTY); + else + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + } } private boolean downloadJsonFiles(Bundle task) { @@ -105,17 +112,16 @@ public class ProviderAPI extends IntentService { LeapSRPSession client = new LeapSRPSession(username, password.toCharArray(), params); byte[] A = client.exponential(); try { - JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(A).toString(16)); + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); if(saltAndB.length() > 0) { byte[] B = saltAndB.getString("B").getBytes(); salt = saltAndB.getString("salt"); params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); - //client = new SRPClientSession(username, password.toCharArray(), params); client = new LeapSRPSession(username, password.toCharArray(), params); A = client.exponential(); - saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(A).toString(16)); - String Bhex = saltAndB.getString("B"); - byte[] M1 = client.response(new BigInteger(Bhex, 16).toByteArray()); + saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); + byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); + byte[] M1 = client.response(Bbytes); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify(M2) == false ) throw new SecurityException("Failed to validate server reply"); @@ -162,7 +168,7 @@ public class ProviderAPI extends IntentService { private byte[] sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - String parameter_chain = "client_auth" + "=" + new BigInteger(m1).toString(16); + String parameter_chain = "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16); HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.COOKIE_STORE, client.getCookieStore()); @@ -175,7 +181,9 @@ public class ProviderAPI extends IntentService { return new byte[0]; } - return json_response.getString("M2").getBytes(); + byte[] M2_not_trimmed = new BigInteger(json_response.getString("M2"), 16).toByteArray(); + return Util.trim(M2_not_trimmed); + //return M2_not_trimmed; } private boolean downloadNewProviderDotJSON(Bundle task) { -- cgit v1.2.3 From f9b9827ec1975cb01e83826f0ad77542e514b21f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 17 Apr 2013 21:17:22 +0200 Subject: This commit contains: - SRP algorithm improved (validate method uses trim, and some other trims have been added). - Refactored calculatePasswordHash, so that it receives a String instead of a char array, and now it is capable of escaping "\" correctly. - A 1000*2 successful logins, with a new test that performs 1000 trials for 2 different username/password/server trios. Next step: think about how the user is going to trigger the log in fragment. --- src/se/leap/leapclient/ProviderAPI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 5113ebc1..55686f70 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -109,7 +109,7 @@ public class ProviderAPI extends IntentService { SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); //SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); - LeapSRPSession client = new LeapSRPSession(username, password.toCharArray(), params); + LeapSRPSession client = new LeapSRPSession(username, password, params); byte[] A = client.exponential(); try { JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); @@ -117,14 +117,14 @@ public class ProviderAPI extends IntentService { byte[] B = saltAndB.getString("B").getBytes(); salt = saltAndB.getString("salt"); params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); - client = new LeapSRPSession(username, password.toCharArray(), params); + client = new LeapSRPSession(username, password, params); A = client.exponential(); saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); byte[] M1 = client.response(Bbytes); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify(M2) == false ) - throw new SecurityException("Failed to validate server reply"); + throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); return true; } else return false; -- cgit v1.2.3 From 5c05094401d6ed3c69ab8f64e47278973bc87425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 18 Apr 2013 21:56:06 +0200 Subject: Coded logout method, and tested. --- src/se/leap/leapclient/ProviderAPI.java | 60 +++++++++++++++------------------ 1 file changed, 28 insertions(+), 32 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 55686f70..d47e3b65 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -12,6 +12,7 @@ import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; @@ -63,6 +64,12 @@ public class ProviderAPI extends IntentService { else receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); } + else if ((task = task_for.getBundleExtra(ConfigHelper.logOut)) != null) { + if(logOut(task)) + receiver.send(ConfigHelper.LOGOUT_SUCCESSFUL, Bundle.EMPTY); + else + receiver.send(ConfigHelper.LOGOUT_FAILED, Bundle.EMPTY); + } } private boolean downloadJsonFiles(Bundle task) { @@ -215,38 +222,6 @@ public class ProviderAPI extends IntentService { } } - private boolean downloadJsonFilesBundleExtra(Bundle task) { - //TODO task only contains provider main url -> we need to infer cert_url, provider_name and eip_service_json_url from that. - String provider_main_url = (String) task.get(ConfigHelper.provider_main_url); - String provider_name = ConfigHelper.extractProviderName(provider_main_url); - 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) { - //TODO It could happen when the url is not valid. - 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; @@ -284,8 +259,29 @@ public class ProviderAPI extends IntentService { return json_file_content; } + private JSONObject getJSONFromProvider(String json_url) throws IOException, JSONException { String json_file_content = getStringFromProvider(json_url); return new JSONObject(json_file_content); } + + private boolean logOut(Bundle task) { + DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); + int session_id_index = 0; + //String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/sessions/" + client.getCookieStore().getCookies().get(0).getValue(); + String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); + HttpDelete delete = new HttpDelete(delete_url); + try { + HttpResponse getResponse = client.execute(delete); + HttpEntity responseEntity = getResponse.getEntity(); + responseEntity.consumeContent(); + } catch (ClientProtocolException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } } -- cgit v1.2.3 From 75728462433b19567710f54a9d4767681b10be95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 22 Apr 2013 18:07:07 +0200 Subject: Coded dialog (now there is a button in the Dashboard), time to test. I need to implement bypass for dev.bitmask.net, because bitmask.net is down. --- src/se/leap/leapclient/ProviderAPI.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index d47e3b65..0b114e38 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -83,7 +83,7 @@ public class ProviderAPI extends IntentService { ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); return true; } catch (IOException e) { - // TODO Auto-generated catch block + // TODO e.printStackTrace(); return false; } catch (JSONException e) { @@ -98,7 +98,7 @@ public class ProviderAPI extends IntentService { private boolean registerWithSRP(Bundle task) { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); - String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + String authentication_server = (String) task.get(ConfigHelper.api_url_key); BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); BigInteger salt = ng_1024.probablePrime(1024, null); @@ -110,7 +110,7 @@ public class ProviderAPI extends IntentService { private boolean authenticateBySRP(Bundle task) { String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); - String authentication_server = (String) task.get(ConfigHelper.srp_server_url_key); + String authentication_server = (String) task.get(ConfigHelper.api_url_key); String salt = "abcd"; @@ -269,7 +269,7 @@ public class ProviderAPI extends IntentService { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); int session_id_index = 0; //String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/sessions/" + client.getCookieStore().getCookies().get(0).getValue(); - String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); + String delete_url = task.getString(ConfigHelper.api_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); HttpDelete delete = new HttpDelete(delete_url); try { HttpResponse getResponse = client.execute(delete); -- cgit v1.2.3 From bfe2263d6b73159a4f929bc7b1fdeb724c88e8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 22 Apr 2013 20:17:43 +0200 Subject: Added danger mode: we can bypass dev.bitmask.net hostname io exception. --- src/se/leap/leapclient/ProviderAPI.java | 50 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 0b114e38..63db18e1 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -9,6 +9,10 @@ import java.net.URL; import java.net.UnknownHostException; import java.util.Scanner; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; @@ -195,6 +199,8 @@ public class ProviderAPI extends IntentService { private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; + boolean danger_on = ((Boolean)task.get(ConfigHelper.danger_on)).booleanValue(); + String provider_main_url = (String) task.get(ConfigHelper.provider_main_url); String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); String provider_json_url = guessURL(provider_main_url); @@ -203,7 +209,7 @@ public class ProviderAPI extends IntentService { 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); + provider_json = downloadNewProviderDotJsonWithoutCert(provider_json_url, danger_on); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -223,7 +229,7 @@ public class ProviderAPI extends IntentService { } private JSONObject downloadNewProviderDotJsonWithoutCert( - String provider_json_url) { + String provider_json_url, boolean danger_on) { JSONObject provider_json = null; try { URL provider_url = new URL(provider_json_url); @@ -234,6 +240,12 @@ public class ProviderAPI extends IntentService { } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e1) { + if(danger_on) { + provider_json = downloadNewProviderDotJsonWithoutValidate(provider_json_url); + } + else { + //TODO Show error message advising to check the checkbox if the url is completely trusted. + } e1.printStackTrace(); } catch (JSONException e1) { e1.printStackTrace(); @@ -241,6 +253,40 @@ public class ProviderAPI extends IntentService { return provider_json; } + private JSONObject downloadNewProviderDotJsonWithoutValidate( + String provider_json_url) { + JSONObject provider_json = null; + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + HostnameVerifier hostname_verifier = + HttpsURLConnection.getDefaultHostnameVerifier(); + return hostname_verifier.verify("", session); + } + }; + + // Tell the URLConnection to use our HostnameVerifier + try { + URL url = new URL(provider_json_url); + HttpsURLConnection urlConnection = + (HttpsURLConnection)url.openConnection(); + urlConnection.setHostnameVerifier(hostnameVerifier); + String provider_json_string = new Scanner(url.openStream()).useDelimiter("\\A").next(); + provider_json = new JSONObject(provider_json_string); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return provider_json; + + } + private String guessURL(String provider_main_url) { return provider_main_url + "/provider.json"; } -- cgit v1.2.3 From 69389ee7db23ce7182b21da08d227d88d6cfdc46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 24 Apr 2013 20:01:28 +0200 Subject: "Trust completely" checkbox saves that trust for the new provider entered, so that if in the future the client tries to log in or whatever, it can use the certificate downloaded when added. Log in dialog works ok, showing a toast when authentication fails (by this time, I have not managed to get a correct login due to dev.bitmask.net problems). dev.bitmask.net works perfectly, via adding it as a new provider (MeanderingCode, this is for you ;) ). All GET requests are done by default Android URL class, which means that certificates trusted by Android are also trusted by us. If there are problems when logging in due to certificates, the app is able to use only the certificate associated to the provider in the moment it was selected as the chosen provider. --- src/se/leap/leapclient/ProviderAPI.java | 193 +++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 68 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 63db18e1..04185eda 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,17 +1,26 @@ package se.leap.leapclient; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.math.BigInteger; +import java.security.KeyManagementException; +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 java.util.List; import java.net.MalformedURLException; import java.net.URL; -import java.net.UnknownHostException; import java.util.Scanner; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -36,6 +45,7 @@ import android.app.IntentService; import android.content.Intent; import android.os.Bundle; import android.os.ResultReceiver; +import android.util.Base64; import android.util.Log; public class ProviderAPI extends IntentService { @@ -58,7 +68,7 @@ public class ProviderAPI extends IntentService { } else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { if(downloadNewProviderDotJSON(task)) - receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); else receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } @@ -77,25 +87,21 @@ public class ProviderAPI extends IntentService { } private boolean downloadJsonFiles(Bundle task) { - String cert_url = (String) task.get(ConfigHelper.cert_key); - String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); + String provider_name = task.getString(ConfigHelper.provider_key); + String cert_url = task.getString(ConfigHelper.cert_key); + String eip_service_json_url = task.getString(ConfigHelper.eip_service_key); + boolean danger_on = task.getBoolean(ConfigHelper.danger_on); try { - String cert_string = getStringFromProvider(cert_url); + String cert_string = getStringFromProvider(cert_url, danger_on); + ConfigHelper.addTrustedCertificate(provider_name, cert_string); JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); - JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); + JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); return true; - } catch (IOException e) { - // TODO - e.printStackTrace(); - return false; } catch (JSONException e) { ConfigHelper.rescueJSONException(e); return false; - } catch(Exception e) { - e.printStackTrace(); - return false; } } @@ -135,7 +141,8 @@ public class ProviderAPI extends IntentService { byte[] M1 = client.response(Bbytes); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify(M2) == false ) - throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); + //throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); + return false; return true; } else return false; @@ -199,17 +206,14 @@ public class ProviderAPI extends IntentService { private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; - boolean danger_on = ((Boolean)task.get(ConfigHelper.danger_on)).booleanValue(); + boolean danger_on = task.getBoolean(ConfigHelper.danger_on); String provider_main_url = (String) task.get(ConfigHelper.provider_main_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, danger_on); + provider_json = getJSONFromProvider(provider_json_url, danger_on); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -223,75 +227,128 @@ public class ProviderAPI extends IntentService { ConfigHelper.saveFile(filename, provider_json.toString()); ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - ProviderListContent.addItem(new ProviderItem(provider_name, ConfigHelper.openFileInputStream(filename), custom)); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, ConfigHelper.openFileInputStream(filename), custom, danger_on)); return true; } } - private JSONObject downloadNewProviderDotJsonWithoutCert( - String provider_json_url, boolean danger_on) { - 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 (UnknownHostException e1) { - e1.printStackTrace(); - } catch (IOException e1) { - if(danger_on) { - provider_json = downloadNewProviderDotJsonWithoutValidate(provider_json_url); - } - else { - //TODO Show error message advising to check the checkbox if the url is completely trusted. - } - e1.printStackTrace(); - } catch (JSONException e1) { - e1.printStackTrace(); - } - return provider_json; - } - - private JSONObject downloadNewProviderDotJsonWithoutValidate( - String provider_json_url) { - JSONObject provider_json = null; + private String getStringFromProviderWithoutValidate( + URL provider_json_url) { + + String json_string = ""; HostnameVerifier hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - HostnameVerifier hostname_verifier = - HttpsURLConnection.getDefaultHostnameVerifier(); - return hostname_verifier.verify("", session); - } + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } }; // Tell the URLConnection to use our HostnameVerifier try { - URL url = new URL(provider_json_url); HttpsURLConnection urlConnection = - (HttpsURLConnection)url.openConnection(); - urlConnection.setHostnameVerifier(hostnameVerifier); - String provider_json_string = new Scanner(url.openStream()).useDelimiter("\\A").next(); - provider_json = new JSONObject(provider_json_string); + (HttpsURLConnection)provider_json_url.openConnection(); + urlConnection.setHostnameVerifier(hostnameVerifier); + json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + json_string = getStringFromProviderWithCACertAdded(provider_json_url); + //e.printStackTrace(); } - return provider_json; - + return json_string; } private String guessURL(String provider_main_url) { return provider_main_url + "/provider.json"; } + + private String getStringFromProvider(String string_url, boolean danger_on) { + + String json_file_content = ""; + + URL provider_url = null; + try { + provider_url = new URL(string_url); + json_file_content = new Scanner(provider_url.openStream()).useDelimiter("\\A").next(); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO SSLHandshakeException + // This means that we have not added ca.crt to the trusted certificates. + if(provider_url != null && danger_on) { + json_file_content = getStringFromProviderWithoutValidate(provider_url); + } + //json_file_content = downloadStringFromProviderWithCACertAdded(string_url); + e.printStackTrace(); + } + + return json_file_content; + } + + private String getStringFromProviderWithCACertAdded(URL url) { + String json_file_content = ""; + + // Load CAs from an InputStream + // (could be from a resource or ByteArrayInputStream or ...) + CertificateFactory cf; + try { + cf = CertificateFactory.getInstance("X.509"); + + String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.cert_key); + cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); + byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); + InputStream caInput = new ByteArrayInputStream(cert_bytes); + java.security.cert.Certificate ca; + try { + ca = cf.generateCertificate(caInput); + System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); + } finally { + caInput.close(); + } + + // Create a KeyStore containing our trusted CAs + String keyStoreType = KeyStore.getDefaultType(); + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(null, null); + keyStore.setCertificateEntry("ca", ca); + + // Create a TrustManager that trusts the CAs in our KeyStore + String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); + tmf.init(keyStore); + + // Create an SSLContext that uses our TrustManager + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, tmf.getTrustManagers(), null); + + // Tell the URLConnection to use a SocketFactory from our SSLContext + HttpsURLConnection urlConnection = + (HttpsURLConnection)url.openConnection(); + urlConnection.setSSLSocketFactory(context.getSocketFactory()); + json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + } catch (CertificateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyStoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return json_file_content; + } - private String getStringFromProvider(String string_url) throws IOException { + private String getStringFromProvider_2(String string_url) throws IOException { String json_file_content = ""; @@ -306,8 +363,8 @@ public class ProviderAPI extends IntentService { return json_file_content; } - private JSONObject getJSONFromProvider(String json_url) throws IOException, JSONException { - String json_file_content = getStringFromProvider(json_url); + private JSONObject getJSONFromProvider(String json_url, boolean danger_on) throws JSONException { + String json_file_content = getStringFromProvider(json_url, danger_on); return new JSONObject(json_file_content); } -- cgit v1.2.3 From 09493a9dec5fb235d5c4914eb8f8142e3312e246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 29 Apr 2013 21:32:10 +0200 Subject: Changed the message shown when checking if the password is valid or not. Refactored LeapSRPSession so that there is no need to send A twice. --- src/se/leap/leapclient/ProviderAPI.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 04185eda..66eb3e60 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -131,14 +131,14 @@ public class ProviderAPI extends IntentService { try { JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); if(saltAndB.length() > 0) { - byte[] B = saltAndB.getString("B").getBytes(); - salt = saltAndB.getString("salt"); + /*byte[] B = saltAndB.getString("B").getBytes(); params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); client = new LeapSRPSession(username, password, params); A = client.exponential(); - saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); + saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16));*/ + salt = saltAndB.getString("salt"); byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); - byte[] M1 = client.response(Bbytes); + byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify(M2) == false ) //throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); -- cgit v1.2.3 From ff3d469a9549e3670e097fc0e49c043c84e7b7d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 1 May 2013 18:41:05 +0200 Subject: If the app is restarted with a custom provider selected, the client can request a log in without certificates problems. I've removed the addition of the certificate when downloaded eip-service.json, because I already do that in LeapHttpClient. Solves issue 2367: https://leap.se/code/issues/2367 --- src/se/leap/leapclient/ProviderAPI.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 66eb3e60..4a288787 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -93,7 +93,7 @@ public class ProviderAPI extends IntentService { boolean danger_on = task.getBoolean(ConfigHelper.danger_on); try { String cert_string = getStringFromProvider(cert_url, danger_on); - ConfigHelper.addTrustedCertificate(provider_name, cert_string); + //ConfigHelper.addTrustedCertificate(provider_name, cert_string); JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); @@ -177,9 +177,11 @@ public class ProviderAPI extends IntentService { if(!json_response.isNull("errors") || json_response.has("errors")) { return new JSONObject(); } + + String session_id = ""; List cookies = client.getCookieStore().getCookies(); if(!cookies.isEmpty()) { - String session_id = cookies.get(0).getValue(); + session_id = cookies.get(0).getValue(); } return json_response; } @@ -190,6 +192,8 @@ public class ProviderAPI extends IntentService { HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.COOKIE_STORE, client.getCookieStore()); + String session_id = client.getCookieStore().getCookies().get(0).getValue(); + int number_of_cookies = client.getCookieStore().getCookies().size(); HttpResponse getResponse = client.execute(put, localContext); HttpEntity responseEntity = getResponse.getEntity(); -- cgit v1.2.3 From fb5e26c2ff4f95dd826a3ce3545865ac4388b711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 8 May 2013 18:23:10 +0200 Subject: After loggin in successfully, the new client certificate is downloaded. It is stored in SharedPrefs, with ConfigHelper.cert_key (="cert") key. --- src/se/leap/leapclient/ProviderAPI.java | 146 ++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 45 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 4a288787..bdfd6207 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -12,7 +12,12 @@ import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.List; +import java.net.CookieHandler; +import java.net.CookieManager; +import java.net.HttpCookie; +import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.util.Scanner; @@ -25,13 +30,16 @@ import javax.net.ssl.TrustManagerFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.protocol.ClientContext; import org.apache.http.cookie.Cookie; +import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.jboss.security.Util; @@ -73,10 +81,20 @@ public class ProviderAPI extends IntentService { receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { - if(authenticateBySRP(task)) - receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, Bundle.EMPTY); - else - receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + try { + JSONObject session_idAndResult = authenticateBySRP(task); + if(session_idAndResult.getBoolean(ConfigHelper.resultKey)) { + Bundle session_id_bundle = new Bundle(); + session_id_bundle.putString(ConfigHelper.session_id_cookie_key, session_idAndResult.getString(ConfigHelper.session_id_cookie_key)); + session_id_bundle.putString(ConfigHelper.session_id_key, session_idAndResult.getString(ConfigHelper.session_id_key)); + receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); + } else { + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } else if ((task = task_for.getBundleExtra(ConfigHelper.logOut)) != null) { if(logOut(task)) @@ -84,18 +102,24 @@ public class ProviderAPI extends IntentService { else receiver.send(ConfigHelper.LOGOUT_FAILED, Bundle.EMPTY); } + else if ((task = task_for.getBundleExtra(ConfigHelper.downloadUserAuthedCertificate)) != null) { + if(getNewCert(task)) + receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); + else + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); + } } private boolean downloadJsonFiles(Bundle task) { - String provider_name = task.getString(ConfigHelper.provider_key); - String cert_url = task.getString(ConfigHelper.cert_key); + //String provider_name = task.getString(ConfigHelper.provider_key); + String cert_url = task.getString(ConfigHelper.main_cert_key); String eip_service_json_url = task.getString(ConfigHelper.eip_service_key); boolean danger_on = task.getBoolean(ConfigHelper.danger_on); try { String cert_string = getStringFromProvider(cert_url, danger_on); //ConfigHelper.addTrustedCertificate(provider_name, cert_string); - JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); - ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + JSONObject cert_json = new JSONObject().put(ConfigHelper.main_cert_key, cert_string); + ConfigHelper.saveSharedPref(ConfigHelper.main_cert_key, cert_json); JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); return true; @@ -117,7 +141,9 @@ public class ProviderAPI extends IntentService { return false; } - private boolean authenticateBySRP(Bundle task) { + private JSONObject authenticateBySRP(Bundle task) { + JSONObject successfulAndsession_id = new JSONObject(); + String username = (String) task.get(ConfigHelper.username_key); String password = (String) task.get(ConfigHelper.password_key); String authentication_server = (String) task.get(ConfigHelper.api_url_key); @@ -131,38 +157,36 @@ public class ProviderAPI extends IntentService { try { JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); if(saltAndB.length() > 0) { - /*byte[] B = saltAndB.getString("B").getBytes(); - params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); - client = new LeapSRPSession(username, password, params); - A = client.exponential(); - saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16));*/ salt = saltAndB.getString("salt"); byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); - byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); - if( client.verify(M2) == false ) + //byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); + JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); + if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { //throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); - return false; - return true; + successfulAndsession_id.put(ConfigHelper.resultKey, false); + return successfulAndsession_id; + } else { + successfulAndsession_id.put(ConfigHelper.resultKey, true); + successfulAndsession_id.put(ConfigHelper.session_id_key, session_idAndM2.getString(ConfigHelper.session_id_key)); + successfulAndsession_id.put(ConfigHelper.session_id_cookie_key, session_idAndM2.getString(ConfigHelper.session_id_cookie_key)); + return successfulAndsession_id; + } } - else return false; } catch (ClientProtocolException e1) { // TODO Auto-generated catch block e1.printStackTrace(); - return false; } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); - return false; } catch (JSONException e1) { // TODO Auto-generated catch block e1.printStackTrace(); - return false; } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); - return false; } + return successfulAndsession_id; } private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { @@ -186,7 +210,8 @@ public class ProviderAPI extends IntentService { return json_response; } - private byte[] sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { + private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { + JSONObject session_idAndM2 = new JSONObject(); DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); String parameter_chain = "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16); HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); @@ -200,12 +225,15 @@ public class ProviderAPI extends IntentService { String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); if(!json_response.isNull("errors") || json_response.has("errors")) { - return new byte[0]; + return session_idAndM2; } - + + number_of_cookies = client.getCookieStore().getCookies().size(); byte[] M2_not_trimmed = new BigInteger(json_response.getString("M2"), 16).toByteArray(); - return Util.trim(M2_not_trimmed); - //return M2_not_trimmed; + session_idAndM2.put(ConfigHelper.session_id_cookie_key, client.getCookieStore().getCookies().get(0).getName()); + session_idAndM2.put(ConfigHelper.session_id_key, client.getCookieStore().getCookies().get(0).getValue()); + session_idAndM2.put("M2", Util.trim(M2_not_trimmed)); + return session_idAndM2; } private boolean downloadNewProviderDotJSON(Bundle task) { @@ -229,7 +257,7 @@ public class ProviderAPI extends IntentService { } else { String filename = provider_name + "_provider.json".replaceFirst("__", "_"); ConfigHelper.saveFile(filename, provider_json.toString()); - ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + //ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, ConfigHelper.openFileInputStream(filename), custom, danger_on)); return true; @@ -301,7 +329,8 @@ public class ProviderAPI extends IntentService { try { cf = CertificateFactory.getInstance("X.509"); - String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.cert_key); + String cert_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.main_cert_key); + String cert_string = new JSONObject(cert_json_string).getString(ConfigHelper.main_cert_key); cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); @@ -348,24 +377,12 @@ public class ProviderAPI extends IntentService { } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); } return json_file_content; } - - private String getStringFromProvider_2(String string_url) throws IOException { - - String json_file_content = ""; - - DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - HttpGet get = new HttpGet(string_url); - // Execute the GET call and obtain the response - HttpResponse getResponse = client.execute(get); - HttpEntity responseEntity = getResponse.getEntity(); - - json_file_content = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - - return json_file_content; - } private JSONObject getJSONFromProvider(String json_url, boolean danger_on) throws JSONException { String json_file_content = getStringFromProvider(json_url, danger_on); @@ -391,4 +408,43 @@ public class ProviderAPI extends IntentService { } return true; } + + private boolean getNewCert(Bundle task) { + String provider_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.provider_key); + HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.session_id_cookie_key), task.getString(ConfigHelper.session_id_key)); + + try { + JSONObject provider_json = new JSONObject(provider_json_string); + URL provider_main_url = new URL(provider_json.getString(ConfigHelper.api_url_key).replace("api.", "")); + String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.api_version_key) + "/" + ConfigHelper.cert_key; + + CookieManager cookieManager = new CookieManager(); + cookieManager.getCookieStore().add(provider_main_url.toURI(), session_id_cookie); + CookieHandler.setDefault(cookieManager); + + String danger_on_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.danger_on); + boolean danger_on = new JSONObject(danger_on_json_string).getBoolean(ConfigHelper.danger_on); + String cert_string = getStringFromProvider(new_cert_string_url, danger_on); + if(!cert_string.isEmpty()) { + JSONObject cert_json = new JSONObject().put(ConfigHelper.cert_key, cert_string); + ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + return true; + } else { + return false; + } + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return true; + } } -- cgit v1.2.3 From 84a11bb1620d2b9080992427c847b58007f2304a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 9 May 2013 17:29:38 +0200 Subject: Log in and Log out options are shown only if allow registration is true. Allow registration is present in provider.json. Provider.json is downloaded from both preseeded and custom providers. Authentication success or fail is notified correctly to the user. --- src/se/leap/leapclient/ProviderAPI.java | 90 ++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 12 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index bdfd6207..b44c9971 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -15,7 +15,6 @@ import java.util.List; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; -import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; @@ -30,16 +29,12 @@ import javax.net.ssl.TrustManagerFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.protocol.ClientContext; import org.apache.http.cookie.Cookie; -import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.cookie.BasicClientCookie; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.jboss.security.Util; @@ -74,6 +69,24 @@ public class ProviderAPI extends IntentService { else receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } + else if ((task = task_for.getBundleExtra(ConfigHelper.updateProviderDotJSON)) != null) { + JSONObject result = updateProviderDotJSON(task); + boolean successful; + try { + successful = result.getBoolean(ConfigHelper.resultKey); + if(successful) { + Bundle provider_dot_json_and_danger_on = new Bundle(); + provider_dot_json_and_danger_on.putBoolean(ConfigHelper.danger_on, result.getBoolean(ConfigHelper.danger_on)); + provider_dot_json_and_danger_on.putString(ConfigHelper.provider_key, result.getJSONObject(ConfigHelper.provider_key).toString()); + receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, provider_dot_json_and_danger_on); + } else { + receiver.send(ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { if(downloadNewProviderDotJSON(task)) receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); @@ -172,6 +185,9 @@ public class ProviderAPI extends IntentService { successfulAndsession_id.put(ConfigHelper.session_id_cookie_key, session_idAndM2.getString(ConfigHelper.session_id_cookie_key)); return successfulAndsession_id; } + } else { + successfulAndsession_id.put(ConfigHelper.resultKey, false); + return successfulAndsession_id; } } catch (ClientProtocolException e1) { // TODO Auto-generated catch block @@ -236,6 +252,50 @@ public class ProviderAPI extends IntentService { return session_idAndM2; } + private JSONObject updateProviderDotJSON(Bundle task) { + JSONObject result = new JSONObject(); + boolean custom = task.getBoolean(ConfigHelper.custom); + boolean danger_on = task.getBoolean(ConfigHelper.danger_on); + String provider_json_url = task.getString(ConfigHelper.provider_json_url); + String provider_name = task.getString(ConfigHelper.provider_name); + + JSONObject provider_json = null; + try { + provider_json = getJSONFromProvider(provider_json_url, danger_on); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + try { + return result.put(ConfigHelper.resultKey, false); + } catch (JSONException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + if(provider_json == null) { + try { + return result.put(ConfigHelper.resultKey, false); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + String filename = provider_name + "_provider.json".replaceFirst("__", "_"); + ConfigHelper.saveFile(filename, provider_json.toString()); + //ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); + try { + return result.put(ConfigHelper.resultKey, true).put(ConfigHelper.provider_key, provider_json).put(ConfigHelper.danger_on, danger_on); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return result; + } + private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; boolean danger_on = task.getBoolean(ConfigHelper.danger_on); @@ -259,7 +319,7 @@ public class ProviderAPI extends IntentService { ConfigHelper.saveFile(filename, provider_json.toString()); //ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, ConfigHelper.openFileInputStream(filename), custom, danger_on)); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); return true; } } @@ -291,10 +351,6 @@ public class ProviderAPI extends IntentService { } return json_string; } - - private String guessURL(String provider_main_url) { - return provider_main_url + "/provider.json"; - } private String getStringFromProvider(String string_url, boolean danger_on) { @@ -388,23 +444,33 @@ public class ProviderAPI extends IntentService { String json_file_content = getStringFromProvider(json_url, danger_on); return new JSONObject(json_file_content); } + + private String guessURL(String provider_main_url) { + return provider_main_url + "/provider.json"; + } private boolean logOut(Bundle task) { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); int session_id_index = 0; //String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/sessions/" + client.getCookieStore().getCookies().get(0).getValue(); - String delete_url = task.getString(ConfigHelper.api_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); - HttpDelete delete = new HttpDelete(delete_url); try { + String delete_url = task.getString(ConfigHelper.api_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); + HttpDelete delete = new HttpDelete(delete_url); HttpResponse getResponse = client.execute(delete); HttpEntity responseEntity = getResponse.getEntity(); responseEntity.consumeContent(); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); + return false; + } catch (IndexOutOfBoundsException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); + return false; } return true; } -- cgit v1.2.3 From 80a8106afc8956008beb9d1ed9396f1d695d5b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 13 May 2013 20:39:34 +0200 Subject: A bit more clean. I've upper cased ConfigHelper constants. I've created a new method in ConfigHelper, to send requests to a server, that it's used when sending A and M1. --- src/se/leap/leapclient/ProviderAPI.java | 289 +++++++++++++------------------- 1 file changed, 113 insertions(+), 176 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index b44c9971..00033440 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -11,7 +11,6 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.util.List; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; @@ -32,6 +31,7 @@ import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.ClientContext; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; @@ -63,89 +63,72 @@ public class ProviderAPI extends IntentService { final ResultReceiver receiver = task_for.getParcelableExtra("receiver"); Bundle task; - if((task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)) != null) { - if(!downloadJsonFiles(task)) + if((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_JSON_FILES_BUNDLE_EXTRA)) != null) { + if(!downloadJsonFiles(task)) { receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); - else + } else { receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } } - else if ((task = task_for.getBundleExtra(ConfigHelper.updateProviderDotJSON)) != null) { - JSONObject result = updateProviderDotJSON(task); - boolean successful; - try { - successful = result.getBoolean(ConfigHelper.resultKey); - if(successful) { - Bundle provider_dot_json_and_danger_on = new Bundle(); - provider_dot_json_and_danger_on.putBoolean(ConfigHelper.danger_on, result.getBoolean(ConfigHelper.danger_on)); - provider_dot_json_and_danger_on.putString(ConfigHelper.provider_key, result.getJSONObject(ConfigHelper.provider_key).toString()); - receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, provider_dot_json_and_danger_on); - } else { - receiver.send(ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + else if ((task = task_for.getBundleExtra(ConfigHelper.UPDATE_PROVIDER_DOTJSON)) != null) { + Bundle result = updateProviderDotJSON(task); + if(result.getBoolean(ConfigHelper.RESULT_KEY)) { + receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); + } else { + receiver.send(ConfigHelper.INCORRECTLY_UPDATED_PROVIDER_DOT_JSON, Bundle.EMPTY); } } - else if ((task = task_for.getBundleExtra(ConfigHelper.downloadNewProviderDotJSON)) != null) { - if(downloadNewProviderDotJSON(task)) + else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_NEW_PROVIDER_DOTJSON)) != null) { + if(downloadNewProviderDotJSON(task)) { receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); - else + } else { receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); + } } - else if ((task = task_for.getBundleExtra(ConfigHelper.srpAuth)) != null) { - try { - JSONObject session_idAndResult = authenticateBySRP(task); - if(session_idAndResult.getBoolean(ConfigHelper.resultKey)) { - Bundle session_id_bundle = new Bundle(); - session_id_bundle.putString(ConfigHelper.session_id_cookie_key, session_idAndResult.getString(ConfigHelper.session_id_cookie_key)); - session_id_bundle.putString(ConfigHelper.session_id_key, session_idAndResult.getString(ConfigHelper.session_id_key)); - receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); - } else { - receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); - } - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + else if ((task = task_for.getBundleExtra(ConfigHelper.SRP_AUTH)) != null) { + Bundle session_id_bundle = authenticateBySRP(task); + if(session_id_bundle.getBoolean(ConfigHelper.RESULT_KEY)) { + receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); + } else { + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); } } - else if ((task = task_for.getBundleExtra(ConfigHelper.logOut)) != null) { - if(logOut(task)) + else if ((task = task_for.getBundleExtra(ConfigHelper.LOG_OUT)) != null) { + if(logOut(task)) { receiver.send(ConfigHelper.LOGOUT_SUCCESSFUL, Bundle.EMPTY); - else + } else { receiver.send(ConfigHelper.LOGOUT_FAILED, Bundle.EMPTY); + } } - else if ((task = task_for.getBundleExtra(ConfigHelper.downloadUserAuthedCertificate)) != null) { - if(getNewCert(task)) + else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_USER_AUTHED_CERTIFICATE)) != null) { + if(getNewCert(task)) { receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); - else + } else { receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); + } } } private boolean downloadJsonFiles(Bundle task) { - //String provider_name = task.getString(ConfigHelper.provider_key); - String cert_url = task.getString(ConfigHelper.main_cert_key); - String eip_service_json_url = task.getString(ConfigHelper.eip_service_key); - boolean danger_on = task.getBoolean(ConfigHelper.danger_on); + String cert_url = task.getString(ConfigHelper.MAIN_CERT_KEY); + String eip_service_json_url = task.getString(ConfigHelper.EIP_SERVICE_KEY); + boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); try { String cert_string = getStringFromProvider(cert_url, danger_on); - //ConfigHelper.addTrustedCertificate(provider_name, cert_string); - JSONObject cert_json = new JSONObject().put(ConfigHelper.main_cert_key, cert_string); - ConfigHelper.saveSharedPref(ConfigHelper.main_cert_key, cert_json); + JSONObject cert_json = new JSONObject().put(ConfigHelper.MAIN_CERT_KEY, cert_string); + ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_json); JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); - ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); + ConfigHelper.saveSharedPref(ConfigHelper.EIP_SERVICE_KEY, eip_service_json); return true; } catch (JSONException e) { - ConfigHelper.rescueJSONException(e); return false; } } private boolean registerWithSRP(Bundle task) { - String username = (String) task.get(ConfigHelper.username_key); - String password = (String) task.get(ConfigHelper.password_key); - String authentication_server = (String) task.get(ConfigHelper.api_url_key); + String username = (String) task.get(ConfigHelper.USERNAME_KEY); + String password = (String) task.get(ConfigHelper.PASSWORD_KEY); + String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); BigInteger salt = ng_1024.probablePrime(1024, null); @@ -154,173 +137,127 @@ public class ProviderAPI extends IntentService { return false; } - private JSONObject authenticateBySRP(Bundle task) { - JSONObject successfulAndsession_id = new JSONObject(); - - String username = (String) task.get(ConfigHelper.username_key); - String password = (String) task.get(ConfigHelper.password_key); - String authentication_server = (String) task.get(ConfigHelper.api_url_key); + private Bundle authenticateBySRP(Bundle task) { + Bundle session_id_bundle = new Bundle(); - String salt = "abcd"; + String username = (String) task.get(ConfigHelper.USERNAME_KEY); + String password = (String) task.get(ConfigHelper.PASSWORD_KEY); + String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); - SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), new BigInteger("2").toByteArray(), new BigInteger(salt, 16).toByteArray(), "SHA-256"); - //SRPClientSession client = new SRPClientSession(username, password.toCharArray(), params); + SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); LeapSRPSession client = new LeapSRPSession(username, password, params); byte[] A = client.exponential(); try { JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); if(saltAndB.length() > 0) { - salt = saltAndB.getString("salt"); + String salt = saltAndB.getString(ConfigHelper.SALT_KEY); byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); - //byte[] M2 = sendM1ToSRPServer(authentication_server, username, M1); JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { - //throw new SecurityException("Failed to validate server reply: M2 = " + new BigInteger(1, M2).toString(16)); - successfulAndsession_id.put(ConfigHelper.resultKey, false); - return successfulAndsession_id; + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } else { - successfulAndsession_id.put(ConfigHelper.resultKey, true); - successfulAndsession_id.put(ConfigHelper.session_id_key, session_idAndM2.getString(ConfigHelper.session_id_key)); - successfulAndsession_id.put(ConfigHelper.session_id_cookie_key, session_idAndM2.getString(ConfigHelper.session_id_cookie_key)); - return successfulAndsession_id; + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); + session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); + session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); } } else { - successfulAndsession_id.put(ConfigHelper.resultKey, false); - return successfulAndsession_id; + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } - } catch (ClientProtocolException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (IOException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); + } catch (ClientProtocolException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + } catch (IOException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + } catch (JSONException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } catch (NoSuchAlgorithmException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } - return successfulAndsession_id; + + return session_id_bundle; } private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { - DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - String parameter_chain = "A" + "=" + clientA + "&" + "login" + "=" + username; - HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + parameter_chain); - - HttpResponse getResponse = client.execute(post); - HttpEntity responseEntity = getResponse.getEntity(); - String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors") || json_response.has("errors")) { - return new JSONObject(); - } - - String session_id = ""; - List cookies = client.getCookieStore().getCookies(); - if(!cookies.isEmpty()) { - session_id = cookies.get(0).getValue(); - } - return json_response; + HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + "login=" + username + "&&" + "A=" + clientA); + return sendToServer(post); } private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { + HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16)); + JSONObject json_response = sendToServer(put); + JSONObject session_idAndM2 = new JSONObject(); + if(json_response.length() > 0) { + byte[] M2_not_trimmed = new BigInteger(json_response.getString("M2"), 16).toByteArray(); + Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); + session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); + session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue()); + session_idAndM2.put("M2", Util.trim(M2_not_trimmed)); + } + return session_idAndM2; + } + + private JSONObject sendToServer(HttpUriRequest request) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); - String parameter_chain = "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16); - HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + parameter_chain); HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.COOKIE_STORE, client.getCookieStore()); - String session_id = client.getCookieStore().getCookies().get(0).getValue(); - int number_of_cookies = client.getCookieStore().getCookies().size(); - HttpResponse getResponse = client.execute(put, localContext); + HttpResponse getResponse = client.execute(request, localContext); HttpEntity responseEntity = getResponse.getEntity(); String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); if(!json_response.isNull("errors") || json_response.has("errors")) { - return session_idAndM2; + return new JSONObject(); } - number_of_cookies = client.getCookieStore().getCookies().size(); - byte[] M2_not_trimmed = new BigInteger(json_response.getString("M2"), 16).toByteArray(); - session_idAndM2.put(ConfigHelper.session_id_cookie_key, client.getCookieStore().getCookies().get(0).getName()); - session_idAndM2.put(ConfigHelper.session_id_key, client.getCookieStore().getCookies().get(0).getValue()); - session_idAndM2.put("M2", Util.trim(M2_not_trimmed)); - return session_idAndM2; + return json_response; } - private JSONObject updateProviderDotJSON(Bundle task) { - JSONObject result = new JSONObject(); - boolean custom = task.getBoolean(ConfigHelper.custom); - boolean danger_on = task.getBoolean(ConfigHelper.danger_on); - String provider_json_url = task.getString(ConfigHelper.provider_json_url); - String provider_name = task.getString(ConfigHelper.provider_name); + private Bundle updateProviderDotJSON(Bundle task) { + Bundle result = new Bundle(); + boolean custom = task.getBoolean(ConfigHelper.CUSTOM); + boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); + String provider_json_url = task.getString(ConfigHelper.PROVIDER_JSON_URL); + String provider_name = task.getString(ConfigHelper.PROVIDER_NAME); - JSONObject provider_json = null; try { - provider_json = getJSONFromProvider(provider_json_url, danger_on); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - try { - return result.put(ConfigHelper.resultKey, false); - } catch (JSONException e1) { - // TODO Auto-generated catch block - e1.printStackTrace(); - } - } - - if(provider_json == null) { - try { - return result.put(ConfigHelper.resultKey, false); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } else { - String filename = provider_name + "_provider.json".replaceFirst("__", "_"); - ConfigHelper.saveFile(filename, provider_json.toString()); - //ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + JSONObject provider_json = getJSONFromProvider(provider_json_url, danger_on); + if(provider_json == null) { + result.putBoolean(ConfigHelper.RESULT_KEY, false); + } else { + String filename = provider_name + "_provider.json".replaceFirst("__", "_"); + ConfigHelper.saveFile(filename, provider_json.toString()); - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); - try { - return result.put(ConfigHelper.resultKey, true).put(ConfigHelper.provider_key, provider_json).put(ConfigHelper.danger_on, danger_on); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); + result.putBoolean(ConfigHelper.RESULT_KEY, true); + result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); + result.putBoolean(ConfigHelper.DANGER_ON, danger_on); } + } catch (JSONException e) { + result.putBoolean(ConfigHelper.RESULT_KEY, false); } + return result; } private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; - boolean danger_on = task.getBoolean(ConfigHelper.danger_on); + boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); - String provider_main_url = (String) task.get(ConfigHelper.provider_main_url); + String provider_main_url = (String) task.get(ConfigHelper.PROVIDER_MAIN_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, danger_on); - } 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()); - //ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); return true; + } catch (JSONException e) { + return false; } } @@ -385,8 +322,8 @@ public class ProviderAPI extends IntentService { try { cf = CertificateFactory.getInstance("X.509"); - String cert_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.main_cert_key); - String cert_string = new JSONObject(cert_json_string).getString(ConfigHelper.main_cert_key); + String cert_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); + String cert_string = new JSONObject(cert_json_string).getString(ConfigHelper.MAIN_CERT_KEY); cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); @@ -454,7 +391,7 @@ public class ProviderAPI extends IntentService { int session_id_index = 0; //String delete_url = task.getString(ConfigHelper.srp_server_url_key) + "/sessions/" + client.getCookieStore().getCookies().get(0).getValue(); try { - String delete_url = task.getString(ConfigHelper.api_url_key) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); + String delete_url = task.getString(ConfigHelper.API_URL_KEY) + "/logout" + "?authenticity_token=" + client.getCookieStore().getCookies().get(session_id_index).getValue(); HttpDelete delete = new HttpDelete(delete_url); HttpResponse getResponse = client.execute(delete); HttpEntity responseEntity = getResponse.getEntity(); @@ -476,24 +413,24 @@ public class ProviderAPI extends IntentService { } private boolean getNewCert(Bundle task) { - String provider_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.provider_key); - HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.session_id_cookie_key), task.getString(ConfigHelper.session_id_key)); + String provider_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.PROVIDER_KEY); + HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.SESSION_ID_COOKIE_KEY), task.getString(ConfigHelper.SESSION_ID_KEY)); try { JSONObject provider_json = new JSONObject(provider_json_string); - URL provider_main_url = new URL(provider_json.getString(ConfigHelper.api_url_key).replace("api.", "")); - String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.api_version_key) + "/" + ConfigHelper.cert_key; + URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY).replace("api.", "")); + String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; CookieManager cookieManager = new CookieManager(); cookieManager.getCookieStore().add(provider_main_url.toURI(), session_id_cookie); CookieHandler.setDefault(cookieManager); - String danger_on_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.danger_on); - boolean danger_on = new JSONObject(danger_on_json_string).getBoolean(ConfigHelper.danger_on); + String danger_on_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.DANGER_ON); + boolean danger_on = new JSONObject(danger_on_json_string).getBoolean(ConfigHelper.DANGER_ON); String cert_string = getStringFromProvider(new_cert_string_url, danger_on); if(!cert_string.isEmpty()) { - JSONObject cert_json = new JSONObject().put(ConfigHelper.cert_key, cert_string); - ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + JSONObject cert_json = new JSONObject().put(ConfigHelper.CERT_KEY, cert_string); + ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, cert_json); return true; } else { return false; -- cgit v1.2.3 From 75edcdb601be69f4c1ee6783cf7f80390a9f094d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 14 May 2013 21:03:07 +0200 Subject: Anon certificate is downloaded if possible. I download the anon certificate only if allow_anonymous is true, and before launching Dashboard. I store it in SharedPreferences, with "cert" key, as a JSON object. --- src/se/leap/leapclient/ProviderAPI.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 00033440..d5e164d6 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -100,11 +100,11 @@ public class ProviderAPI extends IntentService { receiver.send(ConfigHelper.LOGOUT_FAILED, Bundle.EMPTY); } } - else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_USER_AUTHED_CERTIFICATE)) != null) { + else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_CERTIFICATE)) != null) { if(getNewCert(task)) { - receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); + receiver.send(ConfigHelper.CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); } else { - receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_AUTHED_USER_CERTIFICATE, Bundle.EMPTY); + receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY); } } } @@ -224,7 +224,9 @@ public class ProviderAPI extends IntentService { JSONObject provider_json = getJSONFromProvider(provider_json_url, danger_on); if(provider_json == null) { result.putBoolean(ConfigHelper.RESULT_KEY, false); - } else { + } else { + ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, new JSONObject().put(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON))); + String filename = provider_name + "_provider.json".replaceFirst("__", "_"); ConfigHelper.saveFile(filename, provider_json.toString()); @@ -414,17 +416,20 @@ public class ProviderAPI extends IntentService { private boolean getNewCert(Bundle task) { String provider_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.PROVIDER_KEY); - HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.SESSION_ID_COOKIE_KEY), task.getString(ConfigHelper.SESSION_ID_KEY)); - + String type_of_certificate = task.getString(ConfigHelper.TYPE_OF_CERTIFICATE); try { JSONObject provider_json = new JSONObject(provider_json_string); URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY).replace("api.", "")); String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; - CookieManager cookieManager = new CookieManager(); - cookieManager.getCookieStore().add(provider_main_url.toURI(), session_id_cookie); - CookieHandler.setDefault(cookieManager); + if(type_of_certificate.equalsIgnoreCase(ConfigHelper.AUTHED_CERTIFICATE)) { + HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.SESSION_ID_COOKIE_KEY), task.getString(ConfigHelper.SESSION_ID_KEY)); + CookieManager cookieManager = new CookieManager(); + cookieManager.getCookieStore().add(provider_main_url.toURI(), session_id_cookie); + CookieHandler.setDefault(cookieManager); + } + String danger_on_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.DANGER_ON); boolean danger_on = new JSONObject(danger_on_json_string).getBoolean(ConfigHelper.DANGER_ON); String cert_string = getStringFromProvider(new_cert_string_url, danger_on); @@ -435,7 +440,6 @@ public class ProviderAPI extends IntentService { } else { return false; } - } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From ac47aab124d63add14189cb3d03e3a05361a7932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 4 Jun 2013 16:31:39 +0200 Subject: Fixed 2 important bugs. LeapSRPSession was doing bad SRP calculations when salt byte array started with a 0. Now I trimmed that array before using it. ProviderAPI was not timing out when a server didn't respond. Now, I use a timeout of 1 second to stop waiting for a response. --- src/se/leap/leapclient/ProviderAPI.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index d5e164d6..a6a2d6be 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -15,8 +15,10 @@ import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; import java.net.MalformedURLException; +import java.net.SocketTimeoutException; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLConnection; import java.util.Scanner; import javax.net.ssl.HostnameVerifier; @@ -296,12 +298,17 @@ public class ProviderAPI extends IntentService { String json_file_content = ""; URL provider_url = null; + int seconds_of_timeout = 1; try { provider_url = new URL(string_url); - json_file_content = new Scanner(provider_url.openStream()).useDelimiter("\\A").next(); + URLConnection url_connection = provider_url.openConnection(); + url_connection.setConnectTimeout(seconds_of_timeout*1000); + json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch(SocketTimeoutException e) { + return ""; } catch (IOException e) { // TODO SSLHandshakeException // This means that we have not added ca.crt to the trusted certificates. @@ -310,8 +317,10 @@ public class ProviderAPI extends IntentService { } //json_file_content = downloadStringFromProviderWithCACertAdded(string_url); e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); } - + return json_file_content; } -- cgit v1.2.3 From 899583d474a0b04e168203ce06195403461b9215 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Sat, 8 Jun 2013 20:55:48 -0600 Subject: Improve retrieving and saving SharedPreferences for different types (String, boolean, JSONObject) --- src/se/leap/leapclient/ProviderAPI.java | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index a6a2d6be..cd19da04 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -117,8 +117,7 @@ public class ProviderAPI extends IntentService { boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); try { String cert_string = getStringFromProvider(cert_url, danger_on); - JSONObject cert_json = new JSONObject().put(ConfigHelper.MAIN_CERT_KEY, cert_string); - ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_json); + ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url, danger_on); ConfigHelper.saveSharedPref(ConfigHelper.EIP_SERVICE_KEY, eip_service_json); return true; @@ -227,7 +226,7 @@ public class ProviderAPI extends IntentService { if(provider_json == null) { result.putBoolean(ConfigHelper.RESULT_KEY, false); } else { - ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, new JSONObject().put(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON))); + ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); String filename = provider_name + "_provider.json".replaceFirst("__", "_"); ConfigHelper.saveFile(filename, provider_json.toString()); @@ -333,8 +332,7 @@ public class ProviderAPI extends IntentService { try { cf = CertificateFactory.getInstance("X.509"); - String cert_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); - String cert_string = new JSONObject(cert_json_string).getString(ConfigHelper.MAIN_CERT_KEY); + String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); @@ -381,10 +379,8 @@ public class ProviderAPI extends IntentService { } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); } + return json_file_content; } @@ -424,10 +420,9 @@ public class ProviderAPI extends IntentService { } private boolean getNewCert(Bundle task) { - String provider_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.PROVIDER_KEY); String type_of_certificate = task.getString(ConfigHelper.TYPE_OF_CERTIFICATE); try { - JSONObject provider_json = new JSONObject(provider_json_string); + JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY); URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY).replace("api.", "")); String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; @@ -439,12 +434,10 @@ public class ProviderAPI extends IntentService { CookieHandler.setDefault(cookieManager); } - String danger_on_json_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.DANGER_ON); - boolean danger_on = new JSONObject(danger_on_json_string).getBoolean(ConfigHelper.DANGER_ON); + boolean danger_on = ConfigHelper.getBoolFromSharedPref(ConfigHelper.DANGER_ON); String cert_string = getStringFromProvider(new_cert_string_url, danger_on); if(!cert_string.isEmpty()) { - JSONObject cert_json = new JSONObject().put(ConfigHelper.CERT_KEY, cert_string); - ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, cert_json); + ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, cert_string); return true; } else { return false; -- cgit v1.2.3 From 265a66e66cffacbd2c99f99bebbcec3bf100a546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 10 Jun 2013 18:43:50 +0200 Subject: OpenVPN certificate is downloaded from API_BASE, using api_uri field from provider.json. This fixes bug #2780 --- src/se/leap/leapclient/ProviderAPI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index cd19da04..a51c3a05 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -423,8 +423,8 @@ public class ProviderAPI extends IntentService { String type_of_certificate = task.getString(ConfigHelper.TYPE_OF_CERTIFICATE); try { JSONObject provider_json = ConfigHelper.getJsonFromSharedPref(ConfigHelper.PROVIDER_KEY); - URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY).replace("api.", "")); - String new_cert_string_url = provider_main_url.getProtocol() + "://" + provider_main_url.getHost() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; + URL provider_main_url = new URL(provider_json.getString(ConfigHelper.API_URL_KEY)); + String new_cert_string_url = provider_main_url.toString() + "/" + provider_json.getString(ConfigHelper.API_VERSION_KEY) + "/" + ConfigHelper.CERT_KEY; if(type_of_certificate.equalsIgnoreCase(ConfigHelper.AUTHED_CERTIFICATE)) { HttpCookie session_id_cookie = new HttpCookie(task.getString(ConfigHelper.SESSION_ID_COOKIE_KEY), task.getString(ConfigHelper.SESSION_ID_KEY)); -- cgit v1.2.3 From 1e2470b1e940877f6fe247a65bccd2b62b621eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 10 Jun 2013 18:56:34 +0200 Subject: Removed unused methods and variables. Variables from LeapSRPSession were there because I used it while testing srp calculations, comparing that strings with the ones from javascript. Unused method from ProviderAPI was there because I foresee I'll have to implement it in the future, but I've removed it since it's already in the history. This fixes #2781. --- src/se/leap/leapclient/ProviderAPI.java | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index a51c3a05..0898ebb8 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -125,18 +125,6 @@ public class ProviderAPI extends IntentService { return false; } } - - private boolean registerWithSRP(Bundle task) { - String username = (String) task.get(ConfigHelper.USERNAME_KEY); - String password = (String) task.get(ConfigHelper.PASSWORD_KEY); - String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); - - BigInteger ng_1024 = new BigInteger(ConfigHelper.NG_1024, 16); - BigInteger salt = ng_1024.probablePrime(1024, null); - byte[] salt_in_bytes = salt.toByteArray(); - - return false; - } private Bundle authenticateBySRP(Bundle task) { Bundle session_id_bundle = new Bundle(); -- cgit v1.2.3 From 6c90e0043ec68254c15562fd12a707f5e45f47e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 11 Jun 2013 19:01:36 +0200 Subject: We are not using SD storage anymore. We were using it to save certificate and provider.json files from chosen provider, so that exporting them was easily done. We don't need that files, because if we wanted to export that files we would be able to recover them easily and updated. This fixes #2783 --- src/se/leap/leapclient/ProviderAPI.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 0898ebb8..10f04c5d 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -217,7 +217,6 @@ public class ProviderAPI extends IntentService { ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); String filename = provider_name + "_provider.json".replaceFirst("__", "_"); - ConfigHelper.saveFile(filename, provider_json.toString()); ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); result.putBoolean(ConfigHelper.RESULT_KEY, true); @@ -243,7 +242,6 @@ public class ProviderAPI extends IntentService { provider_json = getJSONFromProvider(provider_json_url, danger_on); String filename = provider_name + "_provider.json".replaceFirst("__", "_"); - ConfigHelper.saveFile(filename, provider_json.toString()); ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); return true; -- cgit v1.2.3 From 30c7bab5d8618df665e602fdd08bafa010a15497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 13 Jun 2013 17:37:37 +0200 Subject: bitmask json files are downloaded. There was a problem on the assets file "bitmask.url". It had an error in the eip-service url. We should use this file only for main url, and proceed as if it were a new provider but with a preseeded main url. --- src/se/leap/leapclient/ProviderAPI.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 10f04c5d..471eb6cf 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -216,9 +216,7 @@ public class ProviderAPI extends IntentService { } else { ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); - String filename = provider_name + "_provider.json".replaceFirst("__", "_"); - - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); result.putBoolean(ConfigHelper.RESULT_KEY, true); result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); result.putBoolean(ConfigHelper.DANGER_ON, danger_on); @@ -237,17 +235,17 @@ public class ProviderAPI extends IntentService { String provider_main_url = (String) task.get(ConfigHelper.PROVIDER_MAIN_URL); String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); String provider_json_url = guessURL(provider_main_url); - JSONObject provider_json = null; + + JSONObject provider_json; try { provider_json = getJSONFromProvider(provider_json_url, danger_on); - - String filename = provider_name + "_provider.json".replaceFirst("__", "_"); - - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, filename, custom, danger_on)); - return true; + ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); } catch (JSONException e) { - return false; + // TODO Auto-generated catch block + e.printStackTrace(); } + + return true; } private String getStringFromProviderWithoutValidate( -- cgit v1.2.3 From bffd21a326bcb86d814dd3fe2caf5295ea705f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 13 Jun 2013 21:12:24 +0200 Subject: Bypasses self signed certificates. It's working against cdev.bitmask.net and bitmask.net. Look at #2840 for further explanation about self signed certificates. I've also removed some file dependant configuration (when a provider was custom, ConfigurationWizard still tried to read from file a provider.json that now I store in memory via ProviderItem class). --- src/se/leap/leapclient/ProviderAPI.java | 126 +++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 35 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 471eb6cf..f98e4361 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -26,6 +26,8 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -247,34 +249,6 @@ public class ProviderAPI extends IntentService { return true; } - - private String getStringFromProviderWithoutValidate( - URL provider_json_url) { - - String json_string = ""; - HostnameVerifier hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - - // Tell the URLConnection to use our HostnameVerifier - try { - HttpsURLConnection urlConnection = - (HttpsURLConnection)provider_json_url.openConnection(); - urlConnection.setHostnameVerifier(hostnameVerifier); - json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IOException e) { - // TODO Auto-generated catch block - json_string = getStringFromProviderWithCACertAdded(provider_json_url); - //e.printStackTrace(); - } - return json_string; - } private String getStringFromProvider(String string_url, boolean danger_on) { @@ -307,25 +281,56 @@ public class ProviderAPI extends IntentService { return json_file_content; } + private String getStringFromProviderWithoutValidate( + URL provider_json_url) { + + String json_string = ""; + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + try { + HttpsURLConnection urlConnection = + (HttpsURLConnection)provider_json_url.openConnection(); + urlConnection.setHostnameVerifier(hostnameVerifier); + json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + json_string = getStringFromProviderWithCACertAdded(provider_json_url); + //e.printStackTrace(); + } + + return json_string; + } + private String getStringFromProviderWithCACertAdded(URL url) { String json_file_content = ""; - + // Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) + String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); + if(cert_string.isEmpty()) { + cert_string = downloadCertificateWithoutTrusting(url.getProtocol() + "://" + url.getHost() + "/" + "ca.crt"); + ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); + } CertificateFactory cf; try { cf = CertificateFactory.getInstance("X.509"); - String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); java.security.cert.Certificate ca; try { - ca = cf.generateCertificate(caInput); - System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); + ca = cf.generateCertificate(caInput); + System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); } finally { - caInput.close(); + caInput.close(); } // Create a KeyStore containing our trusted CAs @@ -345,7 +350,7 @@ public class ProviderAPI extends IntentService { // Tell the URLConnection to use a SocketFactory from our SSLContext HttpsURLConnection urlConnection = - (HttpsURLConnection)url.openConnection(); + (HttpsURLConnection)url.openConnection(); urlConnection.setSSLSocketFactory(context.getSocketFactory()); json_file_content = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); } catch (CertificateException e) { @@ -364,10 +369,61 @@ public class ProviderAPI extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } - return json_file_content; } + private String downloadCertificateWithoutTrusting(String certificate_url_string) { + + String cert_string = ""; + HostnameVerifier hostnameVerifier = new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + try { + URL certificate_url = new URL(certificate_url_string); + HttpsURLConnection urlConnection = + (HttpsURLConnection)certificate_url.openConnection(); + urlConnection.setHostnameVerifier(hostnameVerifier); + + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + + urlConnection.setSSLSocketFactory(sc.getSocketFactory()); + + cert_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // This should never happen + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return cert_string; + } + private JSONObject getJSONFromProvider(String json_url, boolean danger_on) throws JSONException { String json_file_content = getStringFromProvider(json_url, danger_on); return new JSONObject(json_file_content); -- cgit v1.2.3 From d475ae617d8dc0994a1294be7c8cca338a68fd9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 19 Jun 2013 19:05:12 +0200 Subject: First round of comments. This resolves the first step from issue #2908. Next step: Put user message strings into an appropiate place. --- src/se/leap/leapclient/ProviderAPI.java | 121 ++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 6 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index f98e4361..f8d730e7 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -55,6 +55,15 @@ import android.os.ResultReceiver; import android.util.Base64; import android.util.Log; +/** + * Implements HTTP api methods used to manage communications with the provider server. + * + * It's an IntentService because it downloads data fromt he Internet, so it operates in the background. + * + * @author parmegv + * @author MeanderingCode + * + */ public class ProviderAPI extends IntentService { public ProviderAPI() { @@ -113,6 +122,11 @@ public class ProviderAPI extends IntentService { } } + /** + * Downloads the main cert and the eip-service.json files given through the task parameter + * @param task + * @return true if eip-service.json was parsed as a JSON object correctly. + */ private boolean downloadJsonFiles(Bundle task) { String cert_url = task.getString(ConfigHelper.MAIN_CERT_KEY); String eip_service_json_url = task.getString(ConfigHelper.EIP_SERVICE_KEY); @@ -128,6 +142,12 @@ public class ProviderAPI extends IntentService { } } + /** + * Starts the authentication process using SRP protocol. + * + * @param task containing: username, password and api url. + * @return a bundle with a boolean value mapped to a key named ConfigHelper.RESULT_KEY, and which is true if authentication was successful. + */ private Bundle authenticateBySRP(Bundle task) { Bundle session_id_bundle = new Bundle(); @@ -168,11 +188,31 @@ public class ProviderAPI extends IntentService { return session_id_bundle; } + /** + * Sends an HTTP POST request to the authentication server with the SRP Parameter A. + * @param server_url + * @param username + * @param clientA First SRP parameter sent + * @return response from authentication server + * @throws ClientProtocolException + * @throws IOException + * @throws JSONException + */ private JSONObject sendAToSRPServer(String server_url, String username, String clientA) throws ClientProtocolException, IOException, JSONException { HttpPost post = new HttpPost(server_url + "/sessions.json" + "?" + "login=" + username + "&&" + "A=" + clientA); return sendToServer(post); } + /** + * Sends an HTTP PUT request to the authentication server with the SRP Parameter M1 (or simply M). + * @param server_url + * @param username + * @param m1 Second SRP parameter sent + * @return response from authentication server + * @throws ClientProtocolException + * @throws IOException + * @throws JSONException + */ private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16)); JSONObject json_response = sendToServer(put); @@ -188,6 +228,14 @@ public class ProviderAPI extends IntentService { return session_idAndM2; } + /** + * Executes an HTTP request expecting a JSON response. + * @param request + * @return response from authentication server + * @throws ClientProtocolException + * @throws IOException + * @throws JSONException + */ private JSONObject sendToServer(HttpUriRequest request) throws ClientProtocolException, IOException, JSONException { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); HttpContext localContext = new BasicHttpContext(); @@ -204,6 +252,11 @@ public class ProviderAPI extends IntentService { return json_response; } + /** + * Downloads a provider.json from a given URL, adding a new provider using the given name. + * @param task containing a boolean meaning if the provider is custom or not, another boolean meaning if the user completely trusts this provider, the provider name and its provider.json url. + * @return a bundle with a boolean value mapped to a key named ConfigHelper.RESULT_KEY, and which is true if the update was successful. + */ private Bundle updateProviderDotJSON(Bundle task) { Bundle result = new Bundle(); boolean custom = task.getBoolean(ConfigHelper.CUSTOM); @@ -230,13 +283,18 @@ public class ProviderAPI extends IntentService { return result; } + /** + * Downloads a custom provider provider.json file + * @param task containing a boolean meaning if the user completely trusts this provider, and the provider main url entered in the new custom provider dialog. + * @return true if provider.json file was successfully parsed as a JSON object. + */ private boolean downloadNewProviderDotJSON(Bundle task) { boolean custom = true; boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); String provider_main_url = (String) task.get(ConfigHelper.PROVIDER_MAIN_URL); String provider_name = provider_main_url.replaceFirst("http[s]?://", "").replaceFirst("\\/", "_"); - String provider_json_url = guessURL(provider_main_url); + String provider_json_url = guessProviderDotJsonURL(provider_main_url); JSONObject provider_json; try { @@ -245,11 +303,20 @@ public class ProviderAPI extends IntentService { } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); + return false; } return true; } + /** + * Tries to download whatever is pointed by the string_url. + * + * If danger_on flag is true, SSL exceptions will be managed by futher methods that will try to use some bypass methods. + * @param string_url + * @param danger_on if the user completely trusts this provider + * @return + */ private String getStringFromProvider(String string_url, boolean danger_on) { String json_file_content = ""; @@ -281,8 +348,15 @@ public class ProviderAPI extends IntentService { return json_file_content; } + /** + * Tries to download a string from given url without verifying the hostname. + * + * If a IOException still occurs, it tries with another bypass method: getStringFromProviderWithCACertAdded. + * @param string_url + * @return an empty string if everything fails, the url content if not. + */ private String getStringFromProviderWithoutValidate( - URL provider_json_url) { + URL string_url) { String json_string = ""; HostnameVerifier hostnameVerifier = new HostnameVerifier() { @@ -294,20 +368,25 @@ public class ProviderAPI extends IntentService { try { HttpsURLConnection urlConnection = - (HttpsURLConnection)provider_json_url.openConnection(); + (HttpsURLConnection)string_url.openConnection(); urlConnection.setHostnameVerifier(hostnameVerifier); json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - json_string = getStringFromProviderWithCACertAdded(provider_json_url); + json_string = getStringFromProviderWithCACertAdded(string_url); //e.printStackTrace(); } return json_string; } + /** + * Tries to download the contents of the provided url using main certificate from choosen provider. + * @param url + * @return an empty string if it fails, the url content if not. + */ private String getStringFromProviderWithCACertAdded(URL url) { String json_file_content = ""; @@ -372,6 +451,11 @@ public class ProviderAPI extends IntentService { return json_file_content; } + /** + * Downloads the certificate from the parameter url bypassing self signed certificate SSL errors. + * @param certificate_url_string + * @return the certificate, as a string + */ private String downloadCertificateWithoutTrusting(String certificate_url_string) { String cert_string = ""; @@ -424,15 +508,34 @@ public class ProviderAPI extends IntentService { return cert_string; } + /** + * Downloads a JSON object from the given url. + * + * It first downloads the JSON object as a String, and then parses it to JSON object. + * @param json_url + * @param danger_on if the user completely trusts the certificate of the url address. + * @return + * @throws JSONException + */ private JSONObject getJSONFromProvider(String json_url, boolean danger_on) throws JSONException { String json_file_content = getStringFromProvider(json_url, danger_on); return new JSONObject(json_file_content); } - private String guessURL(String provider_main_url) { + /** + * Tries to guess the provider.json url given the main provider url. + * @param provider_main_url + * @return the guessed provider.json url + */ + private String guessProviderDotJsonURL(String provider_main_url) { return provider_main_url + "/provider.json"; } + /** + * Logs out from the api url retrieved from the task. + * @param task containing api url from which the user will log out + * @return true if there were no exceptions + */ private boolean logOut(Bundle task) { DefaultHttpClient client = LeapHttpClient.getInstance(getApplicationContext()); int session_id_index = 0; @@ -459,6 +562,12 @@ public class ProviderAPI extends IntentService { return true; } + /** + * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate. + * + * @param task containing the type of the certificate to be downloaded + * @return true if certificate was downloaded correctly, false if provider.json or danger_on flag are not present in SharedPreferences, or if the certificate url could not be parsed as a URI, or if there was an SSL error. + */ private boolean getNewCert(Bundle task) { String type_of_certificate = task.getString(ConfigHelper.TYPE_OF_CERTIFICATE); try { @@ -493,7 +602,7 @@ public class ProviderAPI extends IntentService { } catch (URISyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); + return false; } - return true; } } -- cgit v1.2.3 From f4956bb818fb9ed04760e6de3b53b876272da5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 20 Jun 2013 16:52:43 +0200 Subject: User messages are now in string.xml Some more constants added to ConfigHelper. This solves #2908. --- src/se/leap/leapclient/ProviderAPI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index f8d730e7..4dfe200a 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -219,11 +219,11 @@ public class ProviderAPI extends IntentService { JSONObject session_idAndM2 = new JSONObject(); if(json_response.length() > 0) { - byte[] M2_not_trimmed = new BigInteger(json_response.getString("M2"), 16).toByteArray(); + byte[] M2_not_trimmed = new BigInteger(json_response.getString(ConfigHelper.M2_KEY), 16).toByteArray(); Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue()); - session_idAndM2.put("M2", Util.trim(M2_not_trimmed)); + session_idAndM2.put(ConfigHelper.M2_KEY, Util.trim(M2_not_trimmed)); } return session_idAndM2; } @@ -245,7 +245,7 @@ public class ProviderAPI extends IntentService { HttpEntity responseEntity = getResponse.getEntity(); String plain_response = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); JSONObject json_response = new JSONObject(plain_response); - if(!json_response.isNull("errors") || json_response.has("errors")) { + if(!json_response.isNull(ConfigHelper.ERRORS_KEY) || json_response.has(ConfigHelper.ERRORS_KEY)) { return new JSONObject(); } -- cgit v1.2.3 From 65e2f56a8a10877964fb9fc57963d1bf8104801a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 20 Jun 2013 17:47:07 +0200 Subject: No binary library needed. I've decided not to include any lib, but to copy the SRPParameters class to our codebase and Util.trim method to ConfigHelper. --- src/se/leap/leapclient/ProviderAPI.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 4dfe200a..00d7d820 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -41,7 +41,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.Util; import org.jboss.security.srp.SRPParameters; import org.json.JSONException; import org.json.JSONObject; @@ -214,7 +213,7 @@ public class ProviderAPI extends IntentService { * @throws JSONException */ private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) throws ClientProtocolException, IOException, JSONException { - HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, Util.trim(m1)).toString(16)); + HttpPut put = new HttpPut(server_url + "/sessions/" + username +".json" + "?" + "client_auth" + "=" + new BigInteger(1, ConfigHelper.trim(m1)).toString(16)); JSONObject json_response = sendToServer(put); JSONObject session_idAndM2 = new JSONObject(); @@ -223,7 +222,7 @@ public class ProviderAPI extends IntentService { Cookie session_id_cookie = LeapHttpClient.getInstance(getApplicationContext()).getCookieStore().getCookies().get(0); session_idAndM2.put(ConfigHelper.SESSION_ID_COOKIE_KEY, session_id_cookie.getName()); session_idAndM2.put(ConfigHelper.SESSION_ID_KEY, session_id_cookie.getValue()); - session_idAndM2.put(ConfigHelper.M2_KEY, Util.trim(M2_not_trimmed)); + session_idAndM2.put(ConfigHelper.M2_KEY, ConfigHelper.trim(M2_not_trimmed)); } return session_idAndM2; } -- cgit v1.2.3 From 33338d43e0e83329a7c46807e096b8148e19aff7 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Sun, 9 Jun 2013 04:09:03 -0600 Subject: Quite basic staring and stopping of VPN --- src/se/leap/leapclient/ProviderAPI.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 00d7d820..72cc9b62 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -584,8 +584,18 @@ public class ProviderAPI extends IntentService { boolean danger_on = ConfigHelper.getBoolFromSharedPref(ConfigHelper.DANGER_ON); String cert_string = getStringFromProvider(new_cert_string_url, danger_on); - if(!cert_string.isEmpty()) { - ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, cert_string); + if(!cert_string.isEmpty()) { + // API returns concatenated cert & key. Split them for OpenVPN options + String certificate = null, key = null; + String[] certAndKey = cert_string.split("(?<=-\n)"); + for (int i=0; i < certAndKey.length-1; i++){ + if ( certAndKey[i].contains("KEY") ) + key = certAndKey[i++] + certAndKey[i]; + else if ( certAndKey[i].contains("CERTIFICATE") ) + certificate = certAndKey[i++] + certAndKey[i]; + } + ConfigHelper.saveSharedPref(ConfigHelper.CERT_KEY, certificate); + ConfigHelper.saveSharedPref(ConfigHelper.KEY_KEY, key); return true; } else { return false; -- cgit v1.2.3 From 6ada10858719786e489938b3124d1d6015a70421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 25 Jun 2013 17:55:22 +0200 Subject: The added provider is selected automatically. I've also removed a lot of finishes when things go wrong (so that it should be returning to the previous activity/fragment). --- src/se/leap/leapclient/ProviderAPI.java | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 72cc9b62..e7e3918c 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -91,8 +91,9 @@ public class ProviderAPI extends IntentService { } } else if ((task = task_for.getBundleExtra(ConfigHelper.DOWNLOAD_NEW_PROVIDER_DOTJSON)) != null) { - if(downloadNewProviderDotJSON(task)) { - receiver.send(ConfigHelper.CUSTOM_PROVIDER_ADDED, Bundle.EMPTY); + Bundle result = downloadNewProviderDotJSON(task); + if(result.getBoolean(ConfigHelper.RESULT_KEY)) { + receiver.send(ConfigHelper.CORRECTLY_UPDATED_PROVIDER_DOT_JSON, result); } else { receiver.send(ConfigHelper.INCORRECTLY_DOWNLOADED_JSON_FILES, Bundle.EMPTY); } @@ -287,7 +288,8 @@ public class ProviderAPI extends IntentService { * @param task containing a boolean meaning if the user completely trusts this provider, and the provider main url entered in the new custom provider dialog. * @return true if provider.json file was successfully parsed as a JSON object. */ - private boolean downloadNewProviderDotJSON(Bundle task) { + private Bundle downloadNewProviderDotJSON(Bundle task) { + Bundle result = new Bundle(); boolean custom = true; boolean danger_on = task.getBoolean(ConfigHelper.DANGER_ON); @@ -298,14 +300,26 @@ public class ProviderAPI extends IntentService { JSONObject provider_json; try { provider_json = getJSONFromProvider(provider_json_url, danger_on); - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); + if(provider_json == null) { + result.putBoolean(ConfigHelper.RESULT_KEY, false); + } else { + + ConfigHelper.saveSharedPref(ConfigHelper.PROVIDER_KEY, provider_json); + ConfigHelper.saveSharedPref(ConfigHelper.DANGER_ON, danger_on); + ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); + ProviderItem added_provider = new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on); + ProviderListContent.addItem(added_provider); + + result.putString(ConfigHelper.PROVIDER_ID, added_provider.getId()); + result.putBoolean(ConfigHelper.RESULT_KEY, true); + result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); + result.putBoolean(ConfigHelper.DANGER_ON, danger_on); + } } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return false; + result.putBoolean(ConfigHelper.RESULT_KEY, false); } - return true; + return result; } /** -- cgit v1.2.3 From 2c6b2b47a48652d1e43a7f5383d6f91b7c5d06f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 24 Jun 2013 17:18:27 +0200 Subject: We can ignore any certificate. If ssl errors don't vanish using CA cert from provider, we go further and let the certificate not to be validated at all. --- src/se/leap/leapclient/ProviderAPI.java | 69 +++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 12 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index e7e3918c..11ad2e1d 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -11,6 +11,8 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.SecureRandom; +import javax.net.ssl.KeyManager; import java.net.CookieHandler; import java.net.CookieManager; import java.net.HttpCookie; @@ -347,15 +349,13 @@ public class ProviderAPI extends IntentService { } catch(SocketTimeoutException e) { return ""; } catch (IOException e) { - // TODO SSLHandshakeException - // This means that we have not added ca.crt to the trusted certificates. if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); } - //json_file_content = downloadStringFromProviderWithCACertAdded(string_url); - e.printStackTrace(); } catch (Exception e) { - e.printStackTrace(); + if(provider_url != null && danger_on) { + json_file_content = getStringFromProviderWithoutValidate(provider_url); + } } return json_file_content; @@ -389,7 +389,6 @@ public class ProviderAPI extends IntentService { e.printStackTrace(); } catch (IOException e) { json_string = getStringFromProviderWithCACertAdded(string_url); - //e.printStackTrace(); } return json_string; @@ -417,10 +416,10 @@ public class ProviderAPI extends IntentService { cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); InputStream caInput = new ByteArrayInputStream(cert_bytes); - java.security.cert.Certificate ca; + java.security.cert.Certificate dangerous_certificate; try { - ca = cf.generateCertificate(caInput); - System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); + dangerous_certificate = cf.generateCertificate(caInput); + System.out.println("dangerous certificate =" + ((X509Certificate) dangerous_certificate).getSubjectDN()); } finally { caInput.close(); } @@ -429,7 +428,7 @@ public class ProviderAPI extends IntentService { String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); - keyStore.setCertificateEntry("ca", ca); + keyStore.setCertificateEntry("dangerous_certificate", dangerous_certificate); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); @@ -449,8 +448,8 @@ public class ProviderAPI extends IntentService { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // The downloaded certificate doesn't validate our https connection. + json_file_content = getStringFromProviderIgnoringCertificate(url); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -464,6 +463,52 @@ public class ProviderAPI extends IntentService { return json_file_content; } + /** + * Downloads the string that's in the url without regarding certificate validity + */ + private String getStringFromProviderIgnoringCertificate(URL url) { + String string = ""; + try { + class DefaultTrustManager implements X509TrustManager { + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} + + @Override + public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + } + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom()); + + HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); + urlConnection.setSSLSocketFactory(context.getSocketFactory()); + urlConnection.setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); + System.out.println("String ignoring certificate = " + string); + } catch (IOException e) { + // The downloaded certificate doesn't validate our https connection. + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (KeyManagementException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return string; + } + /** * Downloads the certificate from the parameter url bypassing self signed certificate SSL errors. * @param certificate_url_string -- cgit v1.2.3 From 755633af514c8f425f936bc5185815175397937c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 12:54:15 +0200 Subject: Distinguish non LEAP provider and down provider. I've set ProviderAPI to show its own toast depending on the exception that getStringFromProvider issues. If the socket timeout reaches its end, a toast different from when an IOException or a MalformedException occur. --- src/se/leap/leapclient/ProviderAPI.java | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 11ad2e1d..b9cbdf24 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -52,9 +52,11 @@ import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; import android.os.ResultReceiver; import android.util.Base64; import android.util.Log; +import android.widget.Toast; /** * Implements HTTP api methods used to manage communications with the provider server. @@ -67,10 +69,28 @@ import android.util.Log; */ public class ProviderAPI extends IntentService { + private Handler mHandler; + public ProviderAPI() { super("ProviderAPI"); Log.v("ClassName", "Provider API"); } + + @Override + public void onCreate() { + super.onCreate(); + mHandler = new Handler(); + } + + private void displayToast(final int toast_string_id) { + mHandler.post(new Runnable() { + + @Override + public void run() { + Toast.makeText(ProviderAPI.this, toast_string_id, Toast.LENGTH_LONG).show(); + } + }); + } @Override protected void onHandleIntent(Intent task_for) { @@ -304,7 +324,7 @@ public class ProviderAPI extends IntentService { provider_json = getJSONFromProvider(provider_json_url, danger_on); if(provider_json == null) { result.putBoolean(ConfigHelper.RESULT_KEY, false); - } else { + } else { ConfigHelper.saveSharedPref(ConfigHelper.PROVIDER_KEY, provider_json); ConfigHelper.saveSharedPref(ConfigHelper.DANGER_ON, danger_on); @@ -344,14 +364,14 @@ public class ProviderAPI extends IntentService { url_connection.setConnectTimeout(seconds_of_timeout*1000); json_file_content = new Scanner(url_connection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + displayToast(R.string.malformed_url); } catch(SocketTimeoutException e) { - return ""; + displayToast(R.string.server_is_down_message); } catch (IOException e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); } + displayToast(R.string.malformed_url); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); @@ -385,8 +405,7 @@ public class ProviderAPI extends IntentService { urlConnection.setHostnameVerifier(hostnameVerifier); json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Toast.makeText(getApplicationContext(), R.string.malformed_url, Toast.LENGTH_LONG).show(); } catch (IOException e) { json_string = getStringFromProviderWithCACertAdded(string_url); } @@ -450,6 +469,7 @@ public class ProviderAPI extends IntentService { } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. json_file_content = getStringFromProviderIgnoringCertificate(url); + Toast.makeText(getApplicationContext(), R.string.malformed_url, Toast.LENGTH_LONG).show(); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 713078d3348017dd8c229ee52701c2c1b69bd85d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 13:01:07 +0200 Subject: Shows certificate error message. If a download didn't occurr due to an IOException, we assume it was for an SSL error and notify the user telling him/her that LEAP provider is not trusted. --- src/se/leap/leapclient/ProviderAPI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index b9cbdf24..1bc11495 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -371,7 +371,7 @@ public class ProviderAPI extends IntentService { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); } - displayToast(R.string.malformed_url); + displayToast(R.string.certificate_error); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); @@ -405,7 +405,7 @@ public class ProviderAPI extends IntentService { urlConnection.setHostnameVerifier(hostnameVerifier); json_string = new Scanner(urlConnection.getInputStream()).useDelimiter("\\A").next(); } catch (MalformedURLException e) { - Toast.makeText(getApplicationContext(), R.string.malformed_url, Toast.LENGTH_LONG).show(); + displayToast(R.string.malformed_url); } catch (IOException e) { json_string = getStringFromProviderWithCACertAdded(string_url); } @@ -469,7 +469,7 @@ public class ProviderAPI extends IntentService { } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. json_file_content = getStringFromProviderIgnoringCertificate(url); - Toast.makeText(getApplicationContext(), R.string.malformed_url, Toast.LENGTH_LONG).show(); + displayToast(R.string.certificate_error); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 51a1059ed87afb40b639685901f822f6c90e1255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 13:04:45 +0200 Subject: Substituted IOException by SSLHandshakeException. In getStringFromProvider, there is no IOException but an SSLHandshakeException. Substituing this gives our code more semantics. --- src/se/leap/leapclient/ProviderAPI.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 1bc11495..ce9e974d 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -26,6 +26,7 @@ import java.util.Scanner; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManager; -- cgit v1.2.3 From 7aabefb6df93fd96a354efbbf42a2138e171b763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 13:18:40 +0200 Subject: Back to IOException instead of SSL exception. The previous commit broke functionality, and instead of discarding it I've decided to undo with a new commit for future references. It would seem that IOException can be substitued by SSLHandshakeException, but the previous commit proves it cannot. --- src/se/leap/leapclient/ProviderAPI.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index ce9e974d..1bc11495 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -26,7 +26,6 @@ import java.util.Scanner; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManager; -- cgit v1.2.3 From c95194cffd8ca59298f1eed78b73c8d5a7f4c537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 13:31:40 +0200 Subject: Untrusted message is not shown if danger_on = true I forgot to add an else in the IOException from getStringFromProvider. This was causing that even if the user checked the trusted completely beckbox and everything was fine, the "not trusted provider" message was being shown. --- src/se/leap/leapclient/ProviderAPI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 1bc11495..d0001b48 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -370,8 +370,9 @@ public class ProviderAPI extends IntentService { } catch (IOException e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); + } else { + displayToast(R.string.certificate_error); } - displayToast(R.string.certificate_error); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); -- cgit v1.2.3 From acdbbb68f2429986f96d94888c12a01883785170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 10 Jul 2013 07:09:30 +0200 Subject: UnknownHostException separated from IOException. I was treating the former exception simply as a kind of the latter, but user messages are different. Now, each one shows its different error message. --- src/se/leap/leapclient/ProviderAPI.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index d0001b48..4f98e420 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -21,6 +21,7 @@ import java.net.SocketTimeoutException; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; +import java.net.UnknownHostException; import java.util.Scanner; import javax.net.ssl.HostnameVerifier; @@ -467,6 +468,8 @@ public class ProviderAPI extends IntentService { } catch (CertificateException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (UnknownHostException e) { + displayToast(R.string.server_is_down_message); } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. json_file_content = getStringFromProviderIgnoringCertificate(url); -- cgit v1.2.3 From b684f2fdd35064210d7c5ae760c1a2e4939b1ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 14:03:15 +0200 Subject: Pressing back button, we don't choose any provider Once in the provider detail fragment, if the user presses the back button, provider.json is removed from sharedpreferences (so that Dashboard does not start as if the user had selected the canceled provider) and ConfigurationWizard gets the focus. --- src/se/leap/leapclient/ProviderAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 4f98e420..306ffa20 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -294,7 +294,7 @@ public class ProviderAPI extends IntentService { } else { ConfigHelper.saveSharedPref(ConfigHelper.ALLOWED_ANON, provider_json.getJSONObject(ConfigHelper.SERVICE_KEY).getBoolean(ConfigHelper.ALLOWED_ANON)); - ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); + //ProviderListContent.addItem(new ProviderItem(provider_name, provider_json_url, provider_json, custom, danger_on)); result.putBoolean(ConfigHelper.RESULT_KEY, true); result.putString(ConfigHelper.PROVIDER_KEY, provider_json.toString()); result.putBoolean(ConfigHelper.DANGER_ON, danger_on); -- cgit v1.2.3 From 99a4d94564635f0223d447bc9bcf081cadd8ff36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 2 Jul 2013 19:20:58 +0200 Subject: User messages are added to the new recovery dialog When login is not successful, a new recovery dialog is prompted with a message about the previous error. --- src/se/leap/leapclient/ProviderAPI.java | 76 +++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 27 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 306ffa20..5238224e 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -62,7 +62,7 @@ import android.widget.Toast; /** * Implements HTTP api methods used to manage communications with the provider server. * - * It's an IntentService because it downloads data fromt he Internet, so it operates in the background. + * It's an IntentService because it downloads data from the Internet, so it operates in the background. * * @author parmegv * @author MeanderingCode @@ -126,7 +126,10 @@ public class ProviderAPI extends IntentService { if(session_id_bundle.getBoolean(ConfigHelper.RESULT_KEY)) { receiver.send(ConfigHelper.SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle); } else { - receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, Bundle.EMPTY); + Bundle user_message_bundle = new Bundle(); + String user_message_key = getResources().getString(R.string.user_message); + user_message_bundle.putString(user_message_key, session_id_bundle.getString(user_message_key)); + receiver.send(ConfigHelper.SRP_AUTHENTICATION_FAILED, user_message_bundle); } } else if ((task = task_for.getBundleExtra(ConfigHelper.LOG_OUT)) != null) { @@ -176,41 +179,60 @@ public class ProviderAPI extends IntentService { String username = (String) task.get(ConfigHelper.USERNAME_KEY); String password = (String) task.get(ConfigHelper.PASSWORD_KEY); - String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); + if(wellFormedPassword(password)) { + String authentication_server = (String) task.get(ConfigHelper.API_URL_KEY); - SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); - LeapSRPSession client = new LeapSRPSession(username, password, params); - byte[] A = client.exponential(); - try { - JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); - if(saltAndB.length() > 0) { - String salt = saltAndB.getString(ConfigHelper.SALT_KEY); - byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); - byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); - JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); - if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + SRPParameters params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256"); + LeapSRPSession client = new LeapSRPSession(username, password, params); + byte[] A = client.exponential(); + try { + JSONObject saltAndB = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16)); + if(saltAndB.length() > 0) { + String salt = saltAndB.getString(ConfigHelper.SALT_KEY); + byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); + byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); + JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); + if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + } else { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); + session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); + session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); + } } else { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); - session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); - session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); } - } else { + } catch (ClientProtocolException e) { session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message)); + } catch (IOException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message)); + } catch (JSONException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message)); + } catch (NoSuchAlgorithmException e) { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message)); } - } catch (ClientProtocolException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (IOException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (JSONException e) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } catch (NoSuchAlgorithmException e) { + } else { session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_not_valid_password_user_message)); } - + return session_id_bundle; } + /** + * Validates a password + * @param entered_password + * @return true if the entered password length is greater or equal to eight (8). + */ + private boolean wellFormedPassword(String entered_password) { + return entered_password.length() >= 8; + } + /** * Sends an HTTP POST request to the authentication server with the SRP Parameter A. * @param server_url -- cgit v1.2.3 From 3e04f2ab44e5e5e33efcfe515088ec3f918ccef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 12:54:15 +0200 Subject: Distinguish non LEAP provider and down provider. I've set ProviderAPI to show its own toast depending on the exception that getStringFromProvider issues. If the socket timeout reaches its end, a toast different from when an IOException or a MalformedException occur. --- src/se/leap/leapclient/ProviderAPI.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 5238224e..fba0ab01 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -396,6 +396,7 @@ public class ProviderAPI extends IntentService { } else { displayToast(R.string.certificate_error); } + displayToast(R.string.malformed_url); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); -- cgit v1.2.3 From 7202591b0a42cd91a10255720bd80c2218af2093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 29 Jun 2013 13:01:07 +0200 Subject: Shows certificate error message. If a download didn't occurr due to an IOException, we assume it was for an SSL error and notify the user telling him/her that LEAP provider is not trusted. --- src/se/leap/leapclient/ProviderAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index fba0ab01..f3ea5f2e 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -396,7 +396,7 @@ public class ProviderAPI extends IntentService { } else { displayToast(R.string.certificate_error); } - displayToast(R.string.malformed_url); + displayToast(R.string.certificate_error); } catch (Exception e) { if(provider_url != null && danger_on) { json_file_content = getStringFromProviderWithoutValidate(provider_url); -- cgit v1.2.3 From dacf638f7dd15e291cdb23a6cf8317e1dd80ed29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 2 Jul 2013 19:38:48 +0200 Subject: New certificates are added without creating files LeapHttpClient can fetch the main CA certificate downloaded from the provider and add it to its in-memory keystore, without saving the certificate in a file. This is a very important feature, I think it can be cherry picked (it has little modifications, and very localized). It's very important because authentication does not work without this bug fix in the latest branches, because I removed the code that saved the certificate in a file but didn't test the authentication part. --- src/se/leap/leapclient/ProviderAPI.java | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index f3ea5f2e..25a14bb5 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -452,21 +452,10 @@ public class ProviderAPI extends IntentService { if(cert_string.isEmpty()) { cert_string = downloadCertificateWithoutTrusting(url.getProtocol() + "://" + url.getHost() + "/" + "ca.crt"); ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); - } - CertificateFactory cf; + } + try { - cf = CertificateFactory.getInstance("X.509"); - - cert_string = cert_string.replaceFirst("-----BEGIN CERTIFICATE-----", "").replaceFirst("-----END CERTIFICATE-----", "").trim(); - byte[] cert_bytes = Base64.decode(cert_string, Base64.DEFAULT); - InputStream caInput = new ByteArrayInputStream(cert_bytes); - java.security.cert.Certificate dangerous_certificate; - try { - dangerous_certificate = cf.generateCertificate(caInput); - System.out.println("dangerous certificate =" + ((X509Certificate) dangerous_certificate).getSubjectDN()); - } finally { - caInput.close(); - } + java.security.cert.Certificate dangerous_certificate = ConfigHelper.parseX509CertificateFromString(cert_string); // Create a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); -- cgit v1.2.3 From a8d10d9800fcd58d8ee5e3b428b8ba402e83764f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Wed, 10 Jul 2013 21:42:42 +0200 Subject: Shows bad user/password message when appropriate. If an empty json string is received after sending M1 (that means no M2 in return), bad user/password message is shown. This fixes bug 3153. --- src/se/leap/leapclient/ProviderAPI.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 25a14bb5..37856f60 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -192,12 +192,13 @@ public class ProviderAPI extends IntentService { byte[] Bbytes = new BigInteger(saltAndB.getString("B"), 16).toByteArray(); byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes); JSONObject session_idAndM2 = sendM1ToSRPServer(authentication_server, username, M1); - if( client.verify((byte[])session_idAndM2.get("M2")) == false ) { - session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); - } else { + if(session_idAndM2.has("M2") && client.verify((byte[])session_idAndM2.get("M2"))) { session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, true); session_id_bundle.putString(ConfigHelper.SESSION_ID_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_KEY)); session_id_bundle.putString(ConfigHelper.SESSION_ID_COOKIE_KEY, session_idAndM2.getString(ConfigHelper.SESSION_ID_COOKIE_KEY)); + } else { + session_id_bundle.putBoolean(ConfigHelper.RESULT_KEY, false); + session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); } } else { session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_bad_user_password_user_message)); -- cgit v1.2.3 From 492f353e790875da560d8b29bac86e7db0db8922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 16 Jul 2013 18:45:35 +0200 Subject: Erroneous untrusted provider toast with LEAP fixed I've also rearranged how we handle SSL errors. In first place, if the user checked the "Trust completely" checkbox, leap_android tries to use the CA cert pointed out by provider.json. If that does not succeed, it uses an always-returning-true hostname verifier (this was previously done before using CA cert). --- src/se/leap/leapclient/ProviderAPI.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 37856f60..72b134e5 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -397,10 +397,9 @@ public class ProviderAPI extends IntentService { } else { displayToast(R.string.certificate_error); } - displayToast(R.string.certificate_error); } catch (Exception e) { if(provider_url != null && danger_on) { - json_file_content = getStringFromProviderWithoutValidate(provider_url); + json_file_content = getStringFromProviderWithCACertAdded(provider_url); } } @@ -433,7 +432,7 @@ public class ProviderAPI extends IntentService { } catch (MalformedURLException e) { displayToast(R.string.malformed_url); } catch (IOException e) { - json_string = getStringFromProviderWithCACertAdded(string_url); + json_string = getStringFromProviderIgnoringCertificate(string_url); } return json_string; @@ -485,7 +484,7 @@ public class ProviderAPI extends IntentService { displayToast(R.string.server_is_down_message); } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. - json_file_content = getStringFromProviderIgnoringCertificate(url); + json_file_content = getStringFromProviderWithoutValidate(url); displayToast(R.string.certificate_error); } catch (KeyStoreException e) { // TODO Auto-generated catch block -- cgit v1.2.3 From 5ed843dd7dfdddc9c64568a464ed550ba2185ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 16 Jul 2013 19:52:34 +0200 Subject: Certificate message shown when appropiate. Only if all downloading methods fail and the last one throws an IOException, the certificate error message toast is shown. --- src/se/leap/leapclient/ProviderAPI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 72b134e5..db53d6f9 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -485,7 +485,6 @@ public class ProviderAPI extends IntentService { } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. json_file_content = getStringFromProviderWithoutValidate(url); - displayToast(R.string.certificate_error); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -535,6 +534,7 @@ public class ProviderAPI extends IntentService { } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. e.printStackTrace(); + displayToast(R.string.certificate_error); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 6b740cdb44bd4f7181f93b6c15e772d14fb96796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 20 Jul 2013 12:01:11 +0200 Subject: If IOException, use current provider CA cert. If the CA cert was correctly downloaded, we assume it can be used to validate the string download. If CA cert cannot validate that connection, then if the trust completely checkbox was checked it will try with the other methods. If it was not checked, a certificate error is shown (telling the user the provider is not trusted). --- src/se/leap/leapclient/ProviderAPI.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index db53d6f9..a5da4b42 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -392,14 +392,14 @@ public class ProviderAPI extends IntentService { } catch(SocketTimeoutException e) { displayToast(R.string.server_is_down_message); } catch (IOException e) { - if(provider_url != null && danger_on) { - json_file_content = getStringFromProviderWithoutValidate(provider_url); + if(provider_url != null) { + json_file_content = getStringFromProviderWithCACertAdded(provider_url, danger_on); } else { displayToast(R.string.certificate_error); } } catch (Exception e) { if(provider_url != null && danger_on) { - json_file_content = getStringFromProviderWithCACertAdded(provider_url); + json_file_content = getStringFromProviderWithCACertAdded(provider_url, danger_on); } } @@ -441,15 +441,16 @@ public class ProviderAPI extends IntentService { /** * Tries to download the contents of the provided url using main certificate from choosen provider. * @param url + * @param danger_on true to download CA certificate in case it has not been downloaded. * @return an empty string if it fails, the url content if not. */ - private String getStringFromProviderWithCACertAdded(URL url) { + private String getStringFromProviderWithCACertAdded(URL url, boolean danger_on) { String json_file_content = ""; // Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) String cert_string = ConfigHelper.getStringFromSharedPref(ConfigHelper.MAIN_CERT_KEY); - if(cert_string.isEmpty()) { + if(cert_string.isEmpty() && danger_on) { cert_string = downloadCertificateWithoutTrusting(url.getProtocol() + "://" + url.getHost() + "/" + "ca.crt"); ConfigHelper.saveSharedPref(ConfigHelper.MAIN_CERT_KEY, cert_string); } @@ -461,7 +462,7 @@ public class ProviderAPI extends IntentService { String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); - keyStore.setCertificateEntry("dangerous_certificate", dangerous_certificate); + keyStore.setCertificateEntry("provider_ca_certificate", dangerous_certificate); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); @@ -484,7 +485,11 @@ public class ProviderAPI extends IntentService { displayToast(R.string.server_is_down_message); } catch (IOException e) { // The downloaded certificate doesn't validate our https connection. - json_file_content = getStringFromProviderWithoutValidate(url); + if(danger_on) { + json_file_content = getStringFromProviderWithoutValidate(url); + } else { + displayToast(R.string.certificate_error); + } } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 22e90c26036291de66f26ee148bb4c75b68c7764 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Fri, 12 Jul 2013 21:53:57 -0600 Subject: Include GPLv3+ file and header for files in se.leap.leapclient package --- src/se/leap/leapclient/ProviderAPI.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/se/leap/leapclient/ProviderAPI.java') diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index a5da4b42..944a0e7f 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,4 +1,20 @@ -package se.leap.leapclient; +/** + * 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.leapclient; import java.io.ByteArrayInputStream; import java.io.IOException; -- cgit v1.2.3