From 2662a47382b0a74aea747bcdb0b8041d7bc1d8fa Mon Sep 17 00:00:00 2001 From: David Su Date: Thu, 30 May 2019 16:29:02 -0700 Subject: Fix manual connection to Carrier Wifi Fixed to conform to encrypted IMSI protocol even when user manually connected to a network. Previously only auto-connection worked correctly. Bug: 134094526 Test: Manually connect to Carrier Wifi network Test: Auto-connect to Carrier Wifi network Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I1ac5c2083d12e671a4ca89e93e7955c64197b522 --- .../server/wifi/CarrierNetworkEvaluator.java | 3 -- .../com/android/server/wifi/ClientModeImpl.java | 16 +++++++++ .../wifi/hotspot2/PasspointNetworkEvaluator.java | 7 ---- .../server/wifi/CarrierNetworkEvaluatorTest.java | 18 ++++++---- .../android/server/wifi/ClientModeImplTest.java | 41 ++++++++++++++++++---- .../hotspot2/PasspointNetworkEvaluatorTest.java | 22 +++++------- 6 files changed, 70 insertions(+), 37 deletions(-) diff --git a/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java b/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java index 8bd024bf5..52d7d1844 100644 --- a/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/CarrierNetworkEvaluator.java @@ -121,9 +121,6 @@ public class CarrierNetworkEvaluator implements NetworkEvaluator { config.enterpriseConfig = new WifiEnterpriseConfig(); } config.enterpriseConfig.setEapMethod(eapType); - // Send anonymous@realm as EAP-IDENTITY response. - config.enterpriseConfig.setAnonymousIdentity( - TelephonyUtil.getAnonymousIdentityWith3GppRealm(getTelephonyManager())); // Check if we already have a network with the same credentials in WifiConfigManager // database. If yes, we should check if the network is currently blacklisted. diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index f181cd295..bb1230554 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -4273,6 +4273,17 @@ public class ClientModeImpl extends StateMachine { String currentMacAddress = mWifiNative.getMacAddress(mInterfaceName); mWifiInfo.setMacAddress(currentMacAddress); Log.i(TAG, "Connecting with " + currentMacAddress + " as the mac address"); + + if (config.enterpriseConfig != null + && TelephonyUtil.isSimEapMethod(config.enterpriseConfig.getEapMethod()) + && mWifiInjector.getCarrierNetworkConfig() + .isCarrierEncryptionInfoAvailable() + && TextUtils.isEmpty(config.enterpriseConfig.getAnonymousIdentity())) { + String anonAtRealm = TelephonyUtil.getAnonymousIdentityWith3GppRealm( + getTelephonyManager()); + config.enterpriseConfig.setAnonymousIdentity(anonAtRealm); + } + if (mWifiNative.connectToNetwork(mInterfaceName, config)) { mWifiMetrics.logStaEvent(StaEvent.TYPE_CMD_START_CONNECT, config); mLastConnectAttemptTimestamp = mClock.getWallClockMillis(); @@ -4434,6 +4445,11 @@ public class ClientModeImpl extends StateMachine { 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())) { String anonymousIdentity = diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java index a2838b5fd..ec8a009d9 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointNetworkEvaluator.java @@ -221,13 +221,6 @@ public class PasspointNetworkEvaluator implements WifiNetworkSelector.NetworkEva */ private WifiConfiguration createWifiConfigForProvider(PasspointNetworkCandidate networkInfo) { WifiConfiguration config = networkInfo.mProvider.getWifiConfig(); - if (TelephonyUtil.isSimEapMethod(config.enterpriseConfig.getEapMethod()) - && mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()) { - // Send anonymous@realm as EAP-IDENTITY response. - config.enterpriseConfig.setAnonymousIdentity( - TelephonyUtil.getAnonymousIdentityWith3GppRealm( - getTelephonyManager())); - } config.SSID = ScanResultUtil.createQuotedSSID(networkInfo.mScanDetail.getSSID()); if (networkInfo.mMatchStatus == PasspointMatch.HomeProvider) { config.isHomeProviderNetwork = true; diff --git a/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java index 57a40dc8f..c4d5864bf 100644 --- a/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/CarrierNetworkEvaluatorTest.java @@ -38,6 +38,7 @@ import android.util.LocalLog; import androidx.test.filters.SmallTest; import com.android.server.wifi.util.ScanResultUtil; +import com.android.server.wifi.util.TelephonyUtil; import org.junit.After; import org.junit.Before; @@ -260,8 +261,8 @@ public class CarrierNetworkEvaluatorTest { assertTrue(config4.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); assertEquals(config2.configKey(), selected.configKey()); // SSID2 has the highest RSSI - assertEquals("anonymous@wlan.mnc456.mcc123.3gppnetwork.org", - selected.enterpriseConfig.getAnonymousIdentity()); + assertEquals("", selected.enterpriseConfig.getAnonymousIdentity()); + assertTrue(TelephonyUtil.isSimEapMethod(selected.enterpriseConfig.getEapMethod())); } /** @@ -387,18 +388,20 @@ public class CarrierNetworkEvaluatorTest { } /** - * One carrier Wi-Fi network that is visible and supports anonymous identity. + * One carrier Wi-Fi network that is visible and supports encrypted IMSI. * - * Desired behavior: anonymous identity is configured. + * Desired behavior: selected network supports encrypted IMSI by using EAP-SIM/AKA/AKA' + * and has an empty anonymous identity. The anonymous identity will be populated with + * {@code anonymous@} by ClientModeImpl's handling of the + * {@link ClientModeImpl#CMD_START_CONNECT} event. */ @Test - public void testAnonymousIdentityConfigured() { + public void testSupportsEncryptedImsi() { String[] ssids = {CARRIER1_SSID}; String[] bssids = {"6c:f3:7f:ae:8c:f3"}; int[] freqs = {2470}; String[] caps = {"[WPA2-EAP-CCMP]"}; int[] levels = {10}; - String expectedAnonymousIdentity = "anonymous@wlan.mnc456.mcc123.3gppnetwork.org"; when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true); List scanDetails = WifiNetworkSelectorTestUtil.buildScanDetails(ssids, bssids, freqs, caps, levels, mClock); @@ -409,6 +412,7 @@ public class CarrierNetworkEvaluatorTest { mConnectableListener); assertEquals(carrierConfig.configKey(), selected.configKey()); - assertEquals(expectedAnonymousIdentity, selected.enterpriseConfig.getAnonymousIdentity()); + assertEquals("", selected.enterpriseConfig.getAnonymousIdentity()); + assertTrue(TelephonyUtil.isSimEapMethod(selected.enterpriseConfig.getEapMethod())); } } diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 597ccae7b..e839796c9 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -103,7 +103,6 @@ import com.android.server.wifi.nano.WifiMetricsProto.StaEvent; import com.android.server.wifi.nano.WifiMetricsProto.WifiIsUnusableEvent; import com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStats; import com.android.server.wifi.p2p.WifiP2pServiceImpl; -import com.android.server.wifi.util.TelephonyUtil; import com.android.server.wifi.util.WifiPermissionsUtil; import com.android.server.wifi.util.WifiPermissionsWrapper; @@ -1022,17 +1021,20 @@ public class ClientModeImplTest { WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); when(mDataTelephonyManager.getSimOperator()).thenReturn("123456"); when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); - String expectedAnonymousIdentity = TelephonyUtil.getAnonymousIdentityWith3GppRealm( - mTelephonyManager); - // we are using anonymous@ as our anonymous identity before connection - mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(expectedAnonymousIdentity); + mConnectedNetwork.enterpriseConfig.setAnonymousIdentity(""); - triggerConnect(); + String expectedAnonymousIdentity = "anonymous@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( @@ -3537,4 +3539,29 @@ public class ClientModeImplTest { assertNotNull( mCmi.syncGetWifiConfigsForPasspointProfiles(null, mNullAsyncChannel)); } + + /** + * Tests that when {@link ClientModeImpl} receives a SUP_REQUEST_IDENTITY message, it responds + * to the supplicant with the SIM identity. + */ + @Test + public void testSupRequestIdentity_setsIdentityResponse() throws Exception { + mConnectedNetwork = spy(WifiConfigurationTestUtil.createEapNetwork( + WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); + mConnectedNetwork.SSID = DEFAULT_TEST_SSID; + + when(mDataTelephonyManager.getSubscriberId()).thenReturn("3214561234567890"); + when(mDataTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); + when(mDataTelephonyManager.getSimOperator()).thenReturn("321456"); + when(mDataTelephonyManager.getCarrierInfoForImsiEncryption(anyInt())).thenReturn(null); + + triggerConnect(); + + mCmi.sendMessage(WifiMonitor.SUP_REQUEST_IDENTITY, + 0, FRAMEWORK_NETWORK_ID, DEFAULT_TEST_SSID); + mLooper.dispatchAll(); + + verify(mWifiNative).simIdentityResponse(WIFI_IFACE_NAME, FRAMEWORK_NETWORK_ID, + "13214561234567890@wlan.mnc456.mcc321.3gppnetwork.org", ""); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java index ef019b416..c7ce3f127 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointNetworkEvaluatorTest.java @@ -397,25 +397,22 @@ public class PasspointNetworkEvaluatorTest { } /** - * Verify that anonymous identity is configured when matching a SIM credential provider with a - * network that supports encryptedIMSI and anonymous identity. - * - * @throws Exception + * Verify that anonymous identity is empty when matching a SIM credential provider with a + * network that supports encrypted IMSI and anonymous identity. The anonymous identity will be + * populated with {@code anonymous@} by ClientModeImpl's handling of the + * CMD_START_CONNECT event. */ @Test - public void evaluateSIMProviderWithNetworkSupportingEncryptedIMSIAnonymousIdentity() - throws Exception { + public void evaluateSIMProviderWithNetworkSupportingEncryptedIMSI() { // Setup ScanDetail and match providers. - List scanDetails = Arrays.asList(new ScanDetail[]{ - generateScanDetail(TEST_SSID1, TEST_BSSID1)}); + List scanDetails = Collections.singletonList( + generateScanDetail(TEST_SSID1, TEST_BSSID1)); WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork( WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE); config.networkId = TEST_NETWORK_ID; PasspointProvider testProvider = generateProvider(config); Pair homeProvider = Pair.create( testProvider, PasspointMatch.HomeProvider); - String expectedAnonymousIdentity = TelephonyUtil.getAnonymousIdentityWith3GppRealm( - mTelephonyManager); when(mPasspointManager.matchProvider(any(ScanResult.class))).thenReturn(homeProvider); when(testProvider.isSimCredential()).thenReturn(true); // SIM is present @@ -428,9 +425,8 @@ public class PasspointNetworkEvaluatorTest { WifiConfiguration result = mEvaluator.evaluateNetworks(scanDetails, null, null, false, false, mOnConnectableListener); - assertNotNull(result); - assertNotNull(result.enterpriseConfig); - assertEquals(expectedAnonymousIdentity, result.enterpriseConfig.getAnonymousIdentity()); + assertEquals("", result.enterpriseConfig.getAnonymousIdentity()); + assertTrue(TelephonyUtil.isSimEapMethod(result.enterpriseConfig.getEapMethod())); } /** -- cgit v1.2.3