summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHai Shalom <haishalom@google.com>2019-09-23 14:36:13 -0700
committerHai Shalom <haishalom@google.com>2019-09-26 16:17:37 +0000
commit97447d4b970bf7e569d10dc6ca5829d99e9a4e44 (patch)
tree11dc1c84b57d5a69e09d20f26c6f2195ccb714da
parent9e7e454a5bd06f50fb1390197a4578e57b9e210a (diff)
[EAP-SIM] Add NAI realm decoration to pseudonym
The framework stores the last pseudonym given by the server. However, in some cases, it does not contain @<NAI Realm> suffix which some servers require. Check if NAI realm exist, and add @<NAI Realm> to the pseudonym for subsequent connections if missing. Bug: 109795427 Test: atest ClientModeImplTest Change-Id: I74ef92e05e76290cbbf96297ed3329426e8b95a3
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java21
-rw-r--r--service/java/com/android/server/wifi/util/TelephonyUtil.java40
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java64
3 files changed, 114 insertions, 11 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 66c514ad6..535d2f4b2 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -4203,14 +4203,25 @@ public class ClientModeImpl extends StateMachine {
config.enterpriseConfig.getEapMethod())) {
String anonymousIdentity =
mWifiNative.getEapAnonymousIdentity(mInterfaceName);
- if (mVerboseLoggingEnabled) {
- log("EAP Pseudonym: " + anonymousIdentity);
- }
- if (!TelephonyUtil.isAnonymousAtRealmIdentity(anonymousIdentity)) {
+ if (!TextUtils.isEmpty(anonymousIdentity)
+ && !TelephonyUtil
+ .isAnonymousAtRealmIdentity(anonymousIdentity)) {
+ String decoratedPseudonym = TelephonyUtil
+ .decoratePseudonymWith3GppRealm(getTelephonyManager(),
+ anonymousIdentity);
+ if (decoratedPseudonym != null) {
+ anonymousIdentity = decoratedPseudonym;
+ }
+ if (mVerboseLoggingEnabled) {
+ log("EAP Pseudonym: " + anonymousIdentity);
+ }
// Save the pseudonym only if it is a real one
config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity);
- mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
+ } else {
+ // Clear any stored pseudonyms
+ config.enterpriseConfig.setAnonymousIdentity(null);
}
+ mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID);
}
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mObtainingIpState);
diff --git a/service/java/com/android/server/wifi/util/TelephonyUtil.java b/service/java/com/android/server/wifi/util/TelephonyUtil.java
index 4af40ddf2..3154df978 100644
--- a/service/java/com/android/server/wifi/util/TelephonyUtil.java
+++ b/service/java/com/android/server/wifi/util/TelephonyUtil.java
@@ -22,6 +22,7 @@ import android.net.wifi.WifiEnterpriseConfig;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.Pair;
@@ -730,4 +731,43 @@ public class TelephonyUtil {
public static boolean isSimPresent(@Nonnull SubscriptionManager sm) {
return sm.getActiveSubscriptionIdList().length > 0;
}
+
+ /**
+ * Decorates a pseudonym with the NAI realm, in case it wasn't provided by the server
+ *
+ * @param tm TelephonyManager instance
+ * @param pseudonym The pseudonym (temporary identity) provided by the server
+ * @return pseudonym@realm which is based on current MCC/MNC, {@code null} if SIM is
+ * not ready or absent.
+ */
+ public static String decoratePseudonymWith3GppRealm(@NonNull TelephonyManager tm,
+ String pseudonym) {
+ if (tm == null || TextUtils.isEmpty(pseudonym)) {
+ return null;
+ }
+ if (pseudonym.contains("@")) {
+ // Pseudonym is already decorated
+ return pseudonym;
+ }
+ TelephonyManager defaultDataTm = tm.createForSubscriptionId(
+ SubscriptionManager.getDefaultDataSubscriptionId());
+ if (defaultDataTm.getSimState() != TelephonyManager.SIM_STATE_READY) {
+ return null;
+ }
+ String mccMnc = defaultDataTm.getSimOperator();
+ if (mccMnc == null || mccMnc.isEmpty()) {
+ return null;
+ }
+
+ // Extract mcc & mnc from mccMnc
+ String mcc = mccMnc.substring(0, 3);
+ String mnc = mccMnc.substring(3);
+
+ if (mnc.length() == 2) {
+ mnc = "0" + mnc;
+ }
+
+ String realm = String.format(THREE_GPP_NAI_REALM_FORMAT, mnc, mcc);
+ return String.format("%s@%s", pseudonym, realm);
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index 1f762164f..68ce9b16d 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -1044,6 +1044,9 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
+ // Initial value should be "not set"
+ assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+
triggerConnect();
// CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm>
@@ -1063,15 +1066,15 @@ public class ClientModeImplTest extends WifiBaseTest {
mLooper.dispatchAll();
verify(mWifiNative).getEapAnonymousIdentity(any());
- // check that the anonymous identity remains anonymous@<realm> for subsequent connections.
- assertEquals(expectedAnonymousIdentity,
- mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
- // verify that WifiConfigManager#addOrUpdateNetwork() was never called if there is no
- // real pseudonym to be stored. i.e. Encrypted IMSI will be always used
+
+ // Post connection value should remain "not set"
+ assertEquals("", mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+ // verify that WifiConfigManager#addOrUpdateNetwork() was called to clear any previously
+ // stored pseudonym. i.e. to enable Encrypted IMSI for subsequent connections.
// Note: This test will fail if future logic will have additional conditions that would
// trigger "add or update network" operation. The test needs to be updated to account for
// this change.
- verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt());
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt());
}
/**
@@ -1124,6 +1127,55 @@ public class ClientModeImplTest extends WifiBaseTest {
}
/**
+ * Tests anonymous identity is set again whenever a connection is established for the carrier
+ * that supports encrypted IMSI and anonymous identity but real but not decorated pseudonym was
+ * provided for subsequent connections.
+ */
+ @Test
+ public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithNonDecoratedPseudonym()
+ throws Exception {
+ mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork(
+ WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE));
+ when(mDataTelephonyManager.getSimOperator()).thenReturn("123456");
+ when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
+ mConnectedNetwork.enterpriseConfig.setAnonymousIdentity("");
+
+ String realm = "wlan.mnc456.mcc123.3gppnetwork.org";
+ String expectedAnonymousIdentity = "anonymous";
+ String pseudonym = "83bcca9384fca";
+
+ when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true);
+
+ triggerConnect();
+
+ // CMD_START_CONNECT should have set anonymousIdentity to anonymous@<realm>
+ assertEquals(expectedAnonymousIdentity + "@" + realm,
+ mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+
+ when(mWifiConfigManager.getScanDetailCacheForNetwork(FRAMEWORK_NETWORK_ID))
+ .thenReturn(mScanDetailCache);
+ when(mScanDetailCache.getScanDetail(sBSSID)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq));
+ when(mScanDetailCache.getScanResult(sBSSID)).thenReturn(
+ getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult());
+ when(mWifiNative.getEapAnonymousIdentity(anyString()))
+ .thenReturn(pseudonym);
+
+ mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ verify(mWifiNative).getEapAnonymousIdentity(any());
+ assertEquals(pseudonym + "@" + realm,
+ mConnectedNetwork.enterpriseConfig.getAnonymousIdentity());
+ // Verify that WifiConfigManager#addOrUpdateNetwork() was called if there we received a
+ // real pseudonym to be stored. i.e. Encrypted IMSI will be used once, followed by
+ // pseudonym usage in all subsequent connections.
+ // Note: This test will fail if future logic will have additional conditions that would
+ // trigger "add or update network" operation. The test needs to be updated to account for
+ // this change.
+ verify(mWifiConfigManager).addOrUpdateNetwork(any(), anyInt());
+ }
+ /**
* Tests the Passpoint information is set in WifiInfo for Passpoint AP connection.
*/
@Test