【Android R】manualTests#com.android.cts.verifier.security.FingerprintBoundKeysTest fail

发布时间 2023-11-23 11:21:07作者: xiululu

异常日志:

11-12 19:24:47.649 5387 5387 D AndroidRuntime: Shutting down VM
11-12 19:24:47.671 5387 5387 E AndroidRuntime: FATAL EXCEPTION: main
11-12 19:24:47.671 5387 5387 E AndroidRuntime: Process: com.android.cts.verifier, PID: 5387
11-12 19:24:47.671 5387 5387 E AndroidRuntime: java.lang.RuntimeException: Failed to create a symmetric key
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.cts.verifier.security.FingerprintBoundKeysTest.createKey(FingerprintBoundKeysTest.java:181)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.cts.verifier.security.FingerprintBoundKeysTest.startTest(FingerprintBoundKeysTest.java:138)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.cts.verifier.security.FingerprintBoundKeysTest$1.onClick(FingerprintBoundKeysTest.java:118)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.view.View.performClick(View.java:7448)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.view.View.performClickInternal(View.java:7425)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.view.View.access$3600(View.java:810)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:28305)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.os.Looper.loop(Looper.java:223)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7664)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:948)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: Caused by: java.security.InvalidAlgorithmParameterException: java.lang.IllegalStateException: At least one biometric must be enrolled to create keys requiring user authentication for every use
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:252)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi$AES.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:53)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at javax.crypto.KeyGenerator.init(KeyGenerator.java:519)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at javax.crypto.KeyGenerator.init(KeyGenerator.java:502)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at com.android.cts.verifier.security.FingerprintBoundKeysTest.createKey(FingerprintBoundKeysTest.java:162)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: ... 13 more
11-12 19:24:47.671 5387 5387 E AndroidRuntime: Caused by: java.lang.IllegalStateException: At least one biometric must be enrolled to create keys requiring user authentication for every use
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.security.keystore.KeymasterUtils.addSids(KeymasterUtils.java:110)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.security.keystore.KeymasterUtils.addUserAuthArgs(KeymasterUtils.java:174)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: at android.security.keystore.AndroidKeyStoreKeyGeneratorSpi.engineInit(AndroidKeyStoreKeyGeneratorSpi.java:250)
11-12 19:24:47.671 5387 5387 E AndroidRuntime: ... 17 more

看下addSids这个函数:

private static void addSids(KeymasterArguments args, UserAuthArgs spec) {
    // If both biometric and credential are accepted, then just use the root sid from gatekeeper
    if (spec.getUserAuthenticationType() == (KeyProperties.AUTH_BIOMETRIC_STRONG
                                             | KeyProperties.AUTH_DEVICE_CREDENTIAL)) {
        if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
            args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                    KeymasterArguments.toUint64(spec.getBoundToSpecificSecureUserId()));
        } else {
            // The key is authorized for use for the specified amount of time after the user has
            // authenticated. Whatever unlocks the secure lock screen should authorize this key.
            args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                    KeymasterArguments.toUint64(getRootSid()));
        }
    } else {
        List<Long> sids = new ArrayList<>();
         if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_BIOMETRIC_STRONG) != 0) {
             final BiometricManager bm = KeyStore.getApplicationContext()
                     .getSystemService(BiometricManager.class);

             // TODO: Restore permission check in getAuthenticatorIds once the ID is no longer
             // needed here.

             final long[] biometricSids = bm.getAuthenticatorIds();

             if (biometricSids.length == 0) {
                 throw new IllegalStateException(
                         "At least one biometric must be enrolled to create keys requiring user"
                         + " authentication for every use");
             }

             if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
                 sids.add(spec.getBoundToSpecificSecureUserId());
             } else if (spec.isInvalidatedByBiometricEnrollment()) {
                 // The biometric-only SIDs will change on biometric enrollment or removal of all
                 // enrolled templates, invalidating the key.
                 for (long sid : biometricSids) {
                     sids.add(sid);
                 }
             } else {
                 // The root SID will *not* change on fingerprint enrollment, or removal of all
                 // enrolled fingerprints, allowing the key to remain valid.
                 sids.add(getRootSid());
             }
         } else if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_DEVICE_CREDENTIAL)
                         != 0) {
             sids.add(getRootSid());
         } else {
             throw new IllegalStateException("Invalid or no authentication type specified.");
         }

         for (int i = 0; i < sids.size(); i++) {
             args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                     KeymasterArguments.toUint64(sids.get(i)));
         }
     }
 }

经过对BiometricService.java的getAuthenticatorIds函数和调用关系进一步分析,发现与frameworks/base/services/core/java/com/android/server/biometrics/AuthService.java中的getConfiguration方法有关,该方法会读取R.array.config_biometric_sensors的值来生成相关的配置和参数信息,android默认没有配置该值:

/**
 * Allows to test with various device sensor configurations.
 * @param context System Server context
 * @return the sensor configuration from core/res/res/values/config.xml
 */
@VisibleForTesting
public String[] getConfiguration(Context context) {
    return context.getResources().getStringArray(R.array.config_biometric_sensors);
}

默认配置:

frameworks/base/core/res/res/values/config.xml
<!-- List of biometric sensors on the device, in decreasing strength. Consumed by AuthService
     when registering authenticators with BiometricService. Format must be ID:Modality:Strength,
     where: IDs are unique per device, Modality as defined in BiometricAuthenticator.java,
     and Strength as defined in Authenticators.java -->
<string-array name="config_biometric_sensors" translatable="false" >
    <!-- <item>0:2:15</item>  ID0:Fingerprint:Strong -->
</string-array>

修改方法:在板极overlay的config.xml中增加该配置项即可