PasspointConfigStoreData.java revision 49357a30edf5786c8db4bad6f5dbe62545751cc6
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 android.net.wifi.hotspot2.PasspointConfiguration; 20import android.text.TextUtils; 21 22import com.android.internal.util.XmlUtils; 23import com.android.server.wifi.SIMAccessor; 24import com.android.server.wifi.WifiConfigStore; 25import com.android.server.wifi.WifiKeyStore; 26import com.android.server.wifi.util.XmlUtil; 27 28import org.xmlpull.v1.XmlPullParser; 29import org.xmlpull.v1.XmlPullParserException; 30import org.xmlpull.v1.XmlSerializer; 31 32import java.io.IOException; 33import java.util.ArrayList; 34import java.util.List; 35 36/** 37 * Responsible for Passpoint specific configuration store data. There are two types of 38 * configuration data, system wide and user specific. The system wide configurations are stored 39 * in the share store and user specific configurations are store in the user store. 40 * 41 * Below are the current configuration data for each respective store file, the list will 42 * probably grow in the future. 43 * 44 * Share Store (system wide configurations) 45 * - Current provider index - use for assigning provider ID during provider creation, to make 46 * sure each provider will have an unique ID across all users. 47 * 48 * User Store (user specific configurations) 49 * - Provider list - list of Passpoint provider configurations 50 * 51 */ 52public class PasspointConfigStoreData implements WifiConfigStore.StoreData { 53 private static final String XML_TAG_SECTION_HEADER_PASSPOINT_CONFIG_DATA = 54 "PasspointConfigData"; 55 private static final String XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER_LIST = 56 "ProviderList"; 57 private static final String XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER = 58 "Provider"; 59 private static final String XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION = 60 "Configuration"; 61 62 private static final String XML_TAG_PROVIDER_ID = "ProviderID"; 63 private static final String XML_TAG_CREATOR_UID = "CreatorUID"; 64 private static final String XML_TAG_CA_CERTIFICATE_ALIAS = "CaCertificateAlias"; 65 private static final String XML_TAG_CLIENT_CERTIFICATE_ALIAS = "ClientCertificateAlias"; 66 private static final String XML_TAG_CLIENT_PRIVATE_KEY_ALIAS = "ClientPrivateKeyAlias"; 67 68 private static final String XML_TAG_PROVIDER_INDEX = "ProviderIndex"; 69 private static final String XML_TAG_HAS_EVER_CONNECTED = "HasEverConnected"; 70 71 private final WifiKeyStore mKeyStore; 72 private final SIMAccessor mSimAccessor; 73 private final DataSource mDataSource; 74 75 /** 76 * Interface define the data source for the Passpoint configuration store data. 77 */ 78 public interface DataSource { 79 /** 80 * Retrieve the provider list from the data source. 81 * 82 * @return List of {@link PasspointProvider} 83 */ 84 List<PasspointProvider> getProviders(); 85 86 /** 87 * Set the provider list in the data source. 88 * 89 * @param providers The list of providers 90 */ 91 void setProviders(List<PasspointProvider> providers); 92 93 /** 94 * Retrieve the current provider index. 95 * 96 * @return long 97 */ 98 long getProviderIndex(); 99 100 /** 101 * Set the current provider index. 102 * 103 * @param providerIndex The provider index used for provider creation 104 */ 105 void setProviderIndex(long providerIndex); 106 } 107 108 PasspointConfigStoreData(WifiKeyStore keyStore, SIMAccessor simAccessor, 109 DataSource dataSource) { 110 mKeyStore = keyStore; 111 mSimAccessor = simAccessor; 112 mDataSource = dataSource; 113 } 114 115 @Override 116 public void serializeData(XmlSerializer out, boolean shared) 117 throws XmlPullParserException, IOException { 118 if (shared) { 119 serializeShareData(out); 120 } else { 121 serializeUserData(out); 122 } 123 } 124 125 @Override 126 public void deserializeData(XmlPullParser in, int outerTagDepth, boolean shared) 127 throws XmlPullParserException, IOException { 128 if (shared) { 129 deserializeShareData(in, outerTagDepth); 130 } else { 131 deserializeUserData(in, outerTagDepth); 132 } 133 } 134 135 @Override 136 public void resetData(boolean shared) { 137 if (shared) { 138 resetShareData(); 139 } else { 140 resetUserData(); 141 } 142 } 143 144 @Override 145 public String getName() { 146 return XML_TAG_SECTION_HEADER_PASSPOINT_CONFIG_DATA; 147 } 148 149 @Override 150 public boolean supportShareData() { 151 return true; 152 } 153 154 /** 155 * Serialize share data (system wide Passpoint configurations) to a XML block. 156 * 157 * @param out The output stream to serialize data to 158 * @throws XmlPullParserException 159 * @throws IOException 160 */ 161 private void serializeShareData(XmlSerializer out) throws XmlPullParserException, IOException { 162 XmlUtil.writeNextValue(out, XML_TAG_PROVIDER_INDEX, mDataSource.getProviderIndex()); 163 } 164 165 /** 166 * Serialize user data (user specific Passpoint configurations) to a XML block. 167 * 168 * @param out The output stream to serialize data to 169 * @throws XmlPullParserException 170 * @throws IOException 171 */ 172 private void serializeUserData(XmlSerializer out) throws XmlPullParserException, IOException { 173 serializeProviderList(out, mDataSource.getProviders()); 174 } 175 176 /** 177 * Serialize the list of Passpoint providers from the data source to a XML block. 178 * 179 * @param out The output stream to serialize data to 180 * @param providerList The list of providers to serialize 181 * @throws XmlPullParserException 182 * @throws IOException 183 */ 184 private void serializeProviderList(XmlSerializer out, List<PasspointProvider> providerList) 185 throws XmlPullParserException, IOException { 186 if (providerList == null) { 187 return; 188 } 189 XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER_LIST); 190 for (PasspointProvider provider : providerList) { 191 serializeProvider(out, provider); 192 } 193 XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER_LIST); 194 } 195 196 /** 197 * Serialize a Passpoint provider to a XML block. 198 * 199 * @param out The output stream to serialize data to 200 * @param provider The provider to serialize 201 * @throws XmlPullParserException 202 * @throws IOException 203 */ 204 private void serializeProvider(XmlSerializer out, PasspointProvider provider) 205 throws XmlPullParserException, IOException { 206 XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER); 207 XmlUtil.writeNextValue(out, XML_TAG_PROVIDER_ID, provider.getProviderId()); 208 XmlUtil.writeNextValue(out, XML_TAG_CREATOR_UID, provider.getCreatorUid()); 209 XmlUtil.writeNextValue(out, XML_TAG_CA_CERTIFICATE_ALIAS, 210 provider.getCaCertificateAlias()); 211 XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERTIFICATE_ALIAS, 212 provider.getClientCertificateAlias()); 213 XmlUtil.writeNextValue(out, XML_TAG_CLIENT_PRIVATE_KEY_ALIAS, 214 provider.getClientPrivateKeyAlias()); 215 XmlUtil.writeNextValue(out, XML_TAG_HAS_EVER_CONNECTED, provider.getHasEverConnected()); 216 if (provider.getConfig() != null) { 217 XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); 218 PasspointXmlUtils.serializePasspointConfiguration(out, provider.getConfig()); 219 XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION); 220 } 221 XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER); 222 } 223 224 /** 225 * Deserialize share data (system wide Passpoint configurations) from the input stream. 226 * 227 * @param in The input stream to read data from 228 * @param outerTagDepth The tag depth of the current XML section 229 * @throws XmlPullParserException 230 * @throws IOException 231 */ 232 private void deserializeShareData(XmlPullParser in, int outerTagDepth) 233 throws XmlPullParserException, IOException { 234 while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) { 235 String[] valueName = new String[1]; 236 Object value = XmlUtil.readCurrentValue(in, valueName); 237 if (valueName[0] == null) { 238 throw new XmlPullParserException("Missing value name"); 239 } 240 switch (valueName[0]) { 241 case XML_TAG_PROVIDER_INDEX: 242 mDataSource.setProviderIndex((long) value); 243 break; 244 default: 245 throw new XmlPullParserException("Unknown value under share store data " 246 + valueName[0]); 247 } 248 } 249 } 250 251 /** 252 * Deserialize user data (user specific Passpoint configurations) from the input stream. 253 * 254 * @param in The input stream to read data from 255 * @param outerTagDepth The tag depth of the current XML section 256 * @throws XmlPullParserException 257 * @throws IOException 258 */ 259 private void deserializeUserData(XmlPullParser in, int outerTagDepth) 260 throws XmlPullParserException, IOException { 261 String[] headerName = new String[1]; 262 while (XmlUtil.gotoNextSectionOrEnd(in, headerName, outerTagDepth)) { 263 switch (headerName[0]) { 264 case XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER_LIST: 265 mDataSource.setProviders(deserializeProviderList(in, outerTagDepth + 1)); 266 break; 267 default: 268 throw new XmlPullParserException("Unknown Passpoint user store data " 269 + headerName[0]); 270 } 271 } 272 } 273 274 /** 275 * Deserialize a list of Passpoint providers from the input stream. 276 * 277 * @param in The input stream to read data form 278 * @param outerTagDepth The tag depth of the current XML section 279 * @return List of {@link PasspointProvider} 280 * @throws XmlPullParserException 281 * @throws IOException 282 */ 283 private List<PasspointProvider> deserializeProviderList(XmlPullParser in, int outerTagDepth) 284 throws XmlPullParserException, IOException { 285 List<PasspointProvider> providerList = new ArrayList<>(); 286 while (XmlUtil.gotoNextSectionWithNameOrEnd(in, XML_TAG_SECTION_HEADER_PASSPOINT_PROVIDER, 287 outerTagDepth)) { 288 providerList.add(deserializeProvider(in, outerTagDepth + 1)); 289 } 290 return providerList; 291 } 292 293 /** 294 * Deserialize a Passpoint provider from the input stream. 295 * 296 * @param in The input stream to read data from 297 * @param outerTagDepth The tag depth of the current XML section 298 * @return {@link PasspointProvider} 299 * @throws XmlPullParserException 300 * @throws IOException 301 */ 302 private PasspointProvider deserializeProvider(XmlPullParser in, int outerTagDepth) 303 throws XmlPullParserException, IOException { 304 long providerId = Long.MIN_VALUE; 305 int creatorUid = Integer.MIN_VALUE; 306 String caCertificateAlias = null; 307 String clientCertificateAlias = null; 308 String clientPrivateKeyAlias = null; 309 boolean hasEverConnected = false; 310 PasspointConfiguration config = null; 311 while (XmlUtils.nextElementWithin(in, outerTagDepth)) { 312 if (in.getAttributeValue(null, "name") != null) { 313 // Value elements. 314 String[] name = new String[1]; 315 Object value = XmlUtil.readCurrentValue(in, name); 316 switch (name[0]) { 317 case XML_TAG_PROVIDER_ID: 318 providerId = (long) value; 319 break; 320 case XML_TAG_CREATOR_UID: 321 creatorUid = (int) value; 322 break; 323 case XML_TAG_CA_CERTIFICATE_ALIAS: 324 caCertificateAlias = (String) value; 325 break; 326 case XML_TAG_CLIENT_CERTIFICATE_ALIAS: 327 clientCertificateAlias = (String) value; 328 break; 329 case XML_TAG_CLIENT_PRIVATE_KEY_ALIAS: 330 clientPrivateKeyAlias = (String) value; 331 break; 332 case XML_TAG_HAS_EVER_CONNECTED: 333 hasEverConnected = (boolean) value; 334 break; 335 } 336 } else { 337 if (!TextUtils.equals(in.getName(), 338 XML_TAG_SECTION_HEADER_PASSPOINT_CONFIGURATION)) { 339 throw new XmlPullParserException("Unexpected section under Provider: " 340 + in.getName()); 341 } 342 config = PasspointXmlUtils.deserializePasspointConfiguration(in, 343 outerTagDepth + 1); 344 } 345 } 346 if (providerId == Long.MIN_VALUE) { 347 throw new XmlPullParserException("Missing provider ID"); 348 } 349 if (config == null) { 350 throw new XmlPullParserException("Missing Passpoint configuration"); 351 } 352 return new PasspointProvider(config, mKeyStore, mSimAccessor, providerId, creatorUid, 353 caCertificateAlias, clientCertificateAlias, clientPrivateKeyAlias, 354 hasEverConnected); 355 } 356 357 /** 358 * Reset share data (system wide Passpoint configurations). 359 */ 360 private void resetShareData() { 361 mDataSource.setProviderIndex(0); 362 } 363 364 /** 365 * Reset user data (user specific Passpoint configurations). 366 */ 367 private void resetUserData() { 368 mDataSource.setProviders(new ArrayList<PasspointProvider>()); 369 } 370} 371 372