• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi.hotspot2;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assume.assumeTrue;
23 import static org.mockito.Mockito.eq;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 import static org.mockito.MockitoAnnotations.initMocks;
27 
28 import android.net.wifi.EAPConstants;
29 import android.net.wifi.ScanResult;
30 import android.net.wifi.WifiConfiguration;
31 import android.net.wifi.WifiEnterpriseConfig;
32 import android.net.wifi.WifiSsid;
33 import android.net.wifi.hotspot2.PasspointConfiguration;
34 import android.net.wifi.hotspot2.pps.Credential;
35 import android.net.wifi.hotspot2.pps.HomeSp;
36 import android.net.wifi.hotspot2.pps.UpdateParameter;
37 import android.text.TextUtils;
38 import android.util.Base64;
39 import android.util.Pair;
40 
41 import androidx.test.filters.SmallTest;
42 
43 import com.android.modules.utils.build.SdkLevel;
44 import com.android.server.wifi.Clock;
45 import com.android.server.wifi.FakeKeys;
46 import com.android.server.wifi.MboOceConstants;
47 import com.android.server.wifi.WifiBaseTest;
48 import com.android.server.wifi.WifiCarrierInfoManager;
49 import com.android.server.wifi.WifiKeyStore;
50 import com.android.server.wifi.hotspot2.anqp.ANQPElement;
51 import com.android.server.wifi.hotspot2.anqp.CellularNetwork;
52 import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType;
53 import com.android.server.wifi.hotspot2.anqp.DomainNameElement;
54 import com.android.server.wifi.hotspot2.anqp.NAIRealmData;
55 import com.android.server.wifi.hotspot2.anqp.NAIRealmElement;
56 import com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement;
57 import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement;
58 import com.android.server.wifi.hotspot2.anqp.eap.AuthParam;
59 import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod;
60 import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth;
61 import com.android.server.wifi.util.ArrayUtils;
62 import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
63 
64 import org.junit.Before;
65 import org.junit.Test;
66 import org.junit.runner.RunWith;
67 import org.junit.runners.Parameterized;
68 import org.mockito.Mock;
69 
70 import java.nio.charset.StandardCharsets;
71 import java.security.MessageDigest;
72 import java.security.cert.Certificate;
73 import java.security.cert.X509Certificate;
74 import java.util.Arrays;
75 import java.util.BitSet;
76 import java.util.Collection;
77 import java.util.HashMap;
78 import java.util.HashSet;
79 import java.util.Map;
80 import java.util.Set;
81 
82 /**
83  * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointProvider}.
84  */
85 @SmallTest
86 @RunWith(Parameterized.class)
87 public class PasspointProviderTest extends WifiBaseTest {
88     private static final long PROVIDER_ID = 12L;
89     private static final int CREATOR_UID = 1234;
90     private static final String CREATOR_PACKAGE = "com.android.test";
91     private static final String CA_CERTIFICATE_ALIAS = "HS2_12_0";
92     private static final String CA_CERTIFICATE_ALIAS_2 = "HS2_12_1";
93     private static final String CLIENT_CERTIFICATE_ALIAS = "HS2_12";
94     private static final String CLIENT_PRIVATE_KEY_AND_CERT_ALIAS = "HS2_12";
95     private static final String REMEDIATION_CA_CERTIFICATE_ALIAS = "HS2_REMEDIATION_12";
96     private static final String SYSTEM_CA_STORE_PATH = "/system/etc/security/cacerts";
97 
98     private static final int TEST_UPDATE_IDENTIFIER = 1234;
99     private static final int TEST_USAGE_LIMIT_DATA_LIMIT = 100;
100     private static final String TEST_FQDN = "test.com";
101     private static final String TEST_FQDN2 = "test2.com";
102     private static final String TEST_FQDN3 = "test3.com";
103     private static final String TEST_FRIENDLY_NAME = "Friendly Name";
104     private static final long[] TEST_RC_OIS = new long[]{0x1234L, 0x2345L};
105     private static final long[] TEST_IE_RC_OIS = new long[]{0x1234L, 0x2133L};
106     private static final long[] TEST_IE_NO_MATCHED_RC_OIS = new long[]{0x2255L, 0x2133L};
107     private static final Long[] TEST_ANQP_RC_OIS = new Long[]{0x1234L, 0x2133L};
108     private static final Long[] TEST_ANQP_RC_OIS_2 = new Long[]{0x4321L, 0x3321L};
109     private static final String TEST_REALM = "realm.com";
110     private static final String[] TEST_TRUSTED_NAME =
111             new String[]{"trusted.fqdn.com", "another.fqdn.com"};
112     // User credential data
113     private static final String TEST_USERNAME = "username";
114     private static final String TEST_PASSWORD = "password3";
115     // SIM credential data
116     private static final int TEST_EAP_TYPE = WifiEnterpriseConfig.Eap.SIM;
117     private static final int TEST_SIM_CREDENTIAL_TYPE = EAPConstants.EAP_SIM;
118     private static final String TEST_IMSI = "1234567890";
119     private static final int VALID_CARRIER_ID = 1;
120     private static final int VALID_SUBSCRIPTION_ID = 2;
121 
122     private static final String TEST_SSID = "TestSSID";
123     private static final String TEST_SSID_QUOTED = "\"TestSSID\"";
124     private static final String TEST_SSID_2 = "TestSSID2";
125     private static final String TEST_SSID_2_QUOTED = "\"TestSSID2\"";
126     private static final String TEST_BSSID_STRING = "11:22:33:44:55:66";
127     private static final String TEST_BSSID_STRING_2 = "11:22:33:44:55:67";
128     private static final long TEST_HESSID = 0x5678L;
129     private static final int TEST_ANQP_DOMAIN_ID = 0;
130     private static final long TEST_HESSID_2 = 0xaa0aL;
131     private static final int TEST_ANQP_DOMAIN_ID_2 = 1;
132     private static final long TEST_ELAPSED_TIME_SINCE_BOOT = 100000L;
133     private static final String TEST_ANONYMOUS_IDENTITY = "AnonymousIdentity";
134     private static final String USER_CONNECT_CHOICE = "SomeNetworkProfileId";
135     private static final int TEST_RSSI = -50;
136     private static final String TEST_DECORATED_IDENTITY_PREFIX = "androidwifi.dev!";
137 
138     private enum CredentialType {
139         USER,
140         CERT,
141         SIM
142     }
143 
144     @Mock
145     WifiKeyStore mKeyStore;
146     @Mock
147     WifiCarrierInfoManager mWifiCarrierInfoManager;
148     @Mock
149     RoamingConsortium mRoamingConsortium;
150     @Mock
151     Clock mClock;
152     PasspointProvider mProvider;
153     X509Certificate mRemediationCaCertificate;
154     String mExpectedResult;
155 
156     @Parameterized.Parameters
rootCAConfigsForRemediation()157     public static Collection rootCAConfigsForRemediation() {
158         return Arrays.asList(
159                 new Object[][]{
160                         {FakeKeys.CA_CERT0, REMEDIATION_CA_CERTIFICATE_ALIAS}, // For R2 config
161                         {null, null}, // For R1 config
162                 });
163     }
164 
PasspointProviderTest(X509Certificate remediationCaCertificate, String expectedResult)165     public PasspointProviderTest(X509Certificate remediationCaCertificate, String expectedResult) {
166         mRemediationCaCertificate = remediationCaCertificate;
167         mExpectedResult = expectedResult;
168     }
169 
170     /**
171      * Sets up test.
172      */
173     @Before
setUp()174     public void setUp() throws Exception {
175         initMocks(this);
176         when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(null);
177     }
178 
179     /**
180      * Helper function for creating a provider instance for testing.
181      *
182      * @param config The configuration associated with the provider
183      * @return {@link com.android.server.wifi.hotspot2.PasspointProvider}
184      */
createProvider(PasspointConfiguration config)185     private PasspointProvider createProvider(PasspointConfiguration config) {
186         return new PasspointProvider(config, mKeyStore, mWifiCarrierInfoManager, PROVIDER_ID,
187                 CREATOR_UID, CREATOR_PACKAGE, false, mClock);
188     }
189 
190     /**
191      * Verify that the configuration associated with the provider is the same or not the same as the
192      * expected configuration.
193      *
194      * @param expectedConfig The expected configuration
195      * @param equals         Flag indicating equality or inequality check
196      */
verifyInstalledConfig(PasspointConfiguration expectedConfig, boolean equals)197     private void verifyInstalledConfig(PasspointConfiguration expectedConfig, boolean equals) {
198         PasspointConfiguration actualConfig = mProvider.getConfig();
199         if (equals) {
200             assertTrue(actualConfig.equals(expectedConfig));
201         } else {
202             assertFalse(actualConfig.equals(expectedConfig));
203         }
204     }
205 
206     /**
207      * Helper function for creating a Domain Name ANQP element.
208      *
209      * @param domains List of domain names
210      * @return {@link DomainNameElement}
211      */
createDomainNameElement(String[] domains)212     private DomainNameElement createDomainNameElement(String[] domains) {
213         return new DomainNameElement(Arrays.asList(domains));
214     }
215 
216     /**
217      * Helper function for creating a NAI Realm ANQP element.
218      *
219      * @param realm       The realm of the network
220      * @param eapMethodID EAP Method ID
221      * @param authParam   Authentication parameter
222      * @return {@link NAIRealmElement}
223      */
createNAIRealmElement(String realm, int eapMethodID, AuthParam authParam)224     private NAIRealmElement createNAIRealmElement(String realm, int eapMethodID,
225             AuthParam authParam) {
226         Map<Integer, Set<AuthParam>> authParamMap = new HashMap<>();
227         if (authParam != null) {
228             Set<AuthParam> authSet = new HashSet<>();
229             authSet.add(authParam);
230             authParamMap.put(authParam.getAuthTypeID(), authSet);
231         }
232         EAPMethod eapMethod = new EAPMethod(eapMethodID, authParamMap);
233         NAIRealmData realmData = new NAIRealmData(Arrays.asList(new String[]{realm}),
234                 Arrays.asList(new EAPMethod[]{eapMethod}));
235         return new NAIRealmElement(Arrays.asList(new NAIRealmData[]{realmData}));
236     }
237 
238     /**
239      * Helper function for creating a Roaming Consortium ANQP element.
240      *
241      * @param rcOIs Roaming consortium OIs
242      * @return {@link RoamingConsortiumElement}
243      */
createRoamingConsortiumElement(Long[] rcOIs)244     private RoamingConsortiumElement createRoamingConsortiumElement(Long[] rcOIs) {
245         return new RoamingConsortiumElement(Arrays.asList(rcOIs));
246     }
247 
248     /**
249      * Helper function for creating a 3GPP Network ANQP element.
250      *
251      * @param imsiList List of IMSI to be included in a 3GPP Network
252      * @return {@link ThreeGPPNetworkElement}
253      */
createThreeGPPNetworkElement(String[] imsiList)254     private ThreeGPPNetworkElement createThreeGPPNetworkElement(String[] imsiList) {
255         CellularNetwork network = new CellularNetwork(Arrays.asList(imsiList));
256         return new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[]{network}));
257     }
258 
259     /**
260      * Helper function for generating test passpoint configuration for test cases
261      *
262      * @param credentialType which type credential is generated.
263      * @param isLegacy       if true, omit some passpoint fields to avoid breaking comparison
264      *                       between passpoint configuration converted from wifi configuration and
265      *                       generated passpoint configuration.
266      * @return a valid passpoint configuration
267      * @throws Exception
268      */
generateTestPasspointConfiguration( CredentialType credentialType, boolean isLegacy)269     private PasspointConfiguration generateTestPasspointConfiguration(
270             CredentialType credentialType, boolean isLegacy) throws Exception {
271         PasspointConfiguration config = new PasspointConfiguration();
272         if (!isLegacy) {
273             config.setUpdateIdentifier(TEST_UPDATE_IDENTIFIER);
274             config.setUsageLimitDataLimit(TEST_USAGE_LIMIT_DATA_LIMIT);
275         }
276         HomeSp homeSp = new HomeSp();
277         homeSp.setFqdn(TEST_FQDN);
278         homeSp.setFriendlyName(TEST_FRIENDLY_NAME);
279         homeSp.setRoamingConsortiumOis(TEST_RC_OIS);
280         config.setHomeSp(homeSp);
281         Credential credential = new Credential();
282         credential.setRealm(TEST_REALM);
283 
284         if (credentialType == CredentialType.USER) {
285             byte[] base64EncodedPw =
286                     Base64.encode(TEST_PASSWORD.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
287             String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8);
288             Credential.UserCredential userCredential = new Credential.UserCredential();
289             userCredential.setEapType(EAPConstants.EAP_TTLS);
290             userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_MSCHAPV2);
291             userCredential.setUsername(TEST_USERNAME);
292             userCredential.setPassword(encodedPasswordStr);
293             if (!isLegacy) {
294                 credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0});
295             }
296             credential.setUserCredential(userCredential);
297         } else if (credentialType == CredentialType.CERT) {
298             Credential.CertificateCredential certCredential =
299                     new Credential.CertificateCredential();
300             if (!isLegacy) {
301                 certCredential.setCertSha256Fingerprint(
302                         MessageDigest.getInstance("SHA-256")
303                                 .digest(FakeKeys.CLIENT_CERT.getEncoded()));
304                 credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0});
305                 credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
306                 credential.setClientCertificateChain(new X509Certificate[]{FakeKeys.CLIENT_CERT});
307             } else {
308                 certCredential.setCertType(Credential.CertificateCredential.CERT_TYPE_X509V3);
309             }
310             credential.setCertCredential(certCredential);
311         } else if (credentialType == CredentialType.SIM) {
312             Credential.SimCredential simCredential = new Credential.SimCredential();
313             simCredential.setImsi(TEST_IMSI);
314             simCredential.setEapType(EAPConstants.EAP_SIM);
315             credential.setSimCredential(simCredential);
316         }
317         config.setCredential(credential);
318 
319         return config;
320     }
321 
322     /**
323      * Helper function for verifying wifi configuration based on Passpoint configuration
324      *
325      * @param passpointConfig the source of wifi configuration.
326      * @param wifiConfig      wifi configuration be verified.
327      * @throws Exception
328      */
verifyWifiConfigWithTestData( PasspointConfiguration passpointConfig, WifiConfiguration wifiConfig)329     private void verifyWifiConfigWithTestData(
330             PasspointConfiguration passpointConfig, WifiConfiguration wifiConfig) {
331         BitSet allowedProtocols = new BitSet();
332         allowedProtocols.set(WifiConfiguration.Protocol.RSN);
333 
334         HomeSp homeSp = passpointConfig.getHomeSp();
335         Credential credential = passpointConfig.getCredential();
336 
337         // Need to verify field by field since WifiConfiguration doesn't
338         // override equals() function.
339         WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig;
340         assertEquals(homeSp.getFqdn(), wifiConfig.FQDN);
341         assertEquals(homeSp.getFriendlyName(), wifiConfig.providerFriendlyName);
342         assertTrue(Arrays.equals(homeSp.getRoamingConsortiumOis(),
343                 wifiConfig.roamingConsortiumIds));
344 
345         assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP));
346         assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
347         assertEquals(wifiConfig.updateIdentifier,
348                 Integer.toString(passpointConfig.getUpdateIdentifier()));
349         assertEquals(allowedProtocols, wifiConfig.allowedProtocols);
350         assertEquals(Integer.toString(passpointConfig.getUpdateIdentifier()),
351                 wifiConfig.updateIdentifier);
352         assertFalse(wifiConfig.shared);
353         assertEquals(credential.getRealm(), wifiEnterpriseConfig.getRealm());
354         if (passpointConfig.isMacRandomizationEnabled()) {
355             if (passpointConfig.isNonPersistentMacRandomizationEnabled()) {
356                 assertEquals(WifiConfiguration.RANDOMIZATION_NON_PERSISTENT,
357                         wifiConfig.macRandomizationSetting);
358             } else {
359                 assertEquals(WifiConfiguration.RANDOMIZATION_PERSISTENT,
360                         wifiConfig.macRandomizationSetting);
361             }
362         } else {
363             assertEquals(WifiConfiguration.RANDOMIZATION_NONE, wifiConfig.macRandomizationSetting);
364         }
365 
366         if (credential.getUserCredential() != null) {
367             String decodedPassword;
368             Credential.UserCredential userCredential = credential.getUserCredential();
369             try {
370                 byte[] pwOctets = Base64.decode(userCredential.getPassword(), Base64.DEFAULT);
371                 decodedPassword = new String(pwOctets, StandardCharsets.UTF_8);
372             } catch (IllegalArgumentException e) {
373                 decodedPassword = userCredential.getPassword();
374             }
375 
376             assertEquals("anonymous@" + credential.getRealm(),
377                     wifiEnterpriseConfig.getAnonymousIdentity());
378             assertEquals(WifiEnterpriseConfig.Eap.TTLS, wifiEnterpriseConfig.getEapMethod());
379             switch (userCredential.getNonEapInnerMethod()) {
380                 case Credential.UserCredential.AUTH_METHOD_PAP:
381                     assertEquals(WifiEnterpriseConfig.Phase2.PAP,
382                             wifiEnterpriseConfig.getPhase2Method());
383                     break;
384                 case Credential.UserCredential.AUTH_METHOD_MSCHAP:
385                     assertEquals(WifiEnterpriseConfig.Phase2.MSCHAP,
386                             wifiEnterpriseConfig.getPhase2Method());
387                     break;
388                 case Credential.UserCredential.AUTH_METHOD_MSCHAPV2:
389                     assertEquals(WifiEnterpriseConfig.Phase2.MSCHAPV2,
390                             wifiEnterpriseConfig.getPhase2Method());
391                     break;
392             }
393             assertEquals(userCredential.getUsername(), wifiEnterpriseConfig.getIdentity());
394             assertEquals(decodedPassword, wifiEnterpriseConfig.getPassword());
395             assertEquals(decodedPassword, TEST_PASSWORD);
396             assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
397                     wifiConfig.meteredOverride);
398 
399             if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
400                 assertEquals(String.join(";", passpointConfig.getAaaServerTrustedNames()),
401                         wifiEnterpriseConfig.getDomainSuffixMatch());
402             } else {
403                 assertEquals(homeSp.getFqdn(), wifiEnterpriseConfig.getDomainSuffixMatch());
404             }
405 
406             if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
407                 assertEquals(SYSTEM_CA_STORE_PATH, wifiEnterpriseConfig.getCaPath());
408             } else if (ArrayUtils.isEmpty(credential.getCaCertificates())) {
409                 assertEquals(SYSTEM_CA_STORE_PATH, wifiEnterpriseConfig.getCaPath());
410             } else {
411                 assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
412             }
413             if (passpointConfig.getCredential().getCheckAaaServerCertStatus()) {
414                 assertEquals(wifiEnterpriseConfig.getOcsp(),
415                         WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
416             } else {
417                 assertEquals(wifiEnterpriseConfig.getOcsp(),
418                         WifiEnterpriseConfig.OCSP_NONE);
419             }
420         } else if (credential.getCertCredential() != null) {
421             Credential.CertificateCredential certCredential = credential.getCertCredential();
422             assertEquals("anonymous@" + credential.getRealm(),
423                     wifiEnterpriseConfig.getAnonymousIdentity());
424             assertEquals(WifiEnterpriseConfig.Eap.TLS, wifiEnterpriseConfig.getEapMethod());
425             assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE, wifiConfig.meteredOverride);
426             // Domain suffix match
427             if (ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
428                 assertEquals(homeSp.getFqdn(), wifiEnterpriseConfig.getDomainSuffixMatch());
429             } else {
430                 assertEquals(String.join(";", passpointConfig.getAaaServerTrustedNames()),
431                         wifiEnterpriseConfig.getDomainSuffixMatch());
432                 assertEquals(SYSTEM_CA_STORE_PATH, wifiEnterpriseConfig.getCaPath());
433             }
434             // CA certificate
435             if (!ArrayUtils.isEmpty(passpointConfig.getAaaServerTrustedNames())) {
436                 assertEquals(SYSTEM_CA_STORE_PATH, wifiEnterpriseConfig.getCaPath());
437             } else if (!ArrayUtils.isEmpty(credential.getCaCertificates())) {
438                 assertEquals(CA_CERTIFICATE_ALIAS, wifiEnterpriseConfig.getCaCertificateAlias());
439             } else {
440                 assertEquals(SYSTEM_CA_STORE_PATH, wifiEnterpriseConfig.getCaPath());
441             }
442             if (passpointConfig.getCredential().getCheckAaaServerCertStatus()) {
443                 assertEquals(wifiEnterpriseConfig.getOcsp(),
444                         WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
445             } else {
446                 assertEquals(wifiEnterpriseConfig.getOcsp(),
447                         WifiEnterpriseConfig.OCSP_NONE);
448             }
449         } else if (credential.getSimCredential() != null) {
450             Credential.SimCredential simCredential = credential.getSimCredential();
451             switch (simCredential.getEapType()) {
452                 case EAPConstants.EAP_SIM:
453                     assertEquals(WifiEnterpriseConfig.Eap.SIM,
454                             wifiEnterpriseConfig.getEapMethod());
455                     break;
456                 case EAPConstants.EAP_AKA:
457                     assertEquals(WifiEnterpriseConfig.Eap.AKA,
458                             wifiEnterpriseConfig.getEapMethod());
459                     break;
460                 case EAPConstants.EAP_AKA_PRIME:
461                     assertEquals(WifiEnterpriseConfig.Eap.AKA_PRIME,
462                             wifiEnterpriseConfig.getEapMethod());
463                     break;
464             }
465             assertEquals(simCredential.getImsi(), wifiEnterpriseConfig.getPlmn());
466         }
467     }
468 
469     /**
470      * Verify that modification to the configuration used for creating PasspointProvider will not
471      * change the configuration stored inside the PasspointProvider.
472      *
473      * @throws Exception
474      */
475     @Test
verifyModifyOriginalConfig()476     public void verifyModifyOriginalConfig() throws Exception {
477         // Create a placeholder PasspointConfiguration.
478         PasspointConfiguration config = generateTestPasspointConfiguration(
479                 CredentialType.USER, false);
480         mProvider = createProvider(config);
481         verifyInstalledConfig(config, true);
482 
483         // Modify the original configuration, the configuration maintained by the provider
484         // should be unchanged.
485         config.getHomeSp().setFqdn(TEST_FQDN2);
486         verifyInstalledConfig(config, false);
487     }
488 
489     /**
490      * Verify that modification to the configuration retrieved from the PasspointProvider will not
491      * change the configuration stored inside the PasspointProvider.
492      *
493      * @throws Exception
494      */
495     @Test
verifyModifyRetrievedConfig()496     public void verifyModifyRetrievedConfig() throws Exception {
497         // Create a placeholder PasspointConfiguration.
498         PasspointConfiguration config = generateTestPasspointConfiguration(
499                 CredentialType.USER, false);
500         mProvider = createProvider(config);
501         verifyInstalledConfig(config, true);
502 
503         // Modify the retrieved configuration, verify the configuration maintained by the
504         // provider should be unchanged.
505         PasspointConfiguration retrievedConfig = mProvider.getConfig();
506         retrievedConfig.getHomeSp().setFqdn(TEST_FQDN2);
507         verifyInstalledConfig(retrievedConfig, false);
508     }
509 
510     /**
511      * Verify a successful installation of certificates and key.
512      *
513      * @throws Exception
514      */
515     @Test
installCertsAndKeysSuccess()516     public void installCertsAndKeysSuccess() throws Exception {
517         // Create a placeholder configuration with certificate credential.
518         PasspointConfiguration config = generateTestPasspointConfiguration(
519                 CredentialType.CERT, false);
520         Credential credential = config.getCredential();
521         Credential.CertificateCredential certCredential = credential.getCertCredential();
522         credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
523         if (mRemediationCaCertificate != null) {
524             UpdateParameter updateParameter = new UpdateParameter();
525             updateParameter.setCaCertificate(mRemediationCaCertificate);
526             config.setSubscriptionUpdate(updateParameter);
527         }
528         mProvider = createProvider(config);
529 
530         // Install client certificate and key to the keystore successfully.
531         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
532                 .thenReturn(true);
533         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS_2, FakeKeys.CA_CERT1))
534                 .thenReturn(true);
535         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
536                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
537                 new Certificate[]{FakeKeys.CLIENT_CERT}))
538                 .thenReturn(true);
539         when(mKeyStore.putCaCertInKeyStore(REMEDIATION_CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
540                 .thenReturn(true);
541         assertTrue(mProvider.installCertsAndKeys());
542 
543         // Verify client certificate and key in the configuration gets cleared and aliases
544         // are set correctly.
545         PasspointConfiguration curConfig = mProvider.getConfig();
546         assertTrue(curConfig.getCredential().getCaCertificates() == null);
547         assertTrue(curConfig.getCredential().getClientPrivateKey() == null);
548         assertTrue(curConfig.getCredential().getClientCertificateChain() == null);
549         if (mRemediationCaCertificate != null) {
550             assertTrue(curConfig.getSubscriptionUpdate().getCaCertificate() == null);
551         }
552         assertTrue(mProvider.getCaCertificateAliases().equals(
553                 Arrays.asList(CA_CERTIFICATE_ALIAS, CA_CERTIFICATE_ALIAS_2)));
554         assertTrue(mProvider.getClientPrivateKeyAndCertificateAlias()
555                 .equals(CLIENT_PRIVATE_KEY_AND_CERT_ALIAS));
556         assertTrue(mProvider.getClientPrivateKeyAndCertificateAlias()
557                 .equals(CLIENT_PRIVATE_KEY_AND_CERT_ALIAS));
558         assertTrue(TextUtils.equals(mProvider.getRemediationCaCertificateAlias(), mExpectedResult));
559     }
560 
561     /**
562      * Verify a failure installation of certificates and key.
563      */
564     @Test
installCertsAndKeysFailure()565     public void installCertsAndKeysFailure() throws Exception {
566         // Create a placeholder configuration with certificate credential.
567         PasspointConfiguration config = generateTestPasspointConfiguration(
568                 CredentialType.CERT, false);
569         Credential credential = config.getCredential();
570         Credential.CertificateCredential certCredential = credential.getCertCredential();
571         credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
572         config.setCredential(credential);
573 
574         UpdateParameter updateParameter = new UpdateParameter();
575         updateParameter.setCaCertificate(mRemediationCaCertificate);
576         config.setSubscriptionUpdate(updateParameter);
577         mProvider = createProvider(config);
578 
579         // Failed to install client certificate to the keystore.
580         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
581                 .thenReturn(true);
582         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS_2, FakeKeys.CA_CERT1))
583                 .thenReturn(false);
584         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
585                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
586                 new Certificate[]{FakeKeys.CLIENT_CERT}))
587                 .thenReturn(true);
588         when(mKeyStore.putCaCertInKeyStore(REMEDIATION_CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
589                 .thenReturn(true);
590         assertFalse(mProvider.installCertsAndKeys());
591 
592         // Verify certificates and key in the configuration are not cleared and aliases
593         // are not set.
594         PasspointConfiguration curConfig = mProvider.getConfig();
595         assertTrue(curConfig.getCredential().getCaCertificates() != null);
596         assertTrue(curConfig.getCredential().getClientCertificateChain() != null);
597         assertTrue(curConfig.getCredential().getClientPrivateKey() != null);
598         if (mRemediationCaCertificate != null) {
599             assertTrue(curConfig.getSubscriptionUpdate().getCaCertificate() != null);
600         }
601         assertTrue(mProvider.getCaCertificateAliases() == null);
602         assertTrue(mProvider.getClientPrivateKeyAndCertificateAlias() == null);
603         assertTrue(mProvider.getRemediationCaCertificateAlias() == null);
604     }
605 
606     /**
607      * Verify a successful uninstallation of certificates and key.
608      */
609     @Test
uninstallCertsAndKeys()610     public void uninstallCertsAndKeys() throws Exception {
611         // Create a placeholder configuration with certificate credential.
612         PasspointConfiguration config = generateTestPasspointConfiguration(
613                 CredentialType.CERT, false);
614         Credential credential = config.getCredential();
615         Credential.CertificateCredential certCredential = credential.getCertCredential();
616         credential.setCaCertificates(new X509Certificate[]{FakeKeys.CA_CERT0, FakeKeys.CA_CERT1});
617         config.setCredential(credential);
618         if (mRemediationCaCertificate != null) {
619             UpdateParameter updateParameter = new UpdateParameter();
620             updateParameter.setCaCertificate(FakeKeys.CA_CERT0);
621             config.setSubscriptionUpdate(updateParameter);
622         }
623         mProvider = createProvider(config);
624 
625         // Install client certificate and key to the keystore successfully.
626         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
627                 .thenReturn(true);
628         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS_2, FakeKeys.CA_CERT1))
629                 .thenReturn(true);
630         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
631                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
632                 new Certificate[]{FakeKeys.CLIENT_CERT}))
633                 .thenReturn(true);
634         when(mKeyStore.putCaCertInKeyStore(REMEDIATION_CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
635                 .thenReturn(true);
636         assertTrue(mProvider.installCertsAndKeys());
637         assertTrue(mProvider.getCaCertificateAliases().equals(
638                 Arrays.asList(CA_CERTIFICATE_ALIAS, CA_CERTIFICATE_ALIAS_2)));
639         assertTrue(mProvider.getClientPrivateKeyAndCertificateAlias()
640                 .equals(CLIENT_PRIVATE_KEY_AND_CERT_ALIAS));
641         assertTrue(TextUtils.equals(mProvider.getRemediationCaCertificateAlias(), mExpectedResult));
642 
643         // Uninstall certificates and key from the keystore.
644         mProvider.uninstallCertsAndKeys();
645         verify(mKeyStore).removeEntryFromKeyStore(CA_CERTIFICATE_ALIAS);
646         verify(mKeyStore).removeEntryFromKeyStore(CA_CERTIFICATE_ALIAS_2);
647         verify(mKeyStore).removeEntryFromKeyStore(CLIENT_CERTIFICATE_ALIAS);
648         verify(mKeyStore).removeEntryFromKeyStore(CLIENT_PRIVATE_KEY_AND_CERT_ALIAS);
649         if (mRemediationCaCertificate != null) {
650             verify(mKeyStore).removeEntryFromKeyStore(REMEDIATION_CA_CERTIFICATE_ALIAS);
651         }
652 
653         assertTrue(mProvider.getCaCertificateAliases() == null);
654         assertTrue(mProvider.getClientPrivateKeyAndCertificateAlias() == null);
655         assertTrue(mProvider.getRemediationCaCertificateAlias() == null);
656     }
657 
658     /**
659      * Verify that a provider is a home provider when its FQDN matches a domain name in the Domain
660      * Name ANQP element and no NAI realm is provided.
661      *
662      * @throws Exception
663      */
664     @Test
matchFQDNWithoutNAIRealm()665     public void matchFQDNWithoutNAIRealm() throws Exception {
666         // Setup test provider.
667         PasspointConfiguration config = generateTestPasspointConfiguration(
668                 CredentialType.USER, false);
669         mProvider = createProvider(config);
670 
671         // Setup ANQP elements.
672         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
673         anqpElementMap.put(ANQPElementType.ANQPDomName,
674                 createDomainNameElement(new String[]{TEST_FQDN}));
675 
676         assertEquals(PasspointMatch.HomeProvider,
677                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
678     }
679 
680     /**
681      * Verify that a provider is a home provider when its FQDN matches a domain name in the Domain
682      * Name ANQP element and the provider's credential matches the NAI realm provided.
683      *
684      * @throws Exception
685      */
686     @Test
matchFQDNWithNAIRealmMatch()687     public void matchFQDNWithNAIRealmMatch() throws Exception {
688         // Setup test provider.
689         PasspointConfiguration config = generateTestPasspointConfiguration(
690                 CredentialType.USER, false);
691         mProvider = createProvider(config);
692 
693         // Setup Domain Name ANQP element.
694         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
695         anqpElementMap.put(ANQPElementType.ANQPDomName,
696                 createDomainNameElement(new String[]{TEST_FQDN}));
697         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
698                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
699                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
700 
701         assertEquals(PasspointMatch.HomeProvider,
702                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
703     }
704 
705     /**
706      * Verify that Home provider is matched even when the provider's FQDN matches a domain name in
707      * the Domain Name ANQP element but the provider's credential doesn't match the authentication
708      * method provided in the NAI realm. This can happen when the infrastructure provider is not the
709      * identity provider, and authentication method matching is not required in the spec.
710      *
711      * @throws Exception
712      */
713     @Test
matchFQDNWithNAIRealmMismatch()714     public void matchFQDNWithNAIRealmMismatch() throws Exception {
715         // Setup test provider.
716         PasspointConfiguration config = generateTestPasspointConfiguration(
717                 CredentialType.USER, false);
718         mProvider = createProvider(config);
719 
720         // Setup Domain Name ANQP element.
721         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
722         anqpElementMap.put(ANQPElementType.ANQPDomName,
723                 createDomainNameElement(new String[]{TEST_FQDN}));
724         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
725                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
726 
727         assertEquals(PasspointMatch.HomeProvider,
728                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
729     }
730 
731     /**
732      * Verify that a provider is a home provider when its SIM credential matches an 3GPP network
733      * domain name in the Domain Name ANQP element.
734      *
735      * @throws Exception
736      */
737     @Test
matchFQDNWith3GPPNetworkDomainName()738     public void matchFQDNWith3GPPNetworkDomainName() throws Exception {
739         // Setup test provider.
740         PasspointConfiguration config = generateTestPasspointConfiguration(
741                 CredentialType.SIM, false);
742         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(TEST_IMSI))
743                 .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
744         mProvider = createProvider(config);
745 
746         // Setup Domain Name ANQP element.
747         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
748         anqpElementMap.put(ANQPElementType.ANQPDomName,
749                 createDomainNameElement(new String[]{"wlan.mnc456.mcc123.3gppnetwork.org"}));
750 
751         assertEquals(PasspointMatch.HomeProvider,
752                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
753     }
754 
755     /**
756      * Verify that a provider is a home provider when its FQDN, roaming consortium OI, and IMSI all
757      * matched against the ANQP elements, since we prefer matching home provider over roaming
758      * provider.
759      *
760      * @throws Exception
761      */
762     @Test
matchFQDNOverRoamingProvider()763     public void matchFQDNOverRoamingProvider() throws Exception {
764         // Setup test provider.
765         PasspointConfiguration config = generateTestPasspointConfiguration(
766                 CredentialType.SIM, false);
767         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(TEST_IMSI))
768                 .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
769         mProvider = createProvider(config);
770 
771         // Setup ANQP elements.
772         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
773         anqpElementMap.put(ANQPElementType.ANQPDomName,
774                 createDomainNameElement(new String[]{TEST_FQDN}));
775         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
776                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
777         anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
778                 createThreeGPPNetworkElement(new String[]{"123456"}));
779 
780         assertEquals(PasspointMatch.HomeProvider,
781                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
782     }
783 
784     /**
785      * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI in
786      * the roaming consortium ANQP element and no NAI realm is provided.
787      *
788      * @throws Exception
789      */
790     @Test
matchRoamingConsortiumWithoutNAIRealm()791     public void matchRoamingConsortiumWithoutNAIRealm() throws Exception {
792         // Setup test provider.
793         PasspointConfiguration config = generateTestPasspointConfiguration(
794                 CredentialType.SIM, false);
795         mProvider = createProvider(config);
796         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(
797                 eq(config.getCredential().getSimCredential().getImsi())))
798                 .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
799 
800         // Setup Roaming Consortium ANQP element.
801         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
802         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
803                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
804 
805         assertEquals(PasspointMatch.RoamingProvider,
806                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
807 
808         // Confirm the selected RCOI matches the expected value
809         assertEquals(TEST_IE_RC_OIS[0],
810                 mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
811         // Confirm the value is cleared after it was fetched
812         assertEquals(0, mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
813     }
814 
815     /**
816      * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI in
817      * the roaming consortium ANQP element and the provider's credential matches the NAI realm
818      * provided.
819      *
820      * @throws Exception
821      */
822     @Test
matchRoamingConsortiumWithNAIRealmMatch()823     public void matchRoamingConsortiumWithNAIRealmMatch() throws Exception {
824 
825         // Setup test provider.
826         PasspointConfiguration config = generateTestPasspointConfiguration(
827                 CredentialType.USER, false);
828         mProvider = createProvider(config);
829 
830         // Setup Roaming Consortium ANQP element.
831         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
832         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
833                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
834         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
835                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
836                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
837 
838         assertEquals(PasspointMatch.RoamingProvider,
839                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
840     }
841 
842     /**
843      * Verify that there is Roaming provider match when a roaming consortium OI matches an OI in the
844      * roaming consortium ANQP element and regardless of NAI realm mismatch.
845      *
846      * @throws Exception
847      */
848     @Test
matchRoamingConsortiumWithNAIRealmMisMatch()849     public void matchRoamingConsortiumWithNAIRealmMisMatch() throws Exception {
850         // Setup test provider.
851         PasspointConfiguration config = generateTestPasspointConfiguration(
852                 CredentialType.USER, false);
853         mProvider = createProvider(config);
854 
855         // Setup Roaming Consortium ANQP element.
856         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
857         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
858                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
859         // Set up NAI with different EAP method
860         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
861                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
862 
863         assertEquals(PasspointMatch.RoamingProvider,
864                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
865     }
866 
867     /**
868      * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI in
869      * the roaming consortium information element and no NAI realm is provided.
870      *
871      * @throws Exception
872      */
873     @Test
matchRoamingConsortiumIeWithoutNAIRealm()874     public void matchRoamingConsortiumIeWithoutNAIRealm() throws Exception {
875         // Setup test provider.
876         PasspointConfiguration config = generateTestPasspointConfiguration(
877                 CredentialType.USER, false);
878         mProvider = createProvider(config);
879 
880         // Setup Roaming Consortium ANQP element.
881         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
882 
883         // Setup Roaming Consortium Information element.
884         when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
885 
886         assertEquals(PasspointMatch.RoamingProvider,
887                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
888     }
889 
890     /**
891      * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI in
892      * the roaming consortium information element and the provider's credential matches the NAI
893      * realm provided.
894      *
895      * @throws Exception
896      */
897     @Test
matchRoamingConsortiumIeWithNAIRealmMatch()898     public void matchRoamingConsortiumIeWithNAIRealmMatch() throws Exception {
899         // Setup test provider.
900         PasspointConfiguration config = generateTestPasspointConfiguration(
901                 CredentialType.USER, false);
902         mProvider = createProvider(config);
903 
904         // Setup Roaming Consortium ANQP element.
905         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
906 
907         // Setup Roaming Consortium Information element.
908         when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
909         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
910                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
911                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
912 
913         assertEquals(PasspointMatch.RoamingProvider,
914                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
915     }
916 
917     /**
918      * Verify that there is Roaming provider match when a roaming consortium OI matches an OI in the
919      * roaming consortium information element, but NAI realm is not matched. This can happen in
920      * roaming federation where the infrastructure provider is not the identity provider. Page 133
921      * in the Hotspot2.0 specification states: Per subclause 11.25.8 of [2], if the value of HomeOI
922      * matches an OI in the Roaming Consortium advertised by a hotspot operator, successful
923      * authentication with that hotspot is possible.
924      *
925      * @throws Exception
926      */
927     @Test
matchRoamingConsortiumIeWithNAIRealmMismatch()928     public void matchRoamingConsortiumIeWithNAIRealmMismatch() throws Exception {
929         // Setup test provider.
930         PasspointConfiguration config = generateTestPasspointConfiguration(
931                 CredentialType.USER, false);
932         mProvider = createProvider(config);
933 
934         // Setup Roaming Consortium ANQP element.
935         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
936 
937         // Setup Roaming Consortium Information element.
938         when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_RC_OIS);
939         // Set up NAI with different EAP method
940         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
941                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TLS, null));
942 
943         assertEquals(PasspointMatch.RoamingProvider,
944                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
945 
946         // Confirm the selected RCOI matches the expected value
947         assertEquals(TEST_IE_RC_OIS[0],
948                 mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
949         // Confirm the value is cleared after it was fetched
950         assertEquals(0, mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
951     }
952 
953     /**
954      * Verify that none of matched providers are found when a roaming consortium OI doesn't matches
955      * an OI in the roaming consortium information element and none of NAI realms match each other.
956      *
957      * @throws Exception
958      */
959     @Test
misMatchForRoamingConsortiumIeAndNAIRealm()960     public void misMatchForRoamingConsortiumIeAndNAIRealm() throws Exception {
961         // Setup test provider.
962         PasspointConfiguration config = generateTestPasspointConfiguration(
963                 CredentialType.USER, false);
964         mProvider = createProvider(config);
965 
966         // Setup Roaming Consortium ANQP element.
967         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
968 
969         // Setup Roaming Consortium Information element.
970         when(mRoamingConsortium.getRoamingConsortiums()).thenReturn(TEST_IE_NO_MATCHED_RC_OIS);
971 
972         assertEquals(PasspointMatch.None,
973                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
974     }
975 
976     /**
977      * Verify that a provider is a roaming provider when the provider's IMSI parameter and an IMSI
978      * from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element regardless of NAI realm
979      * mismatch.
980      *
981      * @throws Exception
982      */
983     @Test
matchThreeGPPNetworkWithNAIRealmMismatch()984     public void matchThreeGPPNetworkWithNAIRealmMismatch() throws Exception {
985         // Setup test provider.
986         PasspointConfiguration config = generateTestPasspointConfiguration(
987                 CredentialType.SIM, false);
988         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(TEST_IMSI))
989                 .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
990         mProvider = createProvider(config);
991 
992         // Setup 3GPP Network ANQP element.
993         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
994         anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
995                 createThreeGPPNetworkElement(new String[]{"123456"}));
996 
997         // Setup NAI Realm ANQP element with different realm.
998         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
999                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1000                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1001 
1002         assertEquals(PasspointMatch.RoamingProvider,
1003                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1004     }
1005 
1006     /**
1007      * Verify that a provider is a roaming provider when the provider's IMSI parameter and an IMSI
1008      * from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element regardless of NAI realm
1009      * match.
1010      *
1011      * @throws Exception
1012      */
1013     @Test
matchThreeGPPNetworkWithNAIRealmMatch()1014     public void matchThreeGPPNetworkWithNAIRealmMatch() throws Exception {
1015         // Setup test provider.
1016         PasspointConfiguration config = generateTestPasspointConfiguration(
1017                 CredentialType.SIM, false);
1018         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(TEST_IMSI))
1019                 .thenReturn(new Pair<String, Integer>(TEST_IMSI, VALID_CARRIER_ID));
1020         mProvider = createProvider(config);
1021 
1022         // Setup 3GPP Network ANQP element.
1023         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1024         anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
1025                 createThreeGPPNetworkElement(new String[]{"123456"}));
1026 
1027         // Setup NAI Realm ANQP element with same realm.
1028         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1029                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
1030 
1031         assertEquals(PasspointMatch.RoamingProvider,
1032                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1033         assertEquals(VALID_CARRIER_ID, mProvider.getWifiConfig().carrierId);
1034     }
1035 
1036     /**
1037      * Verify that when the SIM card matched by carrier ID of profile is absent, it shouldn't be
1038      * matched even the profile and ANQP elements are matched.
1039      *
1040      * @throws Exception
1041      */
1042     @Test
matchNothingIfSimMatchedByCarrierIdIsAbsent()1043     public void matchNothingIfSimMatchedByCarrierIdIsAbsent() throws Exception {
1044         // Setup test provider.
1045         PasspointConfiguration config = generateTestPasspointConfiguration(
1046                 CredentialType.SIM, false);
1047         config.setCarrierId(VALID_CARRIER_ID);
1048         when(mWifiCarrierInfoManager.getMatchingSubId(eq(VALID_CARRIER_ID)))
1049                 .thenReturn(VALID_SUBSCRIPTION_ID);
1050         when(mWifiCarrierInfoManager.getMatchingImsiBySubId(eq(VALID_SUBSCRIPTION_ID)))
1051                 .thenReturn(null);
1052         mProvider = createProvider(config);
1053 
1054         // Setup 3GPP Network ANQP element.
1055         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1056         anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
1057                 createThreeGPPNetworkElement(new String[]{"123456"}));
1058 
1059         // Setup NAI Realm ANQP element with same realm.
1060         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1061                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
1062 
1063         assertEquals(PasspointMatch.None,
1064                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1065     }
1066 
1067     /**
1068      * Verify that when the SIM card matched by IMSI of profile is absent, it shouldn't be matched
1069      * even the profile and ANQP elements are matched.
1070      *
1071      * @throws Exception
1072      */
1073     @Test
matchNothingIfSimMatchedByImsiIsAbsent()1074     public void matchNothingIfSimMatchedByImsiIsAbsent() throws Exception {
1075         // Setup test provider.
1076         PasspointConfiguration config = generateTestPasspointConfiguration(
1077                 CredentialType.SIM, false);
1078         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(eq(TEST_IMSI)))
1079                 .thenReturn(null);
1080         mProvider = createProvider(config);
1081 
1082         // Setup 3GPP Network ANQP element.
1083         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1084         anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork,
1085                 createThreeGPPNetworkElement(new String[]{"123456"}));
1086 
1087         // Setup NAI Realm ANQP element with same realm.
1088         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1089                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_AKA, null));
1090 
1091         assertEquals(PasspointMatch.None,
1092                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1093     }
1094 
1095     /**
1096      * Verify that a provider is a roaming provider when its credential only matches a NAI realm in
1097      * the NAI Realm ANQP element and not match for Domain Name, RoamingConsortium and 3GPP.
1098      *
1099      * @throws Exception
1100      */
1101     @Test
matchOnlyNAIRealmWithOtherInformationMismatch()1102     public void matchOnlyNAIRealmWithOtherInformationMismatch() throws Exception {
1103         // Setup test provider.
1104         PasspointConfiguration config = generateTestPasspointConfiguration(
1105                 CredentialType.USER, false);
1106         mProvider = createProvider(config);
1107 
1108         // Setup NAI Realm ANQP element.
1109         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1110         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1111                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1112                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1113 
1114         assertEquals(PasspointMatch.RoamingProvider,
1115                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1116     }
1117 
1118     /**
1119      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1120      * user credential.
1121      *
1122      * @throws Exception
1123      */
1124     @Test
getWifiConfigWithUserCredential()1125     public void getWifiConfigWithUserCredential() throws Exception {
1126         // Create provider for R2.
1127         PasspointConfiguration config = generateTestPasspointConfiguration(
1128                 CredentialType.USER, false);
1129         mProvider = createProvider(config);
1130 
1131         // Install certificate.
1132         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
1133                 .thenReturn(true);
1134         assertTrue(mProvider.installCertsAndKeys());
1135 
1136         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1137         // the configuration.
1138         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1139 
1140         // Verify that AAA server trusted names are provisioned.
1141         config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
1142         mProvider = createProvider(config);
1143         verifyWifiConfigWithTestData(config,
1144                 createProvider(config).getWifiConfig());
1145     }
1146 
1147     /**
1148      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1149      * user credential which has AAA server trusted names provisioned.
1150      *
1151      * @throws Exception
1152      */
1153     @Test
getWifiConfigWithUserCredentialHasAaaServerTrustedNames()1154     public void getWifiConfigWithUserCredentialHasAaaServerTrustedNames() throws Exception {
1155         // Create provider for R2.
1156         PasspointConfiguration config = generateTestPasspointConfiguration(
1157                 CredentialType.USER, false);
1158         config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
1159         Credential credential = config.getCredential();
1160         // OCSP (Online Certificate Status Protocol) is required.
1161         credential.setCheckAaaServerCertStatus(true);
1162         mProvider = createProvider(config);
1163 
1164         // Install certificate.
1165         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
1166                 .thenReturn(true);
1167         assertTrue(mProvider.installCertsAndKeys());
1168 
1169         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1170         // the configuration.
1171         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1172 
1173         // Verify that AAA server trusted names are provisioned.
1174         config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
1175         mProvider = createProvider(config);
1176         verifyWifiConfigWithTestData(config,
1177                 createProvider(config).getWifiConfig());
1178     }
1179 
1180     /**
1181      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1182      * user credential which has no CA cert.
1183      *
1184      * @throws Exception
1185      */
1186     @Test
getWifiConfigWithUserCredentialNoCaCert()1187     public void getWifiConfigWithUserCredentialNoCaCert() throws Exception {
1188         // Create provider for R2.
1189         PasspointConfiguration config = generateTestPasspointConfiguration(
1190                 CredentialType.USER, false);
1191         config.getCredential().setCaCertificates(null);
1192         mProvider = createProvider(config);
1193 
1194         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1195         // the configuration.
1196         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1197     }
1198 
1199     /**
1200      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1201      * certificate credential.
1202      *
1203      * @throws Exception
1204      */
1205     @Test
getWifiConfigWithCertCredential()1206     public void getWifiConfigWithCertCredential() throws Exception {
1207         // Create provider.
1208         PasspointConfiguration config = generateTestPasspointConfiguration(
1209                 CredentialType.CERT, false);
1210         mProvider = createProvider(config);
1211 
1212         // Install certificate.
1213         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
1214                 .thenReturn(true);
1215         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
1216                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
1217                 new Certificate[]{FakeKeys.CLIENT_CERT}))
1218                 .thenReturn(true);
1219         assertTrue(mProvider.installCertsAndKeys());
1220 
1221         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1222         // the configuration.
1223         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1224     }
1225 
1226     /**
1227      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1228      * certificate credential which has AAA server trusted names provisioned.
1229      *
1230      * @throws Exception
1231      */
1232     @Test
getWifiConfigWithCertCredentialHasAaaServerTrustedNames()1233     public void getWifiConfigWithCertCredentialHasAaaServerTrustedNames() throws Exception {
1234         // Create provider.
1235         PasspointConfiguration config = generateTestPasspointConfiguration(
1236                 CredentialType.CERT, false);
1237         config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
1238         mProvider = createProvider(config);
1239 
1240         // Install certificate.
1241         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
1242                 .thenReturn(true);
1243         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
1244                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
1245                 new Certificate[]{FakeKeys.CLIENT_CERT}))
1246                 .thenReturn(true);
1247         assertTrue(mProvider.installCertsAndKeys());
1248 
1249         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1250         // the configuration.
1251         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1252     }
1253 
1254     /**
1255      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1256      * certificate credential which has no CA cert.
1257      *
1258      * @throws Exception
1259      */
1260     @Test
getWifiConfigWithCertCredentialNoCaCert()1261     public void getWifiConfigWithCertCredentialNoCaCert() throws Exception {
1262         // Create provider.
1263         PasspointConfiguration config = generateTestPasspointConfiguration(
1264                 CredentialType.CERT, false);
1265         config.getCredential().setCaCertificates(null);
1266         mProvider = createProvider(config);
1267 
1268         // Install certificate.
1269         when(mKeyStore.putUserPrivKeyAndCertsInKeyStore(
1270                 CLIENT_PRIVATE_KEY_AND_CERT_ALIAS, FakeKeys.RSA_KEY1,
1271                 new Certificate[]{FakeKeys.CLIENT_CERT}))
1272                 .thenReturn(true);
1273         assertTrue(mProvider.installCertsAndKeys());
1274 
1275         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1276         // the configuration.
1277         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1278     }
1279 
1280     /**
1281      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1282      * SIM credential.
1283      *
1284      * @throws Exception
1285      */
1286     @Test
getWifiConfigWithSimCredential()1287     public void getWifiConfigWithSimCredential() throws Exception {
1288         // Create provider.
1289         PasspointConfiguration config = generateTestPasspointConfiguration(
1290                 CredentialType.SIM, false);
1291         mProvider = createProvider(config);
1292 
1293         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1294         // the configuration.
1295         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1296     }
1297 
1298     @Test
getWifiConfigWithAutojoinDisable()1299     public void getWifiConfigWithAutojoinDisable() throws Exception {
1300         PasspointConfiguration config = generateTestPasspointConfiguration(
1301                 CredentialType.USER, false);
1302         mProvider = createProvider(config);
1303 
1304         assertTrue(mProvider.getWifiConfig().allowAutojoin);
1305         mProvider.setAutojoinEnabled(false);
1306         assertFalse(mProvider.getWifiConfig().allowAutojoin);
1307     }
1308 
1309     @Test
getWifiConfigWithCarrierMerged()1310     public void getWifiConfigWithCarrierMerged() throws Exception {
1311         PasspointConfiguration config = generateTestPasspointConfiguration(
1312                 CredentialType.USER, false);
1313         config.setCarrierMerged(true);
1314         mProvider = createProvider(config);
1315         assertTrue(mProvider.getWifiConfig().carrierMerged);
1316     }
1317 
1318     @Test
getWifiConfigWithOemPaid()1319     public void getWifiConfigWithOemPaid() throws Exception {
1320         PasspointConfiguration config = generateTestPasspointConfiguration(
1321                 CredentialType.USER, false);
1322         config.setOemPaid(true);
1323         mProvider = createProvider(config);
1324         assertTrue(mProvider.getWifiConfig().oemPaid);
1325     }
1326 
1327     @Test
getWifiConfigWithOemPrivate()1328     public void getWifiConfigWithOemPrivate() throws Exception {
1329         PasspointConfiguration config = generateTestPasspointConfiguration(
1330                 CredentialType.USER, false);
1331         config.setOemPrivate(true);
1332         mProvider = createProvider(config);
1333         assertTrue(mProvider.getWifiConfig().oemPrivate);
1334     }
1335 
1336     /**
1337      * Verify that the mac randomization setting will be included in the generated
1338      * WifiConfiguration.
1339      */
1340     @Test
testSetMacRandomizationEnabledToFalse()1341     public void testSetMacRandomizationEnabledToFalse() throws Exception {
1342         // Create provider.
1343         PasspointConfiguration config = generateTestPasspointConfiguration(
1344                 CredentialType.SIM, false);
1345         mProvider = createProvider(config);
1346         mProvider.setMacRandomizationEnabled(false);
1347         verifyWifiConfigWithTestData(mProvider.getConfig(), mProvider.getWifiConfig());
1348     }
1349 
1350     /**
1351      * Verify the generated WifiConfiguration.macRandomizationSetting defaults to
1352      * RANDOMIZATION_PERSISTENT.
1353      */
1354     @Test
testMacRandomizationSettingDefaultIsPersistent()1355     public void testMacRandomizationSettingDefaultIsPersistent() throws Exception {
1356         PasspointConfiguration config = generateTestPasspointConfiguration(
1357                 CredentialType.SIM, false);
1358         mProvider = createProvider(config);
1359 
1360         assertEquals(WifiConfiguration.RANDOMIZATION_PERSISTENT,
1361                 mProvider.getWifiConfig().macRandomizationSetting);
1362     }
1363 
1364     /**
1365      * Verify the WifiConfiguration is generated properly with settings to use non-persistent MAC
1366      * randomization.
1367      */
1368     @Test
testMacRandomizationSettingNonPersistent()1369     public void testMacRandomizationSettingNonPersistent() throws Exception {
1370         PasspointConfiguration config = generateTestPasspointConfiguration(
1371                 CredentialType.SIM, false);
1372         config.setNonPersistentMacRandomizationEnabled(true);
1373         mProvider = createProvider(config);
1374 
1375         assertEquals(WifiConfiguration.RANDOMIZATION_NON_PERSISTENT,
1376                 mProvider.getWifiConfig().macRandomizationSetting);
1377     }
1378 
1379     /**
1380      * Verify that an expected {@link PasspointConfiguration} will be returned when converting from
1381      * a {@link WifiConfiguration} containing a user credential.
1382      *
1383      * @throws Exception
1384      */
1385     @Test
convertFromWifiConfigWithUserCredential()1386     public void convertFromWifiConfigWithUserCredential() throws Exception {
1387         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1388         WifiConfiguration wifiConfig = new WifiConfiguration();
1389         wifiConfig.FQDN = TEST_FQDN;
1390         wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
1391         wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
1392         wifiConfig.enterpriseConfig.setIdentity(TEST_USERNAME);
1393         wifiConfig.enterpriseConfig.setPassword(TEST_PASSWORD);
1394         wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
1395         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
1396         wifiConfig.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
1397 
1398         // Setup expected {@link PasspointConfiguration}
1399         PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
1400                 CredentialType.USER, true);
1401         Credential.UserCredential userCredential =
1402                 passpointConfig.getCredential().getUserCredential();
1403         userCredential.setNonEapInnerMethod(Credential.UserCredential.AUTH_METHOD_PAP);
1404 
1405         assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
1406     }
1407 
1408     /**
1409      * Verify that an expected {@link PasspointConfiguration} will be returned when converting from
1410      * a {@link WifiConfiguration} containing a SIM credential.
1411      *
1412      * @throws Exception
1413      */
1414     @Test
convertFromWifiConfigWithSimCredential()1415     public void convertFromWifiConfigWithSimCredential() throws Exception {
1416         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1417         WifiConfiguration wifiConfig = new WifiConfiguration();
1418         wifiConfig.FQDN = TEST_FQDN;
1419         wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
1420         wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
1421         wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
1422         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.SIM);
1423         wifiConfig.enterpriseConfig.setPlmn(TEST_IMSI);
1424 
1425         // Setup expected {@link PasspointConfiguration}
1426         PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
1427                 CredentialType.SIM, true);
1428 
1429         assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
1430     }
1431 
1432     /**
1433      * Verify that an expected {@link PasspointConfiguration} will be returned when converting from
1434      * a {@link WifiConfiguration} containing a certificate credential.
1435      *
1436      * @throws Exception
1437      */
1438     @Test
convertFromWifiConfigWithCertCredential()1439     public void convertFromWifiConfigWithCertCredential() throws Exception {
1440         // Setup WifiConfiguration for legacy Passpoint configuraiton.
1441         WifiConfiguration wifiConfig = new WifiConfiguration();
1442         wifiConfig.FQDN = TEST_FQDN;
1443         wifiConfig.providerFriendlyName = TEST_FRIENDLY_NAME;
1444         wifiConfig.roamingConsortiumIds = TEST_RC_OIS;
1445         wifiConfig.enterpriseConfig.setRealm(TEST_REALM);
1446         wifiConfig.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
1447 
1448         // Setup expected {@link PasspointConfiguration}
1449         PasspointConfiguration passpointConfig = generateTestPasspointConfiguration(
1450                 CredentialType.CERT, true);
1451 
1452         assertEquals(passpointConfig, PasspointProvider.convertFromWifiConfig(wifiConfig));
1453     }
1454 
1455     /**
1456      * Verify that {@link PasspointProvider#isSimCredential} will return true for provider that's
1457      * backed by a SIM credential.
1458      *
1459      * @throws Exception
1460      */
1461     @Test
providerBackedBySimCredential()1462     public void providerBackedBySimCredential() throws Exception {
1463         PasspointConfiguration config = generateTestPasspointConfiguration(
1464                 CredentialType.SIM, false);
1465         mProvider = createProvider(config);
1466 
1467         assertTrue(mProvider.isSimCredential());
1468     }
1469 
1470     /**
1471      * Verify that {@link PasspointProvider#isSimCredential} will return false for provider that's
1472      * not backed by a SIM credential.
1473      *
1474      * @throws Exception
1475      */
1476     @Test
providerNotBackedBySimCredential()1477     public void providerNotBackedBySimCredential() throws Exception {
1478         PasspointConfiguration config = generateTestPasspointConfiguration(
1479                 CredentialType.CERT, false);
1480         mProvider = createProvider(config);
1481 
1482         assertFalse(mProvider.isSimCredential());
1483     }
1484 
1485     /**
1486      * Verify that hasEverConnected flag is set correctly using {@link
1487      * PasspointProvider#setHasEverConnected}.
1488      *
1489      * @throws Exception
1490      */
1491     @Test
setHasEverConnected()1492     public void setHasEverConnected() throws Exception {
1493         PasspointConfiguration config = generateTestPasspointConfiguration(
1494                 CredentialType.USER, false);
1495         mProvider = createProvider(config);
1496         verifyInstalledConfig(config, true);
1497 
1498         assertFalse(mProvider.getHasEverConnected());
1499         mProvider.setHasEverConnected(true);
1500         assertTrue(mProvider.getHasEverConnected());
1501     }
1502 
1503     /**
1504      * Verify that a provider is a home provider when there is a match between Other Home Partners
1505      * in the profile and the Domain Name ANQP element.
1506      *
1507      * @throws Exception
1508      */
1509     @Test
getWifiConfigWithUserCredentialAndNonBase64Password()1510     public void getWifiConfigWithUserCredentialAndNonBase64Password() throws Exception {
1511         // Create provider for R2.
1512         PasspointConfiguration config = generateTestPasspointConfiguration(
1513                 CredentialType.USER, false);
1514 
1515         // Update the password to non-Base64
1516         Credential credential = config.getCredential();
1517         Credential.UserCredential userCredential = credential.getUserCredential();
1518         userCredential.setPassword(TEST_PASSWORD);
1519         credential.setUserCredential(userCredential);
1520         config.setCredential(credential);
1521 
1522         mProvider = createProvider(config);
1523 
1524         // Install certificate.
1525         when(mKeyStore.putCaCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0))
1526                 .thenReturn(true);
1527         assertTrue(mProvider.installCertsAndKeys());
1528 
1529         // Retrieve the WifiConfiguration associated with the provider, and verify the content of
1530         // the configuration.
1531         verifyWifiConfigWithTestData(config, mProvider.getWifiConfig());
1532 
1533         // Verify that AAA server trusted names are provisioned.
1534         config.setAaaServerTrustedNames(TEST_TRUSTED_NAME);
1535         mProvider = createProvider(config);
1536         verifyWifiConfigWithTestData(config,
1537                 createProvider(config).getWifiConfig());
1538     }
1539 
1540     /**
1541      * Verify that an expected WifiConfiguration will be returned for a Passpoint provider with a
1542      * user credential.
1543      *
1544      * @throws Exception
1545      */
1546     @Test
matchOtherPartnersDomainName()1547     public void matchOtherPartnersDomainName() throws Exception {
1548         // Setup test provider.
1549         PasspointConfiguration config = generateTestPasspointConfiguration(
1550                 CredentialType.USER, false);
1551 
1552         // Configuration was created with TEST_FQDN as the FQDN, add TEST_FQDN3 as other home
1553         // partner.
1554         HomeSp homeSp = config.getHomeSp();
1555         homeSp.setOtherHomePartners(new String[]{TEST_FQDN3});
1556         config.setHomeSp(homeSp);
1557         mProvider = createProvider(config);
1558 
1559         // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3
1560         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1561         anqpElementMap.put(ANQPElementType.ANQPDomName,
1562                 createDomainNameElement(new String[]{TEST_FQDN2, TEST_FQDN3}));
1563 
1564         assertEquals(PasspointMatch.HomeProvider,
1565                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1566     }
1567 
1568     /**
1569      * Verify that matching Any HomeOI results in a Home Provider match
1570      *
1571      * @throws Exception
1572      */
1573     @Test
matchAnyHomeOi()1574     public void matchAnyHomeOi() throws Exception {
1575         // Setup test provider.
1576         PasspointConfiguration config = generateTestPasspointConfiguration(
1577                 CredentialType.USER, false);
1578         Long[] anqpOis = new Long[]{0x1234L, 0xdeadL, 0xf0cdL};
1579 
1580         // Configuration was created with TEST_FQDN as the FQDN
1581         HomeSp homeSp = config.getHomeSp();
1582         homeSp.setMatchAnyOis(TEST_RC_OIS);
1583         homeSp.setRoamingConsortiumOis(null);
1584         config.setHomeSp(homeSp);
1585         mProvider = createProvider(config);
1586 
1587         // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3
1588         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1589         anqpElementMap.put(ANQPElementType.ANQPDomName,
1590                 createDomainNameElement(new String[]{TEST_FQDN2, TEST_FQDN3}));
1591         // Setup RCOIs advertised by the AP
1592         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
1593                 createRoamingConsortiumElement(anqpOis));
1594 
1595         assertEquals(PasspointMatch.HomeProvider,
1596                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1597     }
1598 
1599     /**
1600      * Verify that non-matching Any HomeOI results in a None Provider match
1601      *
1602      * @throws Exception
1603      */
1604     @Test
matchAnyHomeOiNegative()1605     public void matchAnyHomeOiNegative() throws Exception {
1606         // Setup test provider.
1607         PasspointConfiguration config = generateTestPasspointConfiguration(
1608                 CredentialType.USER, false);
1609         Long[] anqpOis = new Long[]{0x12a4L, 0xceadL, 0xf0cdL};
1610 
1611         // Configuration was created with TEST_FQDN as the FQDN
1612         HomeSp homeSp = config.getHomeSp();
1613         homeSp.setMatchAnyOis(TEST_RC_OIS);
1614         homeSp.setRoamingConsortiumOis(null);
1615         config.setHomeSp(homeSp);
1616         mProvider = createProvider(config);
1617 
1618         // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3
1619         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1620         anqpElementMap.put(ANQPElementType.ANQPDomName,
1621                 createDomainNameElement(new String[]{TEST_FQDN2, TEST_FQDN3}));
1622         // Setup RCOIs advertised by the AP
1623         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
1624                 createRoamingConsortiumElement(anqpOis));
1625 
1626         assertEquals(PasspointMatch.None,
1627                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1628     }
1629 
1630     /**
1631      * Verify that matching All HomeOI results in a Home Provider match
1632      *
1633      * @throws Exception
1634      */
1635     @Test
matchAllHomeOi()1636     public void matchAllHomeOi() throws Exception {
1637         // Setup test provider.
1638         PasspointConfiguration config = generateTestPasspointConfiguration(
1639                 CredentialType.USER, false);
1640         Long[] anqpOis = new Long[]{0x1234L, 0x2345L, 0xabcdL, 0xdeadL, 0xf0cdL};
1641 
1642         // Configuration was created with TEST_FQDN as the FQDN
1643         HomeSp homeSp = config.getHomeSp();
1644         homeSp.setMatchAllOis(TEST_RC_OIS);
1645         homeSp.setRoamingConsortiumOis(null);
1646         config.setHomeSp(homeSp);
1647         mProvider = createProvider(config);
1648 
1649         // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3
1650         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1651         anqpElementMap.put(ANQPElementType.ANQPDomName,
1652                 createDomainNameElement(new String[]{TEST_FQDN2, TEST_FQDN3}));
1653         // Setup RCOIs advertised by the AP
1654         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
1655                 createRoamingConsortiumElement(anqpOis));
1656 
1657         assertEquals(PasspointMatch.HomeProvider,
1658                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1659     }
1660 
1661     /**
1662      * Verify that non-matching All HomeOI results in a None Provider match
1663      *
1664      * @throws Exception
1665      */
1666     @Test
matchAllHomeOiNegative()1667     public void matchAllHomeOiNegative() throws Exception {
1668         // Setup test provider.
1669         PasspointConfiguration config = generateTestPasspointConfiguration(
1670                 CredentialType.USER, false);
1671         // 0x1234 matches, but 0x2345 does not
1672         Long[] anqpOis = new Long[]{0x1234L, 0x5678L, 0xdeadL, 0xf0cdL};
1673 
1674         // Configuration was created with TEST_FQDN as the FQDN
1675         HomeSp homeSp = config.getHomeSp();
1676         homeSp.setMatchAllOis(TEST_RC_OIS);
1677         homeSp.setRoamingConsortiumOis(null);
1678         config.setHomeSp(homeSp);
1679         mProvider = createProvider(config);
1680 
1681         // Setup Domain Name ANQP element to TEST_FQDN2 and TEST_FQDN3
1682         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1683         anqpElementMap.put(ANQPElementType.ANQPDomName,
1684                 createDomainNameElement(new String[]{TEST_FQDN2, TEST_FQDN3}));
1685         // Setup RCOIs advertised by the AP
1686         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
1687                 createRoamingConsortiumElement(anqpOis));
1688 
1689         assertEquals(PasspointMatch.None,
1690                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
1691         assertEquals(0, mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
1692     }
1693 
1694     /**
1695      * Helper function for creating a ScanResult for testing.
1696      *
1697      * @return {@link ScanResult}
1698      */
createTestScanResult()1699     private ScanResult createTestScanResult() {
1700         ScanResult scanResult = new ScanResult();
1701         scanResult.SSID = TEST_SSID;
1702         scanResult.BSSID = TEST_BSSID_STRING;
1703         scanResult.hessid = TEST_HESSID;
1704         scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID;
1705         scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
1706         scanResult.setWifiSsid(WifiSsid.fromString(TEST_SSID_QUOTED));
1707         return scanResult;
1708     }
1709 
1710     /**
1711      * Helper function for creating another ScanResult for testing.
1712      *
1713      * @return {@link ScanResult}
1714      */
createSecondaryTestScanResult()1715     private ScanResult createSecondaryTestScanResult() {
1716         ScanResult scanResult = new ScanResult();
1717         scanResult.SSID = TEST_SSID_2;
1718         scanResult.BSSID = TEST_BSSID_STRING_2;
1719         scanResult.hessid = TEST_HESSID_2;
1720         scanResult.anqpDomainId = TEST_ANQP_DOMAIN_ID_2;
1721         scanResult.flags = ScanResult.FLAG_PASSPOINT_NETWORK;
1722         scanResult.setWifiSsid(WifiSsid.fromString(TEST_SSID_2_QUOTED));
1723         return scanResult;
1724     }
1725     /**
1726      * Verify that a home provider is not matched followed by a Deauthentication-imminent WNM
1727      * notification from the AP that covers a specific BSS.
1728      *
1729      * @throws Exception
1730      */
1731     @Test
noMatchWithBlockedBss()1732     public void noMatchWithBlockedBss() throws Exception {
1733         // Setup test provider.
1734         PasspointConfiguration config = generateTestPasspointConfiguration(
1735                 CredentialType.USER, false);
1736         mProvider = createProvider(config);
1737 
1738         // Setup Domain Name ANQP element.
1739         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1740         anqpElementMap.put(ANQPElementType.ANQPDomName,
1741                 createDomainNameElement(new String[]{TEST_FQDN}));
1742         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1743                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1744                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1745 
1746         ScanResult scanResult = createTestScanResult();
1747         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
1748 
1749         // Confirm this is a match under normal circumstances
1750         assertEquals(PasspointMatch.HomeProvider,
1751                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1752 
1753         // Now block the BSS (simulate Deauth-imminent notification)
1754         mProvider.blockBssOrEss(Utils.parseMac(scanResult.BSSID), false, 300 /* Seconds */);
1755 
1756         // Confirm there is no match
1757         assertEquals(PasspointMatch.None,
1758                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1759 
1760         // Now modify the BSSID
1761         scanResult.BSSID = TEST_BSSID_STRING_2;
1762 
1763         // Confirm there is a match
1764         assertEquals(PasspointMatch.HomeProvider,
1765                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1766 
1767         // Now clear the block
1768         mProvider.clearProviderBlock();
1769         scanResult.BSSID = TEST_BSSID_STRING;
1770 
1771         // Confirm this is a match under normal circumstances
1772         assertEquals(PasspointMatch.HomeProvider,
1773                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1774     }
1775 
1776     /**
1777      * Verify that a home provider is not matched followed by a Deauthentication-imminent WNM
1778      * notification from the AP that covers the entire ESS.
1779      *
1780      * @throws Exception
1781      */
1782     @Test
noMatchWithBlockedEss()1783     public void noMatchWithBlockedEss() throws Exception {
1784         // Setup test provider.
1785         PasspointConfiguration config = generateTestPasspointConfiguration(
1786                 CredentialType.USER, false);
1787         mProvider = createProvider(config);
1788 
1789         // Setup Domain Name ANQP element.
1790         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1791         anqpElementMap.put(ANQPElementType.ANQPDomName,
1792                 createDomainNameElement(new String[]{TEST_FQDN}));
1793         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1794                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1795                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1796 
1797         ScanResult scanResult = createTestScanResult();
1798         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
1799 
1800         // Confirm this is a match under normal circumstances
1801         assertEquals(PasspointMatch.HomeProvider,
1802                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1803 
1804         // Now block the BSS (simulate Deauth-imminent notification)
1805         mProvider.blockBssOrEss(Utils.parseMac(scanResult.BSSID), true, 300 /* Seconds */);
1806 
1807         // Confirm there is no match
1808         assertEquals(PasspointMatch.None,
1809                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1810 
1811         // Now modify the BSSID
1812         scanResult.BSSID = TEST_BSSID_STRING_2;
1813 
1814         // Confirm there is no match
1815         assertEquals(PasspointMatch.None,
1816                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1817     }
1818 
1819     /**
1820      * Verify that a home provider that was not matched followed by a Deauthentication-imminent WNM
1821      * notification from the AP is matched again after the reathentication delay expires.
1822      *
1823      * @throws Exception
1824      */
1825     @Test
blockedBssMatchRestoredAfterDelayExpires()1826     public void blockedBssMatchRestoredAfterDelayExpires() throws Exception {
1827         // Setup test provider.
1828         PasspointConfiguration config = generateTestPasspointConfiguration(
1829                 CredentialType.USER, false);
1830         mProvider = createProvider(config);
1831 
1832         // Setup Domain Name ANQP element.
1833         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1834         anqpElementMap.put(ANQPElementType.ANQPDomName,
1835                 createDomainNameElement(new String[]{TEST_FQDN}));
1836         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1837                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1838                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1839 
1840         ScanResult scanResult = createTestScanResult();
1841         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
1842 
1843         // Confirm this is a match under normal circumstances
1844         assertEquals(PasspointMatch.HomeProvider,
1845                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1846 
1847         // Now block the BSS (simulate Deauth-imminent notification)
1848         mProvider.blockBssOrEss(Utils.parseMac(scanResult.BSSID), false, 300 /* Seconds */);
1849 
1850         // Confirm there is no match
1851         assertEquals(PasspointMatch.None,
1852                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1853 
1854         // Now advance the time to some time in the future, after the delay expires
1855         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT
1856                 + (300 * 1000) + 5000);
1857 
1858         // Confirm there is a match now
1859         assertEquals(PasspointMatch.HomeProvider,
1860                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1861     }
1862 
1863 
1864     /**
1865      * Verify that a home provider that was not matched followed by a Deauthentication-imminent WNM
1866      * notification from the AP is matched again after the reathentication delay expires for WNM
1867      * notifications that do not specify an explicit delay (default is 5 minutes in AOSP).
1868      *
1869      * @throws Exception
1870      */
1871     @Test
blockedBssMatchRestoredAfterDelayExpiresNoDelaySpecified()1872     public void blockedBssMatchRestoredAfterDelayExpiresNoDelaySpecified() throws Exception {
1873         // Setup test provider.
1874         PasspointConfiguration config = generateTestPasspointConfiguration(
1875                 CredentialType.USER, false);
1876         mProvider = createProvider(config);
1877 
1878         // Setup Domain Name ANQP element.
1879         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1880         anqpElementMap.put(ANQPElementType.ANQPDomName,
1881                 createDomainNameElement(new String[]{TEST_FQDN}));
1882         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1883                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1884                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1885 
1886         ScanResult scanResult = createTestScanResult();
1887         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
1888 
1889         // Confirm this is a match under normal circumstances
1890         assertEquals(PasspointMatch.HomeProvider,
1891                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1892 
1893         // Now block the BSS (simulate Deauth-imminent notification)
1894         mProvider.blockBssOrEss(Utils.parseMac(scanResult.BSSID), false, 0 /* Seconds */);
1895 
1896         // Confirm there is no match
1897         assertEquals(PasspointMatch.None,
1898                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1899 
1900         // Now advance the time to some time in the future, after the delay expires
1901         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT
1902                 + (MboOceConstants.DEFAULT_BLOCKLIST_DURATION_MS));
1903 
1904         // Confirm there is a match now
1905         assertEquals(PasspointMatch.HomeProvider,
1906                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1907     }
1908 
1909     /**
1910      * Verify that a WNM-Notification with some invalid values is ignored and doesn't affect
1911      * the provider
1912      *
1913      * @throws Exception
1914      */
1915     @Test
testNoBlockingWithInvalidWnmData()1916     public void testNoBlockingWithInvalidWnmData() throws Exception {
1917         // Setup test provider.
1918         PasspointConfiguration config = generateTestPasspointConfiguration(
1919                 CredentialType.USER, false);
1920         mProvider = createProvider(config);
1921 
1922         // Setup Domain Name ANQP element.
1923         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
1924         anqpElementMap.put(ANQPElementType.ANQPDomName,
1925                 createDomainNameElement(new String[]{TEST_FQDN}));
1926         anqpElementMap.put(ANQPElementType.ANQPNAIRealm,
1927                 createNAIRealmElement(TEST_REALM, EAPConstants.EAP_TTLS,
1928                         new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2)));
1929 
1930         ScanResult scanResult = createTestScanResult();
1931         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
1932 
1933         // Confirm this is a match under normal circumstances
1934         assertEquals(PasspointMatch.HomeProvider,
1935                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1936 
1937         // Test some invalid values
1938         mProvider.blockBssOrEss(Utils.parseMac(scanResult.BSSID), false, -40 /* Seconds */);
1939         assertEquals(PasspointMatch.HomeProvider,
1940                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1941 
1942         mProvider.blockBssOrEss(0, false, 300 /* Seconds */);
1943         assertEquals(PasspointMatch.HomeProvider,
1944                 mProvider.match(anqpElementMap, mRoamingConsortium, scanResult));
1945     }
1946 
1947     /**
1948      * Verify set and get Anonymous Identity on passpoint provider.
1949      */
1950     @Test
testSetAnonymousIdentity()1951     public void testSetAnonymousIdentity() throws Exception {
1952         PasspointConfiguration config = generateTestPasspointConfiguration(
1953                 CredentialType.SIM, false);
1954         mProvider = createProvider(config);
1955         mProvider.setAnonymousIdentity(TEST_ANONYMOUS_IDENTITY);
1956         assertEquals(TEST_ANONYMOUS_IDENTITY, mProvider.getAnonymousIdentity());
1957     }
1958 
1959     /**
1960      * Verify set and get connect choice on passpoint provider.
1961      */
1962     @Test
testSetUserConnectChoice()1963     public void testSetUserConnectChoice() throws Exception {
1964         PasspointConfiguration config = generateTestPasspointConfiguration(
1965                 CredentialType.SIM, false);
1966         mProvider = createProvider(config);
1967         mProvider.setUserConnectChoice(USER_CONNECT_CHOICE, TEST_RSSI);
1968         assertEquals(USER_CONNECT_CHOICE, mProvider.getConnectChoice());
1969         assertEquals(TEST_RSSI, mProvider.getConnectChoiceRssi());
1970         WifiConfiguration configuration = mProvider.getWifiConfig();
1971         assertEquals(USER_CONNECT_CHOICE,
1972                 configuration.getNetworkSelectionStatus().getConnectChoice());
1973         assertEquals(TEST_RSSI, configuration.getNetworkSelectionStatus().getConnectChoiceRssi());
1974     }
1975 
1976 
1977     /**
1978      * Verify that an expected decorated identity prefix is received from getWifiConfig()
1979      *
1980      * @throws Exception
1981      */
1982     @Test
testSetDecoratedIdentityPrefix()1983     public void testSetDecoratedIdentityPrefix() throws Exception {
1984         assumeTrue(SdkLevel.isAtLeastS());
1985         // Create provider for R2.
1986         PasspointConfiguration config = generateTestPasspointConfiguration(
1987                 CredentialType.USER, false);
1988         config.getCredential().setCaCertificates(null);
1989         config.setDecoratedIdentityPrefix(TEST_DECORATED_IDENTITY_PREFIX);
1990         mProvider = createProvider(config);
1991 
1992         assertEquals(TEST_DECORATED_IDENTITY_PREFIX,
1993                 mProvider.getWifiConfig().enterpriseConfig.getDecoratedIdentityPrefix());
1994     }
1995 
1996     @Test
testRcoiMatchMapAgeOut()1997     public void testRcoiMatchMapAgeOut() throws Exception {
1998         // Setup test provider.
1999         PasspointConfiguration config = generateTestPasspointConfiguration(
2000                 CredentialType.SIM, false);
2001         mProvider = createProvider(config);
2002         when(mWifiCarrierInfoManager.getMatchingImsiCarrierId(
2003                 eq(config.getCredential().getSimCredential().getImsi())))
2004                 .thenReturn(new Pair<>(TEST_IMSI, VALID_CARRIER_ID));
2005 
2006         // Setup Roaming Consortium ANQP element.
2007         Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>();
2008         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
2009                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS));
2010 
2011         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT);
2012 
2013         // Roaming provider with RCOI match adds a selected RCOI to the match map
2014         assertEquals(PasspointMatch.RoamingProvider,
2015                 mProvider.match(anqpElementMap, mRoamingConsortium, createTestScanResult()));
2016 
2017         when(mClock.getElapsedSinceBootMillis()).thenReturn(TEST_ELAPSED_TIME_SINCE_BOOT
2018                 + 700_000L);
2019 
2020         anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium,
2021                 createRoamingConsortiumElement(TEST_ANQP_RC_OIS_2));
2022 
2023         // Now a new scan with another SSID and no match after a while
2024         assertEquals(PasspointMatch.None, mProvider.match(anqpElementMap, mRoamingConsortium,
2025                 createSecondaryTestScanResult()));
2026 
2027         // Confirm the selected roaming match map entry for the first SSID is cleared after it was
2028         // aged out
2029         assertEquals(0, mProvider.getAndRemoveMatchedRcoi(TEST_SSID_QUOTED));
2030     }
2031 }
2032