summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2013-03-29 16:30:39 +0100
committerParménides GV <parmegv@sdf.org>2013-03-29 16:30:39 +0100
commit54ad71d09d6cb61fad62d1376cd7b3bf237e16f9 (patch)
tree6b7c978d7c957a78e9a50466c4a1fe34f07b5fa0
parent57ab546646e3e2814be547dd4666ca2de4548597 (diff)
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.
-rw-r--r--src/se/leap/leapclient/ProviderAPI.java270
1 files changed, 35 insertions, 235 deletions
diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java
index eb3afcf..aa1ce30 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<Cookie> 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<Cookie> 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);