Merge "Remove unused driver management JNI calls"
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 1e288ef..f93c8bd 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -49,6 +49,7 @@
import android.os.UserManager;
import android.provider.Settings;
import android.security.KeyStore;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -403,7 +404,8 @@
mWriter = new DelayedDiskWrite();
mIpconfigStore = new IpConfigStore(mWriter);
mWifiNetworkHistory = new WifiNetworkHistory(mContext, mLocalLog, mWriter);
- mWifiSupplicantControl = new WifiSupplicantControl(mContext, wifiNative, mLocalLog);
+ TelephonyManager tm = TelephonyManager.from(mContext);
+ mWifiSupplicantControl = new WifiSupplicantControl(tm, wifiNative, mLocalLog);
mWifiKeyStore = new WifiKeyStore(keyStore);
mBackupManagerProxy = new BackupManagerProxy();
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 63cc35c..971e69e 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -28,6 +28,7 @@
import android.os.UserManager;
import android.provider.Settings;
import android.security.KeyStore;
+import android.telephony.TelephonyManager;
import com.android.internal.R;
import com.android.server.am.BatteryStatsService;
@@ -212,6 +213,11 @@
return mWifiMulticastLockManager;
}
+ public TelephonyManager makeTelephonyManager() {
+ // may not be available when WiFi starts
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
public IWificond makeWificond() {
// We depend on being able to refresh our binder in WifiStateMachine, so don't cache it.
IBinder binder = ServiceManager.getService(WIFICOND_SERVICE_NAME);
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 8c0d36a..18c67e4 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -30,21 +30,19 @@
import android.os.Message;
import android.text.TextUtils;
import android.util.ArraySet;
-import android.util.Base64;
import android.util.LocalLog;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.util.Protocol;
+import com.android.internal.util.StateMachine;
import com.android.server.wifi.hotspot2.IconEvent;
import com.android.server.wifi.hotspot2.Utils;
import com.android.server.wifi.p2p.WifiP2pServiceImpl.P2pStatus;
-
-import com.android.internal.util.Protocol;
-import com.android.internal.util.StateMachine;
+import com.android.server.wifi.util.TelephonyUtil.SimAuthRequestData;
import java.io.IOException;
import java.util.HashMap;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -1338,8 +1336,7 @@
} else if (requestName.startsWith(SIM_STR)) {
Matcher matchGsm = mRequestGsmAuthPattern.matcher(requestName);
Matcher matchUmts = mRequestUmtsAuthPattern.matcher(requestName);
- WifiStateMachine.SimAuthRequestData data =
- new WifiStateMachine.SimAuthRequestData();
+ SimAuthRequestData data = new SimAuthRequestData();
if (matchGsm.find()) {
data.networkId = Integer.parseInt(matchGsm.group(1));
data.protocol = WifiEnterpriseConfig.Eap.SIM;
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 0a3c0ab..131d2b0 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -111,6 +111,8 @@
import com.android.server.wifi.hotspot2.Utils;
import com.android.server.wifi.p2p.WifiP2pServiceImpl;
import com.android.server.wifi.util.TelephonyUtil;
+import com.android.server.wifi.util.TelephonyUtil.SimAuthRequestData;
+import com.android.server.wifi.util.TelephonyUtil.SimAuthResponseData;
import java.io.BufferedReader;
import java.io.FileDescriptor;
@@ -878,15 +880,6 @@
/* Soft ap state */
private State mSoftApState = new SoftApState();
- public static class SimAuthRequestData {
- int networkId;
- int protocol;
- String ssid;
- // EAP-SIM: data[] contains the 3 rand, one for each of the 3 challenges
- // EAP-AKA/AKA': data[] contains rand & authn couple for the single challenge
- String[] data;
- }
-
/**
* One of {@link WifiManager#WIFI_STATE_DISABLED},
* {@link WifiManager#WIFI_STATE_DISABLING},
@@ -930,6 +923,14 @@
*/
private final WorkSource mLastRunningWifiUids = new WorkSource();
+ private TelephonyManager mTelephonyManager;
+ private TelephonyManager getTelephonyManager() {
+ if (mTelephonyManager == null) {
+ mTelephonyManager = mWifiInjector.makeTelephonyManager();
+ }
+ return mTelephonyManager;
+ }
+
private final IBatteryStats mBatteryStats;
private final String mTcpBufferSizes;
@@ -5445,7 +5446,8 @@
&& targetWificonfiguration.allowedKeyManagement
.get(WifiConfiguration.KeyMgmt.IEEE8021X)
&& TelephonyUtil.isSimEapMethod(eapMethod)) {
- String identity = TelephonyUtil.getSimIdentity(mContext, eapMethod);
+ String identity =
+ TelephonyUtil.getSimIdentity(getTelephonyManager(), eapMethod);
if (identity != null) {
mWifiNative.simIdentityResponse(networkId, identity);
identitySent = true;
@@ -7594,142 +7596,6 @@
}
}
- private static int parseHex(char ch) {
- if ('0' <= ch && ch <= '9') {
- return ch - '0';
- } else if ('a' <= ch && ch <= 'f') {
- return ch - 'a' + 10;
- } else if ('A' <= ch && ch <= 'F') {
- return ch - 'A' + 10;
- } else {
- throw new NumberFormatException("" + ch + " is not a valid hex digit");
- }
- }
-
- private byte[] parseHex(String hex) {
- /* This only works for good input; don't throw bad data at it */
- if (hex == null) {
- return new byte[0];
- }
-
- if (hex.length() % 2 != 0) {
- throw new NumberFormatException(hex + " is not a valid hex string");
- }
-
- byte[] result = new byte[(hex.length())/2 + 1];
- result[0] = (byte) ((hex.length())/2);
- for (int i = 0, j = 1; i < hex.length(); i += 2, j++) {
- int val = parseHex(hex.charAt(i)) * 16 + parseHex(hex.charAt(i+1));
- byte b = (byte) (val & 0xFF);
- result[j] = b;
- }
-
- return result;
- }
-
- private static String makeHex(byte[] bytes) {
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append(String.format("%02x", b));
- }
- return sb.toString();
- }
-
- private static String makeHex(byte[] bytes, int from, int len) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < len; i++) {
- sb.append(String.format("%02x", bytes[from+i]));
- }
- return sb.toString();
- }
-
- 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;
- }
-
- // TODO move to TelephonyUtil, same with utilities above
- String getGsmSimAuthResponse(String[] requestData, TelephonyManager tm) {
- StringBuilder sb = new StringBuilder();
- for (String challenge : requestData) {
- if (challenge == null || challenge.isEmpty()) {
- continue;
- }
- logd("RAND = " + challenge);
-
- byte[] rand = null;
- try {
- rand = parseHex(challenge);
- } catch (NumberFormatException e) {
- loge("malformed challenge");
- continue;
- }
-
- String base64Challenge = android.util.Base64.encodeToString(
- rand, android.util.Base64.NO_WRAP);
-
- // Try USIM first for authentication.
- String tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
- TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
- if (tmResponse == null) {
- /* Then, in case of failure, issue may be due to sim type, retry as a simple sim
- */
- tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
- TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
- }
- logv("Raw Response - " + tmResponse);
-
- if (tmResponse == null || tmResponse.length() <= 4) {
- loge("bad response - " + tmResponse);
- return null;
- }
-
- byte[] result = android.util.Base64.decode(tmResponse, android.util.Base64.DEFAULT);
- logv("Hex Response -" + makeHex(result));
- int sres_len = result[0];
- if (sres_len >= result.length) {
- loge("malfomed response - " + tmResponse);
- return null;
- }
- String sres = makeHex(result, 1, sres_len);
- int kc_offset = 1 + sres_len;
- if (kc_offset >= result.length) {
- loge("malfomed response - " + tmResponse);
- return null;
- }
- int kc_len = result[kc_offset];
- if (kc_offset + kc_len > result.length) {
- loge("malfomed response - " + tmResponse);
- return null;
- }
- String kc = makeHex(result, 1 + kc_offset, kc_len);
- sb.append(":" + kc + ":" + sres);
- logv("kc:" + kc + " sres:" + sres);
- }
-
- return sb.toString();
- }
-
- // TODO move to TelephonyUtil
void handleGsmAuthRequest(SimAuthRequestData requestData) {
if (targetWificonfiguration == null
|| targetWificonfiguration.networkId == requestData.networkId) {
@@ -7739,16 +7605,8 @@
return;
}
- TelephonyManager tm = (TelephonyManager)
- mContext.getSystemService(Context.TELEPHONY_SERVICE);
-
- if (tm == null) {
- loge("could not get telephony manager");
- mWifiNative.simAuthFailedResponse(requestData.networkId);
- return;
- }
-
- String response = getGsmSimAuthResponse(requestData.data, tm);
+ String response =
+ TelephonyUtil.getGsmSimAuthResponse(requestData.data, getTelephonyManager());
if (response == null) {
mWifiNative.simAuthFailedResponse(requestData.networkId);
} else {
@@ -7757,13 +7615,7 @@
}
}
- // TODO move to TelephonyUtil
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");
@@ -7771,69 +7623,11 @@
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) {
- tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
- TelephonyManager.AUTHTYPE_EAP_AKA, base64Challenge);
- logv("Raw Response - " + tmResponse);
- } else {
- loge("could not get telephony manager");
- }
- }
-
- boolean good_response = false;
- 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);
- good_response = true;
- } 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);
- good_response = true;
- } else {
- loge("bad response - unknown tag = " + tag);
- }
- } else {
- loge("bad response - " + tmResponse);
- }
-
- if (good_response) {
- String response = sb.toString();
- logv("Supplicant Response -" + response);
- mWifiNative.simAuthResponse(requestData.networkId, res_type, response);
+ SimAuthResponseData response =
+ TelephonyUtil.get3GAuthResponse(requestData, getTelephonyManager());
+ if (response != null) {
+ mWifiNative.simAuthResponse(requestData.networkId, response.type, response.response);
} else {
mWifiNative.umtsAuthFailedResponse(requestData.networkId);
}
diff --git a/service/java/com/android/server/wifi/WifiSupplicantControl.java b/service/java/com/android/server/wifi/WifiSupplicantControl.java
index d05f3ef..15422d3 100644
--- a/service/java/com/android/server/wifi/WifiSupplicantControl.java
+++ b/service/java/com/android/server/wifi/WifiSupplicantControl.java
@@ -16,7 +16,6 @@
package com.android.server.wifi;
-import android.content.Context;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
import android.net.wifi.WifiConfiguration;
@@ -25,6 +24,7 @@
import android.net.wifi.WpsInfo;
import android.net.wifi.WpsResult;
import android.os.FileObserver;
+import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -70,13 +70,14 @@
private static final String TAG = "WifiSupplicantControl";
private final LocalLog mLocalLog;
private final WpaConfigFileObserver mFileObserver;
- private final Context mContext;
+ private final TelephonyManager mTelephonyManager;
private final WifiNative mWifiNative;
private boolean mVerboseLoggingEnabled = false;
- WifiSupplicantControl(Context context, WifiNative wifiNative, LocalLog localLog) {
- mContext = context;
+ WifiSupplicantControl(TelephonyManager telephonyManager, WifiNative wifiNative,
+ LocalLog localLog) {
+ mTelephonyManager = telephonyManager;
mWifiNative = wifiNative;
mLocalLog = localLog;
@@ -885,7 +886,7 @@
if (mVerboseLoggingEnabled) localLog("resetSimNetworks");
for (WifiConfiguration config : configs) {
if (TelephonyUtil.isSimConfig(config)) {
- String currentIdentity = TelephonyUtil.getSimIdentity(mContext,
+ String currentIdentity = TelephonyUtil.getSimIdentity(mTelephonyManager,
config.enterpriseConfig.getEapMethod());
String supplicantIdentity =
mWifiNative.getNetworkVariable(config.networkId, "identity");
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index 3d7ce45..c8f292c 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -16,33 +16,34 @@
package com.android.server.wifi.util;
-import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.telephony.TelephonyManager;
+import android.util.Base64;
+import android.util.Log;
/**
* Utilities for the Wifi Service to interact with telephony.
*/
public class TelephonyUtil {
+ public static final String TAG = "TelephonyUtil";
/**
* Get the identity for the current SIM or null if the sim is not available
*/
- public static String getSimIdentity(Context context, int eapMethod) {
- TelephonyManager tm = TelephonyManager.from(context);
- if (tm != null) {
- String imsi = tm.getSubscriberId();
- String mccMnc = "";
-
- if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
- mccMnc = tm.getSimOperator();
- }
-
- return buildIdentity(eapMethod, imsi, mccMnc);
- } else {
+ public static String getSimIdentity(TelephonyManager tm, int eapMethod) {
+ if (tm == null) {
+ Log.e(TAG, "No valid TelephonyManager");
return null;
}
+ String imsi = tm.getSubscriberId();
+ String mccMnc = "";
+
+ if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
+ mccMnc = tm.getSimOperator();
+ }
+
+ return buildIdentity(eapMethod, imsi, mccMnc);
}
/**
@@ -112,4 +113,244 @@
|| eapMethod == WifiEnterpriseConfig.Eap.AKA
|| eapMethod == WifiEnterpriseConfig.Eap.AKA_PRIME;
}
+
+ // TODO replace some of this code with Byte.parseByte
+ private static int parseHex(char ch) {
+ if ('0' <= ch && ch <= '9') {
+ return ch - '0';
+ } else if ('a' <= ch && ch <= 'f') {
+ return ch - 'a' + 10;
+ } else if ('A' <= ch && ch <= 'F') {
+ return ch - 'A' + 10;
+ } else {
+ throw new NumberFormatException("" + ch + " is not a valid hex digit");
+ }
+ }
+
+ private static byte[] parseHex(String hex) {
+ /* This only works for good input; don't throw bad data at it */
+ if (hex == null) {
+ return new byte[0];
+ }
+
+ if (hex.length() % 2 != 0) {
+ throw new NumberFormatException(hex + " is not a valid hex string");
+ }
+
+ byte[] result = new byte[(hex.length()) / 2 + 1];
+ result[0] = (byte) ((hex.length()) / 2);
+ for (int i = 0, j = 1; i < hex.length(); i += 2, j++) {
+ int val = parseHex(hex.charAt(i)) * 16 + parseHex(hex.charAt(i + 1));
+ byte b = (byte) (val & 0xFF);
+ result[j] = b;
+ }
+
+ return result;
+ }
+
+ private static String makeHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ private static String makeHex(byte[] bytes, int from, int len) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ sb.append(String.format("%02x", bytes[from + i]));
+ }
+ return sb.toString();
+ }
+
+ 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;
+ }
+
+ public static String getGsmSimAuthResponse(String[] requestData, TelephonyManager tm) {
+ if (tm == null) {
+ Log.e(TAG, "No valid TelephonyManager");
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (String challenge : requestData) {
+ if (challenge == null || challenge.isEmpty()) {
+ continue;
+ }
+ Log.d(TAG, "RAND = " + challenge);
+
+ byte[] rand = null;
+ try {
+ rand = parseHex(challenge);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "malformed challenge");
+ continue;
+ }
+
+ String base64Challenge = Base64.encodeToString(rand, Base64.NO_WRAP);
+
+ // Try USIM first for authentication.
+ String tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
+ if (tmResponse == null) {
+ // Then, in case of failure, issue may be due to sim type, retry as a simple sim
+ tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM, base64Challenge);
+ }
+ Log.v(TAG, "Raw Response - " + tmResponse);
+
+ if (tmResponse == null || tmResponse.length() <= 4) {
+ Log.e(TAG, "bad response - " + tmResponse);
+ return null;
+ }
+
+ byte[] result = Base64.decode(tmResponse, Base64.DEFAULT);
+ Log.v(TAG, "Hex Response -" + makeHex(result));
+ int sresLen = result[0];
+ if (sresLen >= result.length) {
+ Log.e(TAG, "malfomed response - " + tmResponse);
+ return null;
+ }
+ String sres = makeHex(result, 1, sresLen);
+ int kcOffset = 1 + sresLen;
+ if (kcOffset >= result.length) {
+ Log.e(TAG, "malfomed response - " + tmResponse);
+ return null;
+ }
+ int kcLen = result[kcOffset];
+ if (kcOffset + kcLen > result.length) {
+ Log.e(TAG, "malfomed response - " + tmResponse);
+ return null;
+ }
+ String kc = makeHex(result, 1 + kcOffset, kcLen);
+ sb.append(":" + kc + ":" + sres);
+ Log.v(TAG, "kc:" + kc + " sres:" + sres);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Data supplied when making a SIM Auth Request
+ */
+ public static class SimAuthRequestData {
+ public SimAuthRequestData() {}
+ public SimAuthRequestData(int networkId, int protocol, String ssid, String[] data) {
+ this.networkId = networkId;
+ this.protocol = protocol;
+ this.ssid = ssid;
+ this.data = data;
+ }
+
+ public int networkId;
+ public int protocol;
+ public String ssid;
+ // EAP-SIM: data[] contains the 3 rand, one for each of the 3 challenges
+ // EAP-AKA/AKA': data[] contains rand & authn couple for the single challenge
+ public String[] data;
+ }
+
+ /**
+ * The response to a SIM Auth request if successful
+ */
+ public static class SimAuthResponseData {
+ public SimAuthResponseData(String type, String response) {
+ this.type = type;
+ this.response = response;
+ }
+
+ public String type;
+ public String response;
+ }
+
+ public static SimAuthResponseData get3GAuthResponse(SimAuthRequestData requestData,
+ TelephonyManager tm) {
+ StringBuilder sb = new StringBuilder();
+ byte[] rand = null;
+ byte[] authn = null;
+ String resType = "UMTS-AUTH";
+
+ if (requestData.data.length == 2) {
+ try {
+ rand = parseHex(requestData.data[0]);
+ authn = parseHex(requestData.data[1]);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "malformed challenge");
+ }
+ } else {
+ Log.e(TAG, "malformed challenge");
+ }
+
+ String tmResponse = "";
+ if (rand != null && authn != null) {
+ String base64Challenge = Base64.encodeToString(concatHex(rand, authn), Base64.NO_WRAP);
+ if (tm != null) {
+ tmResponse = tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, base64Challenge);
+ Log.v(TAG, "Raw Response - " + tmResponse);
+ } else {
+ Log.e(TAG, "No valid TelephonyManager");
+ }
+ }
+
+ boolean goodReponse = false;
+ if (tmResponse != null && tmResponse.length() > 4) {
+ byte[] result = Base64.decode(tmResponse, Base64.DEFAULT);
+ Log.e(TAG, "Hex Response - " + makeHex(result));
+ byte tag = result[0];
+ if (tag == (byte) 0xdb) {
+ Log.v(TAG, "successful 3G authentication ");
+ int resLen = result[1];
+ String res = makeHex(result, 2, resLen);
+ int ckLen = result[resLen + 2];
+ String ck = makeHex(result, resLen + 3, ckLen);
+ int ikLen = result[resLen + ckLen + 3];
+ String ik = makeHex(result, resLen + ckLen + 4, ikLen);
+ sb.append(":" + ik + ":" + ck + ":" + res);
+ Log.v(TAG, "ik:" + ik + "ck:" + ck + " res:" + res);
+ goodReponse = true;
+ } else if (tag == (byte) 0xdc) {
+ Log.e(TAG, "synchronisation failure");
+ int autsLen = result[1];
+ String auts = makeHex(result, 2, autsLen);
+ resType = "UMTS-AUTS";
+ sb.append(":" + auts);
+ Log.v(TAG, "auts:" + auts);
+ goodReponse = true;
+ } else {
+ Log.e(TAG, "bad response - unknown tag = " + tag);
+ }
+ } else {
+ Log.e(TAG, "bad response - " + tmResponse);
+ }
+
+ if (goodReponse) {
+ String response = sb.toString();
+ Log.v(TAG, "Supplicant Response -" + response);
+ return new SimAuthResponseData(resType, response);
+ } else {
+ return null;
+ }
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index dbd8e32..5531eea 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -22,8 +22,8 @@
import static org.mockito.Mockito.*;
import android.app.ActivityManager;
-import android.app.test.TestAlarmManager;
import android.app.test.MockAnswerUtil.AnswerWithArguments;
+import android.app.test.TestAlarmManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -63,7 +63,6 @@
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Base64;
import android.util.Log;
import com.android.internal.R;
@@ -1057,59 +1056,6 @@
assertEquals(true, result);
}
- private String createSimChallengeRequest(byte[] challengeValue) {
- // Produce a base64 encoded length byte + data.
- byte[] challengeLengthAndValue = new byte[challengeValue.length + 1];
- challengeLengthAndValue[0] = (byte) challengeValue.length;
- for (int i = 0; i < challengeValue.length; ++i) {
- challengeLengthAndValue[i + 1] = challengeValue[i];
- }
- return Base64.encodeToString(challengeLengthAndValue, android.util.Base64.NO_WRAP);
- }
-
- private String createSimAuthResponse(byte[] sresValue, byte[] kcValue) {
- // Produce a base64 encoded sres length byte + sres + kc length byte + kc.
- int overallLength = sresValue.length + kcValue.length + 2;
- byte[] result = new byte[sresValue.length + kcValue.length + 2];
- int idx = 0;
- result[idx++] = (byte) sresValue.length;
- for (int i = 0; i < sresValue.length; ++i) {
- result[idx++] = sresValue[i];
- }
- result[idx++] = (byte) kcValue.length;
- for (int i = 0; i < kcValue.length; ++i) {
- result[idx++] = kcValue[i];
- }
- return Base64.encodeToString(result, Base64.NO_WRAP);
- }
-
- /** Verifies function getGsmSimAuthResponse method. */
- @Test
- public void getGsmSimAuthResponseTest() throws Exception {
- TelephonyManager tm = mock(TelephonyManager.class);
- final String[] invalidRequests = { null, "", "XXXX" };
- assertEquals("", mWsm.getGsmSimAuthResponse(invalidRequests, tm));
-
- final String[] failedRequests = { "5E5F" };
- when(tm.getIccAuthentication(anyInt(), anyInt(),
- eq(createSimChallengeRequest(new byte[] { 0x5e, 0x5f })))).thenReturn(null);
- assertEquals(null, mWsm.getGsmSimAuthResponse(failedRequests, tm));
-
- when(tm.getIccAuthentication(2, tm.AUTHTYPE_EAP_SIM,
- createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
- .thenReturn(null);
- when(tm.getIccAuthentication(1, tm.AUTHTYPE_EAP_SIM,
- createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
- .thenReturn(createSimAuthResponse(new byte[] { 0x1D, 0x2C },
- new byte[] { 0x3B, 0x4A }));
- when(tm.getIccAuthentication(1, tm.AUTHTYPE_EAP_SIM,
- createSimChallengeRequest(new byte[] { 0x01, 0x23 })))
- .thenReturn(createSimAuthResponse(new byte[] { 0x33, 0x22 },
- new byte[] { 0x11, 0x00 }));
- assertEquals(":3b4a:1d2c:1100:3322", mWsm.getGsmSimAuthResponse(
- new String[] { "1A2B", "0123" }, tm));
- }
-
/**
* Verifies that, by default, we allow only the "normal" number of log records.
*/
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java b/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
index ceb4b42..884d89f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiSupplicantControlTest.java
@@ -19,7 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import android.content.Context;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
@@ -157,7 +157,7 @@
+ "}\n";
@Mock private WifiNative mWifiNative;
- @Mock private Context mContext;
+ @Mock private TelephonyManager mTelephonyManager;
private WifiSupplicantControl mWifiSupplicantControl;
/**
@@ -166,7 +166,7 @@
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mWifiSupplicantControl = new WifiSupplicantControl(mContext, mWifiNative, null);
+ mWifiSupplicantControl = new WifiSupplicantControl(mTelephonyManager, mWifiNative, null);
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
new file mode 100644
index 0000000..e58d545
--- /dev/null
+++ b/tests/wifitests/src/com/android/server/wifi/util/TelephonyUtilTest.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wifi.util;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import android.net.wifi.WifiEnterpriseConfig;
+import android.telephony.TelephonyManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Base64;
+
+import com.android.server.wifi.util.TelephonyUtil.SimAuthRequestData;
+import com.android.server.wifi.util.TelephonyUtil.SimAuthResponseData;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link com.android.server.wifi.util.TelephonyUtil}.
+ */
+@SmallTest
+public class TelephonyUtilTest {
+
+ @Test
+ public void getSimIdentityEapSim() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getSubscriberId()).thenReturn("3214561234567890");
+ when(tm.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(tm.getSimOperator()).thenReturn("321456");
+ assertEquals("13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org",
+ TelephonyUtil.getSimIdentity(tm, WifiEnterpriseConfig.Eap.SIM));
+ }
+
+ @Test
+ public void getSimIdentityEapAka() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getSubscriberId()).thenReturn("3214561234567890");
+ when(tm.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(tm.getSimOperator()).thenReturn("321456");
+ assertEquals("03214561234567890@wlan.mnc456.mcc321.3gppnetwork.org",
+ TelephonyUtil.getSimIdentity(tm, WifiEnterpriseConfig.Eap.AKA));
+ }
+
+ @Test
+ public void getSimIdentityEapAkaPrime() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getSubscriberId()).thenReturn("3214561234567890");
+ when(tm.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(tm.getSimOperator()).thenReturn("321456");
+ assertEquals("63214561234567890@wlan.mnc456.mcc321.3gppnetwork.org",
+ TelephonyUtil.getSimIdentity(tm, WifiEnterpriseConfig.Eap.AKA_PRIME));
+ }
+
+ @Test
+ public void getSimIdentity2DigitMnc() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getSubscriberId()).thenReturn("321560123456789");
+ when(tm.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(tm.getSimOperator()).thenReturn("32156");
+ assertEquals("1321560123456789@wlan.mnc056.mcc321.3gppnetwork.org",
+ TelephonyUtil.getSimIdentity(tm, WifiEnterpriseConfig.Eap.SIM));
+ }
+
+ @Test
+ public void getSimIdentityUnknownMccMnc() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getSubscriberId()).thenReturn("3214560123456789");
+ when(tm.getSimState()).thenReturn(TelephonyManager.SIM_STATE_UNKNOWN);
+ when(tm.getSimOperator()).thenReturn(null);
+ assertEquals("13214560123456789@wlan.mnc456.mcc321.3gppnetwork.org",
+ TelephonyUtil.getSimIdentity(tm, WifiEnterpriseConfig.Eap.SIM));
+ }
+
+
+
+
+ /**
+ * Produce a base64 encoded length byte + data.
+ */
+ private static String createSimChallengeRequest(byte[] challengeValue) {
+ byte[] challengeLengthAndValue = new byte[challengeValue.length + 1];
+ challengeLengthAndValue[0] = (byte) challengeValue.length;
+ for (int i = 0; i < challengeValue.length; ++i) {
+ challengeLengthAndValue[i + 1] = challengeValue[i];
+ }
+ return Base64.encodeToString(challengeLengthAndValue, android.util.Base64.NO_WRAP);
+ }
+
+ /**
+ * Produce a base64 encoded sres length byte + sres + kc length byte + kc.
+ */
+ private static String createGsmSimAuthResponse(byte[] sresValue, byte[] kcValue) {
+ int overallLength = sresValue.length + kcValue.length + 2;
+ byte[] result = new byte[sresValue.length + kcValue.length + 2];
+ int idx = 0;
+ result[idx++] = (byte) sresValue.length;
+ for (int i = 0; i < sresValue.length; ++i) {
+ result[idx++] = sresValue[i];
+ }
+ result[idx++] = (byte) kcValue.length;
+ for (int i = 0; i < kcValue.length; ++i) {
+ result[idx++] = kcValue[i];
+ }
+ return Base64.encodeToString(result, Base64.NO_WRAP);
+ }
+
+ @Test
+ public void getGsmSimAuthResponseInvalidRequest() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ final String[] invalidRequests = { null, "", "XXXX" };
+ assertEquals("", TelephonyUtil.getGsmSimAuthResponse(invalidRequests, tm));
+ }
+
+ @Test
+ public void getGsmSimAuthResponseFailedSimResponse() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ final String[] failedRequests = { "5E5F" };
+ when(tm.getIccAuthentication(anyInt(), anyInt(),
+ eq(createSimChallengeRequest(new byte[] { 0x5e, 0x5f })))).thenReturn(null);
+
+ assertEquals(null, TelephonyUtil.getGsmSimAuthResponse(failedRequests, tm));
+ }
+
+ @Test
+ public void getGsmSimAuthResponseUsim() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x1b, 0x2b })))
+ .thenReturn(createGsmSimAuthResponse(new byte[] { 0x1D, 0x2C },
+ new byte[] { 0x3B, 0x4A }));
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x01, 0x22 })))
+ .thenReturn(createGsmSimAuthResponse(new byte[] { 0x11, 0x11 },
+ new byte[] { 0x12, 0x34 }));
+
+ assertEquals(":3b4a:1d2c:1234:1111", TelephonyUtil.getGsmSimAuthResponse(
+ new String[] { "1B2B", "0122" }, tm));
+ }
+
+ @Test
+ public void getGsmSimAuthResponseSimpleSim() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
+ .thenReturn(null);
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x1a, 0x2b })))
+ .thenReturn(createGsmSimAuthResponse(new byte[] { 0x1D, 0x2C },
+ new byte[] { 0x3B, 0x4A }));
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x01, 0x23 })))
+ .thenReturn(null);
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_SIM,
+ TelephonyManager.AUTHTYPE_EAP_SIM,
+ createSimChallengeRequest(new byte[] { 0x01, 0x23 })))
+ .thenReturn(createGsmSimAuthResponse(new byte[] { 0x33, 0x22 },
+ new byte[] { 0x11, 0x00 }));
+
+ assertEquals(":3b4a:1d2c:1100:3322", TelephonyUtil.getGsmSimAuthResponse(
+ new String[] { "1A2B", "0123" }, tm));
+ }
+
+ /**
+ * Produce a base64 encoded tag + res length byte + res + ck length byte + ck + ik length byte +
+ * ik.
+ */
+ private static String create3GSimAuthUmtsAuthResponse(byte[] res, byte[] ck, byte[] ik) {
+ byte[] result = new byte[res.length + ck.length + ik.length + 4];
+ int idx = 0;
+ result[idx++] = (byte) 0xdb;
+ result[idx++] = (byte) res.length;
+ for (int i = 0; i < res.length; ++i) {
+ result[idx++] = res[i];
+ }
+ result[idx++] = (byte) ck.length;
+ for (int i = 0; i < ck.length; ++i) {
+ result[idx++] = ck[i];
+ }
+ result[idx++] = (byte) ik.length;
+ for (int i = 0; i < ik.length; ++i) {
+ result[idx++] = ik[i];
+ }
+ return Base64.encodeToString(result, Base64.NO_WRAP);
+ }
+
+ private static String create3GSimAuthUmtsAutsResponse(byte[] auts) {
+ byte[] result = new byte[auts.length + 2];
+ int idx = 0;
+ result[idx++] = (byte) 0xdc;
+ result[idx++] = (byte) auts.length;
+ for (int i = 0; i < auts.length; ++i) {
+ result[idx++] = auts[i];
+ }
+ return Base64.encodeToString(result, Base64.NO_WRAP);
+ }
+
+ @Test
+ public void get3GAuthResponseInvalidRequest() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+ assertEquals(null, TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123"}), tm));
+ assertEquals(null, TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"xyz2", "1234"}), tm));
+ verifyNoMoreInteractions(tm);
+ }
+
+ @Test
+ public void get3GAuthResponseNullIccAuthentication() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, "AgEjAkVn")).thenReturn(null);
+
+ SimAuthResponseData response = TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123", "4567"}), tm);
+ assertNull(response);
+ }
+
+ @Test
+ public void get3GAuthResponseIccAuthenticationTooShort() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, "AgEjAkVn"))
+ .thenReturn(Base64.encodeToString(new byte[] {(byte) 0xdc}, Base64.NO_WRAP));
+
+ SimAuthResponseData response = TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123", "4567"}), tm);
+ assertNull(response);
+ }
+
+ @Test
+ public void get3GAuthResponseBadTag() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, "AgEjAkVn"))
+ .thenReturn(Base64.encodeToString(new byte[] {0x31, 0x1, 0x2, 0x3, 0x4},
+ Base64.NO_WRAP));
+
+ SimAuthResponseData response = TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123", "4567"}), tm);
+ assertNull(response);
+ }
+
+ @Test
+ public void get3GAuthResponseUmtsAuth() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, "AgEjAkVn"))
+ .thenReturn(create3GSimAuthUmtsAuthResponse(new byte[] {0x11, 0x12},
+ new byte[] {0x21, 0x22, 0x23}, new byte[] {0x31}));
+
+ SimAuthResponseData response = TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123", "4567"}), tm);
+ assertNotNull(response);
+ assertEquals("UMTS-AUTH", response.type);
+ assertEquals(":31:212223:1112", response.response);
+ }
+
+ @Test
+ public void get3GAuthResponseUmtsAuts() {
+ TelephonyManager tm = mock(TelephonyManager.class);
+
+ when(tm.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ TelephonyManager.AUTHTYPE_EAP_AKA, "AgEjAkVn"))
+ .thenReturn(create3GSimAuthUmtsAutsResponse(new byte[] {0x22, 0x33}));
+
+ SimAuthResponseData response = TelephonyUtil.get3GAuthResponse(
+ new SimAuthRequestData(0, 0, "SSID", new String[] {"0123", "4567"}), tm);
+ assertNotNull(response);
+ assertEquals("UMTS-AUTS", response.type);
+ assertEquals(":2233", response.response);
+ }
+}