【Android R】manualTests#com.android.cts.verifier.security.FingerprintBoundKeysTest fail
异常日志:
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中增加该配置项即可。