summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-22 21:48:03 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-22 21:48:03 +0000
commitfdf2bed24ecb7c33c5985a60b19944222c496e5b (patch)
treea05ceb5dc8f8206af9356fefcd27c442c1c66a11
parent10d2b68e804660e9e57b4d88c17aefa277e5e48c (diff)
parent011b7110ccbbacbddec862c2cf17fa982845621f (diff)
downloadRemoteKeyProvisioning-fdf2bed24ecb7c33c5985a60b19944222c496e5b.tar.gz
Snap for 11135399 from 011b7110ccbbacbddec862c2cf17fa982845621f to simpleperf-release
Change-Id: I293832db033fcab45b0c641337810e97979d6112
-rw-r--r--OWNERS1
-rw-r--r--app/src/com/android/rkpdapp/interfaces/ServiceManagerInterface.java48
-rw-r--r--app/tests/e2e/src/com/android/rkpdapp/e2etest/KeystoreIntegrationTest.java4
-rw-r--r--app/tests/e2e/src/com/android/rkpdapp/e2etest/RkpdHostTestHelperTests.java7
-rw-r--r--app/tests/unit/src/com/android/rkpdapp/unittest/SystemInterfaceTest.java33
-rw-r--r--app/tests/util/src/com/android/rkpdapp/testutil/SystemInterfaceSelector.java44
6 files changed, 128 insertions, 9 deletions
diff --git a/OWNERS b/OWNERS
index 01955db..2cbf527 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 1084908
sethmo@google.com
vikramgaur@google.com
diff --git a/app/src/com/android/rkpdapp/interfaces/ServiceManagerInterface.java b/app/src/com/android/rkpdapp/interfaces/ServiceManagerInterface.java
index 38766b1..3ba716c 100644
--- a/app/src/com/android/rkpdapp/interfaces/ServiceManagerInterface.java
+++ b/app/src/com/android/rkpdapp/interfaces/ServiceManagerInterface.java
@@ -19,8 +19,11 @@ package com.android.rkpdapp.interfaces;
import android.annotation.TestApi;
import android.hardware.security.keymint.IRemotelyProvisionedComponent;
import android.os.ServiceManager;
+import android.util.Log;
import java.util.Arrays;
+import java.util.Map;
+import java.util.Objects;
/**
* Provides convenience methods for interfacing with ServiceManager class and its static functions.
@@ -28,33 +31,54 @@ import java.util.Arrays;
public class ServiceManagerInterface {
private static final String TAG = "RkpdSvcManagerInterface";
private static SystemInterface[] sInstances;
+ private static Map<String, IRemotelyProvisionedComponent> sBinders;
private ServiceManagerInterface() {
}
- private static SystemInterface createSystemInterface(String serviceName) {
+ private static SystemInterface tryCreateSystemInterface(IRemotelyProvisionedComponent binder,
+ String serviceName) {
+ try {
+ return new SystemInterface(binder, serviceName);
+ } catch (UnsupportedOperationException e) {
+ Log.i(TAG, serviceName + " is unsupported.");
+ return null;
+ }
+ }
+
+ private static IRemotelyProvisionedComponent getBinder(String serviceName) {
IRemotelyProvisionedComponent binder = IRemotelyProvisionedComponent.Stub.asInterface(
ServiceManager.waitForDeclaredService(serviceName));
if (binder == null) {
throw new IllegalArgumentException("Cannot find any implementation for " + serviceName);
}
- return new SystemInterface(binder, serviceName);
+ return binder;
}
/**
* Gets all the instances on this device for IRemotelyProvisionedComponent as an array. The
* returned values each contain a binder for interacting with the instance.
*
- * For testing purposes, the instances may be overridden by setInstances
+ * For testing purposes, the instances may be overridden by either setInstances or setBinders.
*/
public static SystemInterface[] getAllInstances() {
+ if (sBinders != null) {
+ return sBinders.entrySet().stream()
+ .map(x -> tryCreateSystemInterface(x.getValue(), x.getKey()))
+ .filter(Objects::nonNull)
+ .toArray(SystemInterface[]::new);
+ }
if (sInstances != null) {
return sInstances;
}
String irpcInterface = IRemotelyProvisionedComponent.DESCRIPTOR;
return Arrays.stream(ServiceManager.getDeclaredInstances(irpcInterface))
- .map(x -> createSystemInterface(irpcInterface + "/" + x))
+ .map(x -> {
+ String serviceName = irpcInterface + "/" + x;
+ return tryCreateSystemInterface(getBinder(serviceName), serviceName);
+ })
+ .filter(Objects::nonNull)
.toArray(SystemInterface[]::new);
}
@@ -62,10 +86,17 @@ public class ServiceManagerInterface {
* Get a specific system interface instance for a given IRemotelyProvisionedComponent.
* If the given serviceName does not map to a known IRemotelyProvisionedComponent, this
* method throws IllegalArgumentException.
+ * If the given serviceName is not supported, this method throws UnsupportedOperationException.
*
- * For testing purposes, the instances may be overridden by setInstances.
+ * For testing purposes, the instances may be overridden by either setInstances or setBinders.
*/
public static SystemInterface getInstance(String serviceName) {
+ if (sBinders != null) {
+ if (sBinders.containsKey(serviceName)) {
+ return new SystemInterface(sBinders.get(serviceName), serviceName);
+ }
+ throw new IllegalArgumentException("Cannot find any binder for " + serviceName);
+ }
if (sInstances != null) {
for (SystemInterface i : sInstances) {
if (i.getServiceName().equals(serviceName)) {
@@ -75,11 +106,16 @@ public class ServiceManagerInterface {
throw new IllegalArgumentException("Cannot find any implementation for " + serviceName);
}
- return createSystemInterface(serviceName);
+ return new SystemInterface(getBinder(serviceName), serviceName);
}
@TestApi
public static void setInstances(SystemInterface[] instances) {
sInstances = instances;
}
+
+ @TestApi
+ public static void setBinders(Map<String, IRemotelyProvisionedComponent> binders) {
+ sBinders = binders;
+ }
}
diff --git a/app/tests/e2e/src/com/android/rkpdapp/e2etest/KeystoreIntegrationTest.java b/app/tests/e2e/src/com/android/rkpdapp/e2etest/KeystoreIntegrationTest.java
index 46bd879..1d58033 100644
--- a/app/tests/e2e/src/com/android/rkpdapp/e2etest/KeystoreIntegrationTest.java
+++ b/app/tests/e2e/src/com/android/rkpdapp/e2etest/KeystoreIntegrationTest.java
@@ -46,6 +46,7 @@ import com.android.rkpdapp.interfaces.ServiceManagerInterface;
import com.android.rkpdapp.interfaces.SystemInterface;
import com.android.rkpdapp.provisioner.PeriodicProvisioner;
import com.android.rkpdapp.testutil.FakeRkpServer;
+import com.android.rkpdapp.testutil.SystemInterfaceSelector;
import com.android.rkpdapp.testutil.SystemPropertySetter;
import com.android.rkpdapp.utils.Settings;
import com.android.rkpdapp.utils.X509Utils;
@@ -129,7 +130,8 @@ public class KeystoreIntegrationTest {
mKeyStore.load(null);
mKeyDao.deleteAllKeys();
- SystemInterface systemInterface = ServiceManagerInterface.getInstance(mServiceName);
+ SystemInterface systemInterface =
+ SystemInterfaceSelector.getSystemInterfaceForServiceName(mServiceName);
ServiceManagerInterface.setInstances(new SystemInterface[] {systemInterface});
}
diff --git a/app/tests/e2e/src/com/android/rkpdapp/e2etest/RkpdHostTestHelperTests.java b/app/tests/e2e/src/com/android/rkpdapp/e2etest/RkpdHostTestHelperTests.java
index 0eb76be..c1762d5 100644
--- a/app/tests/e2e/src/com/android/rkpdapp/e2etest/RkpdHostTestHelperTests.java
+++ b/app/tests/e2e/src/com/android/rkpdapp/e2etest/RkpdHostTestHelperTests.java
@@ -42,6 +42,7 @@ import com.android.rkpdapp.interfaces.ServerInterface;
import com.android.rkpdapp.interfaces.ServiceManagerInterface;
import com.android.rkpdapp.interfaces.SystemInterface;
import com.android.rkpdapp.provisioner.PeriodicProvisioner;
+import com.android.rkpdapp.testutil.SystemInterfaceSelector;
import com.android.rkpdapp.testutil.TestDatabase;
import com.android.rkpdapp.testutil.TestProvisionedKeyDao;
import com.android.rkpdapp.utils.Settings;
@@ -107,13 +108,15 @@ public class RkpdHostTestHelperTests {
mRealDao = RkpdDatabase.getDatabase(sContext).provisionedKeyDao();
mRealDao.deleteAllKeys();
mTestDao = Room.databaseBuilder(sContext, TestDatabase.class, DB_NAME).build().dao();
- SystemInterface systemInterface = ServiceManagerInterface.getInstance(mServiceName);
- ServiceManagerInterface.setInstances(new SystemInterface[] {systemInterface});
mProvisioner = TestWorkerBuilder.from(
sContext,
PeriodicProvisioner.class,
Executors.newSingleThreadExecutor()).build();
+
+ SystemInterface systemInterface =
+ SystemInterfaceSelector.getSystemInterfaceForServiceName(mServiceName);
+ ServiceManagerInterface.setInstances(new SystemInterface[] {systemInterface});
}
@After
diff --git a/app/tests/unit/src/com/android/rkpdapp/unittest/SystemInterfaceTest.java b/app/tests/unit/src/com/android/rkpdapp/unittest/SystemInterfaceTest.java
index cd86af5..c201e11 100644
--- a/app/tests/unit/src/com/android/rkpdapp/unittest/SystemInterfaceTest.java
+++ b/app/tests/unit/src/com/android/rkpdapp/unittest/SystemInterfaceTest.java
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -53,8 +54,10 @@ import com.android.rkpdapp.interfaces.SystemInterface;
import com.android.rkpdapp.metrics.ProvisioningAttempt;
import com.android.rkpdapp.utils.CborUtils;
+import com.google.common.collect.ImmutableMap;
import com.google.crypto.tink.subtle.Ed25519Sign;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
@@ -93,6 +96,12 @@ public class SystemInterfaceTest {
Assume.assumeTrue(ServiceManager.isDeclared(SERVICE));
}
+ @After
+ public void cleanUp() {
+ ServiceManagerInterface.setBinders(null);
+ ServiceManagerInterface.setInstances(null);
+ }
+
@Test
public void testGetDeclaredInstances() {
SystemInterface[] instances = ServiceManagerInterface.getAllInstances();
@@ -115,6 +124,30 @@ public class SystemInterfaceTest {
}
@Test
+ public void testGetAllInstancesWithUnsupportedService() throws RemoteException {
+ IRemotelyProvisionedComponent mockedBinder = mock(IRemotelyProvisionedComponent.class);
+ doThrow(new UnsupportedOperationException()).when(mockedBinder).getHardwareInfo();
+ ServiceManagerInterface.setBinders(ImmutableMap.of(SERVICE, mockedBinder));
+
+ SystemInterface[] instances = ServiceManagerInterface.getAllInstances();
+ assertThat(instances).isEmpty();
+ }
+
+ @Test
+ public void testGetInstanceWithUnsupportedService() throws RemoteException {
+ IRemotelyProvisionedComponent mockedBinder = mock(IRemotelyProvisionedComponent.class);
+ doThrow(new UnsupportedOperationException()).when(mockedBinder).getHardwareInfo();
+ ServiceManagerInterface.setBinders(ImmutableMap.of(SERVICE, mockedBinder));
+
+ try {
+ SystemInterface ignored = ServiceManagerInterface.getInstance(SERVICE);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ // pass
+ }
+ }
+
+ @Test
public void testGenerateKey() throws CborException, RkpdException, RemoteException {
IRemotelyProvisionedComponent mockedComponent = mock(IRemotelyProvisionedComponent.class);
SystemInterface systemInterface = mockSystemInterface(CborUtils.EC_CURVE_25519,
diff --git a/app/tests/util/src/com/android/rkpdapp/testutil/SystemInterfaceSelector.java b/app/tests/util/src/com/android/rkpdapp/testutil/SystemInterfaceSelector.java
new file mode 100644
index 0000000..0f49691
--- /dev/null
+++ b/app/tests/util/src/com/android/rkpdapp/testutil/SystemInterfaceSelector.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 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.rkpdapp.testutil;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
+
+import android.hardware.security.keymint.IRemotelyProvisionedComponent;
+
+import com.android.rkpdapp.interfaces.ServiceManagerInterface;
+import com.android.rkpdapp.interfaces.SystemInterface;
+
+public class SystemInterfaceSelector {
+ /**
+ * Gets the system interface object for provided service name.
+ */
+ public static SystemInterface getSystemInterfaceForServiceName(String serviceName) {
+ SystemInterface matchingInterface = null;
+ for (SystemInterface systemInterface: ServiceManagerInterface.getAllInstances()) {
+ if (systemInterface.getServiceName().equals(serviceName)) {
+ matchingInterface = systemInterface;
+ }
+ }
+ if (matchingInterface == null) {
+ assertThat(serviceName).isEqualTo(IRemotelyProvisionedComponent.DESCRIPTOR + "/avf");
+ assume().withMessage("AVF is not supported by this system").fail();
+ }
+ return matchingInterface;
+ }
+}