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

Commit cd540d4c authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "keystore-user-data" into main

* changes:
  Harden DevicePolicyManagerService
  Add onUserStorageLocked to signal to Keystore
parents d7e50155 99b5699b
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -123,6 +123,27 @@ public class KeyStoreAuthorization {
        }
    }

    /**
     * Informs Keystore 2.0 that the credential encrypted storage for a particular user has been
     * locked.
     *
     * @param userId - the user's Android user ID
     * @return 0 if successful or a {@code ResponseCode}
     * @hide
     */
    public int onUserStorageLocked(int userId) {
        try {
            getService().onUserStorageLocked(userId);
            return 0;
        } catch (ServiceSpecificException e) {
            Log.e(TAG, "onUserStorageLocked failed", e);
            return e.errorCode;
        } catch (Exception e) {
            Log.e(TAG, "Can not connect to keystore", e);
            return SYSTEM_ERROR;
        }
    }

    /**
     * Gets the last authentication time of the given user and authenticators.
     *
+13 −3
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.security.KeyStoreAuthorization;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArraySet;
@@ -1524,9 +1525,10 @@ class UserController implements Handler.Callback {

    private void dispatchUserLocking(@UserIdInt int userId,
            @Nullable List<KeyEvictedCallback> keyEvictedCallbacks) {
        // Evict the user's credential encryption key. Performed on FgThread to make it
        // serialized with call to UserManagerService.onBeforeUnlockUser in finishUserUnlocking
        // to prevent data corruption.
        // Evict user secrets that require strong authentication to unlock. This includes locking
        // the user's credential-encrypted storage and evicting the user's keystore super keys.
        // Performed on FgThread to make it serialized with call to
        // UserManagerService.onBeforeUnlockUser in finishUserUnlocking to prevent data corruption.
        FgThread.getHandler().post(() -> {
            synchronized (mLock) {
                if (mStartedUsers.get(userId) != null) {
@@ -1540,6 +1542,10 @@ class UserController implements Handler.Callback {
            } catch (RemoteException re) {
                throw re.rethrowAsRuntimeException();
            }
            if (com.android.server.flags.Flags.userDataRefactoring()) {
                // Send communication to keystore to wipe key cache for the given userId.
                mInjector.getKeyStoreAuthorization().onUserStorageLocked(userId);
            }
            if (keyEvictedCallbacks == null) {
                return;
            }
@@ -4045,6 +4051,10 @@ class UserController implements Handler.Callback {
            return mService.mContext.getSystemService(KeyguardManager.class);
        }

        KeyStoreAuthorization getKeyStoreAuthorization() {
            return KeyStoreAuthorization.getInstance();
        }

        void batteryStatsServiceNoteEvent(int code, String name, int uid) {
            mService.mBatteryStatsService.noteEvent(code, name, uid);
        }
+5 −3
Original line number Diff line number Diff line
@@ -2541,10 +2541,12 @@ public class LockSettingsService extends ILockSettings.Stub {
     * reporting the password changed.
     */
    private void notifyPasswordChanged(LockscreenCredential newCredential, @UserIdInt int userId) {
        // Must compute the PasswordMetrics for newCredential outside the mHandler asynchronous
        // call, as once the handler actually runs the thread the newCredential parameter may be
        // zeroized by the caller.
        PasswordMetrics newMetrics = PasswordMetrics.computeForCredential(newCredential);
        mHandler.post(() -> {
            mInjector.getDevicePolicyManager().reportPasswordChanged(
                    PasswordMetrics.computeForCredential(newCredential),
                    userId);
            mInjector.getDevicePolicyManager().reportPasswordChanged(newMetrics, userId);
            LocalServices.getService(WindowManagerInternal.class).reportPasswordChanged(userId);
        });
    }
+20 −7
Original line number Diff line number Diff line
@@ -6050,15 +6050,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    private boolean resetPasswordInternal(String password, long tokenHandle, byte[] token,
            int flags, CallerIdentity caller) {
        final int callingUid = caller.getUid();
        final int userHandle = UserHandle.getUserId(callingUid);
        final boolean isPin = PasswordMetrics.isNumericOnly(password);
        final LockscreenCredential newCredential;
        if (isPin) {
            newCredential = LockscreenCredential.createPin(password);
        } else {
            newCredential = LockscreenCredential.createPasswordOrNone(password);
        try (LockscreenCredential newCredential =
                isPin ? LockscreenCredential.createPin(password) :
                    LockscreenCredential.createPasswordOrNone(password)) {
            return resetPasswordInternal(newCredential, tokenHandle, token, flags, caller);
        }
    }
    private boolean resetPasswordInternal(LockscreenCredential newCredential,
            long tokenHandle, byte[] token, int flags, CallerIdentity caller) {
        final int callingUid = caller.getUid();
        final int userHandle = UserHandle.getUserId(callingUid);
        synchronized (getLockObject()) {
            final PasswordMetrics minMetrics = getPasswordMinimumMetricsUnchecked(userHandle);
            final int complexity = getAggregatedPasswordComplexityLocked(userHandle);
@@ -19437,6 +19440,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    @Override
    public boolean resetPasswordWithToken(ComponentName admin, String callerPackageName,
            String passwordOrNull, byte[] token, int flags) {
        try {
            return resetPasswordWithTokenInternal(admin, callerPackageName, passwordOrNull, token,
                    flags);
        } finally {
            ArrayUtils.zeroize(token);
        }
    }
    public boolean resetPasswordWithTokenInternal(ComponentName admin, String callerPackageName,
            String passwordOrNull, byte[] token,
            int flags) {
        if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) {