Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4613fe41 authored by Ricky Wai's avatar Ricky Wai
Browse files

Add resetKeyStore() in LockSettingsService

Before resetKeyStore(), it will back up child profile keys,
and will be restored after primary profile keystore is cleared.

Bug: 28878708
Change-Id: I0cb4a1f885d468894bc7eb95af694328bf92ce16
parent 4266feeb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+12 −0
Original line number Diff line number Diff line
@@ -531,6 +531,18 @@ public class LockPatternUtils {
        return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    }

    /**
     * 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.
     */
+53 −1
Original line number Diff line number Diff line
@@ -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");
@@ -1066,6 +1075,49 @@ public class LockSettingsService extends ILockSettings.Stub {
        getMountService().fixateNewestUserKeyAuth(userId);
    }

    @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);