PasspointConfigStoreDataTest.java revision 8f4f48b96b690aa099f85aad7a361cf39e431f42
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.setSubscriptionCreationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime()); 111 config.setSubscriptionExpirationTimeInMillis( 112 format.parse("2016-03-01T10:00:00Z").getTime()); 113 config.setSubscriptionType("Gold"); 114 config.setUsageLimitDataLimit(921890); 115 config.setUsageLimitStartTimeInMillis(format.parse("2016-12-01T10:00:00Z").getTime()); 116 config.setUsageLimitTimeLimitInMinutes(120); 117 config.setUsageLimitUsageTimePeriodInMinutes(99910); 118 119 // HomeSP configuration. 120 HomeSp homeSp = new HomeSp(); 121 homeSp.setFriendlyName("Century House"); 122 homeSp.setFqdn("mi6.co.uk"); 123 homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L}); 124 homeSp.setIconUrl("icon.test.com"); 125 Map<String, Long> homeNetworkIds = new HashMap<>(); 126 homeNetworkIds.put("TestSSID", 0x12345678L); 127 homeNetworkIds.put("NullHESSID", null); 128 homeSp.setHomeNetworkIds(homeNetworkIds); 129 homeSp.setMatchAllOis(new long[] {0x11223344}); 130 homeSp.setMatchAnyOis(new long[] {0x55667788}); 131 homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"}); 132 config.setHomeSp(homeSp); 133 134 // Credential configuration. 135 Credential credential = new Credential(); 136 credential.setCreationTimeInMillis(format.parse("2016-01-01T10:00:00Z").getTime()); 137 credential.setExpirationTimeInMillis(format.parse("2016-02-01T10:00:00Z").getTime()); 138 credential.setRealm("shaken.stirred.com"); 139 credential.setCheckAaaServerCertStatus(true); 140 Credential.UserCredential userCredential = new Credential.UserCredential(); 141 userCredential.setUsername("james"); 142 userCredential.setPassword("Ym9uZDAwNw=="); 143 userCredential.setMachineManaged(true); 144 userCredential.setSoftTokenApp("TestApp"); 145 userCredential.setAbleToShare(true); 146 userCredential.setEapType(21); 147 userCredential.setNonEapInnerMethod("MS-CHAP-V2"); 148 credential.setUserCredential(userCredential); 149 Credential.CertificateCredential certCredential = new Credential.CertificateCredential(); 150 certCredential.setCertType("x509v3"); 151 certCredential.setCertSha256Fingerprint(certFingerprint); 152 credential.setCertCredential(certCredential); 153 Credential.SimCredential simCredential = new Credential.SimCredential(); 154 simCredential.setImsi("imsi"); 155 simCredential.setEapType(24); 156 credential.setSimCredential(simCredential); 157 config.setCredential(credential); 158 159 // Policy configuration. 160 Policy policy = new Policy(); 161 List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>(); 162 Policy.RoamingPartner partner1 = new Policy.RoamingPartner(); 163 partner1.setFqdn("test1.fqdn.com"); 164 partner1.setFqdnExactMatch(true); 165 partner1.setPriority(127); 166 partner1.setCountries("us,fr"); 167 Policy.RoamingPartner partner2 = new Policy.RoamingPartner(); 168 partner2.setFqdn("test2.fqdn.com"); 169 partner2.setFqdnExactMatch(false); 170 partner2.setPriority(200); 171 partner2.setCountries("*"); 172 preferredRoamingPartnerList.add(partner1); 173 preferredRoamingPartnerList.add(partner2); 174 policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList); 175 policy.setMinHomeDownlinkBandwidth(23412); 176 policy.setMinHomeUplinkBandwidth(9823); 177 policy.setMinRoamingDownlinkBandwidth(9271); 178 policy.setMinRoamingUplinkBandwidth(2315); 179 policy.setExcludedSsidList(new String[] {"excludeSSID"}); 180 Map<Integer, String> requiredProtoPortMap = new HashMap<>(); 181 requiredProtoPortMap.put(12, "34,92,234"); 182 policy.setRequiredProtoPortMap(requiredProtoPortMap); 183 policy.setMaximumBssLoadValue(23); 184 UpdateParameter policyUpdate = new UpdateParameter(); 185 policyUpdate.setUpdateIntervalInMinutes(120); 186 policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM); 187 policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP); 188 policyUpdate.setServerUri("policy.update.com"); 189 policyUpdate.setUsername("updateUser"); 190 policyUpdate.setBase64EncodedPassword("updatePass"); 191 policyUpdate.setTrustRootCertUrl("update.cert.com"); 192 policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint); 193 policy.setPolicyUpdate(policyUpdate); 194 config.setPolicy(policy); 195 return config; 196 } 197 198 /** 199 * Helper function for serializing store data to a XML block. 200 * 201 * @param share Flag indicating share or user data 202 * @return byte[] 203 * @throws Exception 204 */ 205 private byte[] serializeData(boolean share) throws Exception { 206 final XmlSerializer out = new FastXmlSerializer(); 207 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 208 out.setOutput(outputStream, StandardCharsets.UTF_8.name()); 209 mConfigStoreData.serializeData(out, share); 210 out.flush(); 211 return outputStream.toByteArray(); 212 } 213 214 /** 215 * Helper function for deserializing store data from a XML block. 216 * 217 * @param data The XML block data bytes 218 * @param share Flag indicating share or user data 219 * @throws Exception 220 */ 221 private void deserializeData(byte[] data, boolean share) throws Exception { 222 final XmlPullParser in = Xml.newPullParser(); 223 final ByteArrayInputStream inputStream = new ByteArrayInputStream(data); 224 in.setInput(inputStream, StandardCharsets.UTF_8.name()); 225 mConfigStoreData.deserializeData(in, in.getDepth(), share); 226 } 227 228 /** 229 * Verify that the serialization and deserialization of user store data works as expected. 230 * The data used for serialization matches the result of the deserialization. 231 * 232 * @throws Exception 233 */ 234 @Test 235 public void serializeAndDeserializeUserStoreData() throws Exception { 236 // Setup expected data. 237 List<PasspointProvider> providerList = new ArrayList<>(); 238 providerList.add(new PasspointProvider(createFullPasspointConfiguration(), 239 mKeyStore, mSimAccessor, TEST_PROVIDER_ID, TEST_CREATOR_UID, 240 TEST_CA_CERTIFICATE_ALIAS, TEST_CLIENT_CERTIFICATE_ALIAS, 241 TEST_CLIENT_PRIVATE_KEY_ALIAS)); 242 243 // Serialize data for user store. 244 when(mDataSource.getProviders()).thenReturn(providerList); 245 byte[] data = serializeData(false); 246 247 // Deserialize data for user store and verify the content. 248 ArgumentCaptor<ArrayList> providersCaptor = ArgumentCaptor.forClass(ArrayList.class); 249 deserializeData(data, false); 250 verify(mDataSource).setProviders(providersCaptor.capture()); 251 assertEquals(providerList, providersCaptor.getValue()); 252 } 253 254 /** 255 * Verify that the serialization and deserialization of share store data works as expected. 256 * The data used for serialization matches the result of the deserialization. 257 * 258 * @throws Exception 259 */ 260 @Test 261 public void serializeAndDeserializeShareStoreData() throws Exception { 262 // Setup expected data. 263 long providerIndex = 412; 264 265 // Serialize data for share store. 266 when(mDataSource.getProviderIndex()).thenReturn(providerIndex); 267 byte[] data = serializeData(true); 268 269 // Deserialize data for share store and verify the content. 270 deserializeData(data, true); 271 verify(mDataSource).setProviderIndex(providerIndex); 272 } 273 274 /** 275 * Verify that deserialization of an empty user store data doesn't cause any exception and 276 * the corresponding data source should not be updated. 277 * 278 * @throws Exception 279 */ 280 @Test 281 public void deserializeEmptyUserStoreData() throws Exception { 282 deserializeData(new byte[0], false); 283 verify(mDataSource, never()).setProviders(any(ArrayList.class)); 284 } 285 286 /** 287 * Verify that deserialization of an empty share store data doesn't cause any exception 288 * and the corresponding data source should not be updated. 289 * 290 * @throws Exception 291 */ 292 @Test 293 public void deserializeEmptyShareStoreData() throws Exception { 294 deserializeData(new byte[0], true); 295 verify(mDataSource, never()).setProviderIndex(anyLong()); 296 } 297} 298