/* * Copyright (C) 2016 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.hotspot2; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.net.wifi.EAPConstants; import android.net.wifi.hotspot2.pps.Credential; import android.net.wifi.hotspot2.pps.HomeSp; import android.net.wifi.hotspot2.pps.Policy; import android.net.wifi.hotspot2.pps.UpdateParameter; import android.os.Parcel; import android.test.suitebuilder.annotation.SmallTest; import android.util.Base64; import org.junit.Test; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}. */ @SmallTest public class PasspointConfigurationTest { private static final int MAX_URL_BYTES = 1023; private static final int CERTIFICATE_FINGERPRINT_BYTES = 32; /** * Utility function for creating a {@link android.net.wifi.hotspot2.pps.HomeSP}. * * @return {@link android.net.wifi.hotspot2.pps.HomeSP} */ private static HomeSp createHomeSp() { HomeSp homeSp = new HomeSp(); homeSp.setFqdn("fqdn"); homeSp.setFriendlyName("friendly name"); homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66}); return homeSp; } /** * Utility function for creating a {@link android.net.wifi.hotspot2.pps.Credential}. * * @return {@link android.net.wifi.hotspot2.pps.Credential} */ private static Credential createCredential() { Credential cred = new Credential(); cred.setRealm("realm"); cred.setUserCredential(null); cred.setCertCredential(null); cred.setSimCredential(new Credential.SimCredential()); cred.getSimCredential().setImsi("1234*"); cred.getSimCredential().setEapType(EAPConstants.EAP_SIM); cred.setCaCertificate(null); cred.setClientCertificateChain(null); cred.setClientPrivateKey(null); return cred; } /** * Helper function for creating a {@link Policy} for testing. * * @return {@link Policy} */ private static Policy createPolicy() { Policy policy = new Policy(); policy.setMinHomeDownlinkBandwidth(123); policy.setMinHomeUplinkBandwidth(345); policy.setMinRoamingDownlinkBandwidth(567); policy.setMinRoamingUplinkBandwidth(789); policy.setMaximumBssLoadValue(12); policy.setExcludedSsidList(new String[] {"ssid1", "ssid2"}); HashMap<Integer, String> requiredProtoPortMap = new HashMap<>(); requiredProtoPortMap.put(12, "23,342,123"); requiredProtoPortMap.put(23, "789,372,1235"); policy.setRequiredProtoPortMap(requiredProtoPortMap); List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); partner1.setFqdn("partner1.com"); partner1.setFqdnExactMatch(true); partner1.setPriority(12); partner1.setCountries("us,jp"); Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); partner2.setFqdn("partner2.com"); partner2.setFqdnExactMatch(false); partner2.setPriority(42); partner2.setCountries("ca,fr"); preferredRoamingPartnerList.add(partner1); preferredRoamingPartnerList.add(partner2); policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); UpdateParameter policyUpdate = new UpdateParameter(); policyUpdate.setUpdateIntervalInMinutes(1712); policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); policyUpdate.setServerUri("policy.update.com"); policyUpdate.setUsername("username"); policyUpdate.setBase64EncodedPassword( Base64.encodeToString("password".getBytes(), Base64.DEFAULT)); policyUpdate.setTrustRootCertUrl("trust.cert.com"); policyUpdate.setTrustRootCertSha256Fingerprint( new byte[CERTIFICATE_FINGERPRINT_BYTES]); policy.setPolicyUpdate(policyUpdate); return policy; } private static UpdateParameter createSubscriptionUpdate() { UpdateParameter subUpdate = new UpdateParameter(); subUpdate.setUpdateIntervalInMinutes(9021); subUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); subUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); subUpdate.setServerUri("subscription.update.com"); subUpdate.setUsername("subUsername"); subUpdate.setBase64EncodedPassword( Base64.encodeToString("subPassword".getBytes(), Base64.DEFAULT)); subUpdate.setTrustRootCertUrl("subscription.trust.cert.com"); subUpdate.setTrustRootCertSha256Fingerprint(new byte[CERTIFICATE_FINGERPRINT_BYTES]); return subUpdate; } /** * Helper function for creating a {@link PasspointConfiguration} for testing. * * @return {@link PasspointConfiguration} */ private static PasspointConfiguration createConfig() { PasspointConfiguration config = new PasspointConfiguration(); config.setHomeSp(createHomeSp()); config.setCredential(createCredential()); config.setPolicy(createPolicy()); config.setSubscriptionUpdate(createSubscriptionUpdate()); Map<String, byte[]> trustRootCertList = new HashMap<>(); trustRootCertList.put("trustRoot.cert1.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); trustRootCertList.put("trustRoot.cert2.com", new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.setTrustRootCertList(trustRootCertList); config.setUpdateIdentifier(1); config.setCredentialPriority(120); config.setSubscriptionCreationTimeInMs(231200); config.setSubscriptionExpirationTimeInMs(2134232); config.setSubscriptionType("Gold"); config.setUsageLimitUsageTimePeriodInMinutes(3600); config.setUsageLimitStartTimeInMs(124214213); config.setUsageLimitDataLimit(14121); config.setUsageLimitTimeLimitInMinutes(78912); return config; } /** * Verify parcel write and read consistency for the given configuration. * * @param writeConfig The configuration to verify * @throws Exception */ private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception { Parcel parcel = Parcel.obtain(); writeConfig.writeToParcel(parcel, 0); parcel.setDataPosition(0); // Rewind data position back to the beginning for read. PasspointConfiguration readConfig = PasspointConfiguration.CREATOR.createFromParcel(parcel); assertTrue(readConfig.equals(writeConfig)); } /** * Verify parcel read/write for a default configuration. * * @throws Exception */ @Test public void verifyParcelWithDefault() throws Exception { verifyParcel(new PasspointConfiguration()); } /** * Verify parcel read/write for a configuration that contained the full configuration. * * @throws Exception */ @Test public void verifyParcelWithFullConfiguration() throws Exception { verifyParcel(createConfig()); } /** * Verify parcel read/write for a configuration that doesn't contain HomeSP. * * @throws Exception */ @Test public void verifyParcelWithoutHomeSP() throws Exception { PasspointConfiguration config = createConfig(); config.setHomeSp(null); verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain Credential. * * @throws Exception */ @Test public void verifyParcelWithoutCredential() throws Exception { PasspointConfiguration config = createConfig(); config.setCredential(null); verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain Policy. * * @throws Exception */ @Test public void verifyParcelWithoutPolicy() throws Exception { PasspointConfiguration config = createConfig(); config.setPolicy(null); verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain subscription update. * * @throws Exception */ @Test public void verifyParcelWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.setSubscriptionUpdate(null); verifyParcel(config); } /** * Verify parcel read/write for a configuration that doesn't contain trust root certificate * list. * * @throws Exception */ @Test public void verifyParcelWithoutTrustRootCertList() throws Exception { PasspointConfiguration config = createConfig(); config.setTrustRootCertList(null); verifyParcel(config); } /** * Verify that a default/empty configuration is invalid. * * @throws Exception */ @Test public void validateDefaultConfig() throws Exception { PasspointConfiguration config = new PasspointConfiguration(); assertFalse(config.validate()); } /** * Verify that a configuration contained all fields is valid. * * @throws Exception */ @Test public void validateFullConfig() throws Exception { PasspointConfiguration config = createConfig(); assertTrue(config.validate()); } /** * Verify that a configuration without Credential is invalid. * * @throws Exception */ @Test public void validateConfigWithoutCredential() throws Exception { PasspointConfiguration config = createConfig(); config.setCredential(null); assertFalse(config.validate()); } /** * Verify that a configuration without HomeSP is invalid. * * @throws Exception */ @Test public void validateConfigWithoutHomeSp() throws Exception { PasspointConfiguration config = createConfig(); config.setHomeSp(null); assertFalse(config.validate()); } /** * Verify that a configuration without Policy is valid, since Policy configurations * are optional (applied for Hotspot 2.0 Release only). * * @throws Exception */ @Test public void validateConfigWithoutPolicy() throws Exception { PasspointConfiguration config = createConfig(); config.setPolicy(null); assertTrue(config.validate()); } /** * Verify that a configuration without subscription update is valid, since subscription * update configurations are optional (applied for Hotspot 2.0 Release only). * * @throws Exception */ @Test public void validateConfigWithoutSubscriptionUpdate() throws Exception { PasspointConfiguration config = createConfig(); config.setSubscriptionUpdate(null); assertTrue(config.validate()); } /** * Verify that a configuration with a trust root certificate URL exceeding the max size * is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertUrl() throws Exception { PasspointConfiguration config = createConfig(); byte[] rawUrlBytes = new byte[MAX_URL_BYTES + 1]; Map<String, byte[]> trustRootCertList = new HashMap<>(); Arrays.fill(rawUrlBytes, (byte) 'a'); trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8), new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.setTrustRootCertList(trustRootCertList); assertFalse(config.validate()); trustRootCertList = new HashMap<>(); trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]); config.setTrustRootCertList(trustRootCertList); assertFalse(config.validate()); } /** * Verify that a configuration with an invalid trust root certificate fingerprint is invalid. * * @throws Exception */ @Test public void validateConfigWithInvalidTrustRootCertFingerprint() throws Exception { PasspointConfiguration config = createConfig(); Map<String, byte[]> trustRootCertList = new HashMap<>(); trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES + 1]); config.setTrustRootCertList(trustRootCertList); assertFalse(config.validate()); trustRootCertList = new HashMap<>(); trustRootCertList.put("test.cert.com", new byte[CERTIFICATE_FINGERPRINT_BYTES - 1]); config.setTrustRootCertList(trustRootCertList); assertFalse(config.validate()); trustRootCertList = new HashMap<>(); trustRootCertList.put("test.cert.com", null); config.setTrustRootCertList(trustRootCertList); assertFalse(config.validate()); } /** * Verify that copy constructor works when pass in a null source. * * @throws Exception */ @Test public void validateCopyConstructorWithNullSource() throws Exception { PasspointConfiguration copyConfig = new PasspointConfiguration(null); PasspointConfiguration defaultConfig = new PasspointConfiguration(); assertTrue(copyConfig.equals(defaultConfig)); } /** * Verify that copy constructor works when pass in a valid source. * * @throws Exception */ @Test public void validateCopyConstructorWithValidSource() throws Exception { PasspointConfiguration sourceConfig = createConfig(); PasspointConfiguration copyConfig = new PasspointConfiguration(sourceConfig); assertTrue(copyConfig.equals(sourceConfig)); } }