Skip to content
Snippets Groups Projects
Commit ddbcdfef authored by Gabriel Biren's avatar Gabriel Biren Committed by Android (Google) Code Review
Browse files

Merge changes Idb3905ce,I5111a20a into main

* changes:
  Add unit tests for WifiKeystore.
  Move getLegacyKeystore to the WifiBlobStore class.
parents f8bd1ec6 e2229449
No related branches found
No related tags found
No related merge requests found
......@@ -16,6 +16,9 @@
package android.net.wifi;
import android.os.ServiceManager;
import android.security.legacykeystore.ILegacyKeystore;
import com.android.internal.net.ConnectivityBlobStore;
/**
......@@ -24,6 +27,7 @@ import com.android.internal.net.ConnectivityBlobStore;
*/
public class WifiBlobStore extends ConnectivityBlobStore {
private static final String DB_NAME = "WifiBlobStore.db";
private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
private static WifiBlobStore sInstance;
private WifiBlobStore() {
super(DB_NAME);
......@@ -36,4 +40,10 @@ public class WifiBlobStore extends ConnectivityBlobStore {
}
return sInstance;
}
/** Returns an interface to access the Legacy Keystore service. */
public static ILegacyKeystore getLegacyKeystore() {
return ILegacyKeystore.Stub.asInterface(
ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
}
}
......@@ -20,7 +20,6 @@ import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.os.Binder;
import android.os.Process;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
import android.security.legacykeystore.ILegacyKeystore;
import android.util.Log;
......@@ -37,12 +36,6 @@ import java.util.Set;
@SuppressLint("UnflaggedApi") // Promoting from @SystemApi(MODULE_LIBRARIES)
public final class WifiKeystore {
private static final String TAG = "WifiKeystore";
private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
private static ILegacyKeystore getLegacyKeystore() {
return ILegacyKeystore.Stub.asInterface(
ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
}
/** @hide */
WifiKeystore() {
......@@ -93,7 +86,7 @@ public final class WifiKeystore {
return blob;
}
Log.i(TAG, "Searching for blob in Legacy Keystore");
return getLegacyKeystore().get(alias, Process.WIFI_UID);
return WifiBlobStore.getLegacyKeystore().get(alias, Process.WIFI_UID);
} catch (ServiceSpecificException e) {
if (e.errorCode != ILegacyKeystore.ERROR_ENTRY_NOT_FOUND) {
Log.e(TAG, "Failed to get blob.", e);
......@@ -122,7 +115,7 @@ public final class WifiKeystore {
Log.i(TAG, "remove blob. alias " + alias);
blobStoreSuccess = WifiBlobStore.getInstance().remove(alias);
// Legacy Keystore will throw an exception if the alias is not found.
getLegacyKeystore().remove(alias, Process.WIFI_UID);
WifiBlobStore.getLegacyKeystore().remove(alias, Process.WIFI_UID);
legacyKsSuccess = true;
} catch (ServiceSpecificException e) {
if (e.errorCode != ILegacyKeystore.ERROR_ENTRY_NOT_FOUND) {
......@@ -151,7 +144,8 @@ public final class WifiKeystore {
try {
// Aliases from WifiBlobStore will be pre-trimmed.
final String[] blobStoreAliases = WifiBlobStore.getInstance().list(prefix);
final String[] legacyAliases = getLegacyKeystore().list(prefix, Process.WIFI_UID);
final String[] legacyAliases =
WifiBlobStore.getLegacyKeystore().list(prefix, Process.WIFI_UID);
for (int i = 0; i < legacyAliases.length; ++i) {
legacyAliases[i] = legacyAliases[i].substring(prefix.length());
}
......
/*
* Copyright (C) 2024 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 android.net.wifi;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.withSettings;
import android.os.ServiceSpecificException;
import android.security.legacykeystore.ILegacyKeystore;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import java.util.Arrays;
/** Unit tests for {@link WifiKeystore} */
public class WifiKeystoreTest {
public static final String TEST_ALIAS = "someAliasString";
public static final byte[] TEST_VALUE = new byte[]{10, 11, 12};
@Mock private ILegacyKeystore mLegacyKeystore;
@Mock private WifiBlobStore mWifiBlobStore;
private MockitoSession mSession;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mSession = ExtendedMockito.mockitoSession()
.mockStatic(WifiBlobStore.class, withSettings().lenient())
.startMocking();
when(WifiBlobStore.getLegacyKeystore()).thenReturn(mLegacyKeystore);
when(WifiBlobStore.getInstance()).thenReturn(mWifiBlobStore);
}
@After
public void cleanup() {
validateMockitoUsage();
if (mSession != null) {
mSession.finishMocking();
}
}
/**
* Test that put() only writes to the WifiBlobStore database.
*/
@Test
public void testPut() throws Exception {
WifiKeystore.put(TEST_ALIAS, TEST_VALUE);
verify(mWifiBlobStore).put(anyString(), any());
verify(mLegacyKeystore, never()).put(anyString(), anyInt(), any());
}
/**
* Test that if the alias is found in the WifiBlobStore database,
* then the legacy database is not searched.
*/
@Test
public void testGet_wifiBlobStoreDb() throws Exception {
when(mWifiBlobStore.get(anyString())).thenReturn(TEST_VALUE);
assertArrayEquals(TEST_VALUE, WifiKeystore.get(TEST_ALIAS));
verify(mWifiBlobStore).get(anyString());
verify(mLegacyKeystore, never()).get(anyString(), anyInt());
}
/**
* Test that if the alias is not found in the WifiBlobStore database,
* then the legacy database is searched.
*/
@Test
public void testGet_legacyDb() throws Exception {
when(mWifiBlobStore.get(anyString())).thenReturn(null);
when(mLegacyKeystore.get(anyString(), anyInt())).thenReturn(TEST_VALUE);
assertArrayEquals(TEST_VALUE, WifiKeystore.get(TEST_ALIAS));
verify(mWifiBlobStore).get(anyString());
verify(mLegacyKeystore).get(anyString(), anyInt());
}
/**
* Test that get() returns a non-null value if the alias is
* not found in either database.
*/
@Test
public void testGet_notFound() throws Exception {
when(mWifiBlobStore.get(anyString())).thenReturn(null);
when(mLegacyKeystore.get(anyString(), anyInt()))
.thenThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND));
assertNotNull(WifiKeystore.get(TEST_ALIAS));
}
/**
* Test that remove() returns true if the alias is removed
* from at least one database.
*/
@Test
public void testRemove_success() throws Exception {
// Only removed from WifiBlobStore
when(mWifiBlobStore.remove(anyString())).thenReturn(true);
doThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND))
.when(mLegacyKeystore).remove(anyString(), anyInt());
assertTrue(WifiKeystore.remove(TEST_ALIAS));
// Only removed from Legacy Keystore
when(mWifiBlobStore.remove(anyString())).thenReturn(false);
doNothing().when(mLegacyKeystore).remove(anyString(), anyInt());
assertTrue(WifiKeystore.remove(TEST_ALIAS));
// Removed from both WifiBlobStore and Legacy Keystore
when(mWifiBlobStore.remove(anyString())).thenReturn(true);
doNothing().when(mLegacyKeystore).remove(anyString(), anyInt());
assertTrue(WifiKeystore.remove(TEST_ALIAS));
}
/**
* Test that remove() returns false if the alias is not removed
* from any database.
*/
@Test
public void testRemove_notFound() throws Exception {
when(mWifiBlobStore.remove(anyString())).thenReturn(false);
doThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND))
.when(mLegacyKeystore).remove(anyString(), anyInt());
assertFalse(WifiKeystore.remove(TEST_ALIAS));
}
/**
* Test that list() retrieves aliases from both the WifiBlobStore
* and Legacy Keystore databases. The results should be de-duplicated.
*/
@Test
public void testList() throws Exception {
// Aliases retrieved from WifiBlobStore will be pre-trimmed.
String[] blobStoreAliases = new String[]{"1", "2"};
String[] legacyDbAliases = new String[]{TEST_ALIAS + "2", TEST_ALIAS + "3"};
when(mWifiBlobStore.list(anyString())).thenReturn(blobStoreAliases);
when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyDbAliases);
// Alias 2 exists in both DBs and should be de-duplicated.
String[] expected = new String[]{"1", "2", "3"};
String[] retrieved = WifiKeystore.list(TEST_ALIAS);
Arrays.sort(retrieved);
assertArrayEquals(expected, retrieved);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment