summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2019-10-22 13:42:45 -0700
committerRoshan Pius <rpius@google.com>2019-11-14 11:18:00 -0800
commita161d62d9baac95a087cb3252d51c1fd101d24fa (patch)
tree4213efe8d35f12e1bd993bc35931b322a4da8f74
parentbc8fa0c163c40afa999ac71cc78687bb845131ab (diff)
WifiConfigStore: Encrypt credentials for networks (1/4)
Changes in the CL: a) Introduced a new config store version. The new version gets rid of the integrity computation & adds support for encryption of credential data. b) Changed DataIntegrityChecker to WifiConfigStoreEncryptionUtil to help the different config store modules to encrypt/decrypt their credential data to be stored. c) Pass the version & the new EncryptionUtil to all the config store modules. The version is needed for the modules to handle upgrades. d) Use the WIFI_UID to store encryption key in keystore (to help ease migrate keys if we move to a separate process in R) Actual encryption of credential data/handling of upgrades will be added in the next CL. Bug: 140485110 Test: atest com.android.server.wifi Change-Id: I522b11ef2ffbdbf0ff19ae4f2643023df3843e5e Merged-In: I522b11ef2ffbdbf0ff19ae4f2643023df3843e5e
-rw-r--r--service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java10
-rw-r--r--service/java/com/android/server/wifi/NetworkListStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/NetworkRequestStoreData.java9
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionStoreData.java9
-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/WifiConfigStore.java209
-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/WifiConfigStoreEncryptionUtil.java (renamed from service/java/com/android/server/wifi/util/DataIntegrityChecker.java)139
-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/WifiConfigStoreTest.java294
-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
24 files changed, 263 insertions, 615 deletions
diff --git a/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java b/service/java/com/android/server/wifi/DeletedEphemeralSsidsStoreData.java
index 0c064884c..3575ff254 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.NonNull;
+
+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,
+ @NonNull 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,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkListStoreData.java b/service/java/com/android/server/wifi/NetworkListStoreData.java
index 696647185..981e97c7e 100644
--- a/service/java/com/android/server/wifi/NetworkListStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkListStoreData.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.annotation.NonNull;
import android.content.Context;
import android.net.IpConfiguration;
import android.net.wifi.WifiConfiguration;
@@ -25,6 +26,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,13 +68,16 @@ public abstract class NetworkListStoreData implements WifiConfigStore.StoreData
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
serializeNetworkList(out, mConfigurations);
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/NetworkRequestStoreData.java b/service/java/com/android/server/wifi/NetworkRequestStoreData.java
index 8d1244f05..3a5143f56 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.NonNull;
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,
+ @NonNull 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,
+ @NonNull 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..e9503b7e4 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -16,6 +16,7 @@
package com.android.server.wifi;
+import android.annotation.NonNull;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiNetworkSuggestion;
@@ -26,6 +27,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,13 +100,16 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
}
@Override
- public void serializeData(XmlSerializer out)
+ public void serializeData(XmlSerializer out,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
serializeNetworkSuggestionsMap(out, mDataSource.toSerialize());
}
@Override
- public void deserializeData(XmlPullParser in, int outerTagDepth)
+ public void deserializeData(XmlPullParser in, int outerTagDepth,
+ @WifiConfigStore.Version int version,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
diff --git a/service/java/com/android/server/wifi/RandomizedMacStoreData.java b/service/java/com/android/server/wifi/RandomizedMacStoreData.java
index 1e4d972ef..8e47ee7bf 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.NonNull;
+
+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,
+ @NonNull 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,
+ @NonNull 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..1339dae38 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.NonNull;
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,
+ @NonNull 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,
+ @NonNull 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..1d146a0e1 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.NonNull;
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,
+ @NonNull 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,
+ @NonNull 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/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java
index e189d00e1..efe4a4c8d 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;
@@ -106,17 +105,33 @@ public class WifiConfigStore {
/**
* 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.
@@ -291,8 +306,9 @@ 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 =
+ new WifiConfigStoreEncryptionUtil(file.getName());
+ return new StoreFile(file, fileId, encryptionUtil);
}
/**
@@ -427,88 +443,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 +575,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 +601,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 +613,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 +632,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 +650,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 +661,16 @@ 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.readNextValueWithName(in, XML_TAG_INTEGRITY_ENCRYPTED_DATA);
+ XmlUtil.readNextValueWithName(in, XML_TAG_INTEGRITY_IV);
}
/**
@@ -790,14 +722,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) {
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil) {
mAtomicFile = new AtomicFile(file);
mFileName = file.getAbsolutePath();
mFileId = fileId;
- mDataIntegrityChecker = dataIntegrityChecker;
+ mEncryptionUtil = encryptionUtil;
}
/**
@@ -810,6 +742,13 @@ public class WifiConfigStore {
}
/**
+ * @return Returns the encryption util used for this store file.
+ */
+ public @NonNull 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 +801,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 +820,9 @@ 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, @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException;
/**
@@ -918,10 +831,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,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException;
/**
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java b/service/java/com/android/server/wifi/hotspot2/PasspointConfigSharedStoreData.java
index 419ea7993..9abccb94b 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.NonNull;
+
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,
+ @NonNull 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,
+ @NonNull 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..1001b1189 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.NonNull;
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,
+ @NonNull 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,
+ @NonNull WifiConfigStoreEncryptionUtil encryptionUtil)
throws XmlPullParserException, IOException {
// Ignore empty reads.
if (in == null) {
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/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/WifiConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
index b59e367dd..9c16b1257 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigStoreTest.java
@@ -21,7 +21,6 @@ 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 +33,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 +42,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 +71,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 +164,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 +188,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)))
+ when(mEncryptionUtil.encrypt(any(byte[].class)))
.thenReturn(ZEROED_ENCRYPTED_DATA);
- when(mDataIntegrityChecker.isOk(any(byte[].class), any(EncryptedData.class)))
- .thenReturn(true);
+ 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 +424,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 +454,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 +631,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 +647,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 +663,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 +681,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 +731,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,188 +807,19 @@ 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());
- }
-
- /**
- * Tests the write API behaviour when integrity check fails.
- * Expected behaviour: The read should return an empty store data.
- */
- @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);
+ 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 read API behaviour to ensure that the integrity data is parsed from the file and
- * used for checking integrity of the file.
+ * Tests the read API behaviour to ensure that the integrity data is parsed from the file.
*/
@Test
- public void testReadParsesIntegrityData() throws Exception {
+ public void testReadVersion2StoreFile() throws Exception {
byte[] encryptedData = new byte[EncryptedData.ENCRYPTED_DATA_LENGTH];
byte[] iv = new byte[EncryptedData.IV_LENGTH];
Random random = new Random();
@@ -1033,40 +856,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 +875,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 +926,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));
- }
-}