PasspointConfigStoreDataTest.java revision 07816a4745b8030911869ceb58fa735e47834fe4
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; 31import com.android.server.wifi.SIMAccessor; 32import com.android.server.wifi.WifiKeyStore; 33 34import org.junit.Before; 35import org.junit.Test; 36import org.mockito.ArgumentCaptor; 37import org.mockito.Mock; 38import org.mockito.MockitoAnnotations; 39import org.xmlpull.v1.XmlPullParser; 40import org.xmlpull.v1.XmlSerializer; 41 42import java.io.ByteArrayInputStream; 43import java.io.ByteArrayOutputStream; 44import java.nio.charset.StandardCharsets; 45import java.text.DateFormat; 46import java.text.SimpleDateFormat; 47import java.util.ArrayList; 48import java.util.Arrays; 49import java.util.HashMap; 50import java.util.List; 51import java.util.Map; 52 53/** 54 * Unit tests for {@link com.android.server.wifi.hotspot2.PasspointConfigStoreData}. 55 */ 56@SmallTest 57public class PasspointConfigStoreDataTest { 58 private static final String TEST_CA_CERTIFICATE_ALIAS = "CaCert"; 59 private static final String TEST_CLIENT_CERTIFICATE_ALIAS = "ClientCert"; 60 private static final String TEST_CLIENT_PRIVATE_KEY_ALIAS = "ClientPrivateKey"; 61 private static final long TEST_PROVIDER_ID = 1; 62 private static final int TEST_CREATOR_UID = 1234; 63 64 @Mock WifiKeyStore mKeyStore; 65 @Mock SIMAccessor mSimAccessor; 66 @Mock PasspointConfigStoreData.DataSource mDataSource; 67 PasspointConfigStoreData mConfigStoreData; 68 69 /** Sets up test. */ 70 @Before 71 public void setUp() throws Exception { 72 MockitoAnnotations.initMocks(this); 73 mConfigStoreData = new PasspointConfigStoreData(mKeyStore, mSimAccessor, mDataSource); 74 } 75 76 /** 77 * Helper function for generating a {@link PasspointConfiguration} for testing the XML 78 * serialization/deserialization logic. 79 * 80 * @return {@link PasspointConfiguration} 81 * @throws Exception 82 */ 83 private PasspointConfiguration createFullPasspointConfiguration() throws Exception { 84 DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 85 byte[] certFingerprint = new byte[32]; 86 Arrays.fill(certFingerprint, (byte) 0x1f); 87 88 PasspointConfiguration config = new PasspointConfiguration(); 89 config.setUpdateIdentifier(12); 90 config.setCredentialPriority(99); 91 92 // AAA Server trust root. 93 Map<String, byte[]> trustRootCertList = new HashMap<>(); 94 trustRootCertList.put("server1.trust.root.com", certFingerprint); 95 config.setTrustRootCertList(trustRootCertList); 96 97 // Subscription update. 98 UpdateParameter subscriptionUpdate = new UpdateParameter(); 99 subscriptionUpdate.setUpdateIntervalInMinutes(120); 100 subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP); 101 subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER); 102 subscriptionUpdate.setServerUri("subscription.update.com"); 103 subscriptionUpdate.setUsername("subscriptionUser"); 104 subscriptionUpdate.setBase64EncodedPassword("subscriptionPass"); 105 subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com"); 106 subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); 107 config.setSubscriptionUpdate(subscriptionUpdate); 108 109 // Subscription parameters. 110 config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); 111 config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime()); 112 config.setSubscriptionType("Gold"); 113 config.setUsageLimitDataLimit(921890); 114 config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime()); 115 config.setUsageLimitTimeLimitInMinutes(120); 116 config.setUsageLimitUsageTimePeriodInMinutes(99910); 117 118 // HomeSP configuration. 119 HomeSp homeSp = new HomeSp(); 120 homeSp.setFriendlyName("Century House"); 121 homeSp.setFqdn("mi6.co.uk"); 122 homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); 123 homeSp.setIconUrl("icon.test.com"); 124 Map<String, Long> homeNetworkIds = new HashMap<>(); 125 homeNetworkIds.put("TestSSID", 0x12345678L); 126 homeNetworkIds.put("NullHESSID", null); 127 homeSp.setHomeNetworkIds(homeNetworkIds); 128 homeSp.setMatchAllOis(new long[] {0x11223344}); 129 homeSp.setMatchAnyOis(new long[] {0x55667788}); 130 homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); 131 config.setHomeSp(homeSp); 132 133 // Credential configuration. 134 Credential credential = new Credential(); 135 credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime()); 136 credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime()); 137 credential.setRealm("shaken.stirred.com"); 138 credential.setCheckAaaServerCertStatus(true); 139 Credential.UserCredential userCredential = new Credential.UserCredential(); 140 userCredential.setUsername("james"); 141 userCredential.setPassword("Ym9uZDAwNw=="); 142 userCredential.setMachineManaged(true); 143 userCredential.setSoftTokenApp("TestApp"); 144 userCredential.setAbleToShare(true); 145 userCredential.setEapType(21); 146 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 147 credential.setUserCredential(userCredential); 148 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 149 certCredential.setCertType("x509v3"); 150 certCredential.setCertSha256Fingerprint(certFingerprint); 151 credential.setCertCredential(certCredential); 152 Credential.SimCredential simCredential = new Credential.SimCredential(); 153 simCredential.setImsi("imsi"); 154 simCredential.setEapType(24); 155 credential.setSimCredential(simCredential); 156 config.setCredential(credential); 157 158 // Policy configuration. 159 Policy policy = new Policy(); 160 List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); 161 Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); 162 partner1.setFqdn("test1.fqdn.com"); 163 partner1.setFqdnExactMatch(true); 164 partner1.setPriority(127); 165 partner1.setCountries("us,fr"); 166 Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); 167 partner2.setFqdn("test2.fqdn.com"); 168 partner2.setFqdnExactMatch(false); 169 partner2.setPriority(200); 170 partner2.setCountries("*"); 171 preferredRoamingPartnerList.add(partner1); 172 preferredRoamingPartnerList.add(partner2); 173 policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); 174 policy.setMinHomeDownlinkBandwidth(23412); 175 policy.setMinHomeUplinkBandwidth(9823); 176 policy.setMinRoamingDownlinkBandwidth(9271); 177 policy.setMinRoamingUplinkBandwidth(2315); 178 policy.setExcludedSsidList(new String[] {"excludeSSID"}); 179 Map<Integer, String> requiredProtoPortMap = new HashMap<>(); 180 requiredProtoPortMap.put(12, "34,92,234"); 181 policy.setRequiredProtoPortMap(requiredProtoPortMap); 182 policy.setMaximumBssLoadValue(23); 183 UpdateParameter policyUpdate = new UpdateParameter(); 184 policyUpdate.setUpdateIntervalInMinutes(120); 185 policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); 186 policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); 187 policyUpdate.setServerUri("policy.update.com"); 188 policyUpdate.setUsername("updateUser"); 189 policyUpdate.setBase64EncodedPassword("updatePass"); 190 policyUpdate.setTrustRootCertUrl("update.cert.com"); 191 policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); 192 policy.setPolicyUpdate(policyUpdate); 193 config.setPolicy(policy); 194 return config; 195 } 196 197 /** 198 * Helper function for serializing store data to a XML block. 199 * 200 * @param share Flag indicating share or user data 201 * @return byte[] 202 * @throws Exception 203 */ 204 private byte[] serializeData(boolean share) throws Exception { 205 final XmlSerializer out = new FastXmlSerializer(); 206 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 207 out.setOutput(outputStream, StandardCharsets.UTF_8.name()); 208 mConfigStoreData.serializeData(out, share); 209 out.flush(); 210 return outputStream.toByteArray(); 211 } 212 213 /** 214 * Helper function for deserializing store data from a XML block. 215 * 216 * @param data The XML block data bytes 217 * @param share Flag indicating share or user data 218 * @throws Exception 219 */ 220 private void deserializeData(byte[] data, boolean share) throws Exception { 221 final XmlPullParser in = Xml.newPullParser(); 222 final ByteArrayInputStream inputStream = new ByteArrayInputStream(data); 223 in.setInput(inputStream, StandardCharsets.UTF_8.name()); 224 mConfigStoreData.deserializeData(in, in.getDepth(), share); 225 } 226 227 /** 228 * Verify that the serialization and deserialization of user store data works as expected. 229 * The data used for serialization matches the result of the deserialization. 230 * 231 * @throws Exception 232 */ 233 @Test 234 public void serializeAndDeserializeUserStoreData() throws Exception { 235 // Setup expected data. 236 List<PasspointProvider> providerList = new ArrayList<>(); 237 providerList.add(new PasspointProvider(createFullPasspointConfiguration(), 238 mKeyStore, mSimAccessor, TEST_PROVIDER_ID, TEST_CREATOR_UID, 239 TEST_CA_CERTIFICATE_ALIAS, TEST_CLIENT_CERTIFICATE_ALIAS, 240 TEST_CLIENT_PRIVATE_KEY_ALIAS)); 241 242 // Serialize data for user store. 243 when(mDataSource.getProviders()).thenReturn(providerList); 244 byte[] data = serializeData(false); 245 246 // Deserialize data for user store and verify the content. 247 ArgumentCaptor<ArrayList> providersCaptor = ArgumentCaptor.forClass(ArrayList.class); 248 deserializeData(data, false); 249 verify(mDataSource).setProviders(providersCaptor.capture()); 250 assertEquals(providerList, providersCaptor.getValue()); 251 } 252 253 /** 254 * Verify that the serialization and deserialization of share store data works as expected. 255 * The data used for serialization matches the result of the deserialization. 256 * 257 * @throws Exception 258 */ 259 @Test 260 public void serializeAndDeserializeShareStoreData() throws Exception { 261 // Setup expected data. 262 long providerIndex = 412; 263 264 // Serialize data for share store. 265 when(mDataSource.getProviderIndex()).thenReturn(providerIndex); 266 byte[] data = serializeData(true); 267 268 // Deserialize data for share store and verify the content. 269 deserializeData(data, true); 270 verify(mDataSource).setProviderIndex(providerIndex); 271 } 272 273 /** 274 * Verify that deserialization of an empty user store data doesn't cause any exception and 275 * the corresponding data source should not be updated. 276 * 277 * @throws Exception 278 */ 279 @Test 280 public void deserializeEmptyUserStoreData() throws Exception { 281 deserializeData(new byte[0], false); 282 verify(mDataSource, never()).setProviders(any(ArrayList.class)); 283 } 284 285 /** 286 * Verify that deserialization of an empty share store data doesn't cause any exception 287 * and the corresponding data source should not be updated. 288 * 289 * @throws Exception 290 */ 291 @Test 292 public void deserializeEmptyShareStoreData() throws Exception { 293 deserializeData(new byte[0], true); 294 verify(mDataSource, never()).setProviderIndex(anyLong()); 295 } 296} 297