Change existing LockPatternUtil APIs to fail untrusted password updates.

Add alternative APIs to allow untrusted password changes explicitly, so the caller
can choose to use them if needed.

Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/locksettings/
Bug: 120039091
Change-Id: I4ca03c9185081d300d7e325965b1e20515e33d51
This commit is contained in:
Irina Dumitrescu
2019-02-28 17:34:19 +00:00
parent 445d56756a
commit c90674dcc2
8 changed files with 140 additions and 80 deletions

View File

@@ -1680,7 +1680,6 @@ Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[
Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V
Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V

View File

@@ -42,7 +42,7 @@ 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);
void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId);
void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange);
void resetKeyStore(int userId);
VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId,
in ICheckCredentialProgressCallback progressCallback);

View File

@@ -669,17 +669,25 @@ public class LockPatternUtils {
/**
* Clear any lock pattern or password.
*/
public void clearLock(byte[] savedCredential, int userHandle) {
public boolean clearLock(byte[] savedCredential, int userHandle) {
return clearLock(savedCredential, userHandle, false);
}
/**
* Clear any lock pattern or password, with the option to ignore incorrect existing credential.
*/
public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) {
final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle);
try{
getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE,
savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle,
allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Failed to clear lock", e);
setKeyguardStoredPasswordQuality(currentQuality, userHandle);
return;
return false;
}
if (userHandle == UserHandle.USER_SYSTEM) {
@@ -689,6 +697,7 @@ public class LockPatternUtils {
}
onAfterChangingPassword(userHandle);
return true;
}
/**
@@ -726,19 +735,28 @@ public class LockPatternUtils {
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
* @param savedPattern The previously saved pattern, converted to byte[] format
* @param userId the user whose pattern is to be saved.
*
* @return whether this was successful or not.
*/
public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
this.saveLockPattern(pattern, null, userId);
public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
int userId) {
return saveLockPattern(pattern, savedPattern, userId, false);
}
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
* @param savedPattern The previously saved pattern, converted to byte[] format
* @param userId the user whose pattern is to be saved.
* @param allowUntrustedChange whether we want to allow saving a new password if the existing
* password being provided is incorrect.
*
* @return whether this was successful or not.
*/
public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
int userId) {
public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
int userId, boolean allowUntrustedChange) {
if (!hasSecureLockScreen()) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
@@ -753,11 +771,11 @@ public class LockPatternUtils {
setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId);
try {
getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern,
PASSWORD_QUALITY_SOMETHING, userId);
PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Couldn't save lock pattern", e);
setKeyguardStoredPasswordQuality(currentQuality, userId);
return;
return false;
}
// Update the device encryption password.
if (userId == UserHandle.USER_SYSTEM
@@ -771,6 +789,7 @@ public class LockPatternUtils {
reportPatternWasChosen(userId);
onAfterChangingPassword(userId);
return true;
}
private void updateCryptoUserInfo(int userId) {
@@ -873,17 +892,20 @@ public class LockPatternUtils {
* password.
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
* android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
*
* @return whether this was successful or not.
*
* @deprecated Pass password as a byte array
*/
@Deprecated
public void saveLockPassword(String password, String savedPassword, int requestedQuality,
public boolean saveLockPassword(String password, String savedPassword, int requestedQuality,
int userHandle) {
byte[] passwordBytes = password != null ? password.getBytes() : null;
byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null;
saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
}
/**
@@ -893,11 +915,34 @@ public class LockPatternUtils {
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
* android.content.ComponentName)}
* android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
*
* @return whether this was successful or not.
*/
public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
int userHandle) {
return saveLockPassword(password, savedPassword, requestedQuality,
userHandle, false);
}
/**
* Save a lock password. Does not ensure that the password is as good
* as the requested mode, but will adjust the mode to be as good as the
* password.
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
* android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
* @param allowUntrustedChange whether we want to allow saving a new password if the existing
* password being provided is incorrect.
*
* @return whether this method saved the new password successfully or not. This flow will fail
* and return false if the given credential is wrong and allowUntrustedChange is false.
*/
public boolean saveLockPassword(byte[] password, byte[] savedPassword,
int requestedQuality, int userHandle, boolean allowUntrustedChange) {
if (!hasSecureLockScreen()) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
@@ -919,16 +964,17 @@ public class LockPatternUtils {
setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle);
try {
getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
requestedQuality, userHandle);
requestedQuality, userHandle, allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Unable to save lock password", e);
setKeyguardStoredPasswordQuality(currentQuality, userHandle);
return;
return false;
}
updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle);
updatePasswordHistory(password, userHandle);
onAfterChangingPassword(userHandle);
return true;
}
/**

View File

@@ -323,8 +323,8 @@ public class LockSettingsService extends ILockSettings.Stub {
}
Arrays.fill(newPasswordChars, '\u0000');
final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD,
managedUserPassword, quality, managedUserId);
setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword,
quality, managedUserId, false);
// We store a private credential for the managed user that's unlocked by the primary
// account holder's credential. As such, the user will never be prompted to enter this
// password directly, so we always store a password.
@@ -1302,12 +1302,14 @@ public class LockSettingsService extends ILockSettings.Stub {
if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE,
profilePasswordMap.get(managedUserId),
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
false);
} else {
Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
// Supplying null here would lead to untrusted credential change
setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null,
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
true);
}
mStorage.removeChildProfileLock(managedUserId);
removeKeystoreProfileKey(managedUserId);
@@ -1330,8 +1332,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// should call setLockCredentialInternal.
@Override
public void setLockCredential(byte[] credential, int type,
byte[] savedCredential, int requestedQuality, int userId)
throws RemoteException {
byte[] savedCredential, int requestedQuality, int userId,
boolean allowUntrustedChange) throws RemoteException {
if (!mLockPatternUtils.hasSecureLockScreen()) {
throw new UnsupportedOperationException(
@@ -1339,7 +1341,8 @@ public class LockSettingsService extends ILockSettings.Stub {
}
checkWritePermission(userId);
synchronized (mSeparateChallengeLock) {
setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId);
setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId,
allowUntrustedChange);
setSeparateProfileChallengeEnabledLocked(userId, true, null);
notifyPasswordChanged(userId);
}
@@ -1347,7 +1350,8 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
byte[] savedCredential, int requestedQuality, int userId,
boolean allowUntrustedChange) throws RemoteException {
// Normalize savedCredential and credential such that empty string is always represented
// as null.
if (savedCredential == null || savedCredential.length == 0) {
@@ -1359,7 +1363,7 @@ public class LockSettingsService extends ILockSettings.Stub {
synchronized (mSpManager) {
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
requestedQuality, userId);
requestedQuality, userId, allowUntrustedChange);
return;
}
}
@@ -1410,7 +1414,7 @@ public class LockSettingsService extends ILockSettings.Stub {
initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
currentHandle.type, requestedQuality, userId);
spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
requestedQuality, userId);
requestedQuality, userId, allowUntrustedChange);
return;
}
}
@@ -1705,7 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub {
mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
if (shouldReEnrollBaseZero) {
setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false);
}
}
@@ -1796,7 +1800,7 @@ public class LockSettingsService extends ILockSettings.Stub {
storedHash.type == CREDENTIAL_TYPE_PATTERN
? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
: DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
/* TODO(roosa): keep the same password quality */, userId);
/* TODO(roosa): keep the same password quality */, userId, false);
if (!hasChallenge) {
notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
// Use credentials to create recoverable keystore snapshot.
@@ -1841,7 +1845,7 @@ public class LockSettingsService extends ILockSettings.Stub {
/* TODO(roosa): keep the same password quality */;
if (shouldReEnroll) {
setLockCredentialInternal(credential, storedHash.type, credential,
reEnrollQuality, userId);
reEnrollQuality, userId, false);
} else {
// Now that we've cleared of all required GK migration, let's do the final
// migration to synthetic password.
@@ -2544,7 +2548,8 @@ public class LockSettingsService extends ILockSettings.Stub {
@GuardedBy("mSpManager")
private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
byte[] savedCredential, int requestedQuality, int userId,
boolean allowUntrustedChange) throws RemoteException {
if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
if (isManagedProfileWithUnifiedLock(userId)) {
// get credential from keystore when managed profile has unified lock
@@ -2565,27 +2570,31 @@ public class LockSettingsService extends ILockSettings.Stub {
VerifyCredentialResponse response = authResult.gkResponse;
AuthenticationToken auth = authResult.authToken;
// If existing credential is provided, then it must match.
// If existing credential is provided, the existing credential must match.
if (savedCredential != null && auth == null) {
throw new RemoteException("Failed to enroll " +
(credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
throw new IllegalStateException("Failed to enroll "
+ (credentialType == CREDENTIAL_TYPE_PASSWORD
? "password" : "pattern"));
}
boolean untrustedReset = false;
if (auth != null) {
onAuthTokenKnownForUser(userId, auth);
} else if (response != null
&& response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
} else if (response == null) {
throw new IllegalStateException("Password change failed.");
} else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
// We are performing an untrusted credential change, by DevicePolicyManager or other
// internal callers that don't provide the existing credential
Slog.w(TAG, "Untrusted credential change invoked");
// Try to get a cached auth token, so we can keep SP unchanged.
auth = mSpCache.get(userId);
if (!allowUntrustedChange) {
throw new IllegalStateException("Untrusted credential change was invoked but it was"
+ " not allowed. This is likely a bug. Auth token is null: "
+ Boolean.toString(auth == null));
}
untrustedReset = true;
} else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
(response != null ? "rate limit exceeded" : "failed"));
return;
} else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
throw new IllegalStateException("Rate limit exceeded, so password was not changed.");
}
if (auth != null) {

View File

@@ -5133,11 +5133,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final boolean result;
try {
if (token == null) {
// This is the legacy reset password for DPM. Here we want to be able to override
// the old device password without necessarily knowing it.
if (!TextUtils.isEmpty(password)) {
mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality,
userHandle);
userHandle, /*allowUntrustedChange */true);
} else {
mLockPatternUtils.clearLock(null, userHandle);
mLockPatternUtils.clearLock(null, userHandle,
/*allowUntrustedChange */ true);
}
result = true;
} else {

View File

@@ -61,12 +61,12 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// clear password
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, true);
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// set a new password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -81,7 +81,7 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// Untrusted change password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
assertNotEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertNotEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -99,7 +99,7 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
// Untrusted change password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
// Verify the password
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
@@ -124,10 +124,12 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests {
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// Untrusted change password
assertExpectException(IllegalStateException.class, /* messageRegex= */ null,
assertExpectException(
IllegalStateException.class,
/* messageRegex= */ "Untrusted credential reset not possible without cached SP",
() -> mService.setLockCredential(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID));
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true));
assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// Verify the new password doesn't work but the old one still does

View File

@@ -85,9 +85,9 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
try {
mService.setLockCredential("newpwd".getBytes(), CREDENTIAL_TYPE_PASSWORD,
"badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
"badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
fail("Did not fail when enrolling using incorrect credential");
} catch (RemoteException expected) {
} catch (IllegalStateException expected) {
assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
}
assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
@@ -97,7 +97,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
final String PASSWORD = "password";
initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD.getBytes(),
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
assertFalse(mService.havePassword(PRIMARY_USER_ID));
assertFalse(mService.havePattern(PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -108,7 +108,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
final String secondUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-2";
mService.setLockCredential(firstUnifiedPassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -143,15 +143,16 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
mStorageManager.setIgnoreBadUnlock(true);
// Change primary password and verify that profile SID remains
mService.setLockCredential(secondUnifiedPassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
firstUnifiedPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, firstUnifiedPassword.getBytes(),
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
// Clear unified challenge
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID,
false);
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
@@ -162,7 +163,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
final String profilePassword = "testManagedProfileSeparateChallenge-profile";
mService.setLockCredential(primaryPassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
/* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
* credential as part of verifyCredential() before the new credential is committed in
* StorageManager. So we relax the check in our mock StorageManager to allow that.
@@ -170,7 +171,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
mStorageManager.setIgnoreBadUnlock(true);
mService.setLockCredential(profilePassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID);
PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
@@ -197,7 +198,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
// Change primary credential and make sure we don't affect profile
mStorageManager.setIgnoreBadUnlock(true);
mService.setLockCredential("pwd".getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
profilePassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
@@ -208,7 +209,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
private void testCreateCredential(int userId, String credential, int type, int quality)
throws RemoteException {
mService.setLockCredential(credential.getBytes(), type, null, quality,
userId);
userId, false);
assertVerifyCredentials(userId, credential, type, -1);
}
@@ -218,7 +219,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
try {
mService.setLockCredential(credential.getBytes(), type, null, quality,
userId);
userId, false);
fail("An exception should have been thrown.");
} catch (UnsupportedOperationException e) {
// Success - the exception was expected.
@@ -233,7 +234,7 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
final long sid = 1234;
initializeStorageWithCredential(userId, oldCredential, oldType, sid);
mService.setLockCredential(newCredential.getBytes(), newType, oldCredential.getBytes(),
quality, userId);
quality, userId, false);
assertVerifyCredentials(userId, newCredential, newType, sid);
}

View File

@@ -102,7 +102,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
disableSyntheticPassword();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
enableSyntheticPassword();
@@ -127,7 +127,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
: PASSWORD_QUALITY_UNSPECIFIED;
int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
: LockPatternUtils.CREDENTIAL_TYPE_NONE;
mService.setLockCredential(password, type, null, quality, userId);
mService.setLockCredential(password, type, null, quality, userId, false);
}
public void testSyntheticPasswordChangeCredential() throws RemoteException {
@@ -137,7 +137,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -166,12 +166,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// clear password
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// set a new password
mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -186,7 +186,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -245,7 +245,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
final byte[] password = "getASyntheticPassword".getBytes();
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
reset(mAuthSecretService);
mService.onUnlockUser(PRIMARY_USER_ID);
@@ -257,7 +257,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
final byte[] UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd".getBytes();
disableSyntheticPassword();
mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -294,9 +294,9 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
"testManagedProfileSeparateChallengeMigration-profile".getBytes();
disableSyntheticPassword();
mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
@@ -404,7 +404,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, password,
PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
mLocalService.setLockCredentialWithToken(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token,
@@ -443,7 +443,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
// Set up pre-SP user password
disableSyntheticPassword();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
enableSyntheticPassword();
long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
@@ -491,12 +491,12 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
public void testgetHashFactorPrimaryUser() throws RemoteException {
final byte[] password = "password".getBytes();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
assertNotNull(hashFactor);
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
assertNotNull(newHashFactor);
// Hash factor should never change after password change/removal
@@ -506,7 +506,7 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
final byte[] pattern = "1236".getBytes();
mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
}
@@ -515,9 +515,9 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
final byte[] primaryPassword = "primary".getBytes();
final byte[] profilePassword = "profile".getBytes();
mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
}