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