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

Commit bb883208 authored by Rubin Xu's avatar Rubin Xu
Browse files

Introduce LockscreenCredential to LockSettingsService

Use LockscreenCredential as the representation format for credentials
throughout the LSS system service, until when the raw credential bits
are needed. Most of the changes are just mechanical, except in places
when null was used to represent empty credential, but now it has its
own concrete object.

Test: atest com.android.server.locksettings
Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest
Test: atest MixedManagedProfileOwnerTest#testResetPasswordWithToken
Test: atest com.android.cts.devicepolicy.PasswordComplexityTest
Test: atest com.android.cts.devicepolicy.ManagedProfilePasswordTest
Bug:65239740
Change-Id: I3997c3c2b6651d11a0e447448ac3a8523a18fa36
parent b77d972a
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.security.keystore.recovery.KeyChainSnapshot;
import android.security.keystore.recovery.KeyChainProtectionParams;
import android.security.keystore.recovery.RecoveryCertPath;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.VerifyCredentialResponse;

import java.util.Map;
@@ -42,19 +43,19 @@ interface ILockSettings {
    long getLong(in String key, in long defaultValue, in int userId);
    @UnsupportedAppUsage
    String getString(in String key, in String defaultValue, in int userId);
    boolean setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange);
    boolean setLockCredential(in LockscreenCredential credential, in LockscreenCredential savedCredential, int userId, boolean allowUntrustedChange);
    void resetKeyStore(int userId);
    VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId,
    VerifyCredentialResponse checkCredential(in LockscreenCredential credential, int userId,
            in ICheckCredentialProgressCallback progressCallback);
    VerifyCredentialResponse verifyCredential(in byte[] credential, int type, long challenge, int userId);
    VerifyCredentialResponse verifyTiedProfileChallenge(in byte[] credential, int type, long challenge, int userId);
    VerifyCredentialResponse verifyCredential(in LockscreenCredential credential, long challenge, int userId);
    VerifyCredentialResponse verifyTiedProfileChallenge(in LockscreenCredential credential, long challenge, int userId);
    boolean checkVoldPassword(int userId);
    @UnsupportedAppUsage
    boolean havePattern(int userId);
    @UnsupportedAppUsage
    boolean havePassword(int userId);
    byte[] getHashFactor(in byte[] currentCredential, int userId);
    void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in byte[] managedUserPassword);
    byte[] getHashFactor(in LockscreenCredential currentCredential, int userId);
    void setSeparateProfileChallengeEnabled(int userId, boolean enabled, in LockscreenCredential managedUserPassword);
    boolean getSeparateProfileChallengeEnabled(int userId);
    void registerStrongAuthTracker(in IStrongAuthTracker tracker);
    void unregisterStrongAuthTracker(in IStrongAuthTracker tracker);
+14 −19
Original line number Diff line number Diff line
@@ -59,10 +59,10 @@ import android.util.SparseLongArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;

import libcore.util.HexEncoding;

import com.google.android.collect.Lists;

import libcore.util.HexEncoding;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.MessageDigest;
@@ -383,7 +383,7 @@ public class LockPatternUtils {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response = getLockSettings().verifyCredential(
                    credential.getCredential(), credential.getType(), challenge, userId);
                    credential, challenge, userId);
            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return response.getPayload();
            } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
@@ -413,8 +413,7 @@ public class LockPatternUtils {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response = getLockSettings().checkCredential(
                    credential.getCredential(), credential.getType(),
                    userId, wrapCallback(progressCallback));
                    credential, userId, wrapCallback(progressCallback));

            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return true;
