Loading services/core/java/com/android/server/biometrics/BiometricService.java +4 −4 Original line number Diff line number Diff line Loading @@ -725,7 +725,7 @@ public class BiometricService extends SystemService { return -1; } if (!Utils.isValidAuthenticatorConfig(promptInfo)) { if (!Utils.isValidAuthenticatorConfig(getContext(), promptInfo)) { throw new SecurityException("Invalid authenticator configuration"); } Loading Loading @@ -763,7 +763,7 @@ public class BiometricService extends SystemService { + ", Caller=" + callingUserId + ", Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading Loading @@ -1038,7 +1038,7 @@ public class BiometricService extends SystemService { + ", Caller=" + callingUserId + ", Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading @@ -1060,7 +1060,7 @@ public class BiometricService extends SystemService { Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading services/core/java/com/android/server/biometrics/Utils.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import static android.hardware.biometrics.BiometricManager.Authenticators; Loading Loading @@ -233,17 +234,18 @@ public class Utils { * @param promptInfo * @return */ static boolean isValidAuthenticatorConfig(PromptInfo promptInfo) { static boolean isValidAuthenticatorConfig(Context context, PromptInfo promptInfo) { final int authenticators = promptInfo.getAuthenticators(); return isValidAuthenticatorConfig(authenticators); return isValidAuthenticatorConfig(context, authenticators); } /** * Checks if the authenticator configuration is a valid combination of the public APIs * @param authenticators * @return * Checks if the authenticator configuration is a valid combination of the public APIs. * * throws {@link SecurityException} if the caller requests for mandatory biometrics without * {@link SET_BIOMETRIC_DIALOG_ADVANCED} permission */ static boolean isValidAuthenticatorConfig(int authenticators) { static boolean isValidAuthenticatorConfig(Context context, int authenticators) { // The caller is not required to set the authenticators. But if they do, check the below. if (authenticators == 0) { return true; Loading Loading @@ -271,6 +273,9 @@ public class Utils { } else if (biometricBits == Authenticators.BIOMETRIC_WEAK) { return true; } else if (isMandatoryBiometricsRequested(authenticators)) { //TODO(b/347123256): Update CTS test context.enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_ADVANCED, "Must have SET_BIOMETRIC_DIALOG_ADVANCED permission"); return true; } Loading services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java +45 −11 Original line number Diff line number Diff line Loading @@ -16,12 +16,20 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.hardware.biometrics.BiometricManager.Authenticators; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; Loading @@ -36,8 +44,12 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @Presubmit @SmallTest Loading @@ -45,6 +57,17 @@ public class UtilsTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Rule public MockitoRule mockitorule = MockitoJUnit.rule(); @Mock private Context mContext; @Before public void setUp() { doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission( eq(SET_BIOMETRIC_DIALOG_ADVANCED), any()); } @Test public void testCombineAuthenticatorBundles_withKeyDeviceCredential_andKeyAuthenticators() { Loading Loading @@ -162,28 +185,39 @@ public class UtilsTest { @Test public void testIsValidAuthenticatorConfig() { assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.EMPTY_SET)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.EMPTY_SET)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_WEAK)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_WEAK)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_CONVENIENCE)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_CONVENIENCE)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_CONVENIENCE assertFalse(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_CONVENIENCE | Authenticators.DEVICE_CREDENTIAL)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_MAX_STRENGTH)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_MAX_STRENGTH)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_MIN_STRENGTH)); assertThrows(SecurityException.class, () -> Utils.isValidAuthenticatorConfig( mContext, Authenticators.MANDATORY_BIOMETRICS)); doNothing().when(mContext).enforceCallingOrSelfPermission( eq(SET_BIOMETRIC_DIALOG_ADVANCED), any()); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_MIN_STRENGTH)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.MANDATORY_BIOMETRICS)); // The rest of the bits are not allowed to integrate with the public APIs for (int i = 8; i < 32; i++) { Loading @@ -192,7 +226,7 @@ public class UtilsTest { || authenticator == Authenticators.MANDATORY_BIOMETRICS) { continue; } assertFalse(Utils.isValidAuthenticatorConfig(1 << i)); assertFalse(Utils.isValidAuthenticatorConfig(mContext, 1 << i)); } } Loading Loading
services/core/java/com/android/server/biometrics/BiometricService.java +4 −4 Original line number Diff line number Diff line Loading @@ -725,7 +725,7 @@ public class BiometricService extends SystemService { return -1; } if (!Utils.isValidAuthenticatorConfig(promptInfo)) { if (!Utils.isValidAuthenticatorConfig(getContext(), promptInfo)) { throw new SecurityException("Invalid authenticator configuration"); } Loading Loading @@ -763,7 +763,7 @@ public class BiometricService extends SystemService { + ", Caller=" + callingUserId + ", Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading Loading @@ -1038,7 +1038,7 @@ public class BiometricService extends SystemService { + ", Caller=" + callingUserId + ", Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading @@ -1060,7 +1060,7 @@ public class BiometricService extends SystemService { Slog.d(TAG, "getSupportedModalities: Authenticators=" + authenticators); if (!Utils.isValidAuthenticatorConfig(authenticators)) { if (!Utils.isValidAuthenticatorConfig(getContext(), authenticators)) { throw new SecurityException("Invalid authenticator configuration"); } Loading
services/core/java/com/android/server/biometrics/Utils.java +11 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; import static android.hardware.biometrics.BiometricManager.Authenticators; Loading Loading @@ -233,17 +234,18 @@ public class Utils { * @param promptInfo * @return */ static boolean isValidAuthenticatorConfig(PromptInfo promptInfo) { static boolean isValidAuthenticatorConfig(Context context, PromptInfo promptInfo) { final int authenticators = promptInfo.getAuthenticators(); return isValidAuthenticatorConfig(authenticators); return isValidAuthenticatorConfig(context, authenticators); } /** * Checks if the authenticator configuration is a valid combination of the public APIs * @param authenticators * @return * Checks if the authenticator configuration is a valid combination of the public APIs. * * throws {@link SecurityException} if the caller requests for mandatory biometrics without * {@link SET_BIOMETRIC_DIALOG_ADVANCED} permission */ static boolean isValidAuthenticatorConfig(int authenticators) { static boolean isValidAuthenticatorConfig(Context context, int authenticators) { // The caller is not required to set the authenticators. But if they do, check the below. if (authenticators == 0) { return true; Loading Loading @@ -271,6 +273,9 @@ public class Utils { } else if (biometricBits == Authenticators.BIOMETRIC_WEAK) { return true; } else if (isMandatoryBiometricsRequested(authenticators)) { //TODO(b/347123256): Update CTS test context.enforceCallingOrSelfPermission(SET_BIOMETRIC_DIALOG_ADVANCED, "Must have SET_BIOMETRIC_DIALOG_ADVANCED permission"); return true; } Loading
services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java +45 −11 Original line number Diff line number Diff line Loading @@ -16,12 +16,20 @@ package com.android.server.biometrics; import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED; import static android.hardware.biometrics.BiometricManager.Authenticators; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricManager; Loading @@ -36,8 +44,12 @@ import android.platform.test.flag.junit.DeviceFlagsValueProvider; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @Presubmit @SmallTest Loading @@ -45,6 +57,17 @@ public class UtilsTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Rule public MockitoRule mockitorule = MockitoJUnit.rule(); @Mock private Context mContext; @Before public void setUp() { doThrow(SecurityException.class).when(mContext).enforceCallingOrSelfPermission( eq(SET_BIOMETRIC_DIALOG_ADVANCED), any()); } @Test public void testCombineAuthenticatorBundles_withKeyDeviceCredential_andKeyAuthenticators() { Loading Loading @@ -162,28 +185,39 @@ public class UtilsTest { @Test public void testIsValidAuthenticatorConfig() { assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.EMPTY_SET)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.EMPTY_SET)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_WEAK)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_WEAK)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG)); assertTrue(Utils.isValidAuthenticatorConfig(Authenticators.DEVICE_CREDENTIAL assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_CONVENIENCE)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_CONVENIENCE)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_CONVENIENCE assertFalse(Utils.isValidAuthenticatorConfig(mContext, Authenticators.BIOMETRIC_CONVENIENCE | Authenticators.DEVICE_CREDENTIAL)); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_MAX_STRENGTH)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_MAX_STRENGTH)); assertFalse(Utils.isValidAuthenticatorConfig( mContext, Authenticators.BIOMETRIC_MIN_STRENGTH)); assertThrows(SecurityException.class, () -> Utils.isValidAuthenticatorConfig( mContext, Authenticators.MANDATORY_BIOMETRICS)); doNothing().when(mContext).enforceCallingOrSelfPermission( eq(SET_BIOMETRIC_DIALOG_ADVANCED), any()); assertFalse(Utils.isValidAuthenticatorConfig(Authenticators.BIOMETRIC_MIN_STRENGTH)); assertTrue(Utils.isValidAuthenticatorConfig(mContext, Authenticators.MANDATORY_BIOMETRICS)); // The rest of the bits are not allowed to integrate with the public APIs for (int i = 8; i < 32; i++) { Loading @@ -192,7 +226,7 @@ public class UtilsTest { || authenticator == Authenticators.MANDATORY_BIOMETRICS) { continue; } assertFalse(Utils.isValidAuthenticatorConfig(1 << i)); assertFalse(Utils.isValidAuthenticatorConfig(mContext, 1 << i)); } } Loading