Add tests for use of private and test API configurations in authenticate operations.

Fix: 230118936
Test: atest AuthServiceTest
Change-Id: Iaa60e70ec64a1fd2eb0429ec24efc65b656a307d
This commit is contained in:
Joe Bolinger
2023-01-21 00:30:26 +00:00
parent d12050a440
commit 26dbe0cf29

View File

@@ -16,16 +16,23 @@
package com.android.server.biometrics;
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.TEST_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_CANCELED;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_SUCCESS;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -53,11 +60,14 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Stubber;
import java.util.List;
@@ -65,11 +75,13 @@ import java.util.List;
@SmallTest
public class AuthServiceTest {
private static final String TAG = "AuthServiceTest";
private static final String TEST_OP_PACKAGE_NAME = "test_package";
private AuthService mAuthService;
@Rule
public MockitoRule mockitorule = MockitoJUnit.rule();
@Mock
private Context mContext;
@Mock
@@ -97,8 +109,6 @@ public class AuthServiceTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// Placeholder test config
final String[] config = {
"0:2:15", // ID0:Fingerprint:Strong
@@ -123,10 +133,13 @@ public class AuthServiceTest {
when(mInjector.getIrisService()).thenReturn(mIrisService);
when(mInjector.getAppOps(any())).thenReturn(mAppOpsManager);
when(mInjector.isHidlDisabled(any())).thenReturn(false);
setInternalAndTestBiometricPermissions(mContext, false /* hasPermission */);
}
@Test
public void testRegisterNullService_doesNotRegister() throws Exception {
setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
// Config contains Fingerprint, Iris, Face, but services are all null
@@ -259,6 +272,40 @@ public class AuthServiceTest {
verify(mReceiver).onError(eq(TYPE_NONE), eq(BIOMETRIC_ERROR_CANCELED), anyInt());
}
@Test
public void testAuthenticate_throwsWhenUsingTestConfigurations() {
final PromptInfo promptInfo = mock(PromptInfo.class);
when(promptInfo.containsPrivateApiConfigurations()).thenReturn(false);
when(promptInfo.containsTestConfigurations()).thenReturn(true);
testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo);
}
@Test
public void testAuthenticate_throwsWhenUsingPrivateApis() {
final PromptInfo promptInfo = mock(PromptInfo.class);
when(promptInfo.containsPrivateApiConfigurations()).thenReturn(true);
when(promptInfo.containsTestConfigurations()).thenReturn(false);
testAuthenticate_throwsWhenUsingTestConfigurations(promptInfo);
}
private void testAuthenticate_throwsWhenUsingTestConfigurations(PromptInfo promptInfo) {
mAuthService = new AuthService(mContext, mInjector);
mAuthService.onStart();
assertThrows(SecurityException.class, () -> {
mAuthService.mImpl.authenticate(
null /* token */,
10 /* sessionId */,
2 /* userId */,
mReceiver,
TEST_OP_PACKAGE_NAME,
promptInfo);
waitForIdle();
});
}
@Test
public void testCanAuthenticate_callsBiometricServiceCanAuthenticate() throws Exception {
mAuthService = new AuthService(mContext, mInjector);
@@ -283,8 +330,10 @@ public class AuthServiceTest {
}
@Test
public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics() throws
Exception {
public void testHasEnrolledBiometrics_callsBiometricServiceHasEnrolledBiometrics()
throws Exception {
setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
mAuthService = new AuthService(mContext, mInjector);
mAuthService.onStart();
@@ -307,6 +356,8 @@ public class AuthServiceTest {
@Test
public void testRegisterKeyguardCallback_callsBiometricServiceRegisterKeyguardCallback()
throws Exception {
setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
mAuthService = new AuthService(mContext, mInjector);
mAuthService.onStart();
@@ -320,6 +371,20 @@ public class AuthServiceTest {
eq(callback), eq(UserHandle.getCallingUserId()));
}
private static void setInternalAndTestBiometricPermissions(
Context context, boolean hasPermission) {
for (String p : List.of(TEST_BIOMETRIC, MANAGE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) {
when(context.checkCallingPermission(eq(p))).thenReturn(hasPermission
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
when(context.checkCallingOrSelfPermission(eq(p))).thenReturn(hasPermission
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
final Stubber doPermCheck =
hasPermission ? doNothing() : doThrow(SecurityException.class);
doPermCheck.when(context).enforceCallingPermission(eq(p), any());
doPermCheck.when(context).enforceCallingOrSelfPermission(eq(p), any());
}
}
private static void waitForIdle() {
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}