From 0b3eca3c05190e5824638f3da25b8b3167dc9d60 Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 14 Jan 2020 12:12:22 -0800 Subject: fix soft reboot caused by KeyStore exception The Mac handle obtained from AndroidKeyStore is sometimes invalidated by the AndroidKeyStore based on some LRU technique. This change make sure that we always get a valid handle. And adds exception handling to make sure a crash will not happen for the same reason again. If KeyStore continuously fails to generate MAC address, we will use locally generated MAC as it is the next best option. Bug: 146203882 Test: atest FrameworksWifiTests Merged-In: I8a3b810ba95898a96d81fe57979db4787e1a46c4 Change-Id: I8a3b810ba95898a96d81fe57979db4787e1a46c4 (cherry-picked from e299359a6e6e9e13217862f7f66627eccbff46ce) --- .../android/server/wifi/MacAddressUtilTest.java | 15 ++++++++++++++ .../android/server/wifi/WifiConfigManagerTest.java | 24 +++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java b/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java index 253310840..7e598db31 100644 --- a/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/MacAddressUtilTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.security.ProviderException; import java.util.Random; import javax.crypto.Mac; @@ -69,4 +70,18 @@ public class MacAddressUtilTest { assertTrue(WifiConfiguration.isValidMacAddressForRandomization(macAddress)); } } + + /** + * Verify the java.security.ProviderException is caught. + */ + @Test + public void testCalculatePersistentMacCatchesException() { + when(mMac.doFinal(any())).thenThrow(new ProviderException("error occurred")); + try { + WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); + assertNull(mMacAddressUtil.calculatePersistentMacForConfiguration(config, mMac)); + } catch (Exception e) { + fail("Exception not caught."); + } + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 23eea328f..6fa1868cb 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -303,13 +303,27 @@ public class WifiConfigManagerTest { } /** - * Verifies that the Mac randomization secret hashfunction is obtained after |loadFromStore|. + * Verify that a randomized MAC address is generated even if the KeyStore operation fails. */ @Test - public void testMacHashIsObtainedAfterLoadFromStore() { - verify(mMacAddressUtil, never()).obtainMacRandHashFunction(anyInt()); - assertTrue(mWifiConfigManager.loadFromStore()); - verify(mMacAddressUtil).obtainMacRandHashFunction(anyInt()); + public void testRandomizedMacIsGeneratedEvenIfKeyStoreFails() { + when(mMacAddressUtil.calculatePersistentMacForConfiguration(any(), any())).thenReturn(null); + + // Try adding a network. + WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + List networks = new ArrayList<>(); + networks.add(openNetwork); + verifyAddNetworkToWifiConfigManager(openNetwork); + List retrievedNetworks = + mWifiConfigManager.getConfiguredNetworksWithPasswords(); + + // Verify that we have attempted to generate the MAC address twice (1 retry) + verify(mMacAddressUtil, times(2)).calculatePersistentMacForConfiguration(any(), any()); + assertEquals(1, retrievedNetworks.size()); + + // Verify that despite KeyStore returning null, we are still getting a valid MAC address. + assertNotEquals(WifiInfo.DEFAULT_MAC_ADDRESS, + retrievedNetworks.get(0).getRandomizedMacAddress().toString()); } /** -- cgit v1.2.3 From d7d14da8eafb570f00287ac715d31ebca6fca164 Mon Sep 17 00:00:00 2001 From: Kai Shi Date: Tue, 25 Feb 2020 17:09:21 -0800 Subject: Add EAP methods in WifiMetrics To help find the root cause of high authentication failure rate in enterprise network, add EAP method and authentication phase2 method in connection event metrics. Bug: 150237135 Test: manual Test: atest com.android.server.wifi Change-Id: I0c4ab436b1e43cc52d4bd4dab6c01db53fec91a6 --- .../com/android/server/wifi/WifiMetricsTest.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java index 73ac30f41..11769576c 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java @@ -58,6 +58,7 @@ import android.net.wifi.IOnWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.SupplicantState; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.net.wifi.WifiSsid; @@ -1371,10 +1372,17 @@ public class WifiMetricsTest { when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM); ScanResult scanResult = mock(ScanResult.class); scanResult.level = SCAN_RESULT_LEVEL; + scanResult.capabilities = "EAP"; WifiConfiguration config = mock(WifiConfiguration.class); config.SSID = "\"" + SSID + "\""; config.dtimInterval = CONFIG_DTIM; config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; + config.allowedKeyManagement = new BitSet(); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); + config.enterpriseConfig = new WifiEnterpriseConfig(); + config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS); + config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2); WifiConfiguration.NetworkSelectionStatus networkSelectionStat = mock(WifiConfiguration.NetworkSelectionStatus.class); when(networkSelectionStat.getCandidate()).thenReturn(scanResult); @@ -1395,7 +1403,9 @@ public class WifiMetricsTest { WifiMetricsProto.ConnectionEvent.HLF_NONE, WifiMetricsProto.ConnectionEvent.FAILURE_REASON_UNKNOWN); + //Change configuration to open without randomization config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; + scanResult.capabilities = ""; //Create a connection event using the config and a scan detail mWifiMetrics.startConnectionEvent(config, "Green", WifiMetricsProto.ConnectionEvent.ROAM_NONE); @@ -1411,8 +1421,20 @@ public class WifiMetricsTest { //Check that the correct values are being flowed through assertEquals(2, mDecodedProto.connectionEvent.length); assertEquals(CONFIG_DTIM, mDecodedProto.connectionEvent[0].routerFingerprint.dtim); + assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_ENTERPRISE, + mDecodedProto.connectionEvent[0].routerFingerprint.authentication); + assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_TTLS, + mDecodedProto.connectionEvent[0].routerFingerprint.eapMethod); + assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_MSCHAPV2, + mDecodedProto.connectionEvent[0].routerFingerprint.authPhase2Method); assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[0].signalStrength); assertEquals(NETWORK_DETAIL_DTIM, mDecodedProto.connectionEvent[1].routerFingerprint.dtim); + assertEquals(WifiMetricsProto.RouterFingerPrint.AUTH_OPEN, + mDecodedProto.connectionEvent[1].routerFingerprint.authentication); + assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_EAP_UNKNOWN, + mDecodedProto.connectionEvent[1].routerFingerprint.eapMethod); + assertEquals(WifiMetricsProto.RouterFingerPrint.TYPE_PHASE2_NONE, + mDecodedProto.connectionEvent[1].routerFingerprint.authPhase2Method); assertEquals(SCAN_RESULT_LEVEL, mDecodedProto.connectionEvent[1].signalStrength); assertEquals(NETWORK_DETAIL_WIFIMODE, mDecodedProto.connectionEvent[1].routerFingerprint.routerTechnology); -- cgit v1.2.3 From e6813a5870911b10561db2c259c072123c1c513a Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Mon, 2 Mar 2020 17:56:31 -0800 Subject: Enterprise suggestion's catificate share same lifecycle as suggestion Enterprise network suggestion's catificate will add to keystore immediately after add the suggestion, and will only remove after suggestion is removed. Bug: 150500247 Test: atest com.android.server.wifi Merged-In: I85fb81a98f16b6a343fb35ce31e1426e333773b0 Change-Id: Icbe49911d7ca93b03dfdf728ad88057c31aa5974 --- .../android/server/wifi/WifiConfigManagerTest.java | 6 ++- .../com/android/server/wifi/WifiKeyStoreTest.java | 56 ++++++++++++++++++++++ .../wifi/WifiNetworkSuggestionsManagerTest.java | 33 ++++++++++++- 3 files changed, 93 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index 6fa1868cb..6a7785e5e 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -683,13 +683,14 @@ public class WifiConfigManagerTest { */ @Test public void testAddSingleSuggestionNetwork() throws Exception { - WifiConfiguration suggestionNetwork = WifiConfigurationTestUtil.createOpenNetwork(); + WifiConfiguration suggestionNetwork = WifiConfigurationTestUtil.createEapNetwork(); suggestionNetwork.ephemeral = true; suggestionNetwork.fromWifiNetworkSuggestion = true; List networks = new ArrayList<>(); networks.add(suggestionNetwork); verifyAddSuggestionOrRequestNetworkToWifiConfigManager(suggestionNetwork); + verify(mWifiKeyStore, never()).updateNetworkKeys(any(), any()); List retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords(); @@ -699,6 +700,9 @@ public class WifiConfigManagerTest { // Ensure that this is not returned in the saved network list. assertTrue(mWifiConfigManager.getSavedNetworks(Process.WIFI_UID).isEmpty()); verify(mWcmListener, never()).onSavedNetworkAdded(suggestionNetwork.networkId); + assertTrue(mWifiConfigManager + .removeNetwork(suggestionNetwork.networkId, TEST_CREATOR_UID)); + verify(mWifiKeyStore, never()).removeKeys(any()); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java index 7079a2d53..7649d1ba4 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java @@ -16,11 +16,19 @@ package com.android.server.wifi; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.AdditionalMatchers.aryEq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.validateMockitoUsage; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.os.Process; import android.security.Credentials; @@ -34,6 +42,8 @@ import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.security.cert.X509Certificate; + /** * Unit tests for {@link com.android.server.wifi.WifiConfigManager}. */ @@ -43,8 +53,10 @@ public class WifiKeyStoreTest { @Mock private KeyStore mKeyStore; private WifiKeyStore mWifiKeyStore; + private static final String TEST_KEY_ID = "blah"; private static final String USER_CERT_ALIAS = "aabbccddee"; private static final String [] USER_CA_CERT_ALIAS = {"aacccddd", "bbbqqqqmmm"}; + private static final String TEST_PACKAGE_NAME = "TestApp"; /** * Setup the mocks and an instance of WifiConfigManager before each test. @@ -57,6 +69,16 @@ public class WifiKeyStoreTest { when(mWifiEnterpriseConfig.getClientCertificateAlias()).thenReturn(USER_CERT_ALIAS); when(mWifiEnterpriseConfig.getCaCertificateAliases()) .thenReturn(USER_CA_CERT_ALIAS); + when(mKeyStore.put(anyString(), any(), anyInt(), anyInt())).thenReturn(true); + when(mKeyStore.importKey(anyString(), any(), anyInt(), anyInt())).thenReturn(true); + when(mWifiEnterpriseConfig.getClientPrivateKey()).thenReturn(FakeKeys.RSA_KEY1); + when(mWifiEnterpriseConfig.getClientCertificate()).thenReturn(FakeKeys.CLIENT_CERT); + when(mWifiEnterpriseConfig.getCaCertificate()).thenReturn(FakeKeys.CA_CERT0); + when(mWifiEnterpriseConfig.getClientCertificateChain()) + .thenReturn(new X509Certificate[] {FakeKeys.CLIENT_CERT}); + when(mWifiEnterpriseConfig.getCaCertificates()) + .thenReturn(new X509Certificate[] {FakeKeys.CA_CERT0}); + when(mWifiEnterpriseConfig.getKeyId(any())).thenReturn(TEST_KEY_ID); } /** @@ -129,4 +151,38 @@ public class WifiKeyStoreTest { mWifiKeyStore.removeKeys(mWifiEnterpriseConfig); verifyNoMoreInteractions(mKeyStore); } + + /** + * Add two same network credential one is from user saved, the other is from suggestion. + * Both oh them should be installed successfully and has different alias, and will not override + * each other. + */ + @Test + public void testAddFromBothSavedAndSuggestionNetwork() throws Exception { + WifiConfiguration savedNetwork = WifiConfigurationTestUtil.createEapNetwork(); + WifiConfiguration suggestionNetwork = new WifiConfiguration(savedNetwork); + savedNetwork.enterpriseConfig = mWifiEnterpriseConfig; + suggestionNetwork.enterpriseConfig = mWifiEnterpriseConfig; + suggestionNetwork.fromWifiNetworkSuggestion = true; + suggestionNetwork.creatorName = TEST_PACKAGE_NAME; + + assertTrue(mWifiKeyStore.updateNetworkKeys(savedNetwork, null)); + assertTrue(mWifiKeyStore.updateNetworkKeys(suggestionNetwork, null)); + + String savedNetworkAlias = savedNetwork.getKeyIdForCredentials(null); + String savedNetworkCaAlias = savedNetworkAlias; + + String suggestionNetworkAlias = suggestionNetwork.getKeyIdForCredentials(null); + String suggestionNetworkCaAlias = suggestionNetworkAlias; + + assertNotEquals(savedNetworkAlias, suggestionNetworkAlias); + + verify(mWifiEnterpriseConfig).setClientCertificateAlias(eq(savedNetworkAlias)); + verify(mWifiEnterpriseConfig).setCaCertificateAliases( + aryEq(new String[] {savedNetworkCaAlias})); + + verify(mWifiEnterpriseConfig).setClientCertificateAlias(eq(suggestionNetworkAlias)); + verify(mWifiEnterpriseConfig).setCaCertificateAliases( + aryEq(new String[] {suggestionNetworkCaAlias})); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java index 612fdf575..9e183e729 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java @@ -102,6 +102,7 @@ public class WifiNetworkSuggestionsManagerTest { private @Mock NetworkSuggestionStoreData mNetworkSuggestionStoreData; private @Mock ClientModeImpl mClientModeImpl; private @Mock WifiMetrics mWifiMetrics; + private @Mock WifiKeyStore mWifiKeyStore; private TestLooper mLooper; private ArgumentCaptor mAppOpChangedListenerCaptor = ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class); @@ -161,7 +162,7 @@ public class WifiNetworkSuggestionsManagerTest { mWifiNetworkSuggestionsManager = new WifiNetworkSuggestionsManager(mContext, new Handler(mLooper.getLooper()), mWifiInjector, mWifiPermissionsUtil, mWifiConfigManager, mWifiConfigStore, - mWifiMetrics); + mWifiMetrics, mWifiKeyStore); verify(mContext).getResources(); verify(mContext).getSystemService(Context.APP_OPS_SERVICE); verify(mContext).getSystemService(Context.NOTIFICATION_SERVICE); @@ -308,6 +309,36 @@ public class WifiNetworkSuggestionsManagerTest { assertTrue(mWifiNetworkSuggestionsManager.getAllNetworkSuggestions().isEmpty()); } + @Test + public void testAddRemoveEnterpriseNetworkSuggestion() { + WifiNetworkSuggestion networkSuggestion1 = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createEapNetwork(), false, false, TEST_UID_1, + TEST_PACKAGE_1); + WifiNetworkSuggestion networkSuggestion2 = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createEapNetwork(), false, false, TEST_UID_2, + TEST_PACKAGE_2); + + List networkSuggestionList = + new ArrayList() {{ + add(networkSuggestion1); + add(networkSuggestion2); + }}; + when(mWifiKeyStore.updateNetworkKeys(eq(networkSuggestion1.wifiConfiguration), any())) + .thenReturn(true); + when(mWifiKeyStore.updateNetworkKeys(eq(networkSuggestion2.wifiConfiguration), any())) + .thenReturn(false); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.add(networkSuggestionList, TEST_UID_1, + TEST_PACKAGE_1)); + + Set allNetworkSuggestions = + mWifiNetworkSuggestionsManager.getAllNetworkSuggestions(); + assertEquals(1, allNetworkSuggestions.size()); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), + TEST_UID_1, TEST_PACKAGE_1)); + verify(mWifiKeyStore).removeKeys(any()); + } /** * Verify successful replace (add,remove, add) of network suggestions. */ -- cgit v1.2.3 From 924050178386e73cc459ec19e47afd7c304c4068 Mon Sep 17 00:00:00 2001 From: "Nate(Qiang) Jiang" Date: Fri, 6 Mar 2020 16:05:17 -0800 Subject: Fix removing enterprise suggestion certificate Make when remove a enterprise suggestion, use the internal config object to remove ketStore. Which has certificate alias. Bug: 150500247 Test: atest com.android.server.wifi Merged-In: Id020e16fb6c26f38eb217248f7296b9ae4b0e781 Change-Id: I8015d87599d843e022805ce69fd5a4eae4d7b066 --- .../com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java index 9e183e729..dabdfd569 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java @@ -334,6 +334,10 @@ public class WifiNetworkSuggestionsManagerTest { Set allNetworkSuggestions = mWifiNetworkSuggestionsManager.getAllNetworkSuggestions(); assertEquals(1, allNetworkSuggestions.size()); + WifiNetworkSuggestion removingSuggestion = new WifiNetworkSuggestion( + WifiConfigurationTestUtil.createEapNetwork(), false, false, TEST_UID_1, + TEST_PACKAGE_1); + removingSuggestion.wifiConfiguration.SSID = networkSuggestion1.wifiConfiguration.SSID; assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), TEST_UID_1, TEST_PACKAGE_1)); -- cgit v1.2.3 From 4354285b8de3345d5146f68ce2d17be83b4f34a4 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 11 Mar 2020 13:57:36 -0700 Subject: [Passpoint] Fix Passpoint matching algorithm for Home networks Match Home networks if there is an FQDN match (without realm or method), or if OtherHomePartners element exists and matches the other advertised FQDNs, or if HomeOIList element exists and matches advertised RCOIs. Bug: 151245024 Test: atest PasspointProviderTest ANQPMatcherTest Change-Id: I7bf9c98c853c3973d30ce2651bdea49546dae4b5 Merged-In: I513f83a6d545b9ae7da5577ee163ce7d186f006e --- .../server/wifi/hotspot2/ANQPMatcherTest.java | 127 ++++++++------ .../wifi/hotspot2/PasspointProviderTest.java | 189 ++++++++++++++++++++- 2 files changed, 256 insertions(+), 60 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java index 4d4ea4487..df9c332a3 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/ANQPMatcherTest.java @@ -33,7 +33,6 @@ import com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement; import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement; import com.android.server.wifi.hotspot2.anqp.eap.AuthParam; import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod; -import com.android.server.wifi.hotspot2.anqp.eap.InnerAuthEAP; import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth; import org.junit.Test; @@ -102,7 +101,7 @@ public class ANQPMatcherTest { */ @Test public void matchRoamingConsortiumWithNullElement() throws Exception { - assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0])); + assertFalse(ANQPMatcher.matchRoamingConsortium(null, new long[0], false)); } /** @@ -116,23 +115,22 @@ public class ANQPMatcherTest { long oi = 0x1234L; RoamingConsortiumElement element = new RoamingConsortiumElement(Arrays.asList(new Long[] {oi})); - assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi})); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, new long[] {oi}, false)); } /** - * Verify that an indeterminate match will be returned when matching a null NAI Realm + * Verify that no match will be returned when matching a null NAI Realm * ANQP element. * * @throws Exception */ @Test public void matchNAIRealmWithNullElement() throws Exception { - assertEquals(AuthMatch.INDETERMINATE, ANQPMatcher.matchNAIRealm(null, "test.com", - EAPConstants.EAP_TLS, new InnerAuthEAP(EAPConstants.EAP_TTLS))); + assertFalse(ANQPMatcher.matchNAIRealm(null, "test.com")); } /** - * Verify that an indeterminate match will be returned when matching a NAI Realm + * Verify that no match will be returned when matching a NAI Realm * ANQP element contained no NAI realm data. * * @throws Exception @@ -140,8 +138,7 @@ public class ANQPMatcherTest { @Test public void matchNAIRealmWithEmtpyRealmData() throws Exception { NAIRealmElement element = new NAIRealmElement(new ArrayList()); - assertEquals(AuthMatch.INDETERMINATE, ANQPMatcher.matchNAIRealm(element, "test.com", - EAPConstants.EAP_TLS, null)); + assertFalse(ANQPMatcher.matchNAIRealm(element, "test.com")); } /** @@ -157,38 +154,11 @@ public class ANQPMatcherTest { Arrays.asList(new String[] {realm}), new ArrayList()); NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.REALM, ANQPMatcher.matchNAIRealm(element, realm, - EAPConstants.EAP_TLS, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that method match will be returned when the specified EAP - * method only matches a eap method in the NAI Realm ANQP element if the element does not have - * auth params. - * - * @throws Exception - */ - @Test - public void matchNAIRealmWithMethodMatch() throws Exception { - // Test data. - String providerRealm = "test.com"; - String anqpRealm = "test2.com"; - NonEAPInnerAuth authParam = new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAP); - int eapMethodID = EAPConstants.EAP_TLS; - - // Setup NAI Realm element that has EAP method and no auth params. - EAPMethod method = new EAPMethod(eapMethodID, new HashMap>()); - NAIRealmData realmData = new NAIRealmData( - Arrays.asList(new String[]{anqpRealm}), Arrays.asList(new EAPMethod[]{method})); - NAIRealmElement element = new NAIRealmElement( - Arrays.asList(new NAIRealmData[]{realmData})); - - assertEquals(AuthMatch.METHOD, - ANQPMatcher.matchNAIRealm(element, providerRealm, eapMethodID, authParam)); - } - - /** - * Verify that a realm and method match will be returned when the specified realm and EAP + * Verify that a realm match will be returned when the specified realm and EAP * method matches a realm in the NAI Realm ANQP element. * * @throws Exception @@ -206,12 +176,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.REALM | AuthMatch.METHOD, - ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that an exact match will be returned when the specified realm, EAP + * Verify that a realm match will be returned when the specified realm, EAP * method, and the authentication parameter matches a realm with the associated EAP method and * authentication parameter in the NAI Realm ANQP element. * @@ -235,12 +204,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.EXACT, - ANQPMatcher.matchNAIRealm(element, realm, eapMethodID, authParam)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that a mismatch (AuthMatch.NONE) will be returned when the specified EAP method + * Verify that a realm match will be returned when the specified EAP method * doesn't match with the corresponding EAP method in the NAI Realm ANQP element. * * @throws Exception @@ -263,12 +231,11 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - assertEquals(AuthMatch.NONE, - ANQPMatcher.matchNAIRealm(element, realm, EAPConstants.EAP_TLS, null)); + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** - * Verify that a mismatch (AuthMatch.NONE) will be returned when the specified authentication + * Verify that a realm match will be returned when the specified authentication * parameter doesn't match with the corresponding authentication parameter in the NAI Realm * ANQP element. * @@ -292,10 +259,8 @@ public class ANQPMatcherTest { NAIRealmElement element = new NAIRealmElement( Arrays.asList(new NAIRealmData[] {realmData})); - // Mismatch in authentication type. - assertEquals(AuthMatch.NONE, - ANQPMatcher.matchNAIRealm(element, realm, EAPConstants.EAP_TTLS, - new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_PAP))); + // Mismatch in authentication type which we ignore. + assertTrue(ANQPMatcher.matchNAIRealm(element, realm)); } /** @@ -458,4 +423,64 @@ public class ANQPMatcherTest { assertEquals(-1, ANQPMatcher.getCarrierEapMethodFromMatchingNAIRealm(TEST_3GPP_FQDN, element)); } + + /** + * Verify that match is found when HomeOI contains some of the RCOIs advertised by an AP marked + * as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that no match is found when HomeOI does not contain any of the RCOIs advertised by an + * AP marked as not required. + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0xabc2L, 0x1232L}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, false)); + } + + /** + * Verify that match is found when HomeOI contains all of the RCOIs advertised by an AP marked + * as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xabcdL, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertTrue(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } + + /** + * Verify that match is not found when HomeOI does not contain all of the RCOIs advertised by an + * AP marked as required. + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + long[] providerOis = new long[] {0x1234L, 0x5678L, 0xabcdL}; + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + RoamingConsortiumElement element = + new RoamingConsortiumElement(Arrays.asList(anqpOis)); + assertFalse(ANQPMatcher.matchRoamingConsortium(element, providerOis, true)); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java index 31229c562..c35d67301 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointProviderTest.java @@ -478,9 +478,10 @@ public class PasspointProviderTest { } /** - * Verify that there is no match when the provider's FQDN matches a domain name in the - * Domain Name ANQP element but the provider's credential doesn't match the authentication - * method provided in the NAI realm. + * Verify that Home provider is matched even when the provider's FQDN matches a domain name in + * the Domain Name ANQP element but the provider's credential doesn't match the authentication + * method provided in the NAI realm. This can happen when the infrastructure provider is not + * the identity provider, and authentication method matching is not required in the spec. * * @throws Exception */ @@ -509,7 +510,8 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, mProvider.match(anqpElementMap, mRoamingConsortium)); + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); } /** @@ -657,8 +659,8 @@ public class PasspointProviderTest { } /** - * Verify that there is no match when a roaming consortium OI matches an OI - * in the roaming consortium ANQP element and but NAI realm is not matched. + * Verify that there is Roaming provider match when a roaming consortium OI matches an OI + * in the roaming consortium ANQP element and regardless of NAI realm mismatch. * * @throws Exception */ @@ -689,7 +691,7 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } @@ -766,8 +768,14 @@ public class PasspointProviderTest { } /** - * Verify that there is no match when a roaming consortium OI matches an OI + * Verify that there is Roaming provider match when a roaming consortium OI matches an OI * in the roaming consortium information element, but NAI realm is not matched. + * This can happen in roaming federation where the infrastructure provider is not the + * identity provider. + * Page 133 in the Hotspot2.0 specification states: + * Per subclause 11.25.8 of [2], if the value of HomeOI matches an OI in the Roaming + * Consortium advertised by a hotspot operator, successful authentication with that hotspot + * is possible. * * @throws Exception */ @@ -799,7 +807,7 @@ public class PasspointProviderTest { anqpElementMap.put(ANQPElementType.ANQPNAIRealm, createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); - assertEquals(PasspointMatch.None, + assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap, mRoamingConsortium)); } @@ -1354,4 +1362,167 @@ public class PasspointProviderTest { mProvider.setHasEverConnected(true); assertTrue(mProvider.getHasEverConnected()); } + + /** + * Verify that an expected WifiConfiguration will be returned for a Passpoint provider + * with a user credential. + * + * @throws Exception + */ + @Test + public void matchOtherPartnersDomainName() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setOtherHomePartners(new String [] {"test3.com"}); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that matching Any HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAnyOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x1234L, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching Any HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAnyHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAnyOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x12a4L, 0xceadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that matching All HomeOI results in a Home Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOi() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAllOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + Long[] anqpOis = new Long[] {0x1234L, 0x2345L, 0xabcdL, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.HomeProvider, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } + + /** + * Verify that non-matching All HomeOI results in a None Provider match + * + * @throws Exception + */ + @Test + public void matchAllHomeOiNegative() throws Exception { + // Setup test provider. + PasspointConfiguration config = new PasspointConfiguration(); + HomeSp homeSp = new HomeSp(); + homeSp.setFqdn("test1.com"); + homeSp.setMatchAllOis(new long[] {0x1234L, 0x2345L}); + homeSp.setRoamingConsortiumOis(null); + config.setHomeSp(homeSp); + Credential credential = new Credential(); + credential.setUserCredential(new Credential.UserCredential()); + config.setCredential(credential); + mProvider = createProvider(config); + verifyInstalledConfig(config, true); + + // 0x1234 matches, but 0x2345 does not + Long[] anqpOis = new Long[] {0x1234L, 0x5678L, 0xdeadL, 0xf0cdL}; + + // Setup Domain Name ANQP element to test2.com and test3.com + Map anqpElementMap = new HashMap<>(); + anqpElementMap.put(ANQPElementType.ANQPDomName, + createDomainNameElement(new String[] {"test2.com", "test3.com"})); + // Setup RCOIs advertised by the AP + anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, + createRoamingConsortiumElement(anqpOis)); + + assertEquals(PasspointMatch.None, + mProvider.match(anqpElementMap, mRoamingConsortium)); + } } -- cgit v1.2.3