From b2ea6726706b52faa117ee9bedcaddf50b1b9e02 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 21 Jun 2023 02:56:41 +0000 Subject: [PATCH] ChooseLockPassword: convert to use PasswordMetrics#validateCredential() Fix the check for invalid characters in new passwords by switching from PasswordMetrics#validatePassword() to PasswordMetrics#validateCredential(). For more information, see frameworks/base change I5c3c55367c3a294578cd0f97ac0e315a11ed517e. Bug: 219511761 Bug: 232900169 Bug: 243881358 Test: Verified no regressions in 'atest ChooseLockPasswordTest'. Note, this test is currently @Ignored and has 2 failures. I didn't attempt to address that. Test: Set a password containing non-ASCII characters on a device running an older build. Upgraded and verified unlocking still works. Tested that setting a new non-ASCII password is not allowed. Change-Id: I5f1822a34688473cb103eb64dca56e4c19d4dd08 Merged-In: I5f1822a34688473cb103eb64dca56e4c19d4dd08 (cherry picked from commit b547094366a9d49fa23e8e10bbffdee7558af4fc) --- .../settings/password/ChooseLockPassword.java | 15 ++++---- .../password/ChooseLockPasswordTest.java | 34 ++++++++++++++----- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java index deab9f2f9a7..4c229c6a61a 100644 --- a/src/com/android/settings/password/ChooseLockPassword.java +++ b/src/com/android/settings/password/ChooseLockPassword.java @@ -705,18 +705,17 @@ public class ChooseLockPassword extends SettingsActivity { /** * Validates PIN/Password and returns the validation result and updates mValidationErrors - * and mPasswordReused to reflect validation results. + * to reflect validation results. * * @param credential credential the user typed in. * @return whether password satisfies all the requirements. */ @VisibleForTesting boolean validatePassword(LockscreenCredential credential) { - final byte[] password = credential.getCredential(); - mValidationErrors = PasswordMetrics.validatePassword( - mMinMetrics, mMinComplexity, !mIsAlphaMode, password); - if (mValidationErrors.isEmpty() && mLockPatternUtils.checkPasswordHistory( - password, getPasswordHistoryHashFactor(), mUserId)) { + mValidationErrors = PasswordMetrics.validateCredential(mMinMetrics, mMinComplexity, + credential); + if (mValidationErrors.isEmpty() && mLockPatternUtils.checkPasswordHistory( + credential.getCredential(), getPasswordHistoryHashFactor(), mUserId)) { mValidationErrors = Collections.singletonList(new PasswordValidationError(RECENTLY_USED)); } @@ -893,8 +892,8 @@ public class ChooseLockPassword extends SettingsActivity { final boolean canInput = mSaveAndFinishWorker == null; LockscreenCredential password = mIsAlphaMode - ? LockscreenCredential.createPasswordOrNone(mPasswordEntry.getText()) - : LockscreenCredential.createPinOrNone(mPasswordEntry.getText()); + ? LockscreenCredential.createPassword(mPasswordEntry.getText()) + : LockscreenCredential.createPin(mPasswordEntry.getText()); final int length = password.size(); if (mUiStage == Stage.Introduction) { mPasswordRestrictionView.setVisibility(View.VISIBLE); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java index 3fe332246c3..d3c09d013f9 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java @@ -184,6 +184,24 @@ public class ChooseLockPasswordTest { assertThat(flags & FLAG_SECURE).isEqualTo(FLAG_SECURE); } + @Test + public void processAndValidatePasswordRequirements_cannotIncludeInvalidChar() { + PasswordPolicy policy = new PasswordPolicy(); + policy.quality = PASSWORD_QUALITY_UNSPECIFIED; + // Only ASCII 31–127 should be allowed. The invalid character error should also take + // priority over the error that says the password is too short. + String[] passwords = new String[] { "§µ¿¶¥£", "™™™™", "\n\n\n\n", "¡", "é" }; + + for (String password : passwords) { + assertPasswordValidationResult( + /* minMetrics */ policy.getMinMetrics(), + /* minComplexity= */ PASSWORD_COMPLEXITY_NONE, + /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, + /* userEnteredPassword= */ LockscreenCredential.createPassword(password), + "This can't include an invalid character"); + } + } + @Test public void processAndValidatePasswordRequirements_noMinPasswordComplexity() { PasswordPolicy policy = new PasswordPolicy(); @@ -194,7 +212,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_NONE, /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPassword(""), "Must contain at least 1 non-numerical character", "Must be at least 10 characters"); } @@ -208,7 +226,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH, /* passwordType= */ PASSWORD_QUALITY_NUMERIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPin(""), "PIN must be at least 8 digits"); } @@ -221,7 +239,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM, /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPassword(""), "Must be at least 4 characters"); } @@ -235,7 +253,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_LOW, /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPassword(""), "Must contain at least 1 non-numerical character", "Must contain at least 1 numerical digit", "Must be at least 9 characters"); @@ -251,7 +269,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_MEDIUM, /* passwordType= */ PASSWORD_QUALITY_NUMERIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPin(""), "PIN must be at least 11 digits"); } @@ -265,7 +283,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH, /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPassword(""), "Must contain at least 2 special symbols", "Must be at least 6 characters", "Must contain at least 1 letter", @@ -351,7 +369,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ policy.getMinMetrics(), /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH, /* passwordType= */ PASSWORD_QUALITY_ALPHABETIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPassword(""), "Must be at least 6 characters", "If using only numbers, must be at least 8 digits"); } @@ -448,7 +466,7 @@ public class ChooseLockPasswordTest { /* minMetrics */ null, /* minComplexity= */ PASSWORD_COMPLEXITY_HIGH, /* passwordType= */ PASSWORD_QUALITY_NUMERIC, - /* userEnteredPassword= */ LockscreenCredential.createNone(), + /* userEnteredPassword= */ LockscreenCredential.createPin(""), "PIN must be at least 8 digits"); }