Allow constructing a PIN LockscreenCredential with mInvalidChars

KeyguardManager#setLock() (both overloads) and LockSettingsShellCommand
can try to set a PIN containing arbitrary characters.  The check for
digits-only happens in PasswordMetrics#validatePasswordMetrics().
However, due to one of my recent changes, before getting to that point,
constructing the LockscreenCredential throws IllegalArgumentException if
the PIN contains any chars outside ASCII 32–127.  This is because I had
thought this case would only be possible for PASSWORD.

As it's needed for PIN too, allow this case.

Bug: 219511761
Bug: 232900169
Bug: 243881358
Bug: 288904180
Test: atest LockscreenCredentialTest
Change-Id: Icd101f2dbb0c700a0cc5442a81c0c9ac345737b3
This commit is contained in:
Eric Biggers
2023-06-26 22:05:10 +00:00
parent 8057abea1c
commit a775edfa3a
2 changed files with 15 additions and 6 deletions

View File

@@ -64,9 +64,9 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
// is represented as a byte array of length 0.
private byte[] mCredential;
// This indicates that the credential is a password that used characters outside ASCII 32–127.
// This indicates that the credential used characters outside ASCII 32–127.
//
// Such passwords were never intended to be allowed. However, Android 10–14 had a bug where
// Such credentials were never intended to be allowed. However, Android 10–14 had a bug where
// conversion from the chars the user entered to the credential bytes used a simple truncation.
// Thus, any 'char' whose remainder mod 256 was in the range 32–127 was accepted and was
// equivalent to some ASCII character. For example, ™, which is U+2122, was truncated to ASCII
@@ -102,7 +102,6 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
// LockscreenCredential object to be constructed so that the validation logic can run,
// even though the validation logic will ultimately reject the credential as too short.
}
Preconditions.checkArgument(!hasInvalidChars || type == CREDENTIAL_TYPE_PASSWORD);
mType = type;
mCredential = credential;
mHasInvalidChars = hasInvalidChars;
@@ -262,6 +261,9 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
* short
*/
public void validateBasicRequirements() {
if (mHasInvalidChars) {
throw new IllegalArgumentException("credential contains invalid characters");
}
switch (getType()) {
case CREDENTIAL_TYPE_PATTERN:
if (size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
@@ -276,9 +278,6 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
}
break;
case CREDENTIAL_TYPE_PASSWORD:
if (mHasInvalidChars) {
throw new IllegalArgumentException("password contains invalid characters");
}
if (size() < LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
throw new IllegalArgumentException("password must be at least "
+ LockPatternUtils.MIN_LOCK_PASSWORD_SIZE + " characters long.");

View File

@@ -157,6 +157,16 @@ public class LockscreenCredentialTest {
}
}
@Test
public void testPinWithInvalidChars() {
LockscreenCredential pin = LockscreenCredential.createPin("\n\n\n\n");
assertTrue(pin.hasInvalidChars());
try {
pin.validateBasicRequirements();
fail("should not be able to set PIN with invalid chars");
} catch (IllegalArgumentException expected) { }
}
@Test
public void testSanitize() {
LockscreenCredential password = LockscreenCredential.createPassword("password");