summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-11-17 00:10:45 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-11-17 00:10:45 +0000
commitd5f40d3862d639684672bdba709ca598c9d0e248 (patch)
tree8bb3ec31fbb2e671d51aef48afdc9a1ed6b3fe8a
parent7ebfe807c4ef8c41ea13fca1cb844c0f3b6e8fb4 (diff)
parenta9ebe48227eb5befd221451a013cbd0a76eac999 (diff)
downloadandroid_frameworks_opt_net_wifi-d5f40d3862d639684672bdba709ca598c9d0e248.tar.gz
android_frameworks_opt_net_wifi-d5f40d3862d639684672bdba709ca598c9d0e248.tar.bz2
android_frameworks_opt_net_wifi-d5f40d3862d639684672bdba709ca598c9d0e248.zip
Snap for 6013205 from a9ebe48227eb5befd221451a013cbd0a76eac999 to qt-qpr2-release
Change-Id: I16793ede4d0cdb517d5c7a546476eb36c10da8e3
-rw-r--r--service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java12
-rw-r--r--service/java/com/android/server/wifi/NetworkListStoreData.java57
-rw-r--r--service/java/com/android/server/wifi/NetworkRequestStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionStoreData.java58
-rw-r--r--service/java/com/android/server/wifi/RandomizedMacStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/SsidSetStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/WakeupConfigStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/WifiConfigManager.java10
-rw-r--r--service/java/com/android/server/wifi/WifiConfigStore.java245
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java2
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/util/EncryptedData.java27
-rw-r--r--service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java (renamed from service/java/com/android/server/wifi/util/DataIntegrityChecker.java)139
-rw-r--r--service/java/com/android/server/wifi/util/XmlUtil.java630
-rw-r--r--tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java8
-rw-r--r--tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java8
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java12
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java2
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java302
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java7
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java69
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java71
31 files changed, 877 insertions, 896 deletions
diff --git a/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java b/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
index 0c064884c..b71d5a023 100644
--- a/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
+++ b/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
@@ -16,6 +16,9 @@
package com.android.server.wifi;
+import android.annotation.Nullable;
+
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -44,7 +47,8 @@ public class DeletedEphemeralSsidsStoreData implements WifiConfigStore.StoreData
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (mSsidToTimeMap != null) {
XmlUtil.writeNextValue(out, XML_TAG_SSID_LIST, mSsidToTimeMap);
@@ -52,7 +56,9 @@ public class DeletedEphemeralSsidsStoreData implements WifiConfigStore.StoreData
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index f3c5d4b3d..4fbe31867 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -45,6 +45,11 @@ import com.android.server.wifi.util.WifiAsyncChannel;
*/
public class FrameworkFacade {
public static final String TAG = "FrameworkFacade";
+ /**
+ * NIAP global settings flag.
+ * Note: This should be added to {@link android.provider.Settings.Global}.
+ */
+ private static final String NIAP_MODE_SETTINGS_NAME = "niap_mode";
private ActivityManagerInternal mActivityManagerInternal;
@@ -83,6 +88,13 @@ public class FrameworkFacade {
}
/**
+ * Returns whether the device is in NIAP mode or not.
+ */
+ public boolean isNiapModeOn(Context context) {
+ return getIntegerSetting(context, NIAP_MODE_SETTINGS_NAME, 0) == 1;
+ }
+
+ /**
* Helper method for classes to register a ContentObserver
* {@see ContentResolver#registerContentObserver(Uri,boolean,ContentObserver)}.
*
diff --git a/service/java/com/android/server/wifi/NetworkListStoreData.java b/service/java/com/android/server/wifi/NetworkListStoreData.java
index 696647185..52e655b1e 100644
--- a/service/java/com/android/server/wifi/NetworkListStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkListStoreData.java
@@ -16,6 +16,9 @@
package com.android.server.wifi;
+import static com.android.server.wifi.WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION;
+
+import android.annotation.Nullable;
import android.content.Context;
import android.net.IpConfiguration;
import android.net.wifi.WifiConfiguration;
@@ -25,6 +28,7 @@ import android.os.Process;
import android.util.Log;
import android.util.Pair;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.IpConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
@@ -66,19 +70,22 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
- serializeNetworkList(out, mConfigurations);
+ serializeNetworkList(out, mConfigurations, encryptionUtil);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
return;
}
- mConfigurations = parseNetworkList(in, outerTagDepth);
+ mConfigurations = parseNetworkList(in, outerTagDepth, version, encryptionUtil);
}
@Override
@@ -118,33 +125,38 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
*
* @param out The output stream to serialize the data to
* @param networkList The network list to serialize
+ * @param encryptionUtil Instance of {@link WifiConfigStoreEncryptionUtil}
* @throws XmlPullParserException
* @throws IOException
*/
- private void serializeNetworkList(XmlSerializer out, List<WifiConfiguration> networkList)
+ private void serializeNetworkList(XmlSerializer out, List<WifiConfiguration> networkList,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (networkList == null) {
return;
}
for (WifiConfiguration network : networkList) {
- serializeNetwork(out, network);
+ serializeNetwork(out, network, encryptionUtil);
}
}
/**
* Serialize a {@link WifiConfiguration} to an output stream in XML format.
- * @param out
- * @param config
+ *
+ * @param out The output stream to serialize the data to
+ * @param config The network config to serialize
+ * @param encryptionUtil Instance of {@link WifiConfigStoreEncryptionUtil}
* @throws XmlPullParserException
* @throws IOException
*/
- private void serializeNetwork(XmlSerializer out, WifiConfiguration config)
+ private void serializeNetwork(XmlSerializer out, WifiConfiguration config,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK);
// Serialize WifiConfiguration.
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
- WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, config);
+ WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, config, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
// Serialize network selection status.
@@ -162,7 +174,7 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
&& config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
XmlUtil.writeNextSectionStart(
out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
- WifiEnterpriseConfigXmlUtil.writeToXml(out, config.enterpriseConfig);
+ WifiEnterpriseConfigXmlUtil.writeToXml(out, config.enterpriseConfig, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
}
@@ -174,11 +186,15 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
*
* @param in The input stream to read from
* @param outerTagDepth The XML tag depth of the outer XML block
+ * @param version Version of config store file.
+ * @param encryptionUtil Instance of {@link WifiConfigStoreEncryptionUtil}
* @return List of {@link WifiConfiguration}
* @throws XmlPullParserException
* @throws IOException
*/
- private List<WifiConfiguration> parseNetworkList(XmlPullParser in, int outerTagDepth)
+ private List<WifiConfiguration> parseNetworkList(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
List<WifiConfiguration> networkList = new ArrayList<>();
while (XmlUtil.gotoNextSectionWithNameOrEnd(in, XML_TAG_SECTION_HEADER_NETWORK,
@@ -186,7 +202,8 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
// Try/catch only runtime exceptions (like illegal args), any XML/IO exceptions are
// fatal and should abort the entire loading process.
try {
- WifiConfiguration config = parseNetwork(in, outerTagDepth + 1);
+ WifiConfiguration config =
+ parseNetwork(in, outerTagDepth + 1, version, encryptionUtil);
networkList.add(config);
} catch (RuntimeException e) {
// Failed to parse this network, skip it.
@@ -201,11 +218,15 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
*
* @param in The input stream to read from
* @param outerTagDepth The XML tag depth of the outer XML block
+ * @param version Version of config store file.
+ * @param encryptionUtil Instance of {@link WifiConfigStoreEncryptionUtil}
* @return {@link WifiConfiguration}
* @throws XmlPullParserException
* @throws IOException
*/
- private WifiConfiguration parseNetwork(XmlPullParser in, int outerTagDepth)
+ private WifiConfiguration parseNetwork(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
Pair<String, WifiConfiguration> parsedConfig = null;
NetworkSelectionStatus status = null;
@@ -220,7 +241,9 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
throw new XmlPullParserException("Detected duplicate tag for: "
+ XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
}
- parsedConfig = WifiConfigurationXmlUtil.parseFromXml(in, outerTagDepth + 1);
+ parsedConfig = WifiConfigurationXmlUtil.parseFromXml(in, outerTagDepth + 1,
+ version >= ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ encryptionUtil);
break;
case XML_TAG_SECTION_HEADER_NETWORK_STATUS:
if (status != null) {
@@ -242,7 +265,9 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
+ XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
}
enterpriseConfig =
- WifiEnterpriseConfigXmlUtil.parseFromXml(in, outerTagDepth + 1);
+ WifiEnterpriseConfigXmlUtil.parseFromXml(in, outerTagDepth + 1,
+ version >= ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ encryptionUtil);
break;
default:
throw new XmlPullParserException("Unknown tag under "
diff --git a/service/java/com/android/server/wifi/NetworkRequestStoreData.java b/service/java/com/android/server/wifi/NetworkRequestStoreData.java
index 8d1244f05..7457079ae 100644
--- a/service/java/com/android/server/wifi/NetworkRequestStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkRequestStoreData.java
@@ -16,10 +16,12 @@
package com.android.server.wifi;
+import android.annotation.Nullable;
import android.net.MacAddress;
import android.util.Log;
import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
@@ -87,13 +89,16 @@ public class NetworkRequestStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
serializeApprovedAccessPointsMap(out, mDataSource.toSerialize());
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
index 9627a9daa..e973bdbe2 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -16,6 +16,9 @@
package com.android.server.wifi;
+import static com.android.server.wifi.WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION;
+
+import android.annotation.Nullable;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSuggestion;
@@ -26,6 +29,7 @@ import android.util.Pair;
import com.android.internal.util.XmlUtils;
import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
@@ -98,19 +102,23 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
- serializeNetworkSuggestionsMap(out, mDataSource.toSerialize());
+ serializeNetworkSuggestionsMap(out, mDataSource.toSerialize(), encryptionUtil);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
return;
}
- mDataSource.fromDeserialized(parseNetworkSuggestionsMap(in, outerTagDepth));
+ mDataSource.fromDeserialized(
+ parseNetworkSuggestionsMap(in, outerTagDepth, version, encryptionUtil));
}
@Override
@@ -140,7 +148,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws IOException
*/
private void serializeNetworkSuggestionsMap(
- XmlSerializer out, final Map<String, PerAppInfo> networkSuggestionsMap)
+ XmlSerializer out, final Map<String, PerAppInfo> networkSuggestionsMap,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (networkSuggestionsMap == null) {
return;
@@ -155,7 +164,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_PACKAGE_NAME, packageName);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_HAS_USER_APPROVED, hasUserApproved);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_MAX_SIZE, maxSize);
- serializeExtNetworkSuggestions(out, networkSuggestions);
+ serializeExtNetworkSuggestions(out, networkSuggestions, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
}
}
@@ -167,10 +176,11 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws IOException
*/
private void serializeExtNetworkSuggestions(
- XmlSerializer out, final Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions)
+ XmlSerializer out, final Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
- serializeNetworkSuggestion(out, extNetworkSuggestion.wns);
+ serializeNetworkSuggestion(out, extNetworkSuggestion.wns, encryptionUtil);
}
}
@@ -181,13 +191,15 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws IOException
*/
private void serializeNetworkSuggestion(XmlSerializer out,
- final WifiNetworkSuggestion suggestion)
+ final WifiNetworkSuggestion suggestion,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION);
// Serialize WifiConfiguration.
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
- WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, suggestion.wifiConfiguration);
+ WifiConfigurationXmlUtil.writeToXmlForConfigStore(
+ out, suggestion.wifiConfiguration, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
// Serialize enterprise configuration for enterprise networks.
if (suggestion.wifiConfiguration.enterpriseConfig != null
@@ -196,7 +208,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
XmlUtil.writeNextSectionStart(
out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
XmlUtil.WifiEnterpriseConfigXmlUtil.writeToXml(
- out, suggestion.wifiConfiguration.enterpriseConfig);
+ out, suggestion.wifiConfiguration.enterpriseConfig, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
}
@@ -218,7 +230,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws XmlPullParserException
* @throws IOException
*/
- private Map<String, PerAppInfo> parseNetworkSuggestionsMap(XmlPullParser in, int outerTagDepth)
+ private Map<String, PerAppInfo> parseNetworkSuggestionsMap(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
Map<String, PerAppInfo> networkSuggestionsMap = new HashMap<>();
while (XmlUtil.gotoNextSectionWithNameOrEnd(
@@ -233,7 +247,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
int maxSize = (int) XmlUtil.readNextValueWithName(in, XML_TAG_SUGGESTOR_MAX_SIZE);
PerAppInfo perAppInfo = new PerAppInfo(packageName);
Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions =
- parseExtNetworkSuggestions(in, outerTagDepth + 1, perAppInfo);
+ parseExtNetworkSuggestions(
+ in, outerTagDepth + 1, version, encryptionUtil, perAppInfo);
perAppInfo.hasUserApproved = hasUserApproved;
perAppInfo.maxSize = maxSize;
perAppInfo.extNetworkSuggestions.addAll(extNetworkSuggestions);
@@ -253,7 +268,8 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws IOException
*/
private Set<ExtendedWifiNetworkSuggestion> parseExtNetworkSuggestions(
- XmlPullParser in, int outerTagDepth, PerAppInfo perAppInfo)
+ XmlPullParser in, int outerTagDepth, @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil, PerAppInfo perAppInfo)
throws XmlPullParserException, IOException {
Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions = new HashSet<>();
while (XmlUtil.gotoNextSectionWithNameOrEnd(
@@ -262,7 +278,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
// fatal and should abort the entire loading process.
try {
WifiNetworkSuggestion networkSuggestion =
- parseNetworkSuggestion(in, outerTagDepth + 1);
+ parseNetworkSuggestion(in, outerTagDepth + 1, version, encryptionUtil);
extNetworkSuggestions.add(ExtendedWifiNetworkSuggestion.fromWns(
networkSuggestion, perAppInfo));
} catch (RuntimeException e) {
@@ -279,7 +295,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
* @throws XmlPullParserException
* @throws IOException
*/
- private WifiNetworkSuggestion parseNetworkSuggestion(XmlPullParser in, int outerTagDepth)
+ private WifiNetworkSuggestion parseNetworkSuggestion(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
Pair<String, WifiConfiguration> parsedConfig = null;
WifiEnterpriseConfig enterpriseConfig = null;
@@ -324,7 +342,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
+ XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION);
}
parsedConfig = WifiConfigurationXmlUtil.parseFromXml(
- in, outerTagDepth + 1);
+ in, outerTagDepth + 1,
+ version >= ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ encryptionUtil);
break;
case XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION:
if (enterpriseConfig != null) {
@@ -332,7 +352,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
+ XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION);
}
enterpriseConfig = XmlUtil.WifiEnterpriseConfigXmlUtil.parseFromXml(
- in, outerTagDepth + 1);
+ in, outerTagDepth + 1,
+ version >= ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ encryptionUtil);
break;
default:
throw new XmlPullParserException("Unknown tag under "
diff --git a/service/java/com/android/server/wifi/RandomizedMacStoreData.java b/service/java/com/android/server/wifi/RandomizedMacStoreData.java
index 1e4d972ef..ecbd7177f 100644
--- a/service/java/com/android/server/wifi/RandomizedMacStoreData.java
+++ b/service/java/com/android/server/wifi/RandomizedMacStoreData.java
@@ -16,6 +16,9 @@
package com.android.server.wifi;
+import android.annotation.Nullable;
+
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -40,7 +43,8 @@ public class RandomizedMacStoreData implements WifiConfigStore.StoreData {
RandomizedMacStoreData() {}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (mMacMapping != null) {
XmlUtil.writeNextValue(out, XML_TAG_MAC_MAP, mMacMapping);
@@ -48,7 +52,9 @@ public class RandomizedMacStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/SsidSetStoreData.java b/service/java/com/android/server/wifi/SsidSetStoreData.java
index 7d1b99340..36b547cd2 100644
--- a/service/java/com/android/server/wifi/SsidSetStoreData.java
+++ b/service/java/com/android/server/wifi/SsidSetStoreData.java
@@ -16,8 +16,10 @@
package com.android.server.wifi;
+import android.annotation.Nullable;
import android.text.TextUtils;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -74,7 +76,8 @@ public class SsidSetStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
Set<String> ssidSet = mDataSource.getSsids();
if (ssidSet != null && !ssidSet.isEmpty()) {
@@ -83,7 +86,9 @@ public class SsidSetStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/WakeupConfigStoreData.java b/service/java/com/android/server/wifi/WakeupConfigStoreData.java
index d191ee3d6..847d8fbbc 100644
--- a/service/java/com/android/server/wifi/WakeupConfigStoreData.java
+++ b/service/java/com/android/server/wifi/WakeupConfigStoreData.java
@@ -16,10 +16,12 @@
package com.android.server.wifi;
+import android.annotation.Nullable;
import android.util.ArraySet;
import android.util.Log;
import com.android.server.wifi.WifiConfigStore.StoreData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -94,7 +96,8 @@ public class WakeupConfigStoreData implements StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
writeFeatureState(out);
@@ -141,7 +144,9 @@ public class WakeupConfigStoreData implements StoreData {
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (!mHasBeenRead) {
Log.d(TAG, "WifiWake user data has been read");
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index d1734d445..533155d0c 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -3131,7 +3131,8 @@ public class WifiConfigManager {
if (mDeferredUserUnlockRead) {
Log.i(TAG, "Handling user unlock before loading from store.");
List<WifiConfigStore.StoreFile> userStoreFiles =
- WifiConfigStore.createUserFiles(mCurrentUserId);
+ WifiConfigStore.createUserFiles(
+ mCurrentUserId, mFrameworkFacade.isNiapModeOn(mContext));
if (userStoreFiles == null) {
Log.wtf(TAG, "Failed to create user store files");
return false;
@@ -3170,7 +3171,8 @@ public class WifiConfigManager {
private boolean loadFromUserStoreAfterUnlockOrSwitch(int userId) {
try {
List<WifiConfigStore.StoreFile> userStoreFiles =
- WifiConfigStore.createUserFiles(userId);
+ WifiConfigStore.createUserFiles(
+ userId, mFrameworkFacade.isNiapModeOn(mContext));
if (userStoreFiles == null) {
Log.e(TAG, "Failed to create user store files");
return false;
@@ -3180,8 +3182,8 @@ public class WifiConfigManager {
Log.wtf(TAG, "Reading from new store failed. All saved private networks are lost!", e);
return false;
} catch (XmlPullParserException e) {
- Log.wtf(TAG, "XML deserialization of store failed. All saved private networks are" +
- "lost!", e);
+ Log.wtf(TAG, "XML deserialization of store failed. All saved private networks are "
+ + "lost!", e);
return false;
}
loadInternalDataFromUserStore(mNetworkListUserStoreData.getConfigurations(),
diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index e189d00e1..42d9f82cb 100644
--- a/service/java/com/android/server/wifi/WifiConfigStore.java
+++ b/service/java/com/android/server/wifi/WifiConfigStore.java
@@ -35,8 +35,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.AtomicFile;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
-import com.android.server.wifi.util.DataIntegrityChecker;
import com.android.server.wifi.util.EncryptedData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -53,7 +53,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
@@ -62,6 +61,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* This class provides a mechanism to save data to persistent store files {@link StoreFile}.
@@ -101,22 +101,36 @@ public class WifiConfigStore {
private static final String XML_TAG_DOCUMENT_HEADER = "WifiConfigStoreData";
private static final String XML_TAG_VERSION = "Version";
private static final String XML_TAG_HEADER_INTEGRITY = "Integrity";
- private static final String XML_TAG_INTEGRITY_ENCRYPTED_DATA = "EncryptedData";
- private static final String XML_TAG_INTEGRITY_IV = "IV";
/**
* Current config store data version. This will be incremented for any additions.
*/
- private static final int CURRENT_CONFIG_STORE_DATA_VERSION = 2;
+ private static final int CURRENT_CONFIG_STORE_DATA_VERSION = 3;
/** This list of older versions will be used to restore data from older config store. */
/**
* First version of the config store data format.
*/
- private static final int INITIAL_CONFIG_STORE_DATA_VERSION = 1;
+ public static final int INITIAL_CONFIG_STORE_DATA_VERSION = 1;
/**
* Second version of the config store data format, introduced:
* - Integrity info.
*/
- private static final int INTEGRITY_CONFIG_STORE_DATA_VERSION = 2;
+ public static final int INTEGRITY_CONFIG_STORE_DATA_VERSION = 2;
+ /**
+ * Third version of the config store data format,
+ * introduced:
+ * - Encryption of credentials
+ * removed:
+ * - Integrity info.
+ */
+ public static final int ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION = 3;
+
+ @IntDef(suffix = { "_VERSION" }, value = {
+ INITIAL_CONFIG_STORE_DATA_VERSION,
+ INTEGRITY_CONFIG_STORE_DATA_VERSION,
+ ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Version { }
/**
* Alarm tag to use for starting alarms for buffering file writes.
@@ -157,12 +171,6 @@ public class WifiConfigStore {
put(STORE_FILE_USER_GENERAL, STORE_FILE_NAME_USER_GENERAL);
put(STORE_FILE_USER_NETWORK_SUGGESTIONS, STORE_FILE_NAME_USER_NETWORK_SUGGESTIONS);
}};
-
- @VisibleForTesting
- public static final EncryptedData ZEROED_ENCRYPTED_DATA =
- new EncryptedData(
- new byte[EncryptedData.ENCRYPTED_DATA_LENGTH],
- new byte[EncryptedData.IV_LENGTH]);
/**
* Handler instance to post alarm timeouts to
*/
@@ -280,9 +288,11 @@ public class WifiConfigStore {
* @param storeBaseDir Base directory under which the store file is to be stored. The store file
* will be at <storeBaseDir>/wifi/WifiConfigStore.xml.
* @param fileId Identifier for the file. See {@link StoreFileId}.
+ * @param shouldEncryptCredentials Whether to encrypt credentials or not.
* @return new instance of the store file or null if the directory cannot be created.
*/
- private static @Nullable StoreFile createFile(File storeBaseDir, @StoreFileId int fileId) {
+ private static @Nullable StoreFile createFile(File storeBaseDir, @StoreFileId int fileId,
+ boolean shouldEncryptCredentials) {
File storeDir = new File(storeBaseDir, STORE_DIRECTORY_NAME);
if (!storeDir.exists()) {
if (!storeDir.mkdir()) {
@@ -291,17 +301,22 @@ public class WifiConfigStore {
}
}
File file = new File(storeDir, STORE_ID_TO_FILE_NAME.get(fileId));
- DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(file.getName());
- return new StoreFile(file, fileId, dataIntegrityChecker);
+ WifiConfigStoreEncryptionUtil encryptionUtil = null;
+ if (shouldEncryptCredentials) {
+ encryptionUtil = new WifiConfigStoreEncryptionUtil(file.getName());
+ }
+ return new StoreFile(file, fileId, encryptionUtil);
}
/**
* Create a new instance of the shared store file.
*
+ * @param shouldEncryptCredentials Whether to encrypt credentials or not.
* @return new instance of the store file or null if the directory cannot be created.
*/
- public static @Nullable StoreFile createSharedFile() {
- return createFile(Environment.getDataMiscDirectory(), STORE_FILE_SHARED_GENERAL);
+ public static @Nullable StoreFile createSharedFile(boolean shouldEncryptCredentials) {
+ return createFile(Environment.getDataMiscDirectory(), STORE_FILE_SHARED_GENERAL,
+ shouldEncryptCredentials);
}
/**
@@ -309,14 +324,18 @@ public class WifiConfigStore {
* The user store file is inside the user's encrypted data directory.
*
* @param userId userId corresponding to the currently logged-in user.
+ * @param shouldEncryptCredentials Whether to encrypt credentials or not.
* @return List of new instances of the store files created or null if the directory cannot be
* created.
*/
- public static @Nullable List<StoreFile> createUserFiles(int userId) {
+ public static @Nullable List<StoreFile> createUserFiles(int userId,
+ boolean shouldEncryptCredentials) {
List<StoreFile> storeFiles = new ArrayList<>();
for (int fileId : Arrays.asList(
STORE_FILE_USER_GENERAL, STORE_FILE_USER_NETWORK_SUGGESTIONS)) {
- StoreFile storeFile = createFile(Environment.getDataMiscCeDirectory(userId), fileId);
+ StoreFile storeFile =
+ createFile(Environment.getDataMiscCeDirectory(userId), fileId,
+ shouldEncryptCredentials);
if (storeFile == null) {
return null;
}
@@ -427,88 +446,18 @@ public class WifiConfigStore {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- // To compute integrity, write zeroes in the integrity fields. Once the integrity is
- // computed, go back and modfiy the XML fields in place with the computed values.
- writeDocumentMetadata(out, ZEROED_ENCRYPTED_DATA);
+ // First XML header.
+ XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
+ // Next version.
+ XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_CONFIG_STORE_DATA_VERSION);
for (StoreData storeData : storeDataList) {
String tag = storeData.getName();
XmlUtil.writeNextSectionStart(out, tag);
- storeData.serializeData(out);
+ storeData.serializeData(out, storeFile.getEncryptionUtil());
XmlUtil.writeNextSectionEnd(out, tag);
}
XmlUtil.writeDocumentEnd(out, XML_TAG_DOCUMENT_HEADER);
-
- byte[] outBytes = outputStream.toByteArray();
- EncryptedData encryptedData = storeFile.computeIntegrity(outBytes);
- if (encryptedData == null) {
- // should never happen, this is a fatal failure. Abort file write.
- Log.wtf(TAG, "Failed to compute integrity, failing write");
- return null;
- }
- return rewriteDocumentMetadataRawBytes(outBytes, encryptedData);
- }
-
- /**
- * Helper method to write the metadata at the start of every config store file.
- * The metadata consists of:
- * a) Version
- * b) Integrity data computed on the data contents.
- */
- private void writeDocumentMetadata(XmlSerializer out, EncryptedData encryptedData)
- throws XmlPullParserException, IOException {
- // First XML header.
- XmlUtil.writeDocumentStart(out, XML_TAG_DOCUMENT_HEADER);
- // Next version.
- XmlUtil.writeNextValue(out, XML_TAG_VERSION, CURRENT_CONFIG_STORE_DATA_VERSION);
-
- // Next integrity data.
- XmlUtil.writeNextSectionStart(out, XML_TAG_HEADER_INTEGRITY);
- XmlUtil.writeNextValue(out, XML_TAG_INTEGRITY_ENCRYPTED_DATA,
- encryptedData.getEncryptedData());
- XmlUtil.writeNextValue(out, XML_TAG_INTEGRITY_IV, encryptedData.getIv());
- XmlUtil.writeNextSectionEnd(out, XML_TAG_HEADER_INTEGRITY);
- }
-
- /**
- * Helper method to generate the raw bytes containing the the metadata at the start of every
- * config store file.
- *
- * NOTE: This does not create a fully formed XML document (the start tag is not closed for
- * example). This only creates the top portion of the XML which contains the modified
- * integrity data & version along with the XML prolog (metadata):
- * <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
- * <WifiConfigStoreData>
- * <int name="Version" value="2" />
- * <Integrity>
- * <byte-array name="EncryptedData" num="48">!EncryptedData!</byte-array>
- * <byte-array name="IV" num="12">!IV!</byte-array>
- * </Integrity>
- */
- private byte[] generateDocumentMetadataRawBytes(EncryptedData encryptedData)
- throws XmlPullParserException, IOException {
- final XmlSerializer outXml = new FastXmlSerializer();
- final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
- outXml.setOutput(outStream, StandardCharsets.UTF_8.name());
- writeDocumentMetadata(outXml, encryptedData);
- outXml.endDocument();
- return outStream.toByteArray();
- }
-
- /**
- * Helper method to rewrite the existing document metadata in the incoming raw bytes in
- * |inBytes| with the new document metadata created with the provided |encryptedData|.
- *
- * NOTE: This assumes that the metadata in existing XML inside |inBytes| aligns exactly
- * with the new metadata created. So, a simple in place rewrite of the first few bytes (
- * corresponding to metadata section of the document) from |inBytes| will preserve the overall
- * document structure.
- */
- private byte[] rewriteDocumentMetadataRawBytes(byte[] inBytes, EncryptedData encryptedData)
- throws XmlPullParserException, IOException {
- byte[] replaceMetadataBytes = generateDocumentMetadataRawBytes(encryptedData);
- ByteBuffer outByteBuffer = ByteBuffer.wrap(inBytes);
- outByteBuffer.put(replaceMetadataBytes);
- return outByteBuffer.array();
+ return outputStream.toByteArray();
}
/**
@@ -629,10 +578,11 @@ public class WifiConfigStore {
}
// Inform all the provided store data clients that there is nothing in the store for them.
- private void indicateNoDataForStoreDatas(Collection<StoreData> storeDataSet)
+ private void indicateNoDataForStoreDatas(Collection<StoreData> storeDataSet,
+ @Version int version, @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
for (StoreData storeData : storeDataSet) {
- storeData.deserializeData(null, 0);
+ storeData.deserializeData(null, 0, version, encryptionUtil);
}
}
@@ -654,7 +604,8 @@ public class WifiConfigStore {
throws XmlPullParserException, IOException {
List<StoreData> storeDataList = retrieveStoreDataListForStoreFile(storeFile);
if (dataBytes == null) {
- indicateNoDataForStoreDatas(storeDataList);
+ indicateNoDataForStoreDatas(storeDataList, -1 /* unknown */,
+ storeFile.getEncryptionUtil());
return;
}
final XmlPullParser in = Xml.newPullParser();
@@ -665,21 +616,10 @@ public class WifiConfigStore {
int rootTagDepth = in.getDepth() + 1;
XmlUtil.gotoDocumentStart(in, XML_TAG_DOCUMENT_HEADER);
- int version = parseVersionFromXml(in);
- // Version 2 onwards contains integrity data, so check the integrity of the file.
- if (version >= INTEGRITY_CONFIG_STORE_DATA_VERSION) {
- EncryptedData integrityData = parseIntegrityDataFromXml(in, rootTagDepth);
- // To compute integrity, write zeroes in the integrity fields.
- dataBytes = rewriteDocumentMetadataRawBytes(dataBytes, ZEROED_ENCRYPTED_DATA);
- if (!storeFile.checkIntegrity(dataBytes, integrityData)) {
- Log.wtf(TAG, "Integrity mismatch, discarding data from " + storeFile.mFileName);
- return;
- }
- } else {
- // When integrity checking is introduced. The existing data will have no related
- // integrity file for validation. Thus, we will assume the existing data is correct.
- // Integrity will be computed for the next write.
- Log.d(TAG, "No integrity data to check; thus vacously true");
+ @Version int version = parseVersionFromXml(in);
+ // Version 2 contains the now unused integrity data, parse & then discard the information.
+ if (version == INTEGRITY_CONFIG_STORE_DATA_VERSION) {
+ parseAndDiscardIntegrityDataFromXml(in, rootTagDepth);
}
String[] headerName = new String[1];
@@ -695,14 +635,15 @@ public class WifiConfigStore {
throw new XmlPullParserException("Unknown store data: " + headerName[0]
+ ". List of store data: " + storeDataList);
}
- storeData.deserializeData(in, rootTagDepth + 1);
+ storeData.deserializeData(in, rootTagDepth + 1, version,
+ storeFile.getEncryptionUtil());
storeDatasInvoked.add(storeData);
}
// Inform all the other registered store data clients that there is nothing in the store
// for them.
Set<StoreData> storeDatasNotInvoked = new HashSet<>(storeDataList);
storeDatasNotInvoked.removeAll(storeDatasInvoked);
- indicateNoDataForStoreDatas(storeDatasNotInvoked);
+ indicateNoDataForStoreDatas(storeDatasNotInvoked, version, storeFile.getEncryptionUtil());
}
/**
@@ -712,7 +653,7 @@ public class WifiConfigStore {
* @param in XmlPullParser instance pointing to the XML stream.
* @return version number retrieved from the Xml stream.
*/
- private static int parseVersionFromXml(XmlPullParser in)
+ private static @Version int parseVersionFromXml(XmlPullParser in)
throws XmlPullParserException, IOException {
int version = (int) XmlUtil.readNextValueWithName(in, XML_TAG_VERSION);
if (version < INITIAL_CONFIG_STORE_DATA_VERSION
@@ -723,22 +664,15 @@ public class WifiConfigStore {
}
/**
- * Parse the integrity data structure from the XML stream.
- * This is used for both the shared and user config store data.
+ * Parse the integrity data structure from the XML stream and discard it.
*
* @param in XmlPullParser instance pointing to the XML stream.
* @param outerTagDepth Outer tag depth.
- * @return Instance of {@link EncryptedData} retrieved from the Xml stream.
*/
- private static @NonNull EncryptedData parseIntegrityDataFromXml(
- XmlPullParser in, int outerTagDepth)
+ private static void parseAndDiscardIntegrityDataFromXml(XmlPullParser in, int outerTagDepth)
throws XmlPullParserException, IOException {
XmlUtil.gotoNextSectionWithName(in, XML_TAG_HEADER_INTEGRITY, outerTagDepth);
- byte[] encryptedData =
- (byte[]) XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_ENCRYPTED_DATA);
- byte[] iv =
- (byte[]) XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_IV);
- return new EncryptedData(encryptedData, iv);
+ XmlUtil.EncryptedDataXmlUtil.parseFromXml(in, outerTagDepth + 1);
}
/**
@@ -746,6 +680,13 @@ public class WifiConfigStore {
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Dump of WifiConfigStore");
+ pw.println("WifiConfigStore - Store File Begin ----");
+ Stream.of(Arrays.asList(mSharedStore), mUserStores)
+ .flatMap(List::stream)
+ .forEach((storeFile) -> {
+ pw.print("Name: " + storeFile.mFileName);
+ pw.println(", Credentials encrypted: " + storeFile.getEncryptionUtil() != null);
+ });
pw.println("WifiConfigStore - Store Data Begin ----");
for (StoreData storeData : mStoreDataList) {
pw.print("StoreData =>");
@@ -790,14 +731,14 @@ public class WifiConfigStore {
/**
* Integrity checking for the store file.
*/
- private final DataIntegrityChecker mDataIntegrityChecker;
+ private final WifiConfigStoreEncryptionUtil mEncryptionUtil;
public StoreFile(File file, @StoreFileId int fileId,
- @NonNull DataIntegrityChecker dataIntegrityChecker) {
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil) {
mAtomicFile = new AtomicFile(file);
mFileName = file.getAbsolutePath();
mFileId = fileId;
- mDataIntegrityChecker = dataIntegrityChecker;
+ mEncryptionUtil = encryptionUtil;
}
/**
@@ -810,6 +751,13 @@ public class WifiConfigStore {
}
/**
+ * @return Returns the encryption util used for this store file.
+ */
+ public @Nullable WifiConfigStoreEncryptionUtil getEncryptionUtil() {
+ return mEncryptionUtil;
+ }
+
+ /**
* Read the entire raw data from the store file and return in a byte array.
*
* @return raw data read from the file or null if the file is not found or the data has
@@ -862,33 +810,6 @@ public class WifiConfigStore {
// Reset the pending write data after write.
mWriteData = null;
}
-
- /**
- * Compute integrity of |dataWithZeroedIntegrityFields| to be written to the file.
- *
- * @param dataWithZeroedIntegrityFields raw data to be written to the file with the
- * integrity fields zeroed out for integrity
- * calculation.
- * @return Instance of {@link EncryptedData} holding the encrypted integrity data for the
- * raw data to be written to the file.
- */
- public EncryptedData computeIntegrity(byte[] dataWithZeroedIntegrityFields) {
- return mDataIntegrityChecker.compute(dataWithZeroedIntegrityFields);
- }
-
- /**
- * Check integrity of |dataWithZeroedIntegrityFields| read from the file with the integrity
- * data parsed from the file.
- * @param dataWithZeroedIntegrityFields raw data read from the file with the integrity
- * fields zeroed out for integrity calculation.
- * @param parsedEncryptedData Instance of {@link EncryptedData} parsed from the integrity
- * fields in the raw data.
- * @return true if the integrity matches, false otherwise.
- */
- public boolean checkIntegrity(byte[] dataWithZeroedIntegrityFields,
- EncryptedData parsedEncryptedData) {
- return mDataIntegrityChecker.isOk(dataWithZeroedIntegrityFields, parsedEncryptedData);
- }
}
/**
@@ -908,8 +829,10 @@ public class WifiConfigStore {
* Serialize a XML data block to the output stream.
*
* @param out The output stream to serialize the data to
+ * @param encryptionUtil Utility to help encrypt any credential data.
*/
- void serializeData(XmlSerializer out)
+ void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException;
/**
@@ -918,10 +841,14 @@ public class WifiConfigStore {
* @param in The input stream to read the data from. This could be null if there is
* nothing in the store.
* @param outerTagDepth The depth of the outer tag in the XML document
+ * @param version Version of config store file.
+ * @param encryptionUtil Utility to help decrypt any credential data.
+ *
* Note: This will be invoked every time a store file is read, even if there is nothing
* in the store for them.
*/
- void deserializeData(@Nullable XmlPullParser in, int outerTagDepth)
+ void deserializeData(@Nullable XmlPullParser in, int outerTagDepth, @Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException;
/**
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index fe9ebea17..f7212ddfc 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -241,7 +241,7 @@ public class WifiInjector {
mWifiKeyStore = new WifiKeyStore(mKeyStore);
mWifiConfigStore = new WifiConfigStore(
mContext, clientModeImplLooper, mClock, mWifiMetrics,
- WifiConfigStore.createSharedFile());
+ WifiConfigStore.createSharedFile(mFrameworkFacade.isNiapModeOn(mContext)));
SubscriptionManager subscriptionManager =
mContext.getSystemService(SubscriptionManager.class);
// Config Manager
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
index 419ea7993..7f5a6b408 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
@@ -16,7 +16,10 @@
package com.android.server.wifi.hotspot2;
+import android.annotation.Nullable;
+
import com.android.server.wifi.WifiConfigStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -72,13 +75,16 @@ public class PasspointConfigSharedStoreData implements WifiConfigStore.StoreData
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
serializeShareData(out);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
index 0114cfb21..123cf8982 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointConfigUserStoreData.java
@@ -16,6 +16,7 @@
package com.android.server.wifi.hotspot2;
+import android.annotation.Nullable;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.text.TextUtils;
@@ -23,6 +24,7 @@ import com.android.internal.util.XmlUtils;
import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import org.xmlpull.v1.XmlPullParser;
@@ -103,13 +105,16 @@ public class PasspointConfigUserStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
serializeUserData(out);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/util/EncryptedData.java b/service/java/com/android/server/wifi/util/EncryptedData.java
index 91342d335..baec20426 100644
--- a/service/java/com/android/server/wifi/util/EncryptedData.java
+++ b/service/java/com/android/server/wifi/util/EncryptedData.java
@@ -18,21 +18,19 @@ package com.android.server.wifi.util;
import com.android.internal.util.Preconditions;
+import java.util.Arrays;
+import java.util.Objects;
+
/**
- * A class to store data created by {@link DataIntegrityChecker}.
+ * A class to store data created by {@link WifiConfigStoreEncryptionUtil}.
*/
public class EncryptedData {
- public static final int ENCRYPTED_DATA_LENGTH = 48;
- public static final int IV_LENGTH = 12;
-
private final byte[] mEncryptedData;
private final byte[] mIv;
public EncryptedData(byte[] encryptedData, byte[] iv) {
- Preconditions.checkNotNull(encryptedData, iv);
- Preconditions.checkState(encryptedData.length == ENCRYPTED_DATA_LENGTH,
- "encryptedData.length=" + encryptedData.length);
- Preconditions.checkState(iv.length == IV_LENGTH, "iv.length=" + iv.length);
+ Preconditions.checkNotNull(encryptedData);
+ Preconditions.checkNotNull(iv);
mEncryptedData = encryptedData;
mIv = iv;
}
@@ -44,4 +42,17 @@ public class EncryptedData {
public byte[] getIv() {
return mIv;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof EncryptedData)) return false;
+ EncryptedData otherEncryptedData = (EncryptedData) other;
+ return Arrays.equals(this.mEncryptedData, otherEncryptedData.mEncryptedData)
+ && Arrays.equals(this.mIv, otherEncryptedData.mIv);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(Arrays.hashCode(mEncryptedData), Arrays.hashCode(mIv));
+ }
}
diff --git a/service/java/com/android/server/wifi/util/DataIntegrityChecker.java b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
index 6f03a4861..2f9b08f2b 100644
--- a/service/java/com/android/server/wifi/util/DataIntegrityChecker.java
+++ b/service/java/com/android/server/wifi/util/WifiConfigStoreEncryptionUtil.java
@@ -17,22 +17,22 @@
package com.android.server.wifi.util;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Process;
import android.os.SystemProperties;
+import android.security.keystore.AndroidKeyStoreProvider;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import android.util.Log;
-import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
-import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableEntryException;
-import java.security.cert.CertificateException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
@@ -43,34 +43,26 @@ import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
/**
- * Tools to provide integrity checking of byte arrays based on NIAP Common Criteria Protection
- * Profile <a href="https://www.niap-ccevs.org/MMO/PP/-417-/#FCS_STG_EXT.3.1">FCS_STG_EXT.3.1</a>.
+ * Tools to help encrypt/decrypt
*/
-public class DataIntegrityChecker {
- private static final String TAG = "DataIntegrityChecker";
+public class WifiConfigStoreEncryptionUtil {
+ private static final String TAG = "WifiConfigStoreEncryptionUtil";
- private static final String ALIAS_SUFFIX = ".data-integrity-checker-key";
+ private static final String ALIAS_SUFFIX = ".data-encryption-key";
private static final String CIPHER_ALGORITHM = "AES/GCM/NoPadding";
- private static final String DIGEST_ALGORITHM = "SHA-256";
private static final int GCM_TAG_LENGTH = 128;
private static final String KEY_STORE = "AndroidKeyStore";
- /**
- * When KEYSTORE_FAILURE_RETURN_VALUE is true, all cryptographic operation failures will not
- * enforce security and {@link #isOk(byte[], EncryptedData)} always return true.
- */
- private static final boolean KEYSTORE_FAILURE_RETURN_VALUE = true;
-
private final String mDataFileName;
/**
- * Construct a new integrity checker to update and check if/when a data file was altered
- * outside expected conditions.
+ * Construct a new util to help {@link com.android.server.wifi.WifiConfigStore.StoreData}
+ * modules to encrypt/decrypt credential data written/read from this config store file.
*
- * @param dataFileName The full path of the data file for which integrity check is performed.
+ * @param dataFileName The full path of the data file.
* @throws NullPointerException When data file is empty string.
*/
- public DataIntegrityChecker(@NonNull String dataFileName) {
+ public WifiConfigStoreEncryptionUtil(@NonNull String dataFileName) {
if (TextUtils.isEmpty(dataFileName)) {
throw new NullPointerException("dataFileName must not be null or the empty "
+ "string");
@@ -83,80 +75,16 @@ public class DataIntegrityChecker {
}
/**
- * Computes a digest of a byte array, encrypt it, and store the result
- *
- * Call this method immediately before storing the byte array
- *
- * @param data The data desired to ensure integrity
- * @return Instance of {@link EncryptedData} containing the encrypted integrity data.
- */
- public EncryptedData compute(byte[] data) {
- if (data == null || data.length < 1) {
- reportException(new Exception("No data to compute"), "No data to compute.");
- return null;
- }
- byte[] digest = getDigest(data);
- if (digest == null || digest.length < 1) {
- reportException(new Exception("digest null in compute"),
- "digest null in compute");
- return null;
- }
- EncryptedData integrityData = encrypt(digest, getKeyAlias());
- if (integrityData == null) {
- reportException(new Exception("integrityData null in compute"),
- "integrityData null in compute");
- }
- return integrityData;
- }
-
-
- /**
- * Check the integrity of a given byte array
- *
- * Call this method immediately before trusting the byte array. This method will return false
- * when the integrity data calculated on the byte array does not match the encrypted integrity
- * data provided to compare or if there is an underlying issue with the cryptographic functions
- * or the key store.
+ * Encrypt the provided data blob.
*
- * @param data The data to check if its been altered.
- * @param integrityData Encrypted integrity data to be used for comparison.
- * @return true if the integrity data computed on |data| matches the provided |integrityData|.
+ * @param data Data blob to be encrypted.
+ * @return Instance of {@link EncryptedData} containing the encrypted info.
*/
- public boolean isOk(@NonNull byte[] data, @NonNull EncryptedData integrityData) {
- if (data == null || data.length < 1) {
- return KEYSTORE_FAILURE_RETURN_VALUE;
- }
- byte[] currentDigest = getDigest(data);
- if (currentDigest == null || currentDigest.length < 1) {
- reportException(new Exception("current digest null"), "current digest null");
- return KEYSTORE_FAILURE_RETURN_VALUE;
- }
- if (integrityData == null) {
- reportException(new Exception("integrityData null in isOk"),
- "integrityData null in isOk");
- return KEYSTORE_FAILURE_RETURN_VALUE;
- }
- byte[] storedDigest = decrypt(integrityData, getKeyAlias());
- if (storedDigest == null) {
- return KEYSTORE_FAILURE_RETURN_VALUE;
- }
- return constantTimeEquals(storedDigest, currentDigest);
- }
-
- private byte[] getDigest(byte[] data) {
- try {
- return MessageDigest.getInstance(DIGEST_ALGORITHM).digest(data);
- } catch (NoSuchAlgorithmException e) {
- reportException(e, "getDigest could not find algorithm: " + DIGEST_ALGORITHM);
- return null;
- }
- }
-
- private EncryptedData encrypt(byte[] data, String keyAlias) {
+ public @Nullable EncryptedData encrypt(byte[] data) {
EncryptedData encryptedData = null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
- SecretKey secretKeyReference = getOrCreateSecretKey(keyAlias);
+ SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
if (secretKeyReference != null) {
cipher.init(Cipher.ENCRYPT_MODE, secretKeyReference);
encryptedData = new EncryptedData(cipher.doFinal(data), cipher.getIV());
@@ -178,12 +106,18 @@ public class DataIntegrityChecker {
return encryptedData;
}
- private byte[] decrypt(EncryptedData encryptedData, String keyAlias) {
+ /**
+ * Decrypt the original data blob from the provided {@link EncryptedData}.
+ *
+ * @param encryptedData Instance of {@link EncryptedData} containing the encrypted info.
+ * @return Original data blob that was encrypted.
+ */
+ public @Nullable byte[] decrypt(@NonNull EncryptedData encryptedData) {
byte[] decryptedData = null;
try {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, encryptedData.getIv());
- SecretKey secretKeyReference = getOrCreateSecretKey(keyAlias);
+ SecretKey secretKeyReference = getOrCreateSecretKey(getKeyAlias());
if (secretKeyReference != null) {
cipher.init(Cipher.DECRYPT_MODE, secretKeyReference, spec);
decryptedData = cipher.doFinal(encryptedData.getEncryptedData());
@@ -207,8 +141,7 @@ public class DataIntegrityChecker {
private SecretKey getOrCreateSecretKey(String keyAlias) {
SecretKey secretKey = null;
try {
- KeyStore keyStore = KeyStore.getInstance(KEY_STORE);
- keyStore.load(null);
+ KeyStore keyStore = AndroidKeyStoreProvider.getKeyStoreForUid(Process.WIFI_UID);
if (keyStore.containsAlias(keyAlias)) { // The key exists in key store. Get the key.
KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
.getEntry(keyAlias, null);
@@ -227,17 +160,14 @@ public class DataIntegrityChecker {
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setUid(Process.WIFI_UID)
.build();
keyGenerator.init(keyGenParameterSpec);
secretKey = keyGenerator.generateKey();
}
- } catch (CertificateException e) {
- reportException(e, "getOrCreateSecretKey had a certificate exception.");
} catch (InvalidAlgorithmParameterException e) {
reportException(e, "getOrCreateSecretKey had an invalid algorithm parameter");
- } catch (IOException e) {
- reportException(e, "getOrCreateSecretKey had an IO exception.");
} catch (KeyStoreException e) {
reportException(e, "getOrCreateSecretKey cannot find the keystore: " + KEY_STORE);
} catch (NoSuchAlgorithmException e) {
@@ -250,22 +180,6 @@ public class DataIntegrityChecker {
return secretKey;
}
- private boolean constantTimeEquals(byte[] a, byte[] b) {
- if (a == null && b == null) {
- return true;
- }
-
- if (a == null || b == null || a.length != b.length) {
- return false;
- }
-
- byte differenceAccumulator = 0;
- for (int i = 0; i < a.length; ++i) {
- differenceAccumulator |= a[i] ^ b[i];
- }
- return (differenceAccumulator == 0);
- }
-
/* TODO(b/128526030): Remove this error reporting code upon resolving the bug. */
private static final boolean REQUEST_BUG_REPORT = false;
private void reportException(Exception exception, String error) {
@@ -275,4 +189,5 @@ public class DataIntegrityChecker {
SystemProperties.set("ctl.start", "bugreport");
}
}
+
}
diff --git a/service/java/com/android/server/wifi/util/XmlUtil.java b/service/java/com/android/server/wifi/util/XmlUtil.java
index 188d3b5c7..db0f4289b 100644
--- a/service/java/com/android/server/wifi/util/XmlUtil.java
+++ b/service/java/com/android/server/wifi/util/XmlUtil.java
@@ -16,6 +16,7 @@
package com.android.server.wifi.util;
+import android.annotation.Nullable;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
@@ -28,6 +29,7 @@ import android.net.StaticIpConfiguration;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiEnterpriseConfig;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -377,19 +379,51 @@ public class XmlUtil {
}
/**
+ * Write preshared key to the XML stream.
+ *
+ * If encryptionUtil is null or if encryption fails for some reason, the pre-shared
+ * key is stored in plaintext, else the encrypted psk is stored.
+ */
+ private static void writePreSharedKeyToXml(
+ XmlSerializer out, String preSharedKey,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
+ throws XmlPullParserException, IOException {
+ EncryptedData encryptedData = null;
+ if (encryptionUtil != null) {
+ if (preSharedKey != null) {
+ encryptedData = encryptionUtil.encrypt(preSharedKey.getBytes());
+ if (encryptedData == null) {
+ // We silently fail encryption failures!
+ Log.wtf(TAG, "Encryption of preSharedKey failed");
+ }
+ }
+ }
+ if (encryptedData != null) {
+ XmlUtil.writeNextSectionStart(out, XML_TAG_PRE_SHARED_KEY);
+ EncryptedDataXmlUtil.writeToXml(out, encryptedData);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_PRE_SHARED_KEY);
+ } else {
+ XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, preSharedKey);
+ }
+ }
+
+ /**
* Write the Configuration data elements that are common for backup & config store to the
* XML stream.
*
- * @param out XmlSerializer instance pointing to the XML stream.
+ * @param out XmlSerializer instance pointing to the XML stream.
* @param configuration WifiConfiguration object to be serialized.
+ * @param encryptionUtil Instance of {@link EncryptedDataXmlUtil}. Backup/restore stores
+ * keys unencrypted.
*/
public static void writeCommonElementsToXml(
- XmlSerializer out, WifiConfiguration configuration)
+ XmlSerializer out, WifiConfiguration configuration,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextValue(out, XML_TAG_CONFIG_KEY, configuration.configKey());
XmlUtil.writeNextValue(out, XML_TAG_SSID, configuration.SSID);
XmlUtil.writeNextValue(out, XML_TAG_BSSID, configuration.BSSID);
- XmlUtil.writeNextValue(out, XML_TAG_PRE_SHARED_KEY, configuration.preSharedKey);
+ writePreSharedKeyToXml(out, configuration.preSharedKey, encryptionUtil);
writeWepKeysToXml(out, configuration.wepKeys);
XmlUtil.writeNextValue(out, XML_TAG_WEP_TX_KEY_INDEX, configuration.wepTxKeyIndex);
XmlUtil.writeNextValue(out, XML_TAG_HIDDEN_SSID, configuration.hiddenSSID);
@@ -428,7 +462,7 @@ public class XmlUtil {
*/
public static void writeToXmlForBackup(XmlSerializer out, WifiConfiguration configuration)
throws XmlPullParserException, IOException {
- writeCommonElementsToXml(out, configuration);
+ writeCommonElementsToXml(out, configuration, null);
XmlUtil.writeNextValue(out, XML_TAG_METERED_OVERRIDE, configuration.meteredOverride);
}
@@ -436,13 +470,15 @@ public class XmlUtil {
* Write the Configuration data elements for config store from the provided Configuration
* to the XML stream.
*
- * @param out XmlSerializer instance pointing to the XML stream.
+ * @param out XmlSerializer instance pointing to the XML stream.
* @param configuration WifiConfiguration object to be serialized.
+ * @param encryptionUtil Instance of {@link EncryptedDataXmlUtil}.
*/
public static void writeToXmlForConfigStore(
- XmlSerializer out, WifiConfiguration configuration)
+ XmlSerializer out, WifiConfiguration configuration,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
- writeCommonElementsToXml(out, configuration);
+ writeCommonElementsToXml(out, configuration, encryptionUtil);
XmlUtil.writeNextValue(out, XML_TAG_STATUS, configuration.status);
XmlUtil.writeNextValue(out, XML_TAG_FQDN, configuration.FQDN);
XmlUtil.writeNextValue(
@@ -509,13 +545,16 @@ public class XmlUtil {
* Note: This is used for parsing both backup data and config store data. Looping through
* the tags make it easy to add or remove elements in the future versions if needed.
*
- * @param in XmlPullParser instance pointing to the XML stream.
+ * @param in XmlPullParser instance pointing to the XML stream.
* @param outerTagDepth depth of the outer tag in the XML document.
+ * @param shouldExpectEncryptedCredentials Whether to expect encrypted credentials or not.
+ * @param encryptionUtil Instance of {@link EncryptedDataXmlUtil}.
* @return Pair<Config key, WifiConfiguration object> if parsing is successful,
* null otherwise.
*/
public static Pair<String, WifiConfiguration> parseFromXml(
- XmlPullParser in, int outerTagDepth)
+ XmlPullParser in, int outerTagDepth, boolean shouldExpectEncryptedCredentials,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
WifiConfiguration configuration = new WifiConfiguration();
String configKeyInData = null;
@@ -523,147 +562,175 @@ public class XmlUtil {
// Loop through and parse out all the elements from the stream within this section.
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
- String[] valueName = new String[1];
- Object value = XmlUtil.readCurrentValue(in, valueName);
- if (valueName[0] == null) {
- throw new XmlPullParserException("Missing value name");
- }
- switch (valueName[0]) {
- case XML_TAG_CONFIG_KEY:
- configKeyInData = (String) value;
- break;
- case XML_TAG_SSID:
- configuration.SSID = (String) value;
- break;
- case XML_TAG_BSSID:
- configuration.BSSID = (String) value;
- break;
- case XML_TAG_PRE_SHARED_KEY:
- configuration.preSharedKey = (String) value;
- break;
- case XML_TAG_WEP_KEYS:
- populateWepKeysFromXmlValue(value, configuration.wepKeys);
- break;
- case XML_TAG_WEP_TX_KEY_INDEX:
- configuration.wepTxKeyIndex = (int) value;
- break;
- case XML_TAG_HIDDEN_SSID:
- configuration.hiddenSSID = (boolean) value;
- break;
- case XML_TAG_REQUIRE_PMF:
- configuration.requirePMF = (boolean) value;
- break;
- case XML_TAG_ALLOWED_KEY_MGMT:
- byte[] allowedKeyMgmt = (byte[]) value;
- configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
- break;
- case XML_TAG_ALLOWED_PROTOCOLS:
- byte[] allowedProtocols = (byte[]) value;
- configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
- break;
- case XML_TAG_ALLOWED_AUTH_ALGOS:
- byte[] allowedAuthAlgorithms = (byte[]) value;
- configuration.allowedAuthAlgorithms = BitSet.valueOf(allowedAuthAlgorithms);
- break;
- case XML_TAG_ALLOWED_GROUP_CIPHERS:
- byte[] allowedGroupCiphers = (byte[]) value;
- configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
- break;
- case XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
- byte[] allowedPairwiseCiphers = (byte[]) value;
- configuration.allowedPairwiseCiphers =
- BitSet.valueOf(allowedPairwiseCiphers);
- break;
- case XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS:
- byte[] allowedGroupMgmtCiphers = (byte[]) value;
- configuration.allowedGroupManagementCiphers =
- BitSet.valueOf(allowedGroupMgmtCiphers);
- break;
- case XML_TAG_ALLOWED_SUITE_B_CIPHERS:
- byte[] allowedSuiteBCiphers = (byte[]) value;
- configuration.allowedSuiteBCiphers =
- BitSet.valueOf(allowedSuiteBCiphers);
- break;
- case XML_TAG_SHARED:
- configuration.shared = (boolean) value;
- break;
- case XML_TAG_STATUS:
- int status = (int) value;
- // Any network which was CURRENT before reboot needs
- // to be restored to ENABLED.
- if (status == WifiConfiguration.Status.CURRENT) {
- status = WifiConfiguration.Status.ENABLED;
- }
- configuration.status = status;
- break;
- case XML_TAG_FQDN:
- configuration.FQDN = (String) value;
- break;
- case XML_TAG_PROVIDER_FRIENDLY_NAME:
- configuration.providerFriendlyName = (String) value;
- break;
- case XML_TAG_LINKED_NETWORKS_LIST:
- configuration.linkedConfigurations = (HashMap<String, Integer>) value;
- break;
- case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
- configuration.defaultGwMacAddress = (String) value;
- break;
- case XML_TAG_VALIDATED_INTERNET_ACCESS:
- configuration.validatedInternetAccess = (boolean) value;
- break;
- case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
- configuration.noInternetAccessExpected = (boolean) value;
- break;
- case XML_TAG_USER_APPROVED:
- configuration.userApproved = (int) value;
- break;
- case XML_TAG_METERED_HINT:
- configuration.meteredHint = (boolean) value;
- break;
- case XML_TAG_METERED_OVERRIDE:
- configuration.meteredOverride = (int) value;
- break;
- case XML_TAG_USE_EXTERNAL_SCORES:
- configuration.useExternalScores = (boolean) value;
- break;
- case XML_TAG_NUM_ASSOCIATION:
- configuration.numAssociation = (int) value;
- break;
- case XML_TAG_CREATOR_UID:
- configuration.creatorUid = (int) value;
- break;
- case XML_TAG_CREATOR_NAME:
- configuration.creatorName = (String) value;
- break;
- case XML_TAG_CREATION_TIME:
- configuration.creationTime = (String) value;
- break;
- case XML_TAG_LAST_UPDATE_UID:
- configuration.lastUpdateUid = (int) value;
- break;
- case XML_TAG_LAST_UPDATE_NAME:
- configuration.lastUpdateName = (String) value;
- break;
- case XML_TAG_LAST_CONNECT_UID:
- configuration.lastConnectUid = (int) value;
- break;
- case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG:
- configuration.isLegacyPasspointConfig = (boolean) value;
- break;
- case XML_TAG_ROAMING_CONSORTIUM_OIS:
- configuration.roamingConsortiumIds = (long[]) value;
- break;
- case XML_TAG_RANDOMIZED_MAC_ADDRESS:
- configuration.setRandomizedMacAddress(
- MacAddress.fromString((String) value));
- break;
- case XML_TAG_MAC_RANDOMIZATION_SETTING:
- configuration.macRandomizationSetting = (int) value;
- macRandomizationSettingExists = true;
- break;
- default:
- throw new XmlPullParserException(
- "Unknown value name found: " + valueName[0]);
+ if (in.getAttributeValue(null, "name") != null) {
+ // Value elements.
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (valueName[0] == null) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ switch (valueName[0]) {
+ case XML_TAG_CONFIG_KEY:
+ configKeyInData = (String) value;
+ break;
+ case XML_TAG_SSID:
+ configuration.SSID = (String) value;
+ break;
+ case XML_TAG_BSSID:
+ configuration.BSSID = (String) value;
+ break;
+ case XML_TAG_PRE_SHARED_KEY:
+ configuration.preSharedKey = (String) value;
+ break;
+ case XML_TAG_WEP_KEYS:
+ populateWepKeysFromXmlValue(value, configuration.wepKeys);
+ break;
+ case XML_TAG_WEP_TX_KEY_INDEX:
+ configuration.wepTxKeyIndex = (int) value;
+ break;
+ case XML_TAG_HIDDEN_SSID:
+ configuration.hiddenSSID = (boolean) value;
+ break;
+ case XML_TAG_REQUIRE_PMF:
+ configuration.requirePMF = (boolean) value;
+ break;
+ case XML_TAG_ALLOWED_KEY_MGMT:
+ byte[] allowedKeyMgmt = (byte[]) value;
+ configuration.allowedKeyManagement = BitSet.valueOf(allowedKeyMgmt);
+ break;
+ case XML_TAG_ALLOWED_PROTOCOLS:
+ byte[] allowedProtocols = (byte[]) value;
+ configuration.allowedProtocols = BitSet.valueOf(allowedProtocols);
+ break;
+ case XML_TAG_ALLOWED_AUTH_ALGOS:
+ byte[] allowedAuthAlgorithms = (byte[]) value;
+ configuration.allowedAuthAlgorithms = BitSet.valueOf(
+ allowedAuthAlgorithms);
+ break;
+ case XML_TAG_ALLOWED_GROUP_CIPHERS:
+ byte[] allowedGroupCiphers = (byte[]) value;
+ configuration.allowedGroupCiphers = BitSet.valueOf(allowedGroupCiphers);
+ break;
+ case XML_TAG_ALLOWED_PAIRWISE_CIPHERS:
+ byte[] allowedPairwiseCiphers = (byte[]) value;
+ configuration.allowedPairwiseCiphers =
+ BitSet.valueOf(allowedPairwiseCiphers);
+ break;
+ case XML_TAG_ALLOWED_GROUP_MGMT_CIPHERS:
+ byte[] allowedGroupMgmtCiphers = (byte[]) value;
+ configuration.allowedGroupManagementCiphers =
+ BitSet.valueOf(allowedGroupMgmtCiphers);
+ break;
+ case XML_TAG_ALLOWED_SUITE_B_CIPHERS:
+ byte[] allowedSuiteBCiphers = (byte[]) value;
+ configuration.allowedSuiteBCiphers =
+ BitSet.valueOf(allowedSuiteBCiphers);
+ break;
+ case XML_TAG_SHARED:
+ configuration.shared = (boolean) value;
+ break;
+ case XML_TAG_STATUS:
+ int status = (int) value;
+ // Any network which was CURRENT before reboot needs
+ // to be restored to ENABLED.
+ if (status == WifiConfiguration.Status.CURRENT) {
+ status = WifiConfiguration.Status.ENABLED;
+ }
+ configuration.status = status;
+ break;
+ case XML_TAG_FQDN:
+ configuration.FQDN = (String) value;
+ break;
+ case XML_TAG_PROVIDER_FRIENDLY_NAME:
+ configuration.providerFriendlyName = (String) value;
+ break;
+ case XML_TAG_LINKED_NETWORKS_LIST:
+ configuration.linkedConfigurations = (HashMap<String, Integer>) value;
+ break;
+ case XML_TAG_DEFAULT_GW_MAC_ADDRESS:
+ configuration.defaultGwMacAddress = (String) value;
+ break;
+ case XML_TAG_VALIDATED_INTERNET_ACCESS:
+ configuration.validatedInternetAccess = (boolean) value;
+ break;
+ case XML_TAG_NO_INTERNET_ACCESS_EXPECTED:
+ configuration.noInternetAccessExpected = (boolean) value;
+ break;
+ case XML_TAG_USER_APPROVED:
+ configuration.userApproved = (int) value;
+ break;
+ case XML_TAG_METERED_HINT:
+ configuration.meteredHint = (boolean) value;
+ break;
+ case XML_TAG_METERED_OVERRIDE:
+ configuration.meteredOverride = (int) value;
+ break;
+ case XML_TAG_USE_EXTERNAL_SCORES:
+ configuration.useExternalScores = (boolean) value;
+ break;
+ case XML_TAG_NUM_ASSOCIATION:
+ configuration.numAssociation = (int) value;
+ break;
+ case XML_TAG_CREATOR_UID:
+ configuration.creatorUid = (int) value;
+ break;
+ case XML_TAG_CREATOR_NAME:
+ configuration.creatorName = (String) value;
+ break;
+ case XML_TAG_CREATION_TIME:
+ configuration.creationTime = (String) value;
+ break;
+ case XML_TAG_LAST_UPDATE_UID:
+ configuration.lastUpdateUid = (int) value;
+ break;
+ case XML_TAG_LAST_UPDATE_NAME:
+ configuration.lastUpdateName = (String) value;
+ break;
+ case XML_TAG_LAST_CONNECT_UID:
+ configuration.lastConnectUid = (int) value;
+ break;
+ case XML_TAG_IS_LEGACY_PASSPOINT_CONFIG:
+ configuration.isLegacyPasspointConfig = (boolean) value;
+ break;
+ case XML_TAG_ROAMING_CONSORTIUM_OIS:
+ configuration.roamingConsortiumIds = (long[]) value;
+ break;
+ case XML_TAG_RANDOMIZED_MAC_ADDRESS:
+ configuration.setRandomizedMacAddress(
+ MacAddress.fromString((String) value));
+ break;
+ case XML_TAG_MAC_RANDOMIZATION_SETTING:
+ configuration.macRandomizationSetting = (int) value;
+ macRandomizationSettingExists = true;
+ break;
+ default:
+ throw new XmlPullParserException(
+ "Unknown value name found: " + valueName[0]);
+ }
+ } else {
+ String tagName = in.getName();
+ if (tagName == null) {
+ throw new XmlPullParserException("Unexpected null tag found");
+ }
+ switch (tagName) {
+ case XML_TAG_PRE_SHARED_KEY:
+ if (!shouldExpectEncryptedCredentials || encryptionUtil == null) {
+ throw new XmlPullParserException(
+ "Encrypted preSharedKey section not expected");
+ }
+ EncryptedData encryptedData =
+ EncryptedDataXmlUtil.parseFromXml(in, outerTagDepth + 1);
+ byte[] preSharedKeyBytes = encryptionUtil.decrypt(encryptedData);
+ if (preSharedKeyBytes == null) {
+ Log.wtf(TAG, "Decryption of preSharedKey failed");
+ } else {
+ configuration.preSharedKey = new String(preSharedKeyBytes);
+ }
+ break;
+ default:
+ throw new XmlPullParserException(
+ "Unknown tag name found: " + tagName);
+ }
}
}
if (!macRandomizationSettingExists) {
@@ -1019,20 +1086,52 @@ public class XmlUtil {
public static final String XML_TAG_REALM = "Realm";
/**
+ * Write password key to the XML stream.
+ *
+ * If encryptionUtil is null or if encryption fails for some reason, the password is stored
+ * in plaintext, else the encrypted psk is stored.
+ */
+ private static void writePasswordToXml(
+ XmlSerializer out, String password,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
+ throws XmlPullParserException, IOException {
+ EncryptedData encryptedData = null;
+ if (encryptionUtil != null) {
+ if (password != null) {
+ encryptedData = encryptionUtil.encrypt(password.getBytes());
+ if (encryptedData == null) {
+ // We silently fail encryption failures!
+ Log.wtf(TAG, "Encryption of password failed");
+ }
+ }
+ }
+ if (encryptedData != null) {
+ XmlUtil.writeNextSectionStart(out, XML_TAG_PASSWORD);
+ EncryptedDataXmlUtil.writeToXml(out, encryptedData);
+ XmlUtil.writeNextSectionEnd(out, XML_TAG_PASSWORD);
+ } else {
+ XmlUtil.writeNextValue(out, XML_TAG_PASSWORD, password);
+ }
+ }
+
+ /**
* Write the WifiEnterpriseConfig data elements from the provided config to the XML
* stream.
*
- * @param out XmlSerializer instance pointing to the XML stream.
+ * @param out XmlSerializer instance pointing to the XML stream.
* @param enterpriseConfig WifiEnterpriseConfig object to be serialized.
+ * @param encryptionUtil Instance of {@link EncryptedDataXmlUtil}.
*/
- public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig)
+ public static void writeToXml(XmlSerializer out, WifiEnterpriseConfig enterpriseConfig,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextValue(out, XML_TAG_IDENTITY,
enterpriseConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY));
XmlUtil.writeNextValue(out, XML_TAG_ANON_IDENTITY,
enterpriseConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY));
- XmlUtil.writeNextValue(out, XML_TAG_PASSWORD,
- enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY));
+ writePasswordToXml(
+ out, enterpriseConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY),
+ encryptionUtil);
XmlUtil.writeNextValue(out, XML_TAG_CLIENT_CERT,
enterpriseConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY));
XmlUtil.writeNextValue(out, XML_TAG_CA_CERT,
@@ -1060,15 +1159,170 @@ public class XmlUtil {
/**
* Parses the data elements from the provided XML stream to a WifiEnterpriseConfig object.
*
- * @param in XmlPullParser instance pointing to the XML stream.
+ * @param in XmlPullParser instance pointing to the XML stream.
* @param outerTagDepth depth of the outer tag in the XML document.
+ * @param shouldExpectEncryptedCredentials Whether to expect encrypted credentials or not.
+ * @param encryptionUtil Instance of {@link EncryptedDataXmlUtil}.
* @return WifiEnterpriseConfig object if parsing is successful, null otherwise.
*/
- public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth)
+ public static WifiEnterpriseConfig parseFromXml(XmlPullParser in, int outerTagDepth,
+ boolean shouldExpectEncryptedCredentials,
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
// Loop through and parse out all the elements from the stream within this section.
+ while (XmlUtils.nextElementWithin(in, outerTagDepth)) {
+ if (in.getAttributeValue(null, "name") != null) {
+ // Value elements.
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ if (valueName[0] == null) {
+ throw new XmlPullParserException("Missing value name");
+ }
+ switch (valueName[0]) {
+ case XML_TAG_IDENTITY:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
+ break;
+ case XML_TAG_ANON_IDENTITY:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
+ break;
+ case XML_TAG_PASSWORD:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
+ if (shouldExpectEncryptedCredentials
+ && !TextUtils.isEmpty(enterpriseConfig.getFieldValue(
+ WifiEnterpriseConfig.PASSWORD_KEY))) {
+ // Indicates that encryption of password failed when it was last
+ // written.
+ Log.e(TAG, "password value not expected");
+ }
+ break;
+ case XML_TAG_CLIENT_CERT:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
+ break;
+ case XML_TAG_CA_CERT:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
+ break;
+ case XML_TAG_SUBJECT_MATCH:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
+ break;
+ case XML_TAG_ENGINE:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.ENGINE_KEY, (String) value);
+ break;
+ case XML_TAG_ENGINE_ID:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
+ break;
+ case XML_TAG_PRIVATE_KEY_ID:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
+ break;
+ case XML_TAG_ALT_SUBJECT_MATCH:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
+ break;
+ case XML_TAG_DOM_SUFFIX_MATCH:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
+ break;
+ case XML_TAG_CA_PATH:
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
+ break;
+ case XML_TAG_EAP_METHOD:
+ enterpriseConfig.setEapMethod((int) value);
+ break;
+ case XML_TAG_PHASE2_METHOD:
+ enterpriseConfig.setPhase2Method((int) value);
+ break;
+ case XML_TAG_PLMN:
+ enterpriseConfig.setPlmn((String) value);
+ break;
+ case XML_TAG_REALM:
+ enterpriseConfig.setRealm((String) value);
+ break;
+ default:
+ throw new XmlPullParserException(
+ "Unknown value name found: " + valueName[0]);
+ }
+ } else {
+ String tagName = in.getName();
+ if (tagName == null) {
+ throw new XmlPullParserException("Unexpected null tag found");
+ }
+ switch (tagName) {
+ case XML_TAG_PASSWORD:
+ if (!shouldExpectEncryptedCredentials || encryptionUtil == null) {
+ throw new XmlPullParserException(
+ "encrypted password section not expected");
+ }
+ EncryptedData encryptedData =
+ EncryptedDataXmlUtil.parseFromXml(in, outerTagDepth + 1);
+ byte[] passwordBytes = encryptionUtil.decrypt(encryptedData);
+ if (passwordBytes == null) {
+ Log.wtf(TAG, "Decryption of password failed");
+ } else {
+ enterpriseConfig.setFieldValue(
+ WifiEnterpriseConfig.PASSWORD_KEY,
+ new String(passwordBytes));
+ }
+ break;
+ default:
+ throw new XmlPullParserException(
+ "Unknown tag name found: " + tagName);
+ }
+ }
+ }
+ return enterpriseConfig;
+ }
+ }
+
+ /**
+ * Utility class to serialize and deseriaize {@link EncryptedData} object to XML &
+ * vice versa. This is used by {@link com.android.server.wifi.WifiConfigStore} module.
+ */
+ public static class EncryptedDataXmlUtil {
+ /**
+ * List of XML tags corresponding to EncryptedData object elements.
+ */
+ private static final String XML_TAG_ENCRYPTED_DATA = "EncryptedData";
+ private static final String XML_TAG_IV = "IV";
+
+ /**
+ * Write the NetworkSelectionStatus data elements from the provided status to the XML
+ * stream.
+ *
+ * @param out XmlSerializer instance pointing to the XML stream.
+ * @param encryptedData EncryptedData object to be serialized.
+ */
+ public static void writeToXml(XmlSerializer out, EncryptedData encryptedData)
+ throws XmlPullParserException, IOException {
+ XmlUtil.writeNextValue(
+ out, XML_TAG_ENCRYPTED_DATA, encryptedData.getEncryptedData());
+ XmlUtil.writeNextValue(out, XML_TAG_IV, encryptedData.getIv());
+ }
+
+ /**
+ * Parses the EncryptedData data elements from the provided XML stream to a
+ * EncryptedData object.
+ *
+ * @param in XmlPullParser instance pointing to the XML stream.
+ * @param outerTagDepth depth of the outer tag in the XML document.
+ * @return EncryptedData object if parsing is successful, null otherwise.
+ */
+ public static EncryptedData parseFromXml(XmlPullParser in, int outerTagDepth)
+ throws XmlPullParserException, IOException {
+ byte[] encryptedData = null;
+ byte[] iv = null;
+
+ // Loop through and parse out all the elements from the stream within this section.
while (!XmlUtil.isNextSectionEnd(in, outerTagDepth)) {
String[] valueName = new String[1];
Object value = XmlUtil.readCurrentValue(in, valueName);
@@ -1076,72 +1330,18 @@ public class XmlUtil {
throw new XmlPullParserException("Missing value name");
}
switch (valueName[0]) {
- case XML_TAG_IDENTITY:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.IDENTITY_KEY, (String) value);
- break;
- case XML_TAG_ANON_IDENTITY:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.ANON_IDENTITY_KEY, (String) value);
+ case XML_TAG_ENCRYPTED_DATA:
+ encryptedData = (byte[]) value;
break;
- case XML_TAG_PASSWORD:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.PASSWORD_KEY, (String) value);
- break;
- case XML_TAG_CLIENT_CERT:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.CLIENT_CERT_KEY, (String) value);
- break;
- case XML_TAG_CA_CERT:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.CA_CERT_KEY, (String) value);
- break;
- case XML_TAG_SUBJECT_MATCH:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.SUBJECT_MATCH_KEY, (String) value);
- break;
- case XML_TAG_ENGINE:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.ENGINE_KEY, (String) value);
- break;
- case XML_TAG_ENGINE_ID:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.ENGINE_ID_KEY, (String) value);
- break;
- case XML_TAG_PRIVATE_KEY_ID:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, (String) value);
- break;
- case XML_TAG_ALT_SUBJECT_MATCH:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, (String) value);
- break;
- case XML_TAG_DOM_SUFFIX_MATCH:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, (String) value);
- break;
- case XML_TAG_CA_PATH:
- enterpriseConfig.setFieldValue(
- WifiEnterpriseConfig.CA_PATH_KEY, (String) value);
- break;
- case XML_TAG_EAP_METHOD:
- enterpriseConfig.setEapMethod((int) value);
- break;
- case XML_TAG_PHASE2_METHOD:
- enterpriseConfig.setPhase2Method((int) value);
- break;
- case XML_TAG_PLMN:
- enterpriseConfig.setPlmn((String) value);
- break;
- case XML_TAG_REALM:
- enterpriseConfig.setRealm((String) value);
+ case XML_TAG_IV:
+ iv = (byte[]) value;
break;
default:
throw new XmlPullParserException(
"Unknown value name found: " + valueName[0]);
}
}
- return enterpriseConfig;
+ return new EncryptedData(encryptedData, iv);
}
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
index 702aa99df..17b9d1c2e 100644
--- a/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/DeletedEphemeralSsidsStoreDataTest.java
@@ -24,6 +24,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -78,7 +79,8 @@ public class DeletedEphemeralSsidsStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mDeletedEphemeralSsidsStoreData.serializeData(out);
+ mDeletedEphemeralSsidsStoreData.serializeData(
+ out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -94,7 +96,9 @@ public class DeletedEphemeralSsidsStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mDeletedEphemeralSsidsStoreData.deserializeData(in, in.getDepth());
+ mDeletedEphemeralSsidsStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
return mDeletedEphemeralSsidsStoreData.getSsidToTimeMap();
}
diff --git a/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
index 7336c4119..20b6c4f76 100644
--- a/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/NetworkListStoreDataTest.java
@@ -31,6 +31,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtilTest;
import org.junit.Before;
@@ -213,7 +214,7 @@ public class NetworkListStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mNetworkListSharedStoreData.serializeData(out);
+ mNetworkListSharedStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -229,7 +230,9 @@ public class NetworkListStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mNetworkListSharedStoreData.deserializeData(in, in.getDepth());
+ mNetworkListSharedStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
return mNetworkListSharedStoreData.getConfigurations();
}
diff --git a/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
index f40f71bcf..c0f03505e 100644
--- a/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/NetworkRequestStoreDataTest.java
@@ -27,6 +27,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -80,7 +81,7 @@ public class NetworkRequestStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mNetworkRequestStoreData.serializeData(out);
+ mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -92,7 +93,9 @@ public class NetworkRequestStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mNetworkRequestStoreData.deserializeData(in, in.getDepth());
+ mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
index 5c1dcb459..a35c510fc 100644
--- a/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/NetworkSuggestionStoreDataTest.java
@@ -28,6 +28,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
import com.android.server.wifi.WifiNetworkSuggestionsManager.PerAppInfo;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -119,7 +120,7 @@ public class NetworkSuggestionStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mNetworkSuggestionStoreData.serializeData(out);
+ mNetworkSuggestionStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -131,7 +132,9 @@ public class NetworkSuggestionStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mNetworkSuggestionStoreData.deserializeData(in, in.getDepth());
+ mNetworkSuggestionStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
index 4df560fd2..cdd4e6c84 100644
--- a/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/RandomizedMacStoreDataTest.java
@@ -24,6 +24,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -62,7 +63,7 @@ public class RandomizedMacStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mRandomizedMacStoreData.serializeData(out);
+ mRandomizedMacStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -78,7 +79,9 @@ public class RandomizedMacStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mRandomizedMacStoreData.deserializeData(in, in.getDepth());
+ mRandomizedMacStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
return mRandomizedMacStoreData.getMacMapping();
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
index ac6ae21a2..feedc0d2a 100644
--- a/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SsidSetStoreDataTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -29,6 +30,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -80,7 +82,7 @@ public class SsidSetStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mSsidSetStoreData.serializeData(out);
+ mSsidSetStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -95,7 +97,9 @@ public class SsidSetStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mSsidSetStoreData.deserializeData(in, in.getDepth());
+ mSsidSetStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
index c814aef1a..df93eb4fb 100644
--- a/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WakeupConfigStoreDataTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -28,6 +29,7 @@ import android.util.Xml;
import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.google.android.collect.Sets;
@@ -74,7 +76,7 @@ public class WakeupConfigStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mWakeupConfigData.serializeData(out);
+ mWakeupConfigData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -88,7 +90,9 @@ public class WakeupConfigStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mWakeupConfigData.deserializeData(in, in.getDepth());
+ mWakeupConfigData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
@@ -177,7 +181,9 @@ public class WakeupConfigStoreDataTest {
*/
@Test
public void hasBeenReadIsTrueWhenUserStoreIsLoaded() throws Exception {
- mWakeupConfigData.deserializeData(null /* in */, 0 /* outerTagDepth */);
+ mWakeupConfigData.deserializeData(null /* in */, 0 /* outerTagDepth */,
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
assertTrue(mWakeupConfigData.hasBeenRead());
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
index 009429b3f..a004995b9 100644
--- a/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WakeupControllerTest.java
@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -38,6 +39,7 @@ import android.provider.Settings;
import androidx.test.filters.SmallTest;
import com.android.server.wifi.util.ScanResultUtil;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -149,7 +151,9 @@ public class WakeupControllerTest {
private void readUserStore() {
try {
- mWakeupConfigStoreData.deserializeData(null, 0);
+ mWakeupConfigStoreData.deserializeData(null, 0,
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
} catch (XmlPullParserException | IOException e) {
// unreachable
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 0badc6fbd..c4cbc6e50 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -234,7 +234,7 @@ public class WifiConfigManagerTest {
.spyStatic(WifiConfigurationUtil.class)
.strictness(Strictness.LENIENT)
.startMocking();
- when(WifiConfigStore.createUserFiles(anyInt())).thenReturn(mock(List.class));
+ when(WifiConfigStore.createUserFiles(anyInt(), anyBoolean())).thenReturn(mock(List.class));
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mDataTelephonyManager);
when(WifiConfigurationUtil.calculatePersistentMacForConfiguration(any(), any()))
.thenReturn(TEST_RANDOMIZED_MAC);
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
index b59e367dd..efa2d4336 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
@@ -16,12 +16,9 @@
package com.android.server.wifi;
-import static com.android.server.wifi.WifiConfigStore.ZEROED_ENCRYPTED_DATA;
-
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
-import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.app.test.TestAlarmManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -34,8 +31,8 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.WifiConfigStore.StoreData;
import com.android.server.wifi.WifiConfigStore.StoreFile;
-import com.android.server.wifi.util.DataIntegrityChecker;
import com.android.server.wifi.util.EncryptedData;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.XmlUtil;
import libcore.util.HexEncoding;
@@ -43,7 +40,6 @@ import libcore.util.HexEncoding;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParser;
@@ -73,13 +69,7 @@ public class WifiConfigStoreTest {
private static final String TEST_DATA_XML_STRING_FORMAT =
"<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<WifiConfigStoreData>\n"
- + "<int name=\"Version\" value=\"2\" />\n"
- + "<Integrity>\n"
- + "<byte-array name=\"EncryptedData\" num=\"48\">000000000000000000000000000000"
- + "000000000000000000000000000000000000000000000000000000000000000000"
- + "</byte-array>\n"
- + "<byte-array name=\"IV\" num=\"12\">000000000000000000000000</byte-array>\n"
- + "</Integrity>\n"
+ + "<int name=\"Version\" value=\"3\" />\n"
+ "<NetworkList>\n"
+ "<Network>\n"
+ "<WifiConfiguration>\n"
@@ -172,7 +162,7 @@ public class WifiConfigStoreTest {
private TestLooper mLooper;
@Mock private Clock mClock;
@Mock private WifiMetrics mWifiMetrics;
- @Mock private DataIntegrityChecker mDataIntegrityChecker;
+ @Mock private WifiConfigStoreEncryptionUtil mEncryptionUtil;
private MockStoreFile mSharedStore;
private MockStoreFile mUserStore;
private MockStoreFile mUserNetworkSuggestionsStore;
@@ -196,10 +186,10 @@ public class WifiConfigStoreTest {
.thenReturn(mAlarmManager.getAlarmManager());
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getNameForUid(anyInt())).thenReturn(TEST_CREATOR_NAME);
- when(mDataIntegrityChecker.compute(any(byte[].class)))
- .thenReturn(ZEROED_ENCRYPTED_DATA);
- when(mDataIntegrityChecker.isOk(any(byte[].class), any(EncryptedData.class)))
- .thenReturn(true);
+ when(mEncryptionUtil.encrypt(any(byte[].class)))
+ .thenReturn(new EncryptedData(new byte[0], new byte[0]));
+ when(mEncryptionUtil.decrypt(any(EncryptedData.class)))
+ .thenReturn(new byte[0]);
mSharedStore = new MockStoreFile(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
mUserStore = new MockStoreFile(WifiConfigStore.STORE_FILE_USER_GENERAL);
mUserNetworkSuggestionsStore =
@@ -432,9 +422,9 @@ public class WifiConfigStoreTest {
// Ensure that we got the call to deserialize empty shared data, but no user data.
verify(sharedStoreData).resetData();
- verify(sharedStoreData).deserializeData(eq(null), anyInt());
+ verify(sharedStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
verify(userStoreData, never()).resetData();
- verify(userStoreData, never()).deserializeData(any(), anyInt());
+ verify(userStoreData, never()).deserializeData(any(), anyInt(), anyInt(), any());
}
/**
@@ -462,9 +452,9 @@ public class WifiConfigStoreTest {
// Ensure that we got the call to deserialize empty shared & user data.
verify(userStoreData).resetData();
- verify(userStoreData).deserializeData(eq(null), anyInt());
+ verify(userStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
verify(sharedStoreData).resetData();
- verify(sharedStoreData).deserializeData(eq(null), anyInt());
+ verify(sharedStoreData).deserializeData(eq(null), anyInt(), anyInt(), any());
}
/**
@@ -639,9 +629,9 @@ public class WifiConfigStoreTest {
mUserStore.storeRawDataToWrite(null);
mWifiConfigStore.read();
- verify(storeData1).deserializeData(notNull(), anyInt());
- verify(storeData1, never()).deserializeData(eq(null), anyInt());
- verify(storeData2).deserializeData(eq(null), anyInt());
+ verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+ verify(storeData2).deserializeData(eq(null), anyInt(), anyInt(), any());
reset(storeData1, storeData2);
// Scenario 2: StoreData2 in user store file.
@@ -655,9 +645,9 @@ public class WifiConfigStoreTest {
mUserStore.storeRawDataToWrite(fileContentsXmlStringWithOnlyStoreData2.getBytes());
mWifiConfigStore.read();
- verify(storeData1).deserializeData(eq(null), anyInt());
- verify(storeData2).deserializeData(notNull(), anyInt());
- verify(storeData2, never()).deserializeData(eq(null), anyInt());
+ verify(storeData1).deserializeData(eq(null), anyInt(), anyInt(), any());
+ verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
reset(storeData1, storeData2);
// Scenario 3: StoreData1 in shared store file & StoreData2 in user store file.
@@ -671,10 +661,10 @@ public class WifiConfigStoreTest {
mUserStore.storeRawDataToWrite(fileContentsXmlStringWithOnlyStoreData2.getBytes());
mWifiConfigStore.read();
- verify(storeData1).deserializeData(notNull(), anyInt());
- verify(storeData1, never()).deserializeData(eq(null), anyInt());
- verify(storeData2).deserializeData(notNull(), anyInt());
- verify(storeData2, never()).deserializeData(eq(null), anyInt());
+ verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+ verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
reset(storeData1, storeData2);
// Scenario 4: StoreData1 & StoreData2 in shared store file.
@@ -689,10 +679,10 @@ public class WifiConfigStoreTest {
mUserStore.storeRawDataToWrite(null);
mWifiConfigStore.read();
- verify(storeData1).deserializeData(notNull(), anyInt());
- verify(storeData1, never()).deserializeData(eq(null), anyInt());
- verify(storeData2).deserializeData(notNull(), anyInt());
- verify(storeData2, never()).deserializeData(eq(null), anyInt());
+ verify(storeData1).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData1, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
+ verify(storeData2).deserializeData(notNull(), anyInt(), anyInt(), any());
+ verify(storeData2, never()).deserializeData(eq(null), anyInt(), anyInt(), any());
reset(storeData1, storeData2);
}
@@ -739,9 +729,9 @@ public class WifiConfigStoreTest {
verify(userStoreNetworkSuggestionsData).hasNewDataToSerialize();
// Verify that we serialized data from the first 2 data source, but not from the last one.
- verify(sharedStoreData).serializeData(any());
- verify(userStoreData).serializeData(any());
- verify(userStoreNetworkSuggestionsData, never()).serializeData(any());
+ verify(sharedStoreData).serializeData(any(), any());
+ verify(userStoreData).serializeData(any(), any());
+ verify(userStoreNetworkSuggestionsData, never()).serializeData(any(), any());
}
/**
@@ -815,190 +805,21 @@ public class WifiConfigStoreTest {
// Read and verify the data content in the store file (metadata stripped out) has been sent
// to the corresponding store data when integrity check passes.
mWifiConfigStore.read();
- verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
- verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
- // We shouldn't perform any data integrity checks on version 1 file.
- verifyZeroInteractions(mDataIntegrityChecker);
- }
-
- /**
- * Tests the read API behaviour when integrity check fails.
- * Expected behaviour: The read should return an empty store data.
- */
- @Test
- public void testReadWhenIntegrityCheckFails() throws Exception {
- // Register data container.
- StoreData sharedStoreData = mock(StoreData.class);
- when(sharedStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
- when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
- StoreData userStoreData = mock(StoreData.class);
- when(userStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
- when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
- mWifiConfigStore.registerStoreData(sharedStoreData);
- mWifiConfigStore.registerStoreData(userStoreData);
-
- // Read both share and user config store.
- mWifiConfigStore.setUserStores(mUserStores);
-
- // Now store some content in the shared and user data files.
- mUserStore.storeRawDataToWrite(
- String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_USER_DATA).getBytes());
- mSharedStore.storeRawDataToWrite(
- String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_SHARE_DATA).getBytes());
-
- // Read and verify the data content in the store file (metadata stripped out) has been sent
- // to the corresponding store data when integrity check passes.
- mWifiConfigStore.read();
- verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
- verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
- // Read and verify the data content in the store file (metadata stripped out) has not been
- // sent to the corresponding store data when integrity check fails.
- when(mDataIntegrityChecker.isOk(any(byte[].class), any(EncryptedData.class)))
- .thenReturn(false);
- mWifiConfigStore.read();
- verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
- verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
+ verify(sharedStoreData, times(1)).deserializeData(
+ any(XmlPullParser.class), anyInt(),
+ eq(WifiConfigStore.INITIAL_CONFIG_STORE_DATA_VERSION), any());
+ verify(userStoreData, times(1)).deserializeData(
+ any(XmlPullParser.class), anyInt(),
+ eq(WifiConfigStore.INITIAL_CONFIG_STORE_DATA_VERSION), any());
}
/**
- * Tests the write API behaviour when integrity check fails.
- * Expected behaviour: The read should return an empty store data.
+ * Tests the read API behaviour to ensure that the integrity data is parsed from the file.
*/
@Test
- public void testWriteWhenIntegrityComputeFails() throws Exception {
- // Register data container.
- StoreData sharedStoreData = mock(StoreData.class);
- when(sharedStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
- when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
- when(sharedStoreData.hasNewDataToSerialize()).thenReturn(true);
- StoreData userStoreData = mock(StoreData.class);
- when(userStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
- when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
- when(userStoreData.hasNewDataToSerialize()).thenReturn(true);
- mWifiConfigStore.registerStoreData(sharedStoreData);
- mWifiConfigStore.registerStoreData(userStoreData);
-
- // Read both share and user config store.
- mWifiConfigStore.setUserStores(mUserStores);
-
- // Reset store file contents & ensure that the user and store data files are empty.
- mUserStore.storeRawDataToWrite(null);
- mSharedStore.storeRawDataToWrite(null);
- assertNull(mUserStore.getStoreBytes());
- assertNull(mSharedStore.getStoreBytes());
-
- // Write and verify that the data is written to the config store file when integrity
- // computation passes.
- mWifiConfigStore.write(true);
- assertNotNull(mUserStore.getStoreBytes());
- assertNotNull(mSharedStore.getStoreBytes());
- assertTrue(new String(mUserStore.getStoreBytes()).contains(TEST_USER_DATA));
- assertTrue(new String(mSharedStore.getStoreBytes()).contains(TEST_SHARE_DATA));
-
- // Reset store file contents & ensure that the user and store data files are empty.
- mUserStore.storeRawDataToWrite(null);
- mSharedStore.storeRawDataToWrite(null);
- assertNull(mUserStore.getStoreBytes());
- assertNull(mSharedStore.getStoreBytes());
-
- // Write and verify that the data is not written to the config store file when integrity
- // computation fails.
- when(mDataIntegrityChecker.compute(any(byte[].class))).thenReturn(null);
- mWifiConfigStore.write(true);
- assertNull(mUserStore.getStoreBytes());
- assertNull(mSharedStore.getStoreBytes());
- }
-
- /**
- * Tests the write API behaviour to ensure that the integrity data is written to the file.
- */
- @Test
- public void testWriteContainsIntegrityData() throws Exception {
- byte[] encryptedData = new byte[EncryptedData.ENCRYPTED_DATA_LENGTH];
- byte[] iv = new byte[EncryptedData.IV_LENGTH];
- Random random = new Random();
- random.nextBytes(encryptedData);
- random.nextBytes(iv);
- final EncryptedData testEncryptedData = new EncryptedData(encryptedData, iv);
-
- doAnswer(new AnswerWithArguments() {
- public EncryptedData answer(byte[] data) {
- String storeXmlString = new String(data);
- // Verify that we fill in zeros to the data when we compute integrity.
- if (storeXmlString.contains(TEST_SHARE_DATA)) {
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_SHARE_DATA), storeXmlString);
- } else if (storeXmlString.contains(TEST_USER_DATA)) {
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_USER_DATA), storeXmlString);
- }
- return testEncryptedData;
- }
- }).when(mDataIntegrityChecker).compute(any(byte[].class));
-
- // Register data container.
- StoreData sharedStoreData = mock(StoreData.class);
- when(sharedStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_SHARED_GENERAL);
- when(sharedStoreData.getName()).thenReturn(TEST_SHARE_DATA);
- when(sharedStoreData.hasNewDataToSerialize()).thenReturn(true);
- StoreData userStoreData = mock(StoreData.class);
- when(userStoreData.getStoreFileId())
- .thenReturn(WifiConfigStore.STORE_FILE_USER_GENERAL);
- when(userStoreData.getName()).thenReturn(TEST_USER_DATA);
- when(userStoreData.hasNewDataToSerialize()).thenReturn(true);
- mWifiConfigStore.registerStoreData(sharedStoreData);
- mWifiConfigStore.registerStoreData(userStoreData);
-
- // Read both share and user config store.
- mWifiConfigStore.setUserStores(mUserStores);
-
- // Write and verify that the data is written to the config store file when integrity
- // computation passes.
- mWifiConfigStore.write(true);
-
- // Verify that we fill in zeros to the data when we computed integrity.
- verify(mDataIntegrityChecker, times(2)).compute(any(byte[].class));
-
- // Verify the parsed integrity data
- assertNotNull(mUserStore.getStoreBytes());
- assertNotNull(mSharedStore.getStoreBytes());
- String userStoreXmlString = new String(mUserStore.getStoreBytes());
- String sharedStoreXmlString = new String(mSharedStore.getStoreBytes());
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(encryptedData).toLowerCase(),
- HexEncoding.encodeToString(iv).toLowerCase(),
- TEST_USER_DATA), userStoreXmlString);
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(encryptedData).toLowerCase(),
- HexEncoding.encodeToString(iv).toLowerCase(),
- TEST_SHARE_DATA), sharedStoreXmlString);
- }
-
- /**
- * Tests the read API behaviour to ensure that the integrity data is parsed from the file and
- * used for checking integrity of the file.
- */
- @Test
- public void testReadParsesIntegrityData() throws Exception {
- byte[] encryptedData = new byte[EncryptedData.ENCRYPTED_DATA_LENGTH];
- byte[] iv = new byte[EncryptedData.IV_LENGTH];
+ public void testReadVersion2StoreFile() throws Exception {
+ byte[] encryptedData = new byte[0];
+ byte[] iv = new byte[0];
Random random = new Random();
random.nextBytes(encryptedData);
random.nextBytes(iv);
@@ -1033,40 +854,14 @@ public class WifiConfigStoreTest {
TEST_SHARE_DATA).getBytes());
// Read and verify the data content in the store file (metadata stripped out) has been sent
- // to the corresponding store data when integrity check passes.
+ // to the corresponding store data.
mWifiConfigStore.read();
- verify(sharedStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
- verify(userStoreData, times(1)).deserializeData(any(XmlPullParser.class), anyInt());
-
- // Verify that we parsed the integrity data and used it for checking integrity of the file.
- ArgumentCaptor<EncryptedData> integrityCaptor =
- ArgumentCaptor.forClass(EncryptedData.class);
- ArgumentCaptor<byte[]> dataCaptor = ArgumentCaptor.forClass(byte[].class);
- // Will be invoked twice for each file - shared & user store file.
- verify(mDataIntegrityChecker, times(2)).isOk(
- dataCaptor.capture(), integrityCaptor.capture());
- // Verify the parsed integrity data
- assertEquals(2, integrityCaptor.getAllValues().size());
- EncryptedData parsedEncryptedData1 = integrityCaptor.getAllValues().get(0);
- assertArrayEquals(encryptedData, parsedEncryptedData1.getEncryptedData());
- assertArrayEquals(iv, parsedEncryptedData1.getIv());
- EncryptedData parsedEncryptedData2 = integrityCaptor.getAllValues().get(1);
- assertArrayEquals(encryptedData, parsedEncryptedData2.getEncryptedData());
- assertArrayEquals(iv, parsedEncryptedData2.getIv());
-
- // Verify that we fill in zeros to the data when we performed integrity checked.
- assertEquals(2, dataCaptor.getAllValues().size());
- String sharedStoreXmlStringWithZeroedIntegrity =
- new String(dataCaptor.getAllValues().get(0));
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_SHARE_DATA), sharedStoreXmlStringWithZeroedIntegrity);
- String userStoreXmlStringWithZeroedIntegrity = new String(dataCaptor.getAllValues().get(1));
- assertEquals(String.format(TEST_DATA_XML_STRING_FORMAT_V2_WITH_ONE_DATA_SOURCE,
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getEncryptedData()),
- HexEncoding.encodeToString(ZEROED_ENCRYPTED_DATA.getIv()),
- TEST_USER_DATA), userStoreXmlStringWithZeroedIntegrity);
+ verify(sharedStoreData, times(1))
+ .deserializeData(any(XmlPullParser.class), anyInt(),
+ eq(WifiConfigStore.INTEGRITY_CONFIG_STORE_DATA_VERSION), any());
+ verify(userStoreData, times(1))
+ .deserializeData(any(XmlPullParser.class), anyInt(),
+ eq(WifiConfigStore.INTEGRITY_CONFIG_STORE_DATA_VERSION), any());
}
/**
@@ -1078,7 +873,7 @@ public class WifiConfigStoreTest {
private boolean mStoreWritten;
MockStoreFile(@WifiConfigStore.StoreFileId int fileId) {
- super(new File("MockStoreFile"), fileId, mDataIntegrityChecker);
+ super(new File("MockStoreFile"), fileId, mEncryptionUtil);
}
@Override
@@ -1129,13 +924,14 @@ public class WifiConfigStoreTest {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out, WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
XmlUtil.writeNextValue(out, XML_TAG_TEST_DATA, mData);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth, int version,
+ WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
if (in == null) {
return;
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 222c4953a..d20c99c4f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -68,6 +68,7 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.WifiNetworkFactory.AccessPoint;
import com.android.server.wifi.nano.WifiMetricsProto;
import com.android.server.wifi.util.ScanResultUtil;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
import org.junit.After;
@@ -2932,7 +2933,7 @@ public class WifiNetworkFactoryTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mNetworkRequestStoreData.serializeData(out);
+ mNetworkRequestStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -2947,6 +2948,8 @@ public class WifiNetworkFactoryTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mNetworkRequestStoreData.deserializeData(in, in.getDepth());
+ mNetworkRequestStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
index c76e2c878..7a815001c 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreDataTest.java
@@ -25,6 +25,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.WifiConfigStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -62,7 +63,7 @@ public class PasspointConfigSharedStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mConfigStoreData.serializeData(out);
+ mConfigStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -77,7 +78,9 @@ public class PasspointConfigSharedStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mConfigStoreData.deserializeData(in, in.getDepth());
+ mConfigStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
index 82cdb5a90..5278e1933 100644
--- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointConfigUserStoreDataTest.java
@@ -32,6 +32,7 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.server.wifi.SIMAccessor;
import com.android.server.wifi.WifiConfigStore;
import com.android.server.wifi.WifiKeyStore;
+import com.android.server.wifi.util.WifiConfigStoreEncryptionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -213,7 +214,7 @@ public class PasspointConfigUserStoreDataTest {
final XmlSerializer out = new FastXmlSerializer();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
- mConfigStoreData.serializeData(out);
+ mConfigStoreData.serializeData(out, mock(WifiConfigStoreEncryptionUtil.class));
out.flush();
return outputStream.toByteArray();
}
@@ -228,7 +229,9 @@ public class PasspointConfigUserStoreDataTest {
final XmlPullParser in = Xml.newPullParser();
final ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
- mConfigStoreData.deserializeData(in, in.getDepth());
+ mConfigStoreData.deserializeData(in, in.getDepth(),
+ WifiConfigStore.ENCRYPT_CREDENTIALS_CONFIG_STORE_DATA_VERSION,
+ mock(WifiConfigStoreEncryptionUtil.class));
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java b/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
deleted file mode 100644
index c281b6440..000000000
--- a/tests/wifitests/src/com/android/server/wifi/util/DataIntegrityCheckerTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi.util;
-
-import static org.junit.Assert.*;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.io.File;
-
-/**
- * Unit tests for {@link com.android.server.wifi.util.DataIntegrityChecker}.
- */
-public class DataIntegrityCheckerTest {
- private static byte[] sGoodData = {1, 2, 3, 4};
- private static byte[] sBadData = {5, 6, 7, 8};
-
- /**
- * Verify that updating the integrity token with known data and alias will
- * pass the integrity test. This test ensure the expected outcome for
- * unedited data succeeds.
- *
- * @throws Exception
- */
- @Test
- @Ignore
- public void testIntegrityWithKnownDataAndKnownAlias() throws Exception {
- File integrityFile = File.createTempFile("testIntegrityWithKnownDataAndKnownAlias",
- ".tmp");
- DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(
- integrityFile.getParent());
- EncryptedData encryptedData = dataIntegrityChecker.compute(sGoodData);
- assertTrue(dataIntegrityChecker.isOk(sGoodData, encryptedData));
- }
-
- /**
- * Verify that checking the integrity of unknown data and a known alias
- * will fail the integrity test. This test ensure the expected failure for
- * altered data, in fact, fails.
- *
- *
- * @throws Exception
- */
- @Test
- @Ignore
- public void testIntegrityWithUnknownDataAndKnownAlias() throws Exception {
- File integrityFile = File.createTempFile("testIntegrityWithUnknownDataAndKnownAlias",
- ".tmp");
- DataIntegrityChecker dataIntegrityChecker = new DataIntegrityChecker(
- integrityFile.getParent());
- EncryptedData encryptedData = dataIntegrityChecker.compute(sGoodData);
- assertFalse(dataIntegrityChecker.isOk(sBadData, encryptedData));
- }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
index 85b4a9370..8f96bc106 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/XmlUtilTest.java
@@ -35,7 +35,9 @@ import com.android.server.wifi.util.XmlUtil.NetworkSelectionStatusXmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiConfigurationXmlUtil;
import com.android.server.wifi.util.XmlUtil.WifiEnterpriseConfigXmlUtil;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -73,6 +75,13 @@ public class XmlUtilTest {
private static final int TEST_PHASE2_METHOD = WifiEnterpriseConfig.Phase2.MSCHAPV2;
private final String mXmlDocHeader = "XmlUtilTest";
+ private WifiConfigStoreEncryptionUtil mWifiConfigStoreEncryptionUtil = null;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
/**
* Verify that a open WifiConfiguration is serialized & deserialized correctly.
*/
@@ -101,6 +110,22 @@ public class XmlUtilTest {
}
/**
+ * Verify that a psk WifiConfiguration is serialized & deserialized correctly.
+ */
+ @Test
+ public void testPskWifiConfigurationSerializeDeserializeWithEncryption()
+ throws IOException, XmlPullParserException {
+ mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
+ WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
+ EncryptedData encryptedData = new EncryptedData(new byte[0], new byte[0]);
+ when(mWifiConfigStoreEncryptionUtil.encrypt(pskNetwork.preSharedKey.getBytes()))
+ .thenReturn(encryptedData);
+ when(mWifiConfigStoreEncryptionUtil.decrypt(encryptedData))
+ .thenReturn(pskNetwork.preSharedKey.getBytes());
+ serializeDeserializeWifiConfiguration(pskNetwork);
+ }
+
+ /**
* Verify that a psk hidden WifiConfiguration is serialized & deserialized correctly.
*/
@Test
@@ -382,6 +407,37 @@ public class XmlUtilTest {
}
/**
+ * Verify that a WifiEnterpriseConfig object is serialized & deserialized correctly.
+ */
+ @Test
+ public void testWifiEnterpriseConfigSerializeDeserializeWithEncryption()
+ throws IOException, XmlPullParserException {
+ WifiEnterpriseConfig config = new WifiEnterpriseConfig();
+ config.setFieldValue(WifiEnterpriseConfig.IDENTITY_KEY, TEST_IDENTITY);
+ config.setFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY, TEST_ANON_IDENTITY);
+ config.setFieldValue(WifiEnterpriseConfig.PASSWORD_KEY, TEST_PASSWORD);
+ config.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, TEST_CLIENT_CERT);
+ config.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, TEST_CA_CERT);
+ config.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, TEST_SUBJECT_MATCH);
+ config.setFieldValue(WifiEnterpriseConfig.ENGINE_KEY, TEST_ENGINE);
+ config.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, TEST_ENGINE_ID);
+ config.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, TEST_PRIVATE_KEY_ID);
+ config.setFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, TEST_ALTSUBJECT_MATCH);
+ config.setFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, TEST_DOM_SUFFIX_MATCH);
+ config.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, TEST_CA_PATH);
+ config.setEapMethod(TEST_EAP_METHOD);
+ config.setPhase2Method(TEST_PHASE2_METHOD);
+
+ mWifiConfigStoreEncryptionUtil = mock(WifiConfigStoreEncryptionUtil.class);
+ EncryptedData encryptedData = new EncryptedData(new byte[0], new byte[0]);
+ when(mWifiConfigStoreEncryptionUtil.encrypt(TEST_PASSWORD.getBytes()))
+ .thenReturn(encryptedData);
+ when(mWifiConfigStoreEncryptionUtil.decrypt(encryptedData))
+ .thenReturn(TEST_PASSWORD.getBytes());
+ serializeDeserializeWifiEnterpriseConfig(config);
+ }
+
+ /**
* Verify that an illegal argument exception is thrown when trying to parse out a corrupted
* WifiEnterpriseConfig.
*
@@ -473,7 +529,8 @@ public class XmlUtilTest {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
XmlUtil.writeDocumentStart(out, mXmlDocHeader);
- WifiConfigurationXmlUtil.writeToXmlForConfigStore(out, configuration);
+ WifiConfigurationXmlUtil.writeToXmlForConfigStore(
+ out, configuration, mWifiConfigStoreEncryptionUtil);
XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
return outputStream.toByteArray();
}
@@ -485,7 +542,10 @@ public class XmlUtilTest {
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
- return WifiConfigurationXmlUtil.parseFromXml(in, in.getDepth());
+ return WifiConfigurationXmlUtil.parseFromXml(
+ in, in.getDepth(),
+ mWifiConfigStoreEncryptionUtil != null,
+ mWifiConfigStoreEncryptionUtil);
}
/**
@@ -593,7 +653,8 @@ public class XmlUtilTest {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
out.setOutput(outputStream, StandardCharsets.UTF_8.name());
XmlUtil.writeDocumentStart(out, mXmlDocHeader);
- WifiEnterpriseConfigXmlUtil.writeToXml(out, config);
+ WifiEnterpriseConfigXmlUtil.writeToXml(
+ out, config, mWifiConfigStoreEncryptionUtil);
XmlUtil.writeDocumentEnd(out, mXmlDocHeader);
return outputStream.toByteArray();
}
@@ -604,7 +665,9 @@ public class XmlUtilTest {
ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
in.setInput(inputStream, StandardCharsets.UTF_8.name());
XmlUtil.gotoDocumentStart(in, mXmlDocHeader);
- return WifiEnterpriseConfigXmlUtil.parseFromXml(in, in.getDepth());
+ return WifiEnterpriseConfigXmlUtil.parseFromXml(
+ in, in.getDepth(), mWifiConfigStoreEncryptionUtil != null,
+ mWifiConfigStoreEncryptionUtil);
}
private void serializeDeserializeWifiEnterpriseConfig(WifiEnterpriseConfig config)