PasspointProviderTest.java revision 4f4d745ca28b915ea4a7c91ec5df3ea8a2db64ad
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 17package com.android.server.wifi.hotspot2; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertFalse; 21import static org.junit.Assert.assertTrue; 22import static org.mockito.Mockito.verify; 23import static org.mockito.Mockito.when; 24import static org.mockito.MockitoAnnotations.initMocks; 25 26import android.net.wifi.EAPConstants; 27import android.net.wifi.WifiConfiguration; 28import android.net.wifi.WifiEnterpriseConfig; 29import android.net.wifi.hotspot2.PasspointConfiguration; 30import android.net.wifi.hotspot2.pps.Credential; 31import android.net.wifi.hotspot2.pps.HomeSP; 32import android.test.suitebuilder.annotation.SmallTest; 33import android.util.Base64; 34 35import com.android.server.wifi.FakeKeys; 36import com.android.server.wifi.IMSIParameter; 37import com.android.server.wifi.SIMAccessor; 38import com.android.server.wifi.WifiKeyStore; 39import com.android.server.wifi.hotspot2.anqp.ANQPElement; 40import com.android.server.wifi.hotspot2.anqp.CellularNetwork; 41import com.android.server.wifi.hotspot2.anqp.Constants.ANQPElementType; 42import com.android.server.wifi.hotspot2.anqp.DomainNameElement; 43import com.android.server.wifi.hotspot2.anqp.NAIRealmData; 44import com.android.server.wifi.hotspot2.anqp.NAIRealmElement; 45import com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement; 46import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement; 47import com.android.server.wifi.hotspot2.anqp.eap.AuthParam; 48import com.android.server.wifi.hotspot2.anqp.eap.EAPMethod; 49import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth; 50 51import org.junit.Before; 52import org.junit.Test; 53import org.mockito.Mock; 54 55import java.nio.charset.StandardCharsets; 56import java.security.MessageDigest; 57import java.security.cert.X509Certificate; 58import java.util.Arrays; 59import java.util.HashMap; 60import java.util.HashSet; 61import java.util.Map; 62import java.util.Set; 63 64/** 65 * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointProvider}. 66 */ 67@SmallTest 68public class PasspointProviderTest { 69 private static final long PROVIDER_ID = 12L; 70 private static final String CA_CERTIFICATE_ALIAS = "CACERT_HS2_12"; 71 private static final String CLIENT_CERTIFICATE_ALIAS = "USRCERT_HS2_12"; 72 private static final String CLIENT_PRIVATE_KEY_ALIAS = "USRPKEY_HS2_12"; 73 private static final String ALIAS_SUFFIX = "HS2_12"; 74 75 @Mock WifiKeyStore mKeyStore; 76 @Mock SIMAccessor mSimAccessor; 77 PasspointProvider mProvider; 78 79 /** Sets up test. */ 80 @Before 81 public void setUp() throws Exception { 82 initMocks(this); 83 } 84 85 /** 86 * Helper function for creating a provider instance for testing. 87 * 88 * @param config The configuration associated with the provider 89 * @return {@link com.android.server.wifi.hotspot2.PasspointProvider} 90 */ 91 private PasspointProvider createProvider(PasspointConfiguration config) { 92 return new PasspointProvider(config, mKeyStore, mSimAccessor, PROVIDER_ID); 93 } 94 95 /** 96 * Verify that the configuration associated with the provider is the same or not the same 97 * as the expected configuration. 98 * 99 * @param expectedConfig The expected configuration 100 * @param equals Flag indicating equality or inequality check 101 */ 102 private void verifyInstalledConfig(PasspointConfiguration expectedConfig, boolean equals) { 103 PasspointConfiguration actualConfig = mProvider.getConfig(); 104 if (equals) { 105 assertTrue(actualConfig.equals(expectedConfig)); 106 } else { 107 assertFalse(actualConfig.equals(expectedConfig)); 108 } 109 } 110 111 /** 112 * Helper function for creating a Domain Name ANQP element. 113 * 114 * @param domains List of domain names 115 * @return {@link DomainNameElement} 116 */ 117 private DomainNameElement createDomainNameElement(String[] domains) { 118 return new DomainNameElement(Arrays.asList(domains)); 119 } 120 121 /** 122 * Helper function for creating a NAI Realm ANQP element. 123 * 124 * @param realm The realm of the network 125 * @param eapMethodID EAP Method ID 126 * @param authParam Authentication parameter 127 * @return {@link NAIRealmElement} 128 */ 129 private NAIRealmElement createNAIRealmElement(String realm, int eapMethodID, 130 AuthParam authParam) { 131 Map<Integer, Set<AuthParam>> authParamMap = new HashMap<>(); 132 if (authParam != null) { 133 Set<AuthParam> authSet = new HashSet<>(); 134 authSet.add(authParam); 135 authParamMap.put(authParam.getAuthTypeID(), authSet); 136 } 137 EAPMethod eapMethod = new EAPMethod(eapMethodID, authParamMap); 138 NAIRealmData realmData = new NAIRealmData(Arrays.asList(new String[] {realm}), 139 Arrays.asList(new EAPMethod[] {eapMethod})); 140 return new NAIRealmElement(Arrays.asList(new NAIRealmData[] {realmData})); 141 } 142 143 /** 144 * Helper function for creating a Roaming Consortium ANQP element. 145 * 146 * @param rcOIs Roaming consortium OIs 147 * @return {@link RoamingConsortiumElement} 148 */ 149 private RoamingConsortiumElement createRoamingConsortiumElement(Long[] rcOIs) { 150 return new RoamingConsortiumElement(Arrays.asList(rcOIs)); 151 } 152 153 /** 154 * Helper function for creating a 3GPP Network ANQP element. 155 * 156 * @param imsiList List of IMSI to be included in a 3GPP Network 157 * @return {@link ThreeGPPNetworkElement} 158 */ 159 private ThreeGPPNetworkElement createThreeGPPNetworkElement(String[] imsiList) { 160 CellularNetwork network = new CellularNetwork(Arrays.asList(imsiList)); 161 return new ThreeGPPNetworkElement(Arrays.asList(new CellularNetwork[] {network})); 162 } 163 164 /** 165 * Verify that modification to the configuration used for creating PasspointProvider 166 * will not change the configuration stored inside the PasspointProvider. 167 * 168 * @throws Exception 169 */ 170 @Test 171 public void verifyModifyOriginalConfig() throws Exception { 172 // Create a dummy PasspointConfiguration. 173 PasspointConfiguration config = new PasspointConfiguration(); 174 HomeSP homeSp = new HomeSP(); 175 homeSp.setFqdn("test1"); 176 config.setHomeSp(homeSp); 177 Credential credential = new Credential(); 178 credential.setUserCredential(new Credential.UserCredential()); 179 config.setCredential(credential); 180 mProvider = createProvider(config); 181 verifyInstalledConfig(config, true); 182 183 // Modify the original configuration, the configuration maintained by the provider 184 // should be unchanged. 185 config.getHomeSp().setFqdn("test2"); 186 verifyInstalledConfig(config, false); 187 } 188 189 /** 190 * Verify that modification to the configuration retrieved from the PasspointProvider 191 * will not change the configuration stored inside the PasspointProvider. 192 * 193 * @throws Exception 194 */ 195 @Test 196 public void verifyModifyRetrievedConfig() throws Exception { 197 // Create a dummy PasspointConfiguration. 198 PasspointConfiguration config = new PasspointConfiguration(); 199 HomeSP homeSp = new HomeSP(); 200 homeSp.setFqdn("test1"); 201 config.setHomeSp(homeSp); 202 Credential credential = new Credential(); 203 credential.setUserCredential(new Credential.UserCredential()); 204 config.setCredential(credential); 205 mProvider = createProvider(config); 206 verifyInstalledConfig(config, true); 207 208 // Modify the retrieved configuration, verify the configuration maintained by the 209 // provider should be unchanged. 210 PasspointConfiguration retrievedConfig = mProvider.getConfig(); 211 retrievedConfig.getHomeSp().setFqdn("test2"); 212 verifyInstalledConfig(retrievedConfig, false); 213 } 214 215 /** 216 * Verify a successful installation of certificates and key. 217 * 218 * @throws Exception 219 */ 220 @Test 221 public void installCertsAndKeysSuccess() throws Exception { 222 // Create a dummy configuration with certificate credential. 223 PasspointConfiguration config = new PasspointConfiguration(); 224 Credential credential = new Credential(); 225 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 226 certCredential.setCertSha256Fingerprint( 227 MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); 228 credential.setCertCredential(certCredential); 229 credential.setCaCertificate(FakeKeys.CA_CERT0); 230 credential.setClientPrivateKey(FakeKeys.RSA_KEY1); 231 credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); 232 config.setCredential(credential); 233 mProvider = createProvider(config); 234 235 // Install client certificate and key to the keystore successfully. 236 when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0)) 237 .thenReturn(true); 238 when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_ALIAS, FakeKeys.RSA_KEY1)) 239 .thenReturn(true); 240 when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_ALIAS, FakeKeys.CLIENT_CERT)) 241 .thenReturn(true); 242 assertTrue(mProvider.installCertsAndKeys()); 243 244 // Verify client certificate and key in the configuration gets cleared and aliases 245 // are set correctly. 246 PasspointConfiguration curConfig = mProvider.getConfig(); 247 assertTrue(curConfig.getCredential().getCaCertificate() == null); 248 assertTrue(curConfig.getCredential().getClientPrivateKey() == null); 249 assertTrue(curConfig.getCredential().getClientCertificateChain() == null); 250 assertTrue(mProvider.getCaCertificateAlias().equals(CA_CERTIFICATE_ALIAS)); 251 assertTrue(mProvider.getClientPrivateKeyAlias().equals(CLIENT_PRIVATE_KEY_ALIAS)); 252 assertTrue(mProvider.getClientCertificateAlias().equals(CLIENT_CERTIFICATE_ALIAS)); 253 } 254 255 /** 256 * Verify a failure installation of certificates and key. 257 * 258 * @throws Exception 259 */ 260 @Test 261 public void installCertsAndKeysFailure() throws Exception { 262 // Create a dummy configuration with certificate credential. 263 PasspointConfiguration config = new PasspointConfiguration(); 264 Credential credential = new Credential(); 265 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 266 certCredential.setCertSha256Fingerprint( 267 MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); 268 credential.setCertCredential(certCredential); 269 credential.setCaCertificate(FakeKeys.CA_CERT0); 270 credential.setClientPrivateKey(FakeKeys.RSA_KEY1); 271 credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); 272 config.setCredential(credential); 273 mProvider = createProvider(config); 274 275 // Failed to install client certificate to the keystore. 276 when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0)) 277 .thenReturn(true); 278 when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_ALIAS, FakeKeys.RSA_KEY1)) 279 .thenReturn(true); 280 when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_ALIAS, FakeKeys.CLIENT_CERT)) 281 .thenReturn(false); 282 assertFalse(mProvider.installCertsAndKeys()); 283 284 // Verify certificates and key in the configuration are not cleared and aliases 285 // are not set. 286 PasspointConfiguration curConfig = mProvider.getConfig(); 287 assertTrue(curConfig.getCredential().getCaCertificate() != null); 288 assertTrue(curConfig.getCredential().getClientCertificateChain() != null); 289 assertTrue(curConfig.getCredential().getClientPrivateKey() != null); 290 assertTrue(mProvider.getCaCertificateAlias() == null); 291 assertTrue(mProvider.getClientPrivateKeyAlias() == null); 292 assertTrue(mProvider.getClientCertificateAlias() == null); 293 } 294 295 /** 296 * Verify a successful uninstallation of certificates and key. 297 */ 298 @Test 299 public void uninstallCertsAndKeys() throws Exception { 300 // Create a dummy configuration with certificate credential. 301 PasspointConfiguration config = new PasspointConfiguration(); 302 Credential credential = new Credential(); 303 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 304 certCredential.setCertSha256Fingerprint( 305 MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); 306 credential.setCertCredential(certCredential); 307 credential.setCaCertificate(FakeKeys.CA_CERT0); 308 credential.setClientPrivateKey(FakeKeys.RSA_KEY1); 309 credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); 310 config.setCredential(credential); 311 mProvider = createProvider(config); 312 313 // Install client certificate and key to the keystore successfully. 314 when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0)) 315 .thenReturn(true); 316 when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_ALIAS, FakeKeys.RSA_KEY1)) 317 .thenReturn(true); 318 when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_ALIAS, FakeKeys.CLIENT_CERT)) 319 .thenReturn(true); 320 assertTrue(mProvider.installCertsAndKeys()); 321 assertTrue(mProvider.getCaCertificateAlias().equals(CA_CERTIFICATE_ALIAS)); 322 assertTrue(mProvider.getClientPrivateKeyAlias().equals(CLIENT_PRIVATE_KEY_ALIAS)); 323 assertTrue(mProvider.getClientCertificateAlias().equals(CLIENT_CERTIFICATE_ALIAS)); 324 325 // Uninstall certificates and key from the keystore. 326 mProvider.uninstallCertsAndKeys(); 327 verify(mKeyStore).removeEntryFromKeyStore(CA_CERTIFICATE_ALIAS); 328 verify(mKeyStore).removeEntryFromKeyStore(CLIENT_CERTIFICATE_ALIAS); 329 verify(mKeyStore).removeEntryFromKeyStore(CLIENT_PRIVATE_KEY_ALIAS); 330 assertTrue(mProvider.getCaCertificateAlias() == null); 331 assertTrue(mProvider.getClientPrivateKeyAlias() == null); 332 assertTrue(mProvider.getClientCertificateAlias() == null); 333 } 334 335 /** 336 * Verify that a provider is a home provider when its FQDN matches a domain name in the 337 * Domain Name ANQP element and no NAI realm is provided. 338 * 339 * @throws Exception 340 */ 341 @Test 342 public void matchFQDNWithoutNAIRealm() throws Exception { 343 String testDomain = "test.com"; 344 345 // Setup test provider. 346 PasspointConfiguration config = new PasspointConfiguration(); 347 HomeSP homeSp = new HomeSP(); 348 homeSp.setFqdn(testDomain); 349 config.setHomeSp(homeSp); 350 Credential credential = new Credential(); 351 Credential.UserCredential userCredential = new Credential.UserCredential(); 352 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 353 credential.setUserCredential(userCredential); 354 config.setCredential(credential); 355 mProvider = createProvider(config); 356 357 // Setup ANQP elements. 358 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 359 anqpElementMap.put(ANQPElementType.ANQPDomName, 360 createDomainNameElement(new String[] {testDomain})); 361 362 assertEquals(PasspointMatch.HomeProvider, mProvider.match(anqpElementMap)); 363 } 364 365 /** 366 * Verify that a provider is a home provider when its FQDN matches a domain name in the 367 * Domain Name ANQP element and the provider's credential matches the NAI realm provided. 368 * 369 * @throws Exception 370 */ 371 @Test 372 public void matchFQDNWithNAIRealmMatch() throws Exception { 373 String testDomain = "test.com"; 374 String testRealm = "realm.com"; 375 376 // Setup test provider. 377 PasspointConfiguration config = new PasspointConfiguration(); 378 HomeSP homeSp = new HomeSP(); 379 homeSp.setFqdn(testDomain); 380 config.setHomeSp(homeSp); 381 Credential credential = new Credential(); 382 credential.setRealm(testRealm); 383 Credential.UserCredential userCredential = new Credential.UserCredential(); 384 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 385 credential.setUserCredential(userCredential); 386 config.setCredential(credential); 387 mProvider = createProvider(config); 388 389 // Setup Domain Name ANQP element. 390 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 391 anqpElementMap.put(ANQPElementType.ANQPDomName, 392 createDomainNameElement(new String[] {testDomain})); 393 anqpElementMap.put(ANQPElementType.ANQPNAIRealm, 394 createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, 395 new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); 396 397 assertEquals(PasspointMatch.HomeProvider, mProvider.match(anqpElementMap)); 398 } 399 400 /** 401 * Verify that there is no match when the provider's FQDN matches a domain name in the 402 * Domain Name ANQP element but the provider's credential doesn't match the authentication 403 * method provided in the NAI realm. 404 * 405 * @throws Exception 406 */ 407 @Test 408 public void matchFQDNWithNAIRealmMismatch() throws Exception { 409 String testDomain = "test.com"; 410 String testRealm = "realm.com"; 411 412 // Setup test provider. 413 PasspointConfiguration config = new PasspointConfiguration(); 414 HomeSP homeSp = new HomeSP(); 415 homeSp.setFqdn(testDomain); 416 config.setHomeSp(homeSp); 417 Credential credential = new Credential(); 418 credential.setRealm(testRealm); 419 Credential.UserCredential userCredential = new Credential.UserCredential(); 420 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 421 credential.setUserCredential(userCredential); 422 config.setCredential(credential); 423 mProvider = createProvider(config); 424 425 // Setup Domain Name ANQP element. 426 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 427 anqpElementMap.put(ANQPElementType.ANQPDomName, 428 createDomainNameElement(new String[] {testDomain})); 429 anqpElementMap.put(ANQPElementType.ANQPNAIRealm, 430 createNAIRealmElement(testRealm, EAPConstants.EAP_TLS, null)); 431 432 assertEquals(PasspointMatch.None, mProvider.match(anqpElementMap)); 433 } 434 435 /** 436 * Verify that a provider is a home provider when its SIM credential matches an 3GPP network 437 * domain name in the Domain Name ANQP element. 438 * 439 * @throws Exception 440 */ 441 @Test 442 public void match3GPPNetworkDomainName() throws Exception { 443 String testImsi = "1234567890"; 444 445 // Setup test provider. 446 PasspointConfiguration config = new PasspointConfiguration(); 447 config.setHomeSp(new HomeSP()); 448 Credential credential = new Credential(); 449 Credential.SimCredential simCredential = new Credential.SimCredential(); 450 simCredential.setImsi(testImsi); 451 credential.setSimCredential(simCredential); 452 config.setCredential(credential); 453 when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) 454 .thenReturn(Arrays.asList(new String[] {testImsi})); 455 mProvider = createProvider(config); 456 457 // Setup Domain Name ANQP element. 458 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 459 anqpElementMap.put(ANQPElementType.ANQPDomName, 460 createDomainNameElement(new String[] {"wlan.mnc456.mcc123.3gppnetwork.org"})); 461 462 assertEquals(PasspointMatch.HomeProvider, mProvider.match(anqpElementMap)); 463 } 464 465 /** 466 * Verify that a provider is a roaming provider when a roaming consortium OI matches an OI 467 * in the roaming consortium ANQP element. 468 * 469 * @throws Exception 470 */ 471 @Test 472 public void matchRoamingConsortium() throws Exception { 473 long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; 474 Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; 475 476 // Setup test provider. 477 PasspointConfiguration config = new PasspointConfiguration(); 478 HomeSP homeSp = new HomeSP(); 479 homeSp.setRoamingConsortiumOIs(providerRCOIs); 480 config.setHomeSp(homeSp); 481 Credential credential = new Credential(); 482 Credential.UserCredential userCredential = new Credential.UserCredential(); 483 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 484 credential.setUserCredential(userCredential); 485 config.setCredential(credential); 486 mProvider = createProvider(config); 487 488 // Setup Roaming Consortium ANQP element. 489 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 490 anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, 491 createRoamingConsortiumElement(anqpRCOIs)); 492 493 assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap)); 494 } 495 496 /** 497 * Verify that a provider is a roaming provider when the provider's IMSI parameter and an 498 * IMSI from the SIM card matches a MCC-MNC in the 3GPP Network ANQP element. 499 * 500 * @throws Exception 501 */ 502 @Test 503 public void matchThreeGPPNetwork() throws Exception { 504 String testImsi = "1234567890"; 505 506 // Setup test provider. 507 PasspointConfiguration config = new PasspointConfiguration(); 508 config.setHomeSp(new HomeSP()); 509 Credential credential = new Credential(); 510 Credential.SimCredential simCredential = new Credential.SimCredential(); 511 simCredential.setImsi(testImsi); 512 credential.setSimCredential(simCredential); 513 config.setCredential(credential); 514 when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) 515 .thenReturn(Arrays.asList(new String[] {testImsi})); 516 mProvider = createProvider(config); 517 518 // Setup 3GPP Network ANQP element. 519 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 520 anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, 521 createThreeGPPNetworkElement(new String[] {"123456"})); 522 523 assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap)); 524 } 525 526 /** 527 * Verify that a provider is a roaming provider when its credential matches a NAI realm in 528 * the NAI Realm ANQP element. 529 * 530 * @throws Exception 531 */ 532 @Test 533 public void matchNAIRealm() throws Exception { 534 String testRealm = "realm.com"; 535 536 // Setup test provider. 537 PasspointConfiguration config = new PasspointConfiguration(); 538 config.setHomeSp(new HomeSP()); 539 Credential credential = new Credential(); 540 credential.setRealm(testRealm); 541 Credential.UserCredential userCredential = new Credential.UserCredential(); 542 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 543 credential.setUserCredential(userCredential); 544 config.setCredential(credential); 545 mProvider = createProvider(config); 546 547 // Setup NAI Realm ANQP element. 548 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 549 anqpElementMap.put(ANQPElementType.ANQPNAIRealm, 550 createNAIRealmElement(testRealm, EAPConstants.EAP_TTLS, 551 new NonEAPInnerAuth(NonEAPInnerAuth.AUTH_TYPE_MSCHAPV2))); 552 553 assertEquals(PasspointMatch.RoamingProvider, mProvider.match(anqpElementMap)); 554 } 555 556 /** 557 * Verify that a provider is a home provider when its FQDN, roaming consortium OI, and 558 * IMSI all matched against the ANQP elements, since we prefer matching home provider over 559 * roaming provider. 560 * 561 * @throws Exception 562 */ 563 @Test 564 public void matchHomeOverRoamingProvider() throws Exception { 565 // Setup test data. 566 String testDomain = "test.com"; 567 String testImsi = "1234567890"; 568 long[] providerRCOIs = new long[] {0x1234L, 0x2345L}; 569 Long[] anqpRCOIs = new Long[] {0x1234L, 0x2133L}; 570 571 // Setup test provider. 572 PasspointConfiguration config = new PasspointConfiguration(); 573 HomeSP homeSp = new HomeSP(); 574 homeSp.setFqdn(testDomain); 575 homeSp.setRoamingConsortiumOIs(providerRCOIs); 576 config.setHomeSp(homeSp); 577 Credential credential = new Credential(); 578 Credential.SimCredential simCredential = new Credential.SimCredential(); 579 simCredential.setImsi(testImsi); 580 credential.setSimCredential(simCredential); 581 config.setCredential(credential); 582 when(mSimAccessor.getMatchingImsis(new IMSIParameter(testImsi, false))) 583 .thenReturn(Arrays.asList(new String[] {testImsi})); 584 mProvider = createProvider(config); 585 586 // Setup ANQP elements. 587 Map<ANQPElementType, ANQPElement> anqpElementMap = new HashMap<>(); 588 anqpElementMap.put(ANQPElementType.ANQPDomName, 589 createDomainNameElement(new String[] {testDomain})); 590 anqpElementMap.put(ANQPElementType.ANQPRoamingConsortium, 591 createRoamingConsortiumElement(anqpRCOIs)); 592 anqpElementMap.put(ANQPElementType.ANQP3GPPNetwork, 593 createThreeGPPNetworkElement(new String[] {"123456"})); 594 595 assertEquals(PasspointMatch.HomeProvider, mProvider.match(anqpElementMap)); 596 } 597 598 /** 599 * Verify that an expected WifiConfiguration will be returned for a Passpoint provider 600 * with an user credential. 601 * 602 * @throws Exception 603 */ 604 @Test 605 public void getWifiConfigWithUserCredential() throws Exception { 606 // Test data. 607 String fqdn = "test.com"; 608 String friendlyName = "Friendly Name"; 609 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 610 String realm = "realm.com"; 611 String username = "username"; 612 String password = "password"; 613 byte[] base64EncodedPw = 614 Base64.encode(password.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT); 615 String encodedPasswordStr = new String(base64EncodedPw, StandardCharsets.UTF_8); 616 617 // Create provider. 618 PasspointConfiguration config = new PasspointConfiguration(); 619 HomeSP homeSp = new HomeSP(); 620 homeSp.setFqdn(fqdn); 621 homeSp.setFriendlyName(friendlyName); 622 homeSp.setRoamingConsortiumOIs(rcOIs); 623 config.setHomeSp(homeSp); 624 Credential credential = new Credential(); 625 credential.setRealm(realm); 626 Credential.UserCredential userCredential = new Credential.UserCredential(); 627 userCredential.setUsername(username); 628 userCredential.setPassword(encodedPasswordStr); 629 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 630 credential.setUserCredential(userCredential); 631 credential.setCaCertificate(FakeKeys.CA_CERT0); 632 config.setCredential(credential); 633 mProvider = createProvider(config); 634 635 // Install certificate. 636 when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0)) 637 .thenReturn(true); 638 assertTrue(mProvider.installCertsAndKeys()); 639 640 // Retrieve the WifiConfiguration associated with the provider, and verify the content of 641 // the configuration. Need to verify field by field since WifiConfiguration doesn't 642 // override equals() function. 643 WifiConfiguration wifiConfig = mProvider.getWifiConfig(); 644 WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig; 645 assertEquals(fqdn, wifiConfig.FQDN); 646 assertEquals(friendlyName, wifiConfig.providerFriendlyName); 647 assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds)); 648 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); 649 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); 650 assertEquals(realm, wifiEnterpriseConfig.getRealm()); 651 assertEquals("anonymous@" + realm, wifiEnterpriseConfig.getAnonymousIdentity()); 652 assertEquals(WifiEnterpriseConfig.Eap.TTLS, wifiEnterpriseConfig.getEapMethod()); 653 assertEquals(WifiEnterpriseConfig.Phase2.MSCHAPV2, wifiEnterpriseConfig.getPhase2Method()); 654 assertEquals(username, wifiEnterpriseConfig.getIdentity()); 655 assertEquals(password, wifiEnterpriseConfig.getPassword()); 656 assertEquals(ALIAS_SUFFIX, wifiEnterpriseConfig.getCaCertificateAlias()); 657 } 658 659 /** 660 * Verify that an expected WifiConfiguration will be returned for a Passpoint provider 661 * with a certificate credential. 662 * 663 * @throws Exception 664 */ 665 @Test 666 public void getWifiConfigWithCertCredential() throws Exception { 667 // Test data. 668 String fqdn = "test.com"; 669 String friendlyName = "Friendly Name"; 670 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 671 String realm = "realm.com"; 672 673 // Create provider. 674 PasspointConfiguration config = new PasspointConfiguration(); 675 HomeSP homeSp = new HomeSP(); 676 homeSp.setFqdn(fqdn); 677 homeSp.setFriendlyName(friendlyName); 678 homeSp.setRoamingConsortiumOIs(rcOIs); 679 config.setHomeSp(homeSp); 680 Credential credential = new Credential(); 681 credential.setRealm(realm); 682 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 683 certCredential.setCertSha256Fingerprint( 684 MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded())); 685 credential.setCertCredential(certCredential); 686 credential.setCaCertificate(FakeKeys.CA_CERT0); 687 credential.setClientPrivateKey(FakeKeys.RSA_KEY1); 688 credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT}); 689 config.setCredential(credential); 690 mProvider = createProvider(config); 691 692 // Install certificate. 693 when(mKeyStore.putCertInKeyStore(CA_CERTIFICATE_ALIAS, FakeKeys.CA_CERT0)) 694 .thenReturn(true); 695 when(mKeyStore.putKeyInKeyStore(CLIENT_PRIVATE_KEY_ALIAS, FakeKeys.RSA_KEY1)) 696 .thenReturn(true); 697 when(mKeyStore.putCertInKeyStore(CLIENT_CERTIFICATE_ALIAS, FakeKeys.CLIENT_CERT)) 698 .thenReturn(true); 699 assertTrue(mProvider.installCertsAndKeys()); 700 701 // Retrieve the WifiConfiguration associated with the provider, and verify the content of 702 // the configuration. Need to verify field by field since WifiConfiguration doesn't 703 // override equals() function. 704 WifiConfiguration wifiConfig = mProvider.getWifiConfig(); 705 WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig; 706 assertEquals(fqdn, wifiConfig.FQDN); 707 assertEquals(friendlyName, wifiConfig.providerFriendlyName); 708 assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds)); 709 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); 710 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); 711 assertEquals(realm, wifiEnterpriseConfig.getRealm()); 712 assertEquals("anonymous@" + realm, wifiEnterpriseConfig.getAnonymousIdentity()); 713 assertEquals(WifiEnterpriseConfig.Eap.TLS, wifiEnterpriseConfig.getEapMethod()); 714 assertEquals(ALIAS_SUFFIX, wifiEnterpriseConfig.getClientCertificateAlias()); 715 assertEquals(ALIAS_SUFFIX, wifiEnterpriseConfig.getCaCertificateAlias()); 716 } 717 718 /** 719 * Verify that an expected WifiConfiguration will be returned for a Passpoint provider 720 * with a SIM credential. 721 * 722 * @throws Exception 723 */ 724 @Test 725 public void getWifiConfigWithSimCredential() throws Exception { 726 // Test data. 727 String fqdn = "test.com"; 728 String friendlyName = "Friendly Name"; 729 long[] rcOIs = new long[] {0x1234L, 0x2345L}; 730 String realm = "realm.com"; 731 String imsi = "1234*"; 732 733 // Create provider. 734 PasspointConfiguration config = new PasspointConfiguration(); 735 HomeSP homeSp = new HomeSP(); 736 homeSp.setFqdn(fqdn); 737 homeSp.setFriendlyName(friendlyName); 738 homeSp.setRoamingConsortiumOIs(rcOIs); 739 config.setHomeSp(homeSp); 740 Credential credential = new Credential(); 741 credential.setRealm(realm); 742 Credential.SimCredential simCredential = new Credential.SimCredential(); 743 simCredential.setImsi(imsi); 744 simCredential.setEapType(EAPConstants.EAP_SIM); 745 credential.setSimCredential(simCredential); 746 config.setCredential(credential); 747 mProvider = createProvider(config); 748 749 // Retrieve the WifiConfiguration associated with the provider, and verify the content of 750 // the configuration. Need to verify field by field since WifiConfiguration doesn't 751 // override equals() function. 752 WifiConfiguration wifiConfig = mProvider.getWifiConfig(); 753 WifiEnterpriseConfig wifiEnterpriseConfig = wifiConfig.enterpriseConfig; 754 assertEquals(fqdn, wifiConfig.FQDN); 755 assertEquals(friendlyName, wifiConfig.providerFriendlyName); 756 assertTrue(Arrays.equals(rcOIs, wifiConfig.roamingConsortiumIds)); 757 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)); 758 assertTrue(wifiConfig.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)); 759 assertEquals(realm, wifiEnterpriseConfig.getRealm()); 760 assertEquals(WifiEnterpriseConfig.Eap.SIM, wifiEnterpriseConfig.getEapMethod()); 761 assertEquals(imsi, wifiEnterpriseConfig.getPlmn()); 762 } 763} 764