blob: 7f7504d5518a0257ed5eacd1e6b59bd3e79f3c5e [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi.cts;
import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_NONE;
import android.net.Uri;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.text.TextUtils;
import java.lang.reflect.Constructor;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class WifiHotspot2Test extends WifiJUnit3TestBase {
static final int SIM_CREDENTIAL = 0;
static final int USER_CREDENTIAL = 1;
static final int CERT_CREDENTIAL = 2;
private static final String TEST_SSID = "TEST SSID";
private static final String TEST_FRIENDLY_NAME = "Friendly Name";
private static final Map<String, String> TEST_FRIENDLY_NAMES =
new HashMap<String, String>() {
{
put("en", TEST_FRIENDLY_NAME);
put("kr", TEST_FRIENDLY_NAME + 2);
put("jp", TEST_FRIENDLY_NAME + 3);
}
};
private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
private static final String TEST_NAI = "test.access.com";
private static final List<Integer> TEST_METHOD_LIST =
Arrays.asList(1 /* METHOD_SOAP_XML_SPP */);
private static final long SUBSCRIPTION_EXPIRATION_TIME_MS = 1643996661000L;
@Override
protected void setUp() throws Exception {
super.setUp();
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
/**
* Tests {@link PasspointConfiguration#getMeteredOverride()} method.
* <p>
* Test default value
*/
public void testGetMeteredOverride() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
assertEquals(METERED_OVERRIDE_NONE, passpointConfiguration.getMeteredOverride());
}
/**
* Tests {@link PasspointConfiguration#getSubscriptionExpirationTimeMillis()} and
* {@link PasspointConfiguration#setSubscriptionExpirationTimeInMillis(long)}
* <p>
*/
public void testGetSetSubscriptionExpirationTimeMillis() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
assertEquals(Long.MIN_VALUE,
passpointConfiguration.getSubscriptionExpirationTimeMillis());
passpointConfiguration
.setSubscriptionExpirationTimeInMillis(SUBSCRIPTION_EXPIRATION_TIME_MS);
assertEquals(SUBSCRIPTION_EXPIRATION_TIME_MS,
passpointConfiguration.getSubscriptionExpirationTimeMillis());
}
/**
* Tests {@link PasspointConfiguration#getUniqueId()} method.
* <p>
* Test unique identifier is not null
*/
public void testGetUniqueId() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
// Create a configuration and make sure the unique ID is not null
PasspointConfiguration passpointConfiguration1 = createConfig(SIM_CREDENTIAL, "123456*",
18 /* EAP_SIM */);
String uniqueId1 = passpointConfiguration1.getUniqueId();
assertNotNull(uniqueId1);
// Create another configuration and make sure the unique ID is not null
PasspointConfiguration passpointConfiguration2 = createConfig(SIM_CREDENTIAL, "567890*",
23 /* EAP_AKA */);
String uniqueId2 = passpointConfiguration2.getUniqueId();
assertNotNull(uniqueId2);
// Make sure the IDs are not equal
assertFalse(uniqueId1.equals(uniqueId2));
passpointConfiguration2 = createConfig(USER_CREDENTIAL);
assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
passpointConfiguration2 = createConfig(CERT_CREDENTIAL);
assertFalse(uniqueId1.equals(passpointConfiguration2.getUniqueId()));
}
/**
* Tests {@link PasspointConfiguration#isAutojoinEnabled()} method.
* <p>
* Test default value
*/
public void testIsAutojoinEnabled() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
assertTrue(passpointConfiguration.isAutojoinEnabled());
}
/**
* Tests {@link PasspointConfiguration#isMacRandomizationEnabled()} method.
* <p>
* Test default value
*/
public void testIsMacRandomizationEnabled() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = new PasspointConfiguration();
assertTrue(passpointConfiguration.isMacRandomizationEnabled());
}
/**
* Tests {@link PasspointConfiguration#isOsuProvisioned()} method.
* <p>
* Test default value
*/
public void testIsOsuProvisioned() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
assertFalse(passpointConfiguration.isOsuProvisioned());
}
/**
* Tests {@link PasspointConfiguration#PasspointConfiguration(PasspointConfiguration)} method.
* <p>
* Test the PasspointConfiguration copy constructor
*/
public void testPasspointConfigurationCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
PasspointConfiguration passpointConfiguration = createConfig(USER_CREDENTIAL);
PasspointConfiguration copyOfPasspointConfiguration =
new PasspointConfiguration(passpointConfiguration);
assertEquals(passpointConfiguration, copyOfPasspointConfiguration);
}
/**
* Tests {@link HomeSp#HomeSp(HomeSp)} method.
* <p>
* Test the HomeSp copy constructor
*/
public void testHomeSpCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
HomeSp homeSp = createHomeSp();
HomeSp copyOfHomeSp = new HomeSp(homeSp);
assertEquals(copyOfHomeSp, homeSp);
}
/**
* Tests {@link Credential#Credential(Credential)} method.
* <p>
* Test the Credential copy constructor
*/
public void testCredentialCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential credential = createCredentialWithSimCredential("123456*", 18 /* EAP_SIM */);
Credential copyOfCredential = new Credential(credential);
assertEquals(copyOfCredential, credential);
}
/**
* Tests {@link Credential.UserCredential#UserCredential(Credential.UserCredential)} method.
* <p>
* Test the Credential.UserCredential copy constructor
*/
public void testUserCredentialCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential.UserCredential userCredential = new Credential.UserCredential();
userCredential.setUsername("username");
userCredential.setPassword("password");
userCredential.setEapType(21 /* EAP_TTLS */);
userCredential.setNonEapInnerMethod("MS-CHAP");
Credential.UserCredential copyOfUserCredential =
new Credential.UserCredential(userCredential);
assertEquals(copyOfUserCredential, userCredential);
}
/**
* Tests
* {@link Credential.CertificateCredential#CertificateCredential(Credential.CertificateCredential)}
* method.
* <p>
* Test the Credential.CertificateCredential copy constructor
*/
public void testCertCredentialCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
certCredential.setCertType("x509v3");
Credential.CertificateCredential copyOfCertificateCredential =
new Credential.CertificateCredential(certCredential);
assertEquals(copyOfCertificateCredential, certCredential);
}
/**
* Tests {@link Credential.SimCredential#SimCredential(Credential.SimCredential)} method.
* <p>
* Test the Credential.SimCredential copy constructor
*/
public void testSimCredentialCopyConstructor() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential.SimCredential simCredential = new Credential.SimCredential();
simCredential.setImsi("1234*");
simCredential.setEapType(18/* EAP_SIM */);
Credential.SimCredential copyOfSimCredential = new Credential.SimCredential(simCredential);
assertEquals(copyOfSimCredential, simCredential);
}
/**
* Tests {@link Credential#getCaCertificate()} method.
* <p>
* Test that getting a set certificate produces the same value
*/
public void testCredentialGetCertificate() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential credential = new Credential();
credential.setCaCertificate(FakeKeys.CA_CERT0);
assertEquals(FakeKeys.CA_CERT0, credential.getCaCertificate());
}
/**
* Tests {@link Credential#getClientCertificateChain()} and {@link
* Credential#setCaCertificates(X509Certificate[])} methods.
* <p>
* Test that getting a set client certificate chain produces the same value
*/
public void testCredentialClientCertificateChain() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential credential = new Credential();
X509Certificate[] certificates = new X509Certificate[]{FakeKeys.CLIENT_CERT};
credential.setClientCertificateChain(certificates);
assertTrue(Arrays.equals(certificates, credential.getClientCertificateChain()));
}
/**
* Tests {@link Credential#getClientPrivateKey()} and
* {@link Credential#setClientPrivateKey(PrivateKey)}
* methods.
* <p>
* Test that getting a set client private key produces the same value
*/
public void testCredentialSetGetClientPrivateKey() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential credential = new Credential();
credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
}
/**
* Tests {@link Credential#getClientPrivateKey()} and
* {@link Credential#setClientPrivateKey(PrivateKey)}
* methods.
* <p>
* Test that getting a set client private key produces the same value
*/
public void testCredentialGetClientPrivateKey() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
Credential credential = new Credential();
credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
assertEquals(FakeKeys.RSA_KEY1, credential.getClientPrivateKey());
}
private static PasspointConfiguration createConfig(int type) throws Exception {
return createConfig(type, "123456*", 18 /* EAP_SIM */);
}
private static PasspointConfiguration createConfig(int type, String imsi, int eapType)
throws Exception {
PasspointConfiguration config = new PasspointConfiguration();
config.setHomeSp(createHomeSp());
switch (type) {
default:
case SIM_CREDENTIAL:
config.setCredential(
createCredentialWithSimCredential(imsi, eapType));
break;
case USER_CREDENTIAL:
config.setCredential(createCredentialWithUserCredential());
break;
case CERT_CREDENTIAL:
config.setCredential(createCredentialWithCertificateCredential());
break;
}
return config;
}
/**
* Helper function for generating HomeSp for testing.
*
* @return {@link HomeSp}
*/
private static HomeSp createHomeSp() {
HomeSp homeSp = new HomeSp();
homeSp.setFqdn("test.com");
homeSp.setFriendlyName("friendly name");
homeSp.setRoamingConsortiumOis(new long[]{0x55, 0x66});
return homeSp;
}
/**
* Helper function for generating Credential for testing.
*
* @param userCred Instance of UserCredential
* @param certCred Instance of CertificateCredential
* @param simCred Instance of SimCredential
* @param clientCertificateChain Chain of client certificates
* @param clientPrivateKey Client private key
* @param caCerts CA certificates
* @return {@link Credential}
*/
private static Credential createCredential(Credential.UserCredential userCred,
Credential.CertificateCredential certCred,
Credential.SimCredential simCred,
X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
X509Certificate... caCerts) {
Credential cred = new Credential();
cred.setRealm("realm");
cred.setUserCredential(userCred);
cred.setCertCredential(certCred);
cred.setSimCredential(simCred);
return cred;
}
/**
* Helper function for generating certificate credential for testing.
*
* @return {@link Credential}
*/
private static Credential createCredentialWithCertificateCredential()
throws NoSuchAlgorithmException, CertificateEncodingException {
Credential.CertificateCredential certCred = new Credential.CertificateCredential();
certCred.setCertType("x509v3");
certCred.setCertSha256Fingerprint(
MessageDigest.getInstance("SHA-256").digest(
FakeKeys.CLIENT_CERT.getEncoded()));
return createCredential(null, certCred, null, new X509Certificate[]{
FakeKeys.CLIENT_CERT},
FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0,
FakeKeys.CA_CERT1);
}
/**
* Helper function for generating SIM credential for testing.
*
* @return {@link Credential}
*/
private static Credential createCredentialWithSimCredential(String imsi, int eapType) {
Credential.SimCredential simCred = new Credential.SimCredential();
simCred.setImsi(imsi);
simCred.setEapType(eapType);
return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
}
/**
* Helper function for generating user credential for testing.
*
* @return {@link Credential}
*/
private static Credential createCredentialWithUserCredential() {
Credential.UserCredential userCred = new Credential.UserCredential();
userCred.setUsername("username");
userCred.setPassword("password");
userCred.setEapType(21 /* EAP_TTLS */);
userCred.setNonEapInnerMethod("MS-CHAP");
return createCredential(userCred, null, null, null, null,
FakeKeys.CA_CERT0);
}
/**
* Tests {@link OsuProvider#getFriendlyName()} and {@link OsuProvider#getServerUri()} methods.
* <p>
* Test that getting a set friendly name and server URI produces the same value
*/
public void testOsuProviderGetters() throws Exception {
if (!WifiFeature.isWifiSupported(getContext())) {
// skip the test if WiFi is not supported
return;
}
// Using Java reflection to construct an OsuProvider instance because its constructor is
// hidden and not available to apps.
Class<?> osuProviderClass = Class.forName("android.net.wifi.hotspot2.OsuProvider");
Constructor<?> osuProviderClassConstructor = osuProviderClass.getConstructor(String.class,
Map.class, String.class, Uri.class, String.class, List.class);
OsuProvider osuProvider = (OsuProvider) osuProviderClassConstructor.newInstance(TEST_SSID,
TEST_FRIENDLY_NAMES, TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI,
TEST_METHOD_LIST);
String lang = Locale.getDefault().getLanguage();
String friendlyName = TEST_FRIENDLY_NAMES.get(lang);
if (TextUtils.isEmpty(friendlyName)) {
friendlyName = TEST_FRIENDLY_NAMES.get("en");
}
assertEquals(friendlyName, osuProvider.getFriendlyName());
assertEquals(TEST_SERVER_URI, osuProvider.getServerUri());
}
}