summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2014-10-10 10:25:54 +0200
committerParménides GV <parmegv@sdf.org>2014-10-10 10:25:54 +0200
commite1914c01b836d5798f19a3e8dec1a25e064f9f19 (patch)
tree4ee2cb7bd7ab31ae249f1bd408f6912bdab9dc8e /app
parent2b56dd61c0bd9eb6f71405d1d7f07f3051b29601 (diff)
parentbe4879b5f19d9c736fa3bcefdfabbe119cd9391f (diff)
Merge branch 'bug/No-real-pinning-happening-#6093' into develop
Diffstat (limited to 'app')
-rw-r--r--app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java356
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java77
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java13
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Provider.java1
-rw-r--r--app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java295
5 files changed, 328 insertions, 414 deletions
diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
index e729d0bc..b83f33a1 100644
--- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -14,12 +14,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
- package se.leap.bitmaskclient;
+package se.leap.bitmaskclient;
import android.app.IntentService;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
-import android.os.Handler;
import android.os.ResultReceiver;
import android.util.Base64;
import android.util.Log;
@@ -43,6 +43,7 @@ import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
@@ -65,7 +66,6 @@ import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.http.client.ClientProtocolException;
-import org.jboss.security.srp.SRPParameters;
import org.json.JSONException;
import org.json.JSONObject;
import se.leap.bitmaskclient.ProviderListContent.ProviderItem;
@@ -83,8 +83,6 @@ import se.leap.bitmaskclient.R;
*/
public class ProviderAPI extends IntentService {
- private Handler mHandler;
-
final public static String
SET_UP_PROVIDER = "setUpProvider",
DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON",
@@ -128,6 +126,7 @@ public class ProviderAPI extends IntentService {
private static String last_provider_main_url;
private static boolean last_danger_on = false;
private static boolean setting_up_provider = true;
+ private static SharedPreferences preferences;
public static void stop() {
setting_up_provider = false;
@@ -138,12 +137,13 @@ public class ProviderAPI extends IntentService {
Log.v("ClassName", "Provider API");
}
- @Override
- public void onCreate() {
- super.onCreate();
- mHandler = new Handler();
- CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) );
- }
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE);
+ CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) );
+ }
public static String lastProviderMainUrl() {
return last_provider_main_url;
@@ -174,14 +174,14 @@ public class ProviderAPI extends IntentService {
}
}
} else if (action.equalsIgnoreCase(SRP_REGISTER)) {
- Bundle session_id_bundle = registerWithSRP(parameters);
+ Bundle session_id_bundle = tryToRegisterWithSRP(parameters);
if(session_id_bundle.getBoolean(RESULT_KEY)) {
receiver.send(SRP_REGISTRATION_SUCCESSFUL, session_id_bundle);
} else {
receiver.send(SRP_REGISTRATION_FAILED, session_id_bundle);
}
} else if (action.equalsIgnoreCase(SRP_AUTH)) {
- Bundle session_id_bundle = authenticateBySRP(parameters);
+ Bundle session_id_bundle = tryToAuthenticateBySRP(parameters);
if(session_id_bundle.getBoolean(RESULT_KEY)) {
receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle);
} else {
@@ -202,7 +202,7 @@ public class ProviderAPI extends IntentService {
}
}
- private Bundle registerWithSRP(Bundle task) {
+ private Bundle tryToRegisterWithSRP(Bundle task) {
Bundle session_id_bundle = new Bundle();
int progress = 0;
@@ -210,23 +210,7 @@ public class ProviderAPI extends IntentService {
String password = (String) task.get(LogInDialog.PASSWORD);
String authentication_server = (String) task.get(Provider.API_URL);
if(validUserLoginData(username, password)) {
-
- 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[] salt = ConfigHelper.trim(client.calculateNewSalt());
- // byte[] salted_password = client.calculatePasswordHash(username, password, salt);
- /* Calculate password verifier */
- BigInteger password_verifier = client.calculateV(username, password, salt);
- /* Send to the server */
- JSONObject result = sendNewUserDataToSRPServer(authentication_server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16));
- if(result.has(ERRORS))
- session_id_bundle = authFailedNotification(result, username);
- else {
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putString(LogInDialog.PASSWORD, password);
- session_id_bundle.putBoolean(RESULT_KEY, true);
- }
- Log.d(TAG, result.toString());
+ session_id_bundle = registerWithSRP(username, password, authentication_server);
broadcast_progress(progress++);
} else {
if(!wellFormedPassword(password)) {
@@ -242,69 +226,91 @@ public class ProviderAPI extends IntentService {
return session_id_bundle;
}
+
+ private Bundle registerWithSRP(String username, String password, String server) {
+ LeapSRPSession client = new LeapSRPSession(username, password);
+ byte[] salt = client.calculateNewSalt();
+
+ BigInteger password_verifier = client.calculateV(username, password, salt);
+ JSONObject api_result = sendNewUserDataToSRPServer(server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16));
+
+ Bundle result = new Bundle();
+ if(api_result.has(ERRORS))
+ result = authFailedNotification(api_result, username);
+ else {
+ result.putString(LogInDialog.USERNAME, username);
+ result.putString(LogInDialog.PASSWORD, password);
+ result.putBoolean(RESULT_KEY, true);
+ }
+
+ return result;
+ }
/**
* 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 RESULT_KEY, and which is true if authentication was successful.
*/
- private Bundle authenticateBySRP(Bundle task) {
- Bundle session_id_bundle = new Bundle();
+ private Bundle tryToAuthenticateBySRP(Bundle task) {
+ Bundle result = new Bundle();
int progress = 0;
String username = (String) task.get(LogInDialog.USERNAME);
String password = (String) task.get(LogInDialog.PASSWORD);
if(validUserLoginData(username, password)) {
-
- String authentication_server = (String) task.get(Provider.API_URL);
- JSONObject authentication_step_result = new JSONObject();
+ String server = (String) task.get(Provider.API_URL);
- 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();
- broadcast_progress(progress++);
- authentication_step_result = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16));
- try {
- String salt = authentication_step_result.getString(LeapSRPSession.SALT);
- broadcast_progress(progress++);
- byte[] Bbytes = new BigInteger(authentication_step_result.getString("B"), 16).toByteArray();
- byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes);
- if(M1 != null) {
- broadcast_progress(progress++);
- authentication_step_result = sendM1ToSRPServer(authentication_server, username, M1);
- setTokenIfAvailable(authentication_step_result);
- byte[] M2 = new BigInteger(authentication_step_result.getString(LeapSRPSession.M2), 16).toByteArray();
- if(client.verify(M2)) {
- session_id_bundle.putBoolean(RESULT_KEY, true);
- broadcast_progress(progress++);
- } else {
- authFailedNotification(authentication_step_result, username);
- }
- } else {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message));
- }
- } catch (JSONException e) {
- session_id_bundle = authFailedNotification(authentication_step_result, username);
- e.printStackTrace();
- }
+ authenticate(username, password, server);
broadcast_progress(progress++);
} else {
if(!wellFormedPassword(password)) {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true);
+ result.putBoolean(RESULT_KEY, false);
+ result.putString(LogInDialog.USERNAME, username);
+ result.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true);
}
if(username.isEmpty()) {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true);
+ result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(LogInDialog.USERNAME_MISSING, true);
}
}
- return session_id_bundle;
+ return result;
}
+
+ private Bundle authenticate(String username, String password, String server) {
+ Bundle result = new Bundle();
+
+ LeapSRPSession client = new LeapSRPSession(username, password);
+ byte[] A = client.exponential();
+
+ JSONObject step_result = sendAToSRPServer(server, username, new BigInteger(1, A).toString(16));
+ try {
+ String salt = step_result.getString(LeapSRPSession.SALT);
+ byte[] Bbytes = new BigInteger(step_result.getString("B"), 16).toByteArray();
+ byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes);
+ if(M1 != null) {
+ step_result = sendM1ToSRPServer(server, username, M1);
+ setTokenIfAvailable(step_result);
+ byte[] M2 = new BigInteger(step_result.getString(LeapSRPSession.M2), 16).toByteArray();
+ if(client.verify(M2)) {
+ result.putBoolean(RESULT_KEY, true);
+ } else {
+ authFailedNotification(step_result, username);
+ }
+ } else {
+ result.putBoolean(RESULT_KEY, false);
+ result.putString(LogInDialog.USERNAME, username);
+ result.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message));
+ }
+ } catch (JSONException e) {
+ result = authFailedNotification(step_result, username);
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
private boolean setTokenIfAvailable(JSONObject authentication_step_result) {
try {
LeapSRPSession.setToken(authentication_step_result.getString(LeapSRPSession.TOKEN));
@@ -369,13 +375,6 @@ public class ProviderAPI extends IntentService {
* @param username
* @param clientA First SRP parameter sent
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendAToSRPServer(String server_url, String username, String clientA) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -390,13 +389,6 @@ public class ProviderAPI extends IntentService {
* @param username
* @param m1 Second SRP parameter sent
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -412,13 +404,6 @@ public class ProviderAPI extends IntentService {
* @param salted_password
* @param password_verifier
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendNewUserDataToSRPServer(String server_url, String username, String salt, String password_verifier) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -563,12 +548,12 @@ public class ProviderAPI extends IntentService {
private Bundle downloadCACert(boolean danger_on) {
Bundle result = new Bundle();
try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
String ca_cert_url = provider_json.getString(Provider.CA_CERT_URI);
String cert_string = downloadWithCommercialCA(ca_cert_url, danger_on);
if(validCertificate(cert_string) && setting_up_provider) {
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit();
+ preferences.edit().putString(Provider.CA_CERT, cert_string).commit();
result.putBoolean(RESULT_KEY, true);
} else {
String reason_to_fail = pickErrorMessage(cert_string);
@@ -589,21 +574,43 @@ public class ProviderAPI extends IntentService {
return CA_CERT_DOWNLOADED;
}
- private boolean validCertificate(String cert_string) {
- boolean result = false;
- if(!ConfigHelper.checkErroneousDownload(cert_string)) {
- X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string);
- try {
- Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- result = true;
- } catch (CertificateEncodingException e) {
- Log.d(TAG, e.getLocalizedMessage());
- }
- }
+ private boolean validCertificate(String cert_string) {
+ boolean result = false;
+ if(!ConfigHelper.checkErroneousDownload(cert_string)) {
+ X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(cert_string);
+ try {
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
+ String fingerprint = provider_json.getString(Provider.CA_CERT_FINGERPRINT);
+ String encoding = fingerprint.split(":")[0];
+ String expected_fingerprint = fingerprint.split(":")[1];
+ String real_fingerprint = base64toHex(Base64.encodeToString(
+ MessageDigest.getInstance(encoding).digest(certificate.getEncoded()),
+ Base64.DEFAULT));
+
+ result = real_fingerprint.trim().equalsIgnoreCase(expected_fingerprint.trim());
+ } catch (JSONException e) {
+ result = false;
+ } catch (NoSuchAlgorithmException e) {
+ result = false;
+ } catch (CertificateEncodingException e) {
+ result = false;
+ }
+ }
- return result;
+ return result;
+ }
+
+ private String base64toHex(String base64_input) {
+ byte[] byteArray = Base64.decode(base64_input, Base64.DEFAULT);
+ int readBytes = byteArray.length;
+ StringBuffer hexData = new StringBuffer();
+ int onebyte;
+ for (int i=0; i < readBytes; i++) {
+ onebyte = ((0x000000ff & byteArray[i]) | 0xffffff00);
+ hexData.append(Integer.toHexString(onebyte).substring(6));
}
-
+ return hexData.toString();
+ }
private Bundle getAndSetProviderJson(String provider_main_url, boolean danger_on) {
Bundle result = new Bundle();
@@ -615,9 +622,9 @@ public class ProviderAPI extends IntentService {
String name = provider_json.getString(Provider.NAME);
//TODO setProviderName(name);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.KEY, provider_json.toString()).commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_REGISTERED)).commit();
+ preferences.edit().putString(Provider.KEY, provider_json.toString()).commit();
+ preferences.edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit();
+ preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_REGISTERED)).commit();
result.putBoolean(RESULT_KEY, true);
} catch (JSONException e) {
@@ -641,13 +648,13 @@ public class ProviderAPI extends IntentService {
String eip_service_json_string = "";
if(setting_up_provider) {
try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
String eip_service_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
eip_service_json_string = downloadWithProviderCA(eip_service_url, true);
JSONObject eip_service_json = new JSONObject(eip_service_json_string);
eip_service_json.getInt(Provider.API_RETURN_SERIAL);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.KEY, eip_service_json.toString()).commit();
+ preferences.edit().putString(EIP.KEY, eip_service_json.toString()).commit();
result.putBoolean(RESULT_KEY, true);
} catch (JSONException e) {
@@ -772,7 +779,7 @@ public class ProviderAPI extends IntentService {
}
private javax.net.ssl.SSLSocketFactory getProviderSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
- String provider_cert_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.CA_CERT,"");
+ String provider_cert_string = preferences.getString(Provider.CA_CERT,"");
java.security.cert.Certificate provider_certificate = ConfigHelper.parseX509CertificateFromString(provider_cert_string);
@@ -897,81 +904,72 @@ public class ProviderAPI extends IntentService {
private boolean updateVpnCertificate() {
getNewCert();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit();
+ preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit();
Intent updateEIP = new Intent(getApplicationContext(), EIP.class);
updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE);
startService(updateEIP);
return true;
}
- /**
- * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate.
- *
- * @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() {
-
- try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+
+ /**
+ * Downloads a new OpenVPN certificate, attaching authenticated cookie for authenticated certificate.
+ *
+ * @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() {
+ try {
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
- String provider_main_url = provider_json.getString(Provider.API_URL);
- URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE);
+ String provider_main_url = provider_json.getString(Provider.API_URL);
+ URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE);
- boolean danger_on = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getBoolean(ProviderItem.DANGER_ON, false);
+ boolean danger_on = preferences.getBoolean(ProviderItem.DANGER_ON, false);
- String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on);
+ String cert_string = downloadWithProviderCA(new_cert_string_url.toString(), danger_on);
- if(!cert_string.isEmpty()) {
- if(ConfigHelper.checkErroneousDownload(cert_string)) {
- String reason_to_fail = provider_json.getString(ERRORS);
- //result.putString(ConfigHelper.ERRORS_KEY, reason_to_fail);
- //result.putBoolean(ConfigHelper.RESULT_KEY, false);
- return false;
- } else {
-
- // API returns concatenated cert & key. Split them for OpenVPN options
- String certificateString = null, keyString = null;
- String[] certAndKey = cert_string.split("(?<=-\n)");
- for (int i=0; i < certAndKey.length-1; i++){
- if ( certAndKey[i].contains("KEY") ) {
- keyString = certAndKey[i++] + certAndKey[i];
- }
- else if ( certAndKey[i].contains("CERTIFICATE") ) {
- certificateString = certAndKey[i++] + certAndKey[i];
- }
- }
- try {
- RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString);
- keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT );
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit();
-
- X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString);
- certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit();
+ if(cert_string.isEmpty() || ConfigHelper.checkErroneousDownload(cert_string))
+ return false;
+ else
+ return loadCertificate(cert_string);
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
+ } catch (MalformedURLException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ private boolean loadCertificate(String cert_string) {
+ try {
+ // API returns concatenated cert & key. Split them for OpenVPN options
+ String certificateString = null, keyString = null;
+ String[] certAndKey = cert_string.split("(?<=-\n)");
+ for (int i=0; i < certAndKey.length-1; i++){
+ if ( certAndKey[i].contains("KEY") ) {
+ keyString = certAndKey[i++] + certAndKey[i];
+ }
+ else if ( certAndKey[i].contains("CERTIFICATE") ) {
+ certificateString = certAndKey[i++] + certAndKey[i];
+ }
+ }
+ RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString);
+ keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT );
+ preferences.edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit();
+
+ X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString);
+ certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
+ preferences.edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit();
+ preferences.edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit();
- return true;
- } catch (CertificateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false;
- }
- }
- } 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 false;
- }*/
+ return true;
+ } catch (CertificateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ return false;
}
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java b/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java
deleted file mode 100644
index 885b5105..00000000
--- a/app/src/main/java/se/leap/bitmaskclient/LeapHttpClient.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Copyright (c) 2013 LEAP Encryption Access Project and contributers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- package se.leap.bitmaskclient;
-
-import java.security.KeyStore;
-
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.SingleClientConnManager;
-import android.content.Context;
-
-/**
- * Implements an HTTP client, enabling LEAP Android app to manage its own runtime keystore or bypass default Android security measures.
- *
- * @author rafa
- *
- */
-public class LeapHttpClient extends DefaultHttpClient {
-
- private static LeapHttpClient client;
-
- /**
- * If the class scope client is null, it creates one and imports, if existing, the main certificate from Shared Preferences.
- * @param context
- * @return the new client.
- */
- public static LeapHttpClient getInstance(String cert_string) {
- if(client == null) {
- if(cert_string != null) {
- ConfigHelper.addTrustedCertificate("provider_ca_certificate", cert_string);
- }
- }
- return client;
- }
-
- @Override
- protected ClientConnectionManager createClientConnectionManager() {
- SchemeRegistry registry = new SchemeRegistry();
- registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- registry.register(new Scheme("https", newSslSocketFactory(), 443));
-
- return new SingleClientConnManager(getParams(), registry);
- }
-
- /**
- * Uses keystore from ConfigHelper for the SSLSocketFactory.
- * @return
- */
- private SSLSocketFactory newSslSocketFactory() {
- try {
- KeyStore trusted = ConfigHelper.getKeystore();
- SSLSocketFactory sf = new SSLSocketFactory(trusted);
-
- return sf;
- } catch (Exception e) {
- throw new AssertionError(e);
- }
- }
-}
diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
index 29b429d1..a953a710 100644
--- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
+++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
@@ -63,15 +63,16 @@ public class LeapSRPSession {
private static int A_LEN;
+
/** Creates a new SRP server session object from the username, password
verifier,
@param username, the user ID
@param password, the user clear text password
@param params, the SRP parameters for the session
*/
- public LeapSRPSession(String username, String password, SRPParameters params)
+ public LeapSRPSession(String username, String password)
{
- this(username, password, params, null);
+ this(username, password, null);
}
/** Creates a new SRP server session object from the username, password
@@ -81,9 +82,9 @@ public class LeapSRPSession {
@param params, the SRP parameters for the session
@param abytes, the random exponent used in the A public key
*/
- public LeapSRPSession(String username, String password, SRPParameters params,
- byte[] abytes) {
- this.params = params;
+ public LeapSRPSession(String username, String password, byte[] abytes) {
+
+ params = new SRPParameters(new BigInteger(ConfigHelper.NG_1024, 16).toByteArray(), ConfigHelper.G.toByteArray(), BigInteger.ZERO.toByteArray(), "SHA-256");
this.g = new BigInteger(1, params.g);
N_bytes = ConfigHelper.trim(params.N);
this.N = new BigInteger(1, N_bytes);
@@ -159,7 +160,7 @@ public class LeapSRPSession {
public byte[] calculateNewSalt() {
try {
BigInteger salt = new BigInteger(64, SecureRandom.getInstance("SHA1PRNG"));
- return salt.toByteArray();
+ return ConfigHelper.trim(salt.toByteArray());
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/Provider.java b/app/src/main/java/se/leap/bitmaskclient/Provider.java
index 5326709f..8d6385e0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Provider.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Provider.java
@@ -52,6 +52,7 @@ public final class Provider implements Serializable {
KEY = "provider",
CA_CERT = "ca_cert",
CA_CERT_URI = "ca_cert_uri",
+ CA_CERT_FINGERPRINT = "ca_cert_fingerprint",
NAME = "name",
DESCRIPTION = "description",
DOMAIN = "domain",
diff --git a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java
index ab05bc51..3c8ec607 100644
--- a/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/release/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -14,18 +14,25 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
- package se.leap.bitmaskclient;
+package se.leap.bitmaskclient;
+import android.app.IntentService;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.util.Base64;
+import android.util.Log;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
+import java.net.ConnectException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
-import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URISyntaxException;
@@ -33,10 +40,10 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.UnknownHostException;
-import javax.net.ssl.SSLHandshakeException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateEncodingException;
@@ -47,32 +54,21 @@ import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Scanner;
import java.util.NoSuchElementException;
-
+import java.util.Scanner;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
-
import org.apache.http.client.ClientProtocolException;
-import org.jboss.security.srp.SRPParameters;
import org.json.JSONException;
import org.json.JSONObject;
-
import se.leap.bitmaskclient.R;
-import se.leap.bitmaskclient.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;
/**
@@ -86,8 +82,6 @@ import android.util.Log;
*/
public class ProviderAPI extends IntentService {
- private Handler mHandler;
-
final public static String
SET_UP_PROVIDER = "setUpProvider",
DOWNLOAD_NEW_PROVIDER_DOTJSON = "downloadNewProviderDotJSON",
@@ -130,6 +124,7 @@ public class ProviderAPI extends IntentService {
private static String last_provider_main_url;
private static boolean setting_up_provider = true;
+ private static SharedPreferences preferences;
public static void stop() {
setting_up_provider = false;
@@ -140,12 +135,12 @@ public class ProviderAPI extends IntentService {
Log.v("ClassName", "Provider API");
}
- @Override
- public void onCreate() {
- super.onCreate();
- mHandler = new Handler();
- CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER) );
- }
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ preferences = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE);
+ CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER));
+ }
public static String lastProviderMainUrl() {
return last_provider_main_url;
@@ -172,19 +167,19 @@ public class ProviderAPI extends IntentService {
}
}
} else if (action.equalsIgnoreCase(SRP_REGISTER)) {
- Bundle session_id_bundle = registerWithSRP(parameters);
- if(session_id_bundle.getBoolean(RESULT_KEY)) {
- receiver.send(SRP_REGISTRATION_SUCCESSFUL, session_id_bundle);
+ Bundle result = tryToRegister(parameters);
+ if(result.getBoolean(RESULT_KEY)) {
+ receiver.send(SRP_REGISTRATION_SUCCESSFUL, result);
} else {
- receiver.send(SRP_REGISTRATION_FAILED, session_id_bundle);
+ receiver.send(SRP_REGISTRATION_FAILED, result);
}
} else if (action.equalsIgnoreCase(SRP_AUTH)) {
- Bundle session_id_bundle = authenticateBySRP(parameters);
- if(session_id_bundle.getBoolean(RESULT_KEY)) {
- receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, session_id_bundle);
- } else {
- receiver.send(SRP_AUTHENTICATION_FAILED, session_id_bundle);
- }
+ Bundle result = tryToAuthenticate(parameters);
+ if(result.getBoolean(RESULT_KEY)) {
+ receiver.send(SRP_AUTHENTICATION_SUCCESSFUL, result);
+ } else {
+ receiver.send(SRP_AUTHENTICATION_FAILED, result);
+ }
} else if (action.equalsIgnoreCase(LOG_OUT)) {
if(logOut(parameters)) {
receiver.send(LOGOUT_SUCCESSFUL, Bundle.EMPTY);
@@ -192,7 +187,6 @@ public class ProviderAPI extends IntentService {
receiver.send(LOGOUT_FAILED, Bundle.EMPTY);
}
} else if (action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)) {
- Log.d(TAG, "action.equalsIgnoreCase(DOWNLOAD_CERTIFICATE)");
if(updateVpnCertificate()) {
receiver.send(CORRECTLY_DOWNLOADED_CERTIFICATE, Bundle.EMPTY);
} else {
@@ -201,7 +195,7 @@ public class ProviderAPI extends IntentService {
}
}
- private Bundle registerWithSRP(Bundle task) {
+ private Bundle tryToRegister(Bundle task) {
Bundle session_id_bundle = new Bundle();
int progress = 0;
@@ -209,23 +203,7 @@ public class ProviderAPI extends IntentService {
String password = (String) task.get(LogInDialog.PASSWORD);
String authentication_server = (String) task.get(Provider.API_URL);
if(validUserLoginData(username, password)) {
-
- 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[] salt = ConfigHelper.trim(client.calculateNewSalt());
- // byte[] salted_password = client.calculatePasswordHash(username, password, salt);
- /* Calculate password verifier */
- BigInteger password_verifier = client.calculateV(username, password, salt);
- /* Send to the server */
- JSONObject result = sendNewUserDataToSRPServer(authentication_server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16));
- if(result.has(ERRORS))
- session_id_bundle = authFailedNotification(result, username);
- else {
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putString(LogInDialog.PASSWORD, password);
- session_id_bundle.putBoolean(RESULT_KEY, true);
- }
- Log.d(TAG, result.toString());
+ session_id_bundle = register(username, password, authentication_server);
broadcast_progress(progress++);
} else {
if(!wellFormedPassword(password)) {
@@ -241,6 +219,25 @@ public class ProviderAPI extends IntentService {
return session_id_bundle;
}
+
+ private Bundle register(String username, String password, String server) {
+ LeapSRPSession client = new LeapSRPSession(username, password);
+ byte[] salt = client.calculateNewSalt();
+
+ BigInteger password_verifier = client.calculateV(username, password, salt);
+ JSONObject api_result = sendNewUserDataToSRPServer(server, username, new BigInteger(1, salt).toString(16), password_verifier.toString(16));
+
+ Bundle result = new Bundle();
+ if(api_result.has(ERRORS))
+ result = authFailedNotification(api_result, username);
+ else {
+ result.putString(LogInDialog.USERNAME, username);
+ result.putString(LogInDialog.PASSWORD, password);
+ result.putBoolean(RESULT_KEY, true);
+ }
+
+ return result;
+ }
/**
* Starts the authentication process using SRP protocol.
@@ -248,63 +245,66 @@ public class ProviderAPI extends IntentService {
* @param task containing: username, password and api url.
* @return a bundle with a boolean value mapped to a key named RESULT_KEY, and which is true if authentication was successful.
*/
- private Bundle authenticateBySRP(Bundle task) {
- Bundle session_id_bundle = new Bundle();
+ private Bundle tryToAuthenticate(Bundle task) {
+ Bundle result = new Bundle();
int progress = 0;
String username = (String) task.get(LogInDialog.USERNAME);
String password = (String) task.get(LogInDialog.PASSWORD);
if(validUserLoginData(username, password)) {
- String authentication_server = (String) task.get(Provider.API_URL);
- JSONObject authentication_step_result = new JSONObject();
+ String server = (String) task.get(Provider.API_URL);
- 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();
- broadcast_progress(progress++);
- authentication_step_result = sendAToSRPServer(authentication_server, username, new BigInteger(1, A).toString(16));
- try {
- String salt = authentication_step_result.getString(LeapSRPSession.SALT);
- broadcast_progress(progress++);
- byte[] Bbytes = new BigInteger(authentication_step_result.getString("B"), 16).toByteArray();
- byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes);
- if(M1 != null) {
- broadcast_progress(progress++);
- authentication_step_result = sendM1ToSRPServer(authentication_server, username, M1);
- setTokenIfAvailable(authentication_step_result);
- byte[] M2 = new BigInteger(authentication_step_result.getString(LeapSRPSession.M2), 16).toByteArray();
- if(client.verify(M2)) {
- session_id_bundle.putBoolean(RESULT_KEY, true);
- broadcast_progress(progress++);
- } else {
- authFailedNotification(authentication_step_result, username);
- }
- } else {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message));
- }
- } catch (JSONException e) {
- session_id_bundle = authFailedNotification(authentication_step_result, username);
- e.printStackTrace();
- }
+ authenticate(username, password, server);
broadcast_progress(progress++);
} else {
if(!wellFormedPassword(password)) {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putString(LogInDialog.USERNAME, username);
- session_id_bundle.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true);
+ result.putBoolean(RESULT_KEY, false);
+ result.putString(LogInDialog.USERNAME, username);
+ result.putBoolean(LogInDialog.PASSWORD_INVALID_LENGTH, true);
}
if(username.isEmpty()) {
- session_id_bundle.putBoolean(RESULT_KEY, false);
- session_id_bundle.putBoolean(LogInDialog.USERNAME_MISSING, true);
+ result.putBoolean(RESULT_KEY, false);
+ result.putBoolean(LogInDialog.USERNAME_MISSING, true);
}
}
- return session_id_bundle;
+ return result;
}
+ private Bundle authenticate(String username, String password, String server) {
+ Bundle result = new Bundle();
+
+ LeapSRPSession client = new LeapSRPSession(username, password);
+ byte[] A = client.exponential();
+
+ JSONObject step_result = sendAToSRPServer(server, username, new BigInteger(1, A).toString(16));
+ try {
+ String salt = step_result.getString(LeapSRPSession.SALT);
+ byte[] Bbytes = new BigInteger(step_result.getString("B"), 16).toByteArray();
+ byte[] M1 = client.response(new BigInteger(salt, 16).toByteArray(), Bbytes);
+ if(M1 != null) {
+ step_result = sendM1ToSRPServer(server, username, M1);
+ setTokenIfAvailable(step_result);
+ byte[] M2 = new BigInteger(step_result.getString(LeapSRPSession.M2), 16).toByteArray();
+ if(client.verify(M2)) {
+ result.putBoolean(RESULT_KEY, true);
+ } else {
+ authFailedNotification(step_result, username);
+ }
+ } else {
+ result.putBoolean(RESULT_KEY, false);
+ result.putString(LogInDialog.USERNAME, username);
+ result.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_srp_math_error_user_message));
+ }
+ } catch (JSONException e) {
+ result = authFailedNotification(step_result, username);
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
private boolean setTokenIfAvailable(JSONObject authentication_step_result) {
try {
LeapSRPSession.setToken(authentication_step_result.getString(LeapSRPSession.TOKEN));
@@ -369,13 +369,6 @@ public class ProviderAPI extends IntentService {
* @param username
* @param clientA First SRP parameter sent
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendAToSRPServer(String server_url, String username, String clientA) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -390,13 +383,6 @@ public class ProviderAPI extends IntentService {
* @param username
* @param m1 Second SRP parameter sent
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendM1ToSRPServer(String server_url, String username, byte[] m1) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -411,13 +397,6 @@ public class ProviderAPI extends IntentService {
* @param salted_password
* @param password_verifier
* @return response from authentication server
- * @throws ClientProtocolException
- * @throws IOException
- * @throws JSONException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendNewUserDataToSRPServer(String server_url, String username, String salt, String password_verifier) {
Map<String, String> parameters = new HashMap<String, String>();
@@ -435,13 +414,6 @@ public class ProviderAPI extends IntentService {
* @param request_method
* @param parameters
* @return response from authentication server
- * @throws IOException
- * @throws JSONException
- * @throws MalformedURLException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws KeyStoreException
- * @throws KeyManagementException
*/
private JSONObject sendToServer(String url, String request_method, Map<String, String> parameters) {
JSONObject json_response;
@@ -545,7 +517,7 @@ public class ProviderAPI extends IntentService {
}
if(!PROVIDER_JSON_DOWNLOADED)
- current_download = getAndSetProviderJson(last_provider_main_url);
+ current_download = getAndSetProviderJson(last_provider_main_url);
if(PROVIDER_JSON_DOWNLOADED || (current_download.containsKey(RESULT_KEY) && current_download.getBoolean(RESULT_KEY))) {
broadcast_progress(progress++);
PROVIDER_JSON_DOWNLOADED = true;
@@ -569,13 +541,13 @@ public class ProviderAPI extends IntentService {
private Bundle downloadCACert() {
Bundle result = new Bundle();
try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
String ca_cert_url = provider_json.getString(Provider.CA_CERT_URI);
String cert_string = downloadWithCommercialCA(ca_cert_url);
result.putBoolean(RESULT_KEY, true);
if(validCertificate(cert_string) && setting_up_provider) {
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.CA_CERT, cert_string).commit();
+ preferences.edit().putString(Provider.CA_CERT, cert_string).commit();
result.putBoolean(RESULT_KEY, true);
} else {
String reason_to_fail = pickErrorMessage(cert_string);
@@ -596,20 +568,43 @@ public class ProviderAPI extends IntentService {
return CA_CERT_DOWNLOADED;
}
- private boolean validCertificate(String cert_string) {
- boolean result = false;
- if(!ConfigHelper.checkErroneousDownload(cert_string)) {
- X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(cert_string);
- try {
- Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- result = true;
- } catch (CertificateEncodingException e) {
- Log.d(TAG, e.getLocalizedMessage());
- }
- }
+ private boolean validCertificate(String cert_string) {
+ boolean result = false;
+ if(!ConfigHelper.checkErroneousDownload(cert_string)) {
+ X509Certificate certificate = ConfigHelper.parseX509CertificateFromString(cert_string);
+ try {
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
+ String fingerprint = provider_json.getString(Provider.CA_CERT_FINGERPRINT);
+ String encoding = fingerprint.split(":")[0];
+ String expected_fingerprint = fingerprint.split(":")[1];
+ String real_fingerprint = base64toHex(Base64.encodeToString(
+ MessageDigest.getInstance(encoding).digest(certificate.getEncoded()),
+ Base64.DEFAULT));
+
+ result = real_fingerprint.trim().equalsIgnoreCase(expected_fingerprint.trim());
+ } catch (JSONException e) {
+ result = false;
+ } catch (NoSuchAlgorithmException e) {
+ result = false;
+ } catch (CertificateEncodingException e) {
+ result = false;
+ }
+ }
- return result;
+ return result;
+ }
+
+ private String base64toHex(String base64_input) {
+ byte[] byteArray = Base64.decode(base64_input, Base64.DEFAULT);
+ int readBytes = byteArray.length;
+ StringBuffer hexData = new StringBuffer();
+ int onebyte;
+ for (int i=0; i < readBytes; i++) {
+ onebyte = ((0x000000ff & byteArray[i]) | 0xffffff00);
+ hexData.append(Integer.toHexString(onebyte).substring(6));
}
+ return hexData.toString();
+ }
private Bundle getAndSetProviderJson(String provider_main_url) {
Bundle result = new Bundle();
@@ -622,9 +617,9 @@ public class ProviderAPI extends IntentService {
String name = provider_json.getString(Provider.NAME);
//TODO setProviderName(name);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(Provider.KEY, provider_json.toString()).commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putBoolean(EIP.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_REGISTERED)).commit();
+ preferences.edit().putString(Provider.KEY, provider_json.toString()).commit();
+ preferences.edit().putBoolean(EIP.ALLOWED_ANON, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_ANON)).commit();
+ preferences.edit().putBoolean(EIP.ALLOWED_REGISTERED, provider_json.getJSONObject(Provider.SERVICE).getBoolean(EIP.ALLOWED_REGISTERED)).commit();
result.putBoolean(RESULT_KEY, true);
} catch (JSONException e) {
@@ -648,13 +643,13 @@ public class ProviderAPI extends IntentService {
String eip_service_json_string = "";
if(setting_up_provider) {
try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
String eip_service_url = provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.SERVICE_API_PATH;
eip_service_json_string = downloadWithProviderCA(eip_service_url);
JSONObject eip_service_json = new JSONObject(eip_service_json_string);
eip_service_json.getInt(Provider.API_RETURN_SERIAL);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.KEY, eip_service_json.toString()).commit();
+ preferences.edit().putString(EIP.KEY, eip_service_json.toString()).commit();
result.putBoolean(RESULT_KEY, true);
} catch (JSONException e) {
@@ -774,7 +769,7 @@ public class ProviderAPI extends IntentService {
}
private javax.net.ssl.SSLSocketFactory getProviderSSLSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
- String provider_cert_string = getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.CA_CERT,"");
+ String provider_cert_string = preferences.getString(Provider.CA_CERT,"");
java.security.cert.Certificate provider_certificate = ConfigHelper.parseX509CertificateFromString(provider_cert_string);
@@ -899,7 +894,7 @@ public class ProviderAPI extends IntentService {
private boolean updateVpnCertificate() {
getNewCert();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putInt(EIP.PARSED_SERIAL, 0).commit();
+ preferences.edit().putInt(EIP.PARSED_SERIAL, 0).commit();
Intent updateEIP = new Intent(getApplicationContext(), EIP.class);
updateEIP.setAction(EIP.ACTION_UPDATE_EIP_SERVICE);
startService(updateEIP);
@@ -915,7 +910,7 @@ public class ProviderAPI extends IntentService {
private boolean getNewCert() {
try {
- JSONObject provider_json = new JSONObject(getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).getString(Provider.KEY, ""));
+ JSONObject provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
String provider_main_url = provider_json.getString(Provider.API_URL);
URL new_cert_string_url = new URL(provider_main_url + "/" + provider_json.getString(Provider.API_VERSION) + "/" + EIP.CERTIFICATE);
@@ -944,12 +939,12 @@ public class ProviderAPI extends IntentService {
try {
RSAPrivateKey keyCert = ConfigHelper.parseRsaKeyFromString(keyString);
keyString = Base64.encodeToString( keyCert.getEncoded(), Base64.DEFAULT );
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit();
+ preferences.edit().putString(EIP.PRIVATE_KEY, "-----BEGIN RSA PRIVATE KEY-----\n"+keyString+"-----END RSA PRIVATE KEY-----").commit();
X509Certificate certCert = ConfigHelper.parseX509CertificateFromString(certificateString);
certificateString = Base64.encodeToString( certCert.getEncoded(), Base64.DEFAULT);
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit();
- getSharedPreferences(Dashboard.SHARED_PREFERENCES, MODE_PRIVATE).edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit();
+ preferences.edit().putString(EIP.CERTIFICATE, "-----BEGIN CERTIFICATE-----\n"+certificateString+"-----END CERTIFICATE-----").commit();
+ preferences.edit().putString(EIP.DATE_FROM_CERTIFICATE, EIP.certificate_date_format.format(Calendar.getInstance().getTime())).commit();
return true;
} catch (CertificateException e) {
// TODO Auto-generated catch block
@@ -968,10 +963,6 @@ public class ProviderAPI extends IntentService {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
- } /*catch (URISyntaxException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- return false;
- }*/
+ }
}
}