summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/widget/ILockSettings.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java12
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java54
3 files changed, 66 insertions, 1 deletions
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index b2fc2bb8c89f..353c72fd1a90 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,6 +28,7 @@ interface ILockSettings {
long getLong(in String key, in long defaultValue, in int userId);
String getString(in String key, in String defaultValue, in int userId);
void setLockPattern(in String pattern, in String savedPattern, int userId);
+ void resetKeyStore(int userId);
VerifyCredentialResponse checkPattern(in String pattern, int userId);
VerifyCredentialResponse verifyPattern(in String pattern, long challenge, int userId);
void setLockPassword(in String password, in String savedPassword, int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d9b63296dea9..266eba34ea43 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -532,6 +532,18 @@ public class LockPatternUtils {
}
/**
+ * Use it to reset keystore without wiping work profile
+ */
+ public void resetKeyStore(int userId) {
+ try {
+ getLockSettings().resetKeyStore(userId);
+ } catch (RemoteException e) {
+ // It should not happen
+ Log.e(TAG, "Couldn't reset keystore " + e);
+ }
+ }
+
+ /**
* Clear any lock pattern or password.
*/
public void clearLock(int userHandle) {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 596fd441d928..145aeb2125b9 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -46,6 +46,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IProgressListener;
import android.os.Parcel;
+import android.os.Process;
import android.os.RemoteException;
import android.os.storage.IMountService;
import android.os.ServiceManager;
@@ -127,6 +128,14 @@ public class LockSettingsService extends ILockSettings.Stub {
private NotificationManager mNotificationManager;
private UserManager mUserManager;
+ private final KeyStore mKeyStore = KeyStore.getInstance();
+
+ /**
+ * The UIDs that are used for system credential storage in keystore.
+ */
+ private static final int[] SYSTEM_CREDENTIAL_UIDS = {Process.WIFI_UID, Process.VPN_UID,
+ Process.ROOT_UID, Process.SYSTEM_UID};
+
static {
// Just launch the home screen, which happens anyway
ACTION_NULL = new Intent(Intent.ACTION_MAIN);
@@ -647,7 +656,7 @@ public class LockSettingsService extends ILockSettings.Stub {
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
CertificateException, IOException {
- if (DEBUG) Slog.v(TAG, "Unlock keystore for child profile");
+ if (DEBUG) Slog.v(TAG, "Get child profile decrytped key");
byte[] storedData = mStorage.readChildProfileLock(userId);
if (storedData == null) {
throw new FileNotFoundException("Child profile lock file not found");
@@ -1067,6 +1076,49 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@Override
+ public void resetKeyStore(int userId) throws RemoteException {
+ if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+ int managedUserId = -1;
+ String managedUserDecryptedPassword = null;
+ final List<UserInfo> profiles = mUserManager.getProfiles(userId);
+ for (UserInfo pi : profiles) {
+ // Unlock managed profile with unified lock
+ if (pi.isManagedProfile()
+ && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id)
+ && mStorage.hasChildProfileLock(pi.id)) {
+ try {
+ if (managedUserId == -1) {
+ managedUserDecryptedPassword = getDecryptedPasswordForTiedProfile(pi.id);
+ managedUserId = pi.id;
+ } else {
+ // Should not happen
+ Slog.e(TAG, "More than one managed profile, uid1:" + managedUserId
+ + ", uid2:" + pi.id);
+ }
+ } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
+ | NoSuchAlgorithmException | NoSuchPaddingException
+ | InvalidAlgorithmParameterException | IllegalBlockSizeException
+ | BadPaddingException | CertificateException | IOException e) {
+ Slog.e(TAG, "Failed to decrypt child profile key", e);
+ }
+ }
+ }
+ try {
+ // Clear all the users credentials could have been installed in for this user.
+ for (int profileId : mUserManager.getProfileIdsWithDisabled(userId)) {
+ for (int uid : SYSTEM_CREDENTIAL_UIDS) {
+ mKeyStore.clearUid(UserHandle.getUid(profileId, uid));
+ }
+ }
+ } finally {
+ if (managedUserId != -1 && managedUserDecryptedPassword != null) {
+ if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
+ tieProfileLockToParent(managedUserId, managedUserDecryptedPassword);
+ }
+ }
+ }
+
+ @Override
public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException {
return doVerifyPattern(pattern, false, 0, userId);
}