@@ -447,8 +446,7 @@ public class LockPatternUtils {
        throwIfCalledOnMainThread();
        try {
            VerifyCredentialResponse response =
                    getLockSettings().verifyTiedProfileChallenge(
                            credential.getCredential(), credential.getType(), challenge, userId);
                    getLockSettings().verifyTiedProfileChallenge(credential, challenge, userId);

            if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
                return response.getPayload();
@@ -482,7 +480,7 @@ public class LockPatternUtils {
    public byte[] getPasswordHistoryHashFactor(@NonNull LockscreenCredential currentPassword,
            int userId) {
        try {
            return getLockSettings().getHashFactor(currentPassword.getCredential(), userId);
            return getLockSettings().getHashFactor(currentPassword, userId);
        } catch (RemoteException e) {
            Log.e(TAG, "failed to get hash factor", e);
            return null;
@@ -689,9 +687,7 @@ public class LockPatternUtils {

        try {
            if (!getLockSettings().setLockCredential(
                    newCredential.getCredential(), newCredential.getType(),
                    savedCredential.getCredential(),
                    newCredential.getQuality(), userHandle, allowUntrustedChange)) {
                    newCredential, savedCredential, userHandle, allowUntrustedChange)) {
                setKeyguardStoredPasswordQuality(currentQuality, userHandle);
                return false;
            }
@@ -920,17 +916,17 @@ public class LockPatternUtils {
     *
     * @param userHandle Managed profile user id
     * @param enabled True if separate challenge is enabled
     * @param managedUserPassword Managed profile previous password. Null when {@code enabled} is
     * @param profilePassword Managed profile previous password. Null when {@code enabled} is
     *            true
     */
    public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled,
            LockscreenCredential managedUserPassword) {
            LockscreenCredential profilePassword) {
        if (!isManagedProfile(userHandle)) {
            return;
        }
        try {
            getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled,
                    managedUserPassword.getCredential());
                    profilePassword);
            reportEnabledTrustAgentsChanged(userHandle);
        } catch (RemoteException e) {
            Log.e(TAG, "Couldn't update work profile challenge enabled");
@@ -1543,8 +1539,8 @@ public class LockPatternUtils {
     * @param userHandle The user who's lock credential to be changed
     * @return {@code true} if the operation is successful.
     */
    public boolean setLockCredentialWithToken(LockscreenCredential credential, long tokenHandle,
            byte[] token, int userHandle) {
    public boolean setLockCredentialWithToken(@NonNull LockscreenCredential credential,
            long tokenHandle, byte[] token, int userHandle) {
        if (!hasSecureLockScreen()) {
            throw new UnsupportedOperationException(
                    "This operation requires the lock screen feature.");
@@ -1556,9 +1552,8 @@ public class LockPatternUtils {
        setKeyguardStoredPasswordQuality(credential.getQuality(), userHandle);

        try {
            if (!localService.setLockCredentialWithToken(credential.getCredential(),
                    credential.getType(),
                    tokenHandle, token, credential.getQuality(), userHandle)) {
            if (!localService.setLockCredentialWithToken(
                    credential, tokenHandle, token, userHandle)) {
                setKeyguardStoredPasswordQuality(currentQuality, userHandle);
                return false;
            }
+2 −2
Original line number Diff line number Diff line
@@ -59,8 +59,8 @@ public abstract class LockSettingsInternal {
     *
     * @return true if password is set.
     */
    public abstract boolean setLockCredentialWithToken(byte[] credential, int type,
            long tokenHandle, byte[] token, int requestedQuality, int userId);
    public abstract boolean setLockCredentialWithToken(LockscreenCredential credential,
            long tokenHandle, byte[] token, int userId);

    public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId);

+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.widget;

/**
 * A class representing a lockscreen credential.
 */
parcelable LockscreenCredential;
+12 −12
Original line number Diff line number Diff line
@@ -110,6 +110,18 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
                charSequenceToByteArray(password));
    }

    /**
     * Creates a LockscreenCredential object representing a managed password for profile with
     * unified challenge. This credentiall will have type {@code CREDENTIAL_TYPE_PASSWORD} for now.
     * TODO: consider add a new credential type for this. This can then supersede the
     * isLockTiedToParent argument in various places in LSS.
     */
    public static LockscreenCredential createManagedPassword(@NonNull byte[] password) {
        return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD,
                PASSWORD_QUALITY_ALPHABETIC,
                Arrays.copyOf(password, password.length));
    }

    /**
     * Creates a LockscreenCredential object representing the given numeric PIN.
     */
@@ -143,18 +155,6 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
        }
    }

    /**
     * Create a LockscreenCredential object based on raw credential and type
     * TODO: Remove once LSS.setUserPasswordMetrics accepts a LockscreenCredential
     */
    public static LockscreenCredential createRaw(int type, byte[] credential) {
        if (type == CREDENTIAL_TYPE_NONE) {
            return createNone();
        } else {
            return new LockscreenCredential(type, PASSWORD_QUALITY_UNSPECIFIED, credential);
        }
    }

    private void ensureNotZeroized() {
        Preconditions.checkState(mCredential != null, "Credential is already zeroized");
    }
Loading