From 724f5ef108fb3f3aec0ede58b77610000f6bc0c1 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Fri, 7 Jun 2019 13:48:33 -0700 Subject: [Encrypted IMSI] Use the pseudonym if available Update the logic to save the pseudonym, in case a real pseudonym is provided by the EAP server. This will allow the framework to use it in subsequent connections, instead of sending anonymous@ and encrypting the IMSI each time. Bug: 134775152 Test: Auto-connect to Carrier Wi-Fi Test: atest ClientModeImplTest Change-Id: Ie5696f419bc3f5cbc75a39e8a3c0cfa8bfde7021 --- .../com/android/server/wifi/ClientModeImpl.java | 17 +++--- .../android/server/wifi/ClientModeImplTest.java | 65 ++++++++++++++++++++-- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index d98d022b7..a18760c17 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -4287,6 +4287,7 @@ public class ClientModeImpl extends StateMachine { && TextUtils.isEmpty(config.enterpriseConfig.getAnonymousIdentity())) { String anonAtRealm = TelephonyUtil.getAnonymousIdentityWith3GppRealm( getTelephonyManager()); + // Use anonymous@ when pseudonym is not available config.enterpriseConfig.setAnonymousIdentity(anonAtRealm); } @@ -4450,21 +4451,17 @@ public class ClientModeImpl extends StateMachine { // We need to get the updated pseudonym from supplicant for EAP-SIM/AKA/AKA' if (config.enterpriseConfig != null && TelephonyUtil.isSimEapMethod( - config.enterpriseConfig.getEapMethod()) - // if using anonymous@, do not use pseudonym identity on - // reauthentication. Instead, use full authentication using - // anonymous@ followed by encrypted IMSI every time. - // This is because the encrypted IMSI spec does not specify its - // compatibility with the pseudonym identity specified by EAP-AKA. - && !TelephonyUtil.isAnonymousAtRealmIdentity( - config.enterpriseConfig.getAnonymousIdentity())) { + config.enterpriseConfig.getEapMethod())) { String anonymousIdentity = mWifiNative.getEapAnonymousIdentity(mInterfaceName); if (mVerboseLoggingEnabled) { log("EAP Pseudonym: " + anonymousIdentity); } - config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity); - mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID); + if (!TelephonyUtil.isAnonymousAtRealmIdentity(anonymousIdentity)) { + // Save the pseudonym only if it is a real one + config.enterpriseConfig.setAnonymousIdentity(anonymousIdentity); + mWifiConfigManager.addOrUpdateNetwork(config, Process.WIFI_UID); + } } sendNetworkStateChangeBroadcast(mLastBssid); transitionTo(mObtainingIpState); diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index b64bf3de5..a26582c5c 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -1033,10 +1033,10 @@ public class ClientModeImplTest { /** * Tests anonymous identity is set again whenever a connection is established for the carrier - * that supports encrypted IMSI and anonymous identity. + * that supports encrypted IMSI and anonymous identity and no real pseudonym was provided. */ @Test - public void testSetAnonymousIdentityWhenConnectionIsEstablished() throws Exception { + public void testSetAnonymousIdentityWhenConnectionIsEstablishedNoPseudonym() throws Exception { mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); @@ -1059,16 +1059,71 @@ public class ClientModeImplTest { getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq)); when(mScanDetailCache.getScanResult(sBSSID)).thenReturn( getGoogleGuestScanDetail(TEST_RSSI, sBSSID, sFreq).getScanResult()); + when(mWifiNative.getEapAnonymousIdentity(anyString())) + .thenReturn(expectedAnonymousIdentity); mCmi.sendMessage(WifiMonitor.NETWORK_CONNECTION_EVENT, 0, 0, sBSSID); mLooper.dispatchAll(); - // verify that WifiNative#getEapAnonymousIdentity() was never called since we are using - // encrypted IMSI full authentication and not using pseudonym identity. - verify(mWifiNative, never()).getEapAnonymousIdentity(any()); + verify(mWifiNative).getEapAnonymousIdentity(any()); // check that the anonymous identity remains anonymous@ 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 + // 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()); + } + + /** + * Tests anonymous identity is set again whenever a connection is established for the carrier + * that supports encrypted IMSI and anonymous identity but real pseudonym was provided for + * subsequent connections. + */ + @Test + public void testSetAnonymousIdentityWhenConnectionIsEstablishedWithPseudonym() + 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 expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; + String pseudonym = "83bcca9384fca@wlan.mnc456.mcc123.3gppnetwork.org"; + + when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true); + + triggerConnect(); + + // CMD_START_CONNECT should have set anonymousIdentity to anonymous@ + assertEquals(expectedAnonymousIdentity, + 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, + 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()); } /** -- cgit v1.2.3