1/* 2 * Copyright (C) 2017 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.*; 20import static org.mockito.Mockito.*; 21 22import android.net.wifi.hotspot2.PasspointConfiguration; 23import android.net.wifi.hotspot2.pps.Credential; 24import android.net.wifi.hotspot2.pps.HomeSp; 25import android.net.wifi.hotspot2.pps.Policy; 26import android.net.wifi.hotspot2.pps.UpdateParameter; 27import android.test.suitebuilder.annotation.SmallTest; 28import android.util.Xml; 29 30import com.android.internal.util.FastXmlSerializer; 31 32import org.junit.Test; 33import org.xmlpull.v1.XmlPullParser; 34import org.xmlpull.v1.XmlPullParserException; 35import org.xmlpull.v1.XmlSerializer; 36 37import java.io.ByteArrayInputStream; 38import java.io.ByteArrayOutputStream; 39import java.nio.charset.StandardCharsets; 40import java.text.DateFormat; 41import java.text.SimpleDateFormat; 42import java.util.ArrayList; 43import java.util.Arrays; 44import java.util.HashMap; 45import java.util.List; 46import java.util.Map; 47 48/** 49 * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointXmlUtilsTest}. 50 */ 51@SmallTest 52public class PasspointXmlUtilsTest { 53 54 /** 55 * Helper function for generating a {@link PasspointConfiguration} for testing the XML 56 * serialization/deserialization logic. 57 * 58 * @return {@link PasspointConfiguration} 59 * @throws Exception 60 */ 61 private PasspointConfiguration createFullPasspointConfiguration() throws Exception { 62 DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 63 byte[] certFingerprint = new byte[32]; 64 Arrays.fill(certFingerprint, (byte) 0x1f); 65 66 PasspointConfiguration config = new PasspointConfiguration(); 67 config.setUpdateIdentifier(12); 68 config.setCredentialPriority(99); 69 70 // AAA Server trust root. 71 Map<String, byte[]> trustRootCertList = new HashMap<>(); 72 trustRootCertList.put("server1.trust.root.com", certFingerprint); 73 config.setTrustRootCertList(trustRootCertList); 74 75 // Subscription update. 76 UpdateParameter subscriptionUpdate = new UpdateParameter(); 77 subscriptionUpdate.setUpdateIntervalInMinutes(120); 78 subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); 79 subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); 80 subscriptionUpdate.setServerUri("subscription.update.com"); 81 subscriptionUpdate.setUsername("subscriptionUser"); 82 subscriptionUpdate.setBase64EncodedPassword("subscriptionPass"); 83 subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com"); 84 subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); 85 config.setSubscriptionUpdate(subscriptionUpdate); 86 87 // Subscription parameters. 88 config.setSubscriptionCreationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime()); 89 config.setSubscriptionExpirationTimeInMillis( 90 format.parse("2016-03-01T10:00:00Z").getTime()); 91 config.setSubscriptionType("Gold"); 92 config.setUsageLimitDataLimit(921890); 93 config.setUsageLimitStartTimeInMillis(format.parse("2016-12-01T10:00:00Z").getTime()); 94 config.setUsageLimitTimeLimitInMinutes(120); 95 config.setUsageLimitUsageTimePeriodInMinutes(99910); 96 97 // HomeSP configuration. 98 HomeSp homeSp = new HomeSp(); 99 homeSp.setFriendlyName("Century House"); 100 homeSp.setFqdn("mi6.co.uk"); 101 homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); 102 homeSp.setIconUrl("icon.test.com"); 103 Map<String, Long> homeNetworkIds = new HashMap<>(); 104 homeNetworkIds.put("TestSSID", 0x12345678L); 105 homeNetworkIds.put("NullHESSID", null); 106 homeSp.setHomeNetworkIds(homeNetworkIds); 107 homeSp.setMatchAllOis(new long[] {0x11223344}); 108 homeSp.setMatchAnyOis(new long[] {0x55667788}); 109 homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); 110 config.setHomeSp(homeSp); 111 112 // Credential configuration. 113 Credential credential = new Credential(); 114 credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime()); 115 credential.setExpirationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime()); 116 credential.setRealm("shaken.stirred.com"); 117 credential.setCheckAaaServerCertStatus(true); 118 Credential.UserCredential userCredential = new Credential.UserCredential(); 119 userCredential.setUsername("james"); 120 userCredential.setPassword("Ym9uZDAwNw=="); 121 userCredential.setMachineManaged(true); 122 userCredential.setSoftTokenApp("TestApp"); 123 userCredential.setAbleToShare(true); 124 userCredential.setEapType(21); 125 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 126 credential.setUserCredential(userCredential); 127 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 128 certCredential.setCertType("x509v3"); 129 certCredential.setCertSha256Fingerprint(certFingerprint); 130 credential.setCertCredential(certCredential); 131 Credential.SimCredential simCredential = new Credential.SimCredential(); 132 simCredential.setImsi("imsi"); 133 simCredential.setEapType(24); 134 credential.setSimCredential(simCredential); 135 config.setCredential(credential); 136 137 // Policy configuration. 138 Policy policy = new Policy(); 139 List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); 140 Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); 141 partner1.setFqdn("test1.fqdn.com"); 142 partner1.setFqdnExactMatch(true); 143 partner1.setPriority(127); 144 partner1.setCountries("us,fr"); 145 Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); 146 partner2.setFqdn("test2.fqdn.com"); 147 partner2.setFqdnExactMatch(false); 148 partner2.setPriority(200); 149 partner2.setCountries("*"); 150 preferredRoamingPartnerList.add(partner1); 151 preferredRoamingPartnerList.add(partner2); 152 policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); 153 policy.setMinHomeDownlinkBandwidth(23412); 154 policy.setMinHomeUplinkBandwidth(9823); 155 policy.setMinRoamingDownlinkBandwidth(9271); 156 policy.setMinRoamingUplinkBandwidth(2315); 157 policy.setExcludedSsidList(new String[] {"excludeSSID"}); 158 Map<Integer, String> requiredProtoPortMap = new HashMap<>(); 159 requiredProtoPortMap.put(12, "34,92,234"); 160 policy.setRequiredProtoPortMap(requiredProtoPortMap); 161 policy.setMaximumBssLoadValue(23); 162 UpdateParameter policyUpdate = new UpdateParameter(); 163 policyUpdate.setUpdateIntervalInMinutes(120); 164 policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); 165 policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); 166 policyUpdate.setServerUri("policy.update.com"); 167 policyUpdate.setUsername("updateUser"); 168 policyUpdate.setBase64EncodedPassword("updatePass"); 169 policyUpdate.setTrustRootCertUrl("update.cert.com"); 170 policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); 171 policy.setPolicyUpdate(policyUpdate); 172 config.setPolicy(policy); 173 return config; 174 } 175 176 /** 177 * Verify the serialization and deserialization logic of a {@link PasspointConfiguration}. 178 * 179 * 1. Serialize the test config to a XML block 180 * 2. Deserialize the XML block to a {@link PasspointConfiguration} 181 * 3. Verify that the deserialized config is the same as the test config 182 * 183 * @param testConfig The configuration to used for testing 184 * @throws Exception 185 */ 186 private void serializeAndDeserializePasspointConfiguration(PasspointConfiguration testConfig) 187 throws Exception { 188 final XmlSerializer out = new FastXmlSerializer(); 189 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 190 out.setOutput(outputStream, StandardCharsets.UTF_8.name()); 191 PasspointXmlUtils.serializePasspointConfiguration(out, testConfig); 192 out.flush(); 193 194 final XmlPullParser in = Xml.newPullParser(); 195 final ByteArrayInputStream inputStream = 196 new ByteArrayInputStream(outputStream.toByteArray()); 197 in.setInput(inputStream, StandardCharsets.UTF_8.name()); 198 199 PasspointConfiguration deserializedConfig = 200 PasspointXmlUtils.deserializePasspointConfiguration(in, in.getDepth()); 201 assertEquals(testConfig, deserializedConfig); 202 } 203 204 /** 205 * Verify that the serialization and deserialization logic for a full 206 * {@link PasspointConfiguration} (all fields are set) works as expected. 207 * 208 * @throws Exception 209 */ 210 @Test 211 public void serializeAndDeserializeFullPasspointConfiguration() throws Exception { 212 serializeAndDeserializePasspointConfiguration(createFullPasspointConfiguration()); 213 } 214 215 /** 216 * Verify that the serialization and deserialization logic for an empty 217 * {@link PasspointConfiguration} works as expected. 218 * 219 * @throws Exception 220 */ 221 @Test 222 public void serializeAndDeserializeEmptyPasspointConfiguration() throws Exception { 223 serializeAndDeserializePasspointConfiguration(new PasspointConfiguration()); 224 } 225 226 /** 227 * Verify that a XmlPullParserException will be thrown when deserialize a XML block 228 * for a PasspointConfiguraiton containing an unknown tag. 229 * 230 * @throws Exception 231 */ 232 @Test(expected = XmlPullParserException.class) 233 public void deserializePasspointConfigurationWithUnknownTag() throws Exception { 234 String xmlStr = "<UnknownTag>\n" 235 + "</UnknownTag>\n"; 236 final XmlPullParser in = Xml.newPullParser(); 237 final ByteArrayInputStream inputStream = 238 new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8)); 239 in.setInput(inputStream, StandardCharsets.UTF_8.name()); 240 PasspointXmlUtils.deserializePasspointConfiguration(in, in.getDepth()); 241 } 242} 243