diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-22 21:48:03 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-22 21:48:03 +0000 |
commit | fdf2bed24ecb7c33c5985a60b19944222c496e5b (patch) | |
tree | a05ceb5dc8f8206af9356fefcd27c442c1c66a11 | |
parent | 10d2b68e804660e9e57b4d88c17aefa277e5e48c (diff) | |
parent | 011b7110ccbbacbddec862c2cf17fa982845621f (diff) | |
download | RemoteKeyProvisioning-fdf2bed24ecb7c33c5985a60b19944222c496e5b.tar.gz |
Snap for 11135399 from 011b7110ccbbacbddec862c2cf17fa982845621f to simpleperf-release
Change-Id: I293832db033fcab45b0c641337810e97979d6112
6 files changed, 128 insertions, 9 deletions
@@ -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; + } +} |