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