Warn user when removing LSKF in the presence of auth-bound keys
When the user goes through the flow of removing the device's lockscreen
knowledge factor (LSKF), warn them in case they have apps with
auth-bound keys on the device. Auth-bound keys that are bound to the
LSKF's secure user ID (that is, auth-bound keys that can be
authenticated by the user entering their LSKF) will be invalidated
when the LSKF is removed.
That means apps will not be able to decrypt the data encrypted with
these keys or use them to sign anything anymore (potentially effectively
losing the user's ability to prove their identity).
In this case, change the warning message that is shown to the user,
to make it clear wallet apps (that typically use such keys) will stop
working as well as other apps.
Bug: 302109605
Test: Manual, enrolled a PIN, face and fingerprint and tried removing PIN.
A CtsVerifier test will be added later.
Change-Id: I276b744f54763e291abe1f20824da4f8f156679d
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 01979b2..6845e74 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1520,7 +1520,7 @@
<string name="unlock_set_unlock_mode_password">Password</string>
<!-- Title of the dialog shown when the user removes the device lock [CHAR LIMIT=NONE] -->
- <string name="unlock_disable_frp_warning_title">Delete screen lock?</string>
+ <string name="unlock_disable_frp_warning_title">Remove all types of device unlock?</string>
<!-- Title of the dialog shown when the user removes the profile lock [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_title_profile">Remove profile protection?</string>
@@ -1534,12 +1534,20 @@
<string name="unlock_disable_frp_warning_content_pattern_face_fingerprint">"A pattern protects your phone if it\u2019s lost or stolen.<xliff:g id="empty_line">\n\n</xliff:g>This deletes the fingerprint model stored on your device. Your face model will also be permanently and securely deleted. You won\u2019t be able to use your face or fingerprint for authentication in apps."</string>
<!-- Content of the dialog shown when the user removes the device lock PIN [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_content_pin">"A PIN protects your phone if it\u2019s lost or stolen"</string>
+ <!-- Content of the dialog shown when the user removes the device lock PIN and there are apps with auth-bound keys that will be affected [CHAR LIMIT=NONE] -->
+ <string name="unlock_disable_frp_warning_content_pin_authbound_keys">"You will lose saved data like your PIN.<xliff:g id="empty_line">\n\n</xliff:g>Cards set up for tap to pay will be removed.<xliff:g id="empty_line">\n\n</xliff:g>Wallets and other apps that require device unlock may not work properly."</string>
<!-- Content of the dialog shown when the user removes the device lock PIN and the user has fingerprints enrolled [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_content_pin_fingerprint">"A PIN protects your phone if it\u2019s lost or stolen.<xliff:g id="empty_line">\n\n</xliff:g>This also deletes the fingerprint model stored on your device. You won\u2019t be able to use your fingerprint for authentication in apps."</string>
+ <!-- Content of the dialog shown when the user removes the device lock PIN and the user has fingerprints enrolled and there are apps with auth-bound keys that will be affected [CHAR LIMIT=NONE] -->
+ <string name="unlock_disable_frp_warning_content_pin_fingerprint_authbound_keys">"You will lose saved data like your PIN and fingerprint model.<xliff:g id="empty_line">\n\n</xliff:g>Cards set up for tap to pay will be removed.<xliff:g id="empty_line">\n\n</xliff:g>Wallets and other apps that require device unlock may not work properly."</string>
<!-- Content of the dialog shown when the user removes the device lock PIN and the user has face enrolled [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_content_pin_face">"A PIN protects your phone if it\u2019s lost or stolen.<xliff:g id="empty_line">\n\n</xliff:g>Your face model will also be permanently and securely deleted. You won\u2019t be able to use your face for authentication in apps."</string>
+ <!-- Content of the dialog shown when the user removes the device lock PIN and the user has face enrolled and there are apps with auth-bound keys that will be affected [CHAR LIMIT=NONE] -->
+ <string name="unlock_disable_frp_warning_content_pin_face_authbound_keys">"You will lose saved data like your PIN and face model.<xliff:g id="empty_line">\n\n</xliff:g>Cards set up for tap to pay will be removed.<xliff:g id="empty_line">\n\n</xliff:g>Wallets and other apps that require device unlock may not work properly."</string>
<!-- Content of the dialog shown when the user removes the device lock PIN and the user has face authentication and fingerprint enrolled [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_content_pin_face_fingerprint">"A PIN protects your phone if it\u2019s lost or stolen.<xliff:g id="empty_line">\n\n</xliff:g>This deletes the fingerprint model stored on your device. Your face model will also be permanently and securely deleted. You won\u2019t be able to use your face or fingerprint for authentication in apps."</string>
+ <!-- Content of the dialog shown when the user removes the device lock PIN and the user has face authentication and fingerprint enrolled and there are apps with auth-bound keys that will be affected [CHAR LIMIT=NONE] -->
+ <string name="unlock_disable_frp_warning_content_pin_face_fingerprint_authbound_keys">"You will lose saved data like your PIN, face and fingerprint models.<xliff:g id="empty_line">\n\n</xliff:g>Cards set up for tap to pay will be removed.<xliff:g id="empty_line">\n\n</xliff:g>Wallets and other apps that require device unlock may not work properly."</string>
<!-- Content of the dialog shown when the user removes the device lock password [CHAR LIMIT=NONE] -->
<string name="unlock_disable_frp_warning_content_password">"A password protects your phone if it\u2019s lost or stolen"</string>
<!-- Content of the dialog shown when the user removes the device lock password and the user has fingerprints enrolled [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java
index db031e7..178c387 100644
--- a/src/com/android/settings/password/ChooseLockGeneric.java
+++ b/src/com/android/settings/password/ChooseLockGeneric.java
@@ -50,6 +50,9 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
+import android.security.AndroidKeyStoreMaintenance;
+import android.security.GateKeeper;
+import android.security.KeyStoreException;
import android.service.persistentdata.PersistentDataBlockManager;
import android.text.TextUtils;
import android.util.EventLog;
@@ -147,7 +150,6 @@
* ChooseLockGeneric can be relaunched with the same extras.
*/
public static final String EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS = "choose_lock_generic_extras";
-
@VisibleForTesting
static final int CONFIRM_EXISTING_REQUEST = 100;
@VisibleForTesting
@@ -438,7 +440,7 @@
if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(mUserId)) {
// Show the disabling FRP warning only when the user is switching from a secure
// unlock method to an insecure one
- showFactoryResetProtectionWarningDialog(key);
+ showFactoryResetProtectionWarningDialog(key, GateKeeper.getSecureUserId(mUserId));
return true;
} else if (KEY_SKIP_FINGERPRINT.equals(key) || KEY_SKIP_FACE.equals(key)
|| KEY_SKIP_BIOMETRICS.equals(key)) {
@@ -906,7 +908,8 @@
: R.string.unlock_disable_frp_warning_title;
}
- private int getResIdForFactoryResetProtectionWarningMessage() {
+ private int getResIdForFactoryResetProtectionWarningMessage(
+ boolean hasAppsWithAuthBoundKeys) {
final boolean hasFingerprints;
final boolean hasFace;
if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
@@ -935,13 +938,24 @@
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
if (hasFingerprints && hasFace) {
- return R.string.unlock_disable_frp_warning_content_pin_face_fingerprint;
+ return hasAppsWithAuthBoundKeys
+ ?
+ R.string.unlock_disable_frp_warning_content_pin_face_fingerprint_authbound_keys
+ : R.string.unlock_disable_frp_warning_content_pin_face_fingerprint;
} else if (hasFingerprints) {
- return R.string.unlock_disable_frp_warning_content_pin_fingerprint;
+ return hasAppsWithAuthBoundKeys
+ ?
+ R.string.unlock_disable_frp_warning_content_pin_fingerprint_authbound_keys
+ : R.string.unlock_disable_frp_warning_content_pin_fingerprint;
} else if (hasFace) {
- return R.string.unlock_disable_frp_warning_content_pin_face;
+ return hasAppsWithAuthBoundKeys
+ ?
+ R.string.unlock_disable_frp_warning_content_pin_face_authbound_keys
+ : R.string.unlock_disable_frp_warning_content_pin_face;
} else {
- return R.string.unlock_disable_frp_warning_content_pin;
+ return hasAppsWithAuthBoundKeys
+ ? R.string.unlock_disable_frp_warning_content_pin_authbound_keys
+ : R.string.unlock_disable_frp_warning_content_pin;
}
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
@@ -998,9 +1012,26 @@
return false;
}
- private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) {
+ private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet,
+ long userSecureId) {
+ // Call Keystore to find out if this user has apps with authentication-bound
+ // keys associated with the userSecureId of the LSKF to be removed.
+ boolean appsAffectedByFRPRemovalExist;
+ try {
+ long[] appsAffectedByFRPRemoval =
+ AndroidKeyStoreMaintenance.getAllAppUidsAffectedBySid(mUserId,
+ userSecureId);
+ appsAffectedByFRPRemovalExist = appsAffectedByFRPRemoval.length > 0;
+ } catch (KeyStoreException e) {
+ Log.w(TAG, String.format("Failed to get list of apps affected by SID %d removal",
+ userSecureId), e);
+ // Fail closed: If Settings can't reach Keystore, assume (out of caution) that
+ // there are authentication-bound keys that will be invalidated.
+ appsAffectedByFRPRemovalExist = true;
+ }
int title = getResIdForFactoryResetProtectionWarningTitle();
- int message = getResIdForFactoryResetProtectionWarningMessage();
+ int message = getResIdForFactoryResetProtectionWarningMessage(
+ appsAffectedByFRPRemovalExist);
FactoryResetProtectionWarningDialog dialog =
FactoryResetProtectionWarningDialog.newInstance(
title, message, unlockMethodToSet);