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

Commit 0e4385e2 authored by Eric Biggers's avatar Eric Biggers
Browse files

Properly validate credential in setLock(int, byte[], int, byte[])

In KeyguardManager, one of the two overloads of setLock() properly
validates the new credential using the logic in PasswordMetrics, while
the other doesn't.  This appears to be an oversight, and it was allowing
a test to set a PIN containing invalid characters.  Fix this by always
calling PasswordMetrics#validateCredential() on the new credential.

Bug: 219511761
Bug: 232900169
Bug: 243881358
Test: atest android.app.KeyguardManagerTest
Test: atest android.app.cts.KeyguardManagerTest
Test: atest CtsSensorPrivacyTestCases # since it calls setLock()
Change-Id: I46d8bf920526a00d6e6d2145d06c8e39f8047ea8
parent 62dbf253
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import com.android.internal.widget.IWeakEscrowTokenRemovedListener;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockscreenCredential;
import com.android.internal.widget.PasswordValidationError;
import com.android.internal.widget.VerifyCredentialResponse;

import java.nio.charset.Charset;
@@ -885,12 +886,8 @@ public class KeyguardManager {
        }
        Objects.requireNonNull(password, "Password cannot be null.");
        complexity = PasswordMetrics.sanitizeComplexityLevel(complexity);
        // TODO: b/131755827 add devicePolicyManager support for Auto
        DevicePolicyManager devicePolicyManager =
                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        PasswordMetrics adminMetrics =
                devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId());

                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
        try (LockscreenCredential credential = createLockscreenCredential(lockType, password)) {
            return PasswordMetrics.validateCredential(adminMetrics, complexity,
                    credential).size() == 0;
@@ -913,11 +910,8 @@ public class KeyguardManager {
            return -1;
        }
        complexity = PasswordMetrics.sanitizeComplexityLevel(complexity);
        // TODO: b/131755827 add devicePolicyManager support for Auto
        DevicePolicyManager devicePolicyManager =
                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
        PasswordMetrics adminMetrics =
                devicePolicyManager.getPasswordMinimumMetrics(mContext.getUserId());
                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
        PasswordMetrics minMetrics =
                PasswordMetrics.applyComplexity(adminMetrics, isPin, complexity);
        return minMetrics.length;
@@ -1139,6 +1133,14 @@ public class KeyguardManager {
                currentLockType, currentPassword);
        LockscreenCredential newCredential = createLockscreenCredential(
                newLockType, newPassword);
        PasswordMetrics adminMetrics =
                mLockPatternUtils.getRequestedPasswordMetrics(mContext.getUserId());
        List<PasswordValidationError> errors = PasswordMetrics.validateCredential(adminMetrics,
                DevicePolicyManager.PASSWORD_COMPLEXITY_NONE, newCredential);
        if (!errors.isEmpty()) {
            Log.e(TAG, "New credential is not valid: " + errors.get(0));
            return false;
        }
        return mLockPatternUtils.setLockCredential(newCredential, currentCredential, userId);
    }

+16 −0
Original line number Diff line number Diff line
@@ -173,6 +173,22 @@ public class KeyguardManagerTest {
        assertFalse(mKeyguardManager.isDeviceSecure());
    }

    @Test
    public void setLock_validatesCredential() {
        // setLock() should validate the credential before setting it.  Test one example, which is
        // that PINs must contain only ASCII digits 0-9, i.e. bytes 48-57.  Using bytes 0-9 is
        // incorrect and should *not* be accepted.
        byte[] invalidPin = new byte[] { 1, 2, 3, 4 };
        byte[] validPin = "1234".getBytes();

        assertFalse(mKeyguardManager.setLock(KeyguardManager.PIN, invalidPin, -1, null));
        assertFalse(mKeyguardManager.isDeviceSecure());

        assertTrue(mKeyguardManager.setLock(KeyguardManager.PIN, validPin, -1, null));
        assertTrue(mKeyguardManager.isDeviceSecure());
        assertTrue(mKeyguardManager.setLock(-1, null, KeyguardManager.PIN, validPin));
    }

    @Test
    public void checkLock_correctCredentials() {
        // Set to `true` to behave as if SET_INITIAL_LOCK permission had been granted.