WIFI: EAP-AKA End-To-End
- Decode UMTS-AUTH form of CTRL-REQ-SIM request
- manage UMTS authentication
- cleanup useless code
- make Native API simAuthResponse usable for both
EAP-SIM and EAP-AKA
Change-Id: Ie24c59d87ba2e6a17a0da25fa3d58803aab423f9
Signed-off-by: Honore Tricot <honorex.tricot@intel.com>
Signed-off-by: Abdelmajid MLAYEH <abdelmajidx.mlayeh@intel.com>
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 97e8824..227c8d2 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -278,6 +278,19 @@
Pattern.compile("SIM-([0-9]*):GSM-AUTH((:[0-9a-f]+)+) needed for SSID (.+)");
/**
+ * Regex pattern for extracting an external 3G sim authentication request from a string.
+ * Matches a strings like the following:<pre>
+ * CTRL-REQ-SIM-<network id>:UMTS-AUTH:<RAND>:<AUTN> needed for SSID <SSID>
+ * This pattern should find
+ * 1 - id
+ * 2 - Rand
+ * 3 - Autn
+ * 4 - SSID
+ */
+ private static Pattern mRequestUmtsAuthPattern =
+ Pattern.compile("SIM-([0-9]*):UMTS-AUTH:([0-9a-f]+):([0-9a-f]+) needed for SSID (.+)");
+
+ /**
* Regex pattern for extracting SSIDs from request identity string.
* Matches a strings like the following:<pre>
* CTRL-REQ-IDENTITY-xx:Identity needed for SSID XXXX</pre>
@@ -1248,14 +1261,23 @@
}
mStateMachine.sendMessage(SUP_REQUEST_IDENTITY, eventLogCounter, reason, SSID);
} else if (requestName.startsWith(SIM_STR)) {
- Matcher match = mRequestGsmAuthPattern.matcher(requestName);
- if (match.find()) {
- WifiStateMachine.SimAuthRequestData data =
- new WifiStateMachine.SimAuthRequestData();
- data.networkId = Integer.parseInt(match.group(1));
+ Matcher matchGsm = mRequestGsmAuthPattern.matcher(requestName);
+ Matcher matchUmts = mRequestUmtsAuthPattern.matcher(requestName);
+ WifiStateMachine.SimAuthRequestData data =
+ new WifiStateMachine.SimAuthRequestData();
+ if (matchGsm.find()) {
+ data.networkId = Integer.parseInt(matchGsm.group(1));
data.protocol = WifiEnterpriseConfig.Eap.SIM;
- data.ssid = match.group(4);
- data.challenges = match.group(2).split(":");
+ data.ssid = matchGsm.group(4);
+ data.data = matchGsm.group(2).split(":");
+ mStateMachine.sendMessage(SUP_REQUEST_SIM_AUTH, data);
+ } else if (matchUmts.find()) {
+ data.networkId = Integer.parseInt(matchUmts.group(1));
+ data.protocol = WifiEnterpriseConfig.Eap.AKA;
+ data.ssid = matchUmts.group(4);
+ data.data = new String[2];
+ data.data[0] = matchUmts.group(2);
+ data.data[1] = matchUmts.group(3);
mStateMachine.sendMessage(SUP_REQUEST_SIM_AUTH, data);
} else {
Log.e(TAG, "couldn't parse SIM auth request - " + requestName);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index f35ef61..8b9a524 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -732,9 +732,10 @@
}
}
- public boolean simAuthResponse(int id, String response) {
+ public boolean simAuthResponse(int id, String type, String response) {
+ // with type = GSM-AUTH, UMTS-AUTH or UMTS-AUTS
synchronized (mLock) {
- return doBooleanCommand("CTRL-RSP-SIM-" + id + ":GSM-AUTH" + response);
+ return doBooleanCommand("CTRL-RSP-SIM-" + id + ":" + type + response);
}
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 1076e40..95d90bf 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -798,17 +798,9 @@
int networkId;
int protocol;
String ssid;
- String[] challenges;
- }
-
- public static class SimAuthResponseData {
- int id;
- String Kc1;
- String SRES1;
- String Kc2;
- String SRES2;
- String Kc3;
- String SRES3;
+ // EAP-SIM: data[] contains the 3 rand, one for each of the 3 challenges
+ // EAP-AKA: data[] contains rand & authn couple for the single challenge
+ String[] data;
}
/**
@@ -8708,7 +8700,6 @@
return sb.toString();
}
-
private static byte[] concat(byte[] array1, byte[] array2, byte[] array3) {
int len = array1.length + array2.length + array3.length;
@@ -8757,6 +8748,30 @@
return result;
}
+ private static byte[] concatHex(byte[] array1, byte[] array2) {
+
+ int len = array1.length + array2.length;
+
+ byte[] result = new byte[len];
+
+ int index = 0;
+ if (array1.length != 0) {
+ for (byte b : array1) {
+ result[index] = b;
+ index++;
+ }
+ }
+
+ if (array2.length != 0) {
+ for (byte b : array2) {
+ result[index] = b;
+ index++;
+ }
+ }
+
+ return result;
+ }
+
void handleGsmAuthRequest(SimAuthRequestData requestData) {
if (targetWificonfiguration == null
|| targetWificonfiguration.networkId == requestData.networkId) {
@@ -8771,7 +8786,7 @@
if (tm != null) {
StringBuilder sb = new StringBuilder();
- for (String challenge : requestData.challenges) {
+ for (String challenge : requestData.data) {
logd("RAND = " + challenge);
@@ -8811,13 +8826,85 @@
String response = sb.toString();
logv("Supplicant Response -" + response);
- mWifiNative.simAuthResponse(requestData.networkId, response);
+ mWifiNative.simAuthResponse(requestData.networkId, "GSM-AUTH", response);
} else {
loge("could not get telephony manager");
}
}
void handle3GAuthRequest(SimAuthRequestData requestData) {
+ StringBuilder sb = new StringBuilder();
+ byte[] rand = null;
+ byte[] authn = null;
+ String res_type = "UMTS-AUTH";
+ if (targetWificonfiguration == null
+ || targetWificonfiguration.networkId == requestData.networkId) {
+ logd("id matches targetWifiConfiguration");
+ } else {
+ logd("id does not match targetWifiConfiguration");
+ return;
+ }
+ if (requestData.data.length == 2) {
+ try {
+ rand = parseHex(requestData.data[0]);
+ authn = parseHex(requestData.data[1]);
+ } catch (NumberFormatException e) {
+ loge("malformed challenge");
+ }
+ } else {
+ loge("malformed challenge");
+ }
+
+ String tmResponse = "";
+ if (rand != null && authn != null) {
+ String base64Challenge = android.util.Base64.encodeToString(
+ concatHex(rand,authn), android.util.Base64.NO_WRAP);
+
+ TelephonyManager tm = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ if (tm != null) {
+ int appType = 2; // 2 => USIM
+ tmResponse = tm.getIccSimChallengeResponse(appType, base64Challenge);
+ logv("Raw Response - " + tmResponse);
+ } else {
+ loge("could not get telephony manager");
+ }
+ }
+
+ if (tmResponse != null && tmResponse.length() > 4) {
+ byte[] result = android.util.Base64.decode(tmResponse,
+ android.util.Base64.DEFAULT);
+ loge("Hex Response - " + makeHex(result));
+ byte tag = result[0];
+ if (tag == (byte) 0xdb) {
+ logv("successful 3G authentication ");
+ int res_len = result[1];
+ String res = makeHex(result, 2, res_len);
+ int ck_len = result[res_len + 2];
+ String ck = makeHex(result, res_len + 3, ck_len);
+ int ik_len = result[res_len + ck_len + 3];
+ String ik = makeHex(result, res_len + ck_len + 4, ik_len);
+ sb.append(":" + ik + ":" + ck + ":" + res);
+ logv("ik:" + ik + "ck:" + ck + " res:" + res);
+ } else if (tag == (byte) 0xdc) {
+ loge("synchronisation failure");
+ int auts_len = result[1];
+ String auts = makeHex(result, 2, auts_len);
+ res_type = "UMTS-AUTS";
+ sb.append(":" + auts);
+ logv("auts:" + auts);
+ } else {
+ loge("bad response - unknown tag = " + tag);
+ return;
+ }
+ } else {
+ loge("bad response - " + tmResponse);
+ return;
+ }
+
+ String response = sb.toString();
+ logv("Supplicant Response -" + response);
+ mWifiNative.simAuthResponse(requestData.networkId, res_type, response);
}
}