Merge "Move escrow APIs into LockSettingsInternal" into pi-dev
am: e40dcabbc8
Change-Id: I0e6a1c4355243cf8ae0074672bb26f8669343c49
This commit is contained in:
@@ -54,13 +54,6 @@ interface ILockSettings {
|
||||
void userPresent(int userId);
|
||||
int getStrongAuthForUser(int userId);
|
||||
|
||||
long addEscrowToken(in byte[] token, int userId);
|
||||
boolean removeEscrowToken(long handle, int userId);
|
||||
boolean isEscrowTokenActive(long handle, int userId);
|
||||
boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
|
||||
in byte[] token, int requestedQuality, int userId);
|
||||
void unlockUserWithToken(long tokenHandle, in byte[] token, int userId);
|
||||
|
||||
// Keystore RecoveryController methods.
|
||||
// {@code ServiceSpecificException} may be thrown to signal an error, which caller can
|
||||
// convert to {@code RecoveryManagerException}.
|
||||
|
||||
@@ -45,6 +45,7 @@ import android.util.SparseIntArray;
|
||||
import android.util.SparseLongArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.LocalServices;
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import libcore.util.HexEncoding;
|
||||
@@ -1473,6 +1474,13 @@ public class LockPatternUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private LockSettingsInternal getLockSettingsInternal() {
|
||||
LockSettingsInternal service = LocalServices.getService(LockSettingsInternal.class);
|
||||
if (service == null) {
|
||||
throw new SecurityException("Only available to system server itself");
|
||||
}
|
||||
return service;
|
||||
}
|
||||
/**
|
||||
* Create an escrow token for the current user, which can later be used to unlock FBE
|
||||
* or change user password.
|
||||
@@ -1481,44 +1489,41 @@ public class LockPatternUtils {
|
||||
* confirm credential operation in order to activate the token for future use. If the user
|
||||
* has no secure lockscreen, then the token is activated immediately.
|
||||
*
|
||||
* <p>This method is only available to code running in the system server process itself.
|
||||
*
|
||||
* @return a unique 64-bit token handle which is needed to refer to this token later.
|
||||
*/
|
||||
public long addEscrowToken(byte[] token, int userId) {
|
||||
try {
|
||||
return getLockSettings().addEscrowToken(token, userId);
|
||||
} catch (RemoteException re) {
|
||||
return 0L;
|
||||
}
|
||||
return getLockSettingsInternal().addEscrowToken(token, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an escrow token.
|
||||
*
|
||||
* <p>This method is only available to code running in the system server process itself.
|
||||
*
|
||||
* @return true if the given handle refers to a valid token previously returned from
|
||||
* {@link #addEscrowToken}, whether it's active or not. return false otherwise.
|
||||
*/
|
||||
public boolean removeEscrowToken(long handle, int userId) {
|
||||
try {
|
||||
return getLockSettings().removeEscrowToken(handle, userId);
|
||||
} catch (RemoteException re) {
|
||||
return false;
|
||||
}
|
||||
return getLockSettingsInternal().removeEscrowToken(handle, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given escrow token is active or not. Only active token can be used to call
|
||||
* {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken}
|
||||
*
|
||||
* <p>This method is only available to code running in the system server process itself.
|
||||
*/
|
||||
public boolean isEscrowTokenActive(long handle, int userId) {
|
||||
try {
|
||||
return getLockSettings().isEscrowTokenActive(handle, userId);
|
||||
} catch (RemoteException re) {
|
||||
return false;
|
||||
}
|
||||
return getLockSettingsInternal().isEscrowTokenActive(handle, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a user's lock credential with a pre-configured escrow token.
|
||||
*
|
||||
* <p>This method is only available to code running in the system server process itself.
|
||||
*
|
||||
* @param credential The new credential to be set
|
||||
* @param type Credential type: password / pattern / none.
|
||||
* @param requestedQuality the requested password quality by DevicePolicyManager.
|
||||
@@ -1530,55 +1535,55 @@ public class LockPatternUtils {
|
||||
*/
|
||||
public boolean setLockCredentialWithToken(String credential, int type, int requestedQuality,
|
||||
long tokenHandle, byte[] token, int userId) {
|
||||
try {
|
||||
if (type != CREDENTIAL_TYPE_NONE) {
|
||||
if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) {
|
||||
throw new IllegalArgumentException("password must not be null and at least "
|
||||
+ "of length " + MIN_LOCK_PASSWORD_SIZE);
|
||||
}
|
||||
final int quality = computePasswordQuality(type, credential, requestedQuality);
|
||||
if (!getLockSettings().setLockCredentialWithToken(credential, type, tokenHandle,
|
||||
token, quality, userId)) {
|
||||
return false;
|
||||
}
|
||||
setLong(PASSWORD_TYPE_KEY, quality, userId);
|
||||
|
||||
updateEncryptionPasswordIfNeeded(credential, quality, userId);
|
||||
updatePasswordHistory(credential, userId);
|
||||
} else {
|
||||
if (!TextUtils.isEmpty(credential)) {
|
||||
throw new IllegalArgumentException("password must be emtpy for NONE type");
|
||||
}
|
||||
if (!getLockSettings().setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE,
|
||||
tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||
userId)) {
|
||||
return false;
|
||||
}
|
||||
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||
userId);
|
||||
|
||||
if (userId == UserHandle.USER_SYSTEM) {
|
||||
// Set the encryption password to default.
|
||||
updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
|
||||
setCredentialRequiredToDecrypt(false);
|
||||
}
|
||||
LockSettingsInternal localService = getLockSettingsInternal();
|
||||
if (type != CREDENTIAL_TYPE_NONE) {
|
||||
if (TextUtils.isEmpty(credential) || credential.length() < MIN_LOCK_PASSWORD_SIZE) {
|
||||
throw new IllegalArgumentException("password must not be null and at least "
|
||||
+ "of length " + MIN_LOCK_PASSWORD_SIZE);
|
||||
}
|
||||
final int quality = computePasswordQuality(type, credential, requestedQuality);
|
||||
if (!localService.setLockCredentialWithToken(credential, type, tokenHandle,
|
||||
token, quality, userId)) {
|
||||
return false;
|
||||
}
|
||||
setLong(PASSWORD_TYPE_KEY, quality, userId);
|
||||
|
||||
updateEncryptionPasswordIfNeeded(credential, quality, userId);
|
||||
updatePasswordHistory(credential, userId);
|
||||
} else {
|
||||
if (!TextUtils.isEmpty(credential)) {
|
||||
throw new IllegalArgumentException("password must be emtpy for NONE type");
|
||||
}
|
||||
if (!localService.setLockCredentialWithToken(null, CREDENTIAL_TYPE_NONE,
|
||||
tokenHandle, token, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||
userId)) {
|
||||
return false;
|
||||
}
|
||||
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
|
||||
userId);
|
||||
|
||||
if (userId == UserHandle.USER_SYSTEM) {
|
||||
// Set the encryption password to default.
|
||||
updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
|
||||
setCredentialRequiredToDecrypt(false);
|
||||
}
|
||||
onAfterChangingPassword(userId);
|
||||
return true;
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to save lock password ", re);
|
||||
re.rethrowFromSystemServer();
|
||||
}
|
||||
return false;
|
||||
onAfterChangingPassword(userId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
|
||||
try {
|
||||
getLockSettings().unlockUserWithToken(tokenHandle, token, userId);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "Unable to unlock user with token", re);
|
||||
re.rethrowFromSystemServer();
|
||||
}
|
||||
/**
|
||||
* Unlock the specified user by an pre-activated escrow token. This should have the same effect
|
||||
* on device encryption as the user entering his lockscreen credentials for the first time after
|
||||
* boot, this includes unlocking the user's credential-encrypted storage as well as the keystore
|
||||
*
|
||||
* <p>This method is only available to code running in the system server process itself.
|
||||
*
|
||||
* @return {@code true} if the supplied token is valid and unlock succeeds,
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
|
||||
return getLockSettingsInternal().unlockUserWithToken(tokenHandle, token, userId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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;
|
||||
|
||||
|
||||
/**
|
||||
* LockSettingsService local system service interface.
|
||||
*
|
||||
* @hide Only for use within the system server.
|
||||
*/
|
||||
public abstract class LockSettingsInternal {
|
||||
|
||||
/**
|
||||
* Create an escrow token for the current user, which can later be used to unlock FBE
|
||||
* or change user password.
|
||||
*
|
||||
* After adding, if the user currently has lockscreen password, he will need to perform a
|
||||
* confirm credential operation in order to activate the token for future use. If the user
|
||||
* has no secure lockscreen, then the token is activated immediately.
|
||||
*
|
||||
* @return a unique 64-bit token handle which is needed to refer to this token later.
|
||||
*/
|
||||
public abstract long addEscrowToken(byte[] token, int userId);
|
||||
|
||||
/**
|
||||
* Remove an escrow token.
|
||||
* @return true if the given handle refers to a valid token previously returned from
|
||||
* {@link #addEscrowToken}, whether it's active or not. return false otherwise.
|
||||
*/
|
||||
public abstract boolean removeEscrowToken(long handle, int userId);
|
||||
|
||||
/**
|
||||
* Check if the given escrow token is active or not. Only active token can be used to call
|
||||
* {@link #setLockCredentialWithToken} and {@link #unlockUserWithToken}
|
||||
*/
|
||||
public abstract boolean isEscrowTokenActive(long handle, int userId);
|
||||
|
||||
public abstract boolean setLockCredentialWithToken(String credential, int type,
|
||||
long tokenHandle, byte[] token, int requestedQuality, int userId);
|
||||
|
||||
public abstract boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId);
|
||||
}
|
||||
@@ -102,6 +102,7 @@ import com.android.internal.util.Preconditions;
|
||||
import com.android.internal.widget.ICheckCredentialProgressCallback;
|
||||
import com.android.internal.widget.ILockSettings;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockSettingsInternal;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
@@ -436,6 +437,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
mStrongAuthTracker.register(mStrongAuth);
|
||||
|
||||
mSpManager = injector.getSyntheticPasswordManager(mStorage);
|
||||
|
||||
LocalServices.addService(LockSettingsInternal.class, new LocalService());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1041,14 +1044,10 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
|
||||
private boolean isUserSecure(int userId) {
|
||||
synchronized (mSpManager) {
|
||||
try {
|
||||
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
|
||||
long handle = getSyntheticPasswordHandleLocked(userId);
|
||||
return mSpManager.getCredentialType(handle, userId) !=
|
||||
LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// fall through
|
||||
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
|
||||
long handle = getSyntheticPasswordHandleLocked(userId);
|
||||
return mSpManager.getCredentialType(handle, userId) !=
|
||||
LockPatternUtils.CREDENTIAL_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
return mStorage.hasCredential(userId);
|
||||
@@ -2305,7 +2304,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
SyntheticPasswordManager.DEFAULT_HANDLE, userId);
|
||||
}
|
||||
|
||||
private boolean isSyntheticPasswordBasedCredentialLocked(int userId) throws RemoteException {
|
||||
private boolean isSyntheticPasswordBasedCredentialLocked(int userId) {
|
||||
if (userId == USER_FRP) {
|
||||
final int type = mStorage.readPersistentDataBlock().type;
|
||||
return type == PersistentData.TYPE_SP || type == PersistentData.TYPE_SP_WEAVER;
|
||||
@@ -2318,7 +2317,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
|
||||
protected boolean shouldMigrateToSyntheticPasswordLocked(int userId) {
|
||||
long handle = getSyntheticPasswordHandleLocked(userId);
|
||||
// This is a global setting
|
||||
long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
|
||||
@@ -2326,7 +2325,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
|
||||
}
|
||||
|
||||
private void enableSyntheticPasswordLocked() throws RemoteException {
|
||||
private void enableSyntheticPasswordLocked() {
|
||||
setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
|
||||
}
|
||||
|
||||
@@ -2525,9 +2524,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
mRecoverableKeyStoreManager.lockScreenSecretChanged(credentialType, credential, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long addEscrowToken(byte[] token, int userId) throws RemoteException {
|
||||
ensureCallerSystemUid();
|
||||
private long addEscrowToken(byte[] token, int userId) throws RemoteException {
|
||||
if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId);
|
||||
synchronized (mSpManager) {
|
||||
enableSyntheticPasswordLocked();
|
||||
@@ -2559,7 +2556,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
|
||||
private void activateEscrowTokens(AuthenticationToken auth, int userId) {
|
||||
if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
|
||||
synchronized (mSpManager) {
|
||||
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
|
||||
@@ -2570,17 +2567,13 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEscrowTokenActive(long handle, int userId) throws RemoteException {
|
||||
ensureCallerSystemUid();
|
||||
private boolean isEscrowTokenActive(long handle, int userId) {
|
||||
synchronized (mSpManager) {
|
||||
return mSpManager.existsHandle(handle, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEscrowToken(long handle, int userId) throws RemoteException {
|
||||
ensureCallerSystemUid();
|
||||
private boolean removeEscrowToken(long handle, int userId) {
|
||||
synchronized (mSpManager) {
|
||||
if (handle == getSyntheticPasswordHandleLocked(userId)) {
|
||||
Slog.w(TAG, "Cannot remove password handle");
|
||||
@@ -2598,10 +2591,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
|
||||
private boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
|
||||
byte[] token, int requestedQuality, int userId) throws RemoteException {
|
||||
ensureCallerSystemUid();
|
||||
boolean result;
|
||||
synchronized (mSpManager) {
|
||||
if (!mSpManager.hasEscrowData(userId)) {
|
||||
@@ -2650,10 +2641,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockUserWithToken(long tokenHandle, byte[] token, int userId)
|
||||
private boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId)
|
||||
throws RemoteException {
|
||||
ensureCallerSystemUid();
|
||||
AuthenticationResult authResult;
|
||||
synchronized (mSpManager) {
|
||||
if (!mSpManager.hasEscrowData(userId)) {
|
||||
@@ -2663,11 +2652,12 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
tokenHandle, token, userId);
|
||||
if (authResult.authToken == null) {
|
||||
Slog.w(TAG, "Invalid escrow token supplied");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
unlockUser(userId, null, authResult.authToken.deriveDiskEncryptionKey());
|
||||
onAuthTokenKnownForUser(userId, authResult.authToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2732,20 +2722,11 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
|
||||
mSpManager.destroyEscrowData(userId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "disableEscrowTokenOnNonManagedDevices", e);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureCallerSystemUid() throws SecurityException {
|
||||
final int callingUid = mInjector.binderGetCallingUid();
|
||||
if (callingUid != Process.SYSTEM_UID) {
|
||||
throw new SecurityException("Only system can call this API.");
|
||||
}
|
||||
}
|
||||
|
||||
private class DeviceProvisionedObserver extends ContentObserver {
|
||||
private final Uri mDeviceProvisionedUri = Settings.Global.getUriFor(
|
||||
Settings.Global.DEVICE_PROVISIONED);
|
||||
@@ -2834,4 +2815,46 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
private final class LocalService extends LockSettingsInternal {
|
||||
|
||||
@Override
|
||||
public long addEscrowToken(byte[] token, int userId) {
|
||||
try {
|
||||
return LockSettingsService.this.addEscrowToken(token, userId);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeEscrowToken(long handle, int userId) {
|
||||
return LockSettingsService.this.removeEscrowToken(handle, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEscrowTokenActive(long handle, int userId) {
|
||||
return LockSettingsService.this.isEscrowTokenActive(handle, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLockCredentialWithToken(String credential, int type, long tokenHandle,
|
||||
byte[] token, int requestedQuality, int userId) {
|
||||
try {
|
||||
return LockSettingsService.this.setLockCredentialWithToken(credential, type,
|
||||
tokenHandle, token, requestedQuality, userId);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
|
||||
try {
|
||||
return LockSettingsService.this.unlockUserWithToken(tokenHandle, token, userId);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.test.AndroidTestCase;
|
||||
|
||||
import com.android.internal.widget.ILockSettings;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockSettingsInternal;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@@ -67,6 +68,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase {
|
||||
private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
|
||||
|
||||
LockSettingsService mService;
|
||||
LockSettingsInternal mLocalService;
|
||||
|
||||
MockLockSettingsContext mContext;
|
||||
LockSettingsStorageTestable mStorage;
|
||||
@@ -95,6 +97,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase {
|
||||
mDevicePolicyManager = mock(DevicePolicyManager.class);
|
||||
mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
|
||||
|
||||
LocalServices.removeServiceForTest(LockSettingsInternal.class);
|
||||
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
|
||||
LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
|
||||
|
||||
@@ -146,6 +149,7 @@ public class BaseLockSettingsServiceTests extends AndroidTestCase {
|
||||
// Adding a fake Device Owner app which will enable escrow token support in LSS.
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
|
||||
new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
|
||||
mLocalService = LocalServices.getService(LockSettingsInternal.class);
|
||||
}
|
||||
|
||||
private UserInfo installChildProfile(int profileId) {
|
||||
|
||||
@@ -300,14 +300,14 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
|
||||
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
|
||||
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
|
||||
PRIMARY_USER_ID).getResponseCode();
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
mLocalService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
|
||||
|
||||
// Verify DPM gets notified about new device lock
|
||||
@@ -329,16 +329,16 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
|
||||
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
|
||||
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
|
||||
0, PRIMARY_USER_ID).getResponseCode();
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, handle,
|
||||
TOKEN.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
|
||||
mService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
mLocalService.setLockCredentialWithToken(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
|
||||
handle, TOKEN.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
|
||||
mLocalService.setLockCredentialWithToken(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
|
||||
handle, TOKEN.getBytes(), PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
|
||||
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
|
||||
@@ -355,18 +355,19 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
initializeCredentialUnderSP(PASSWORD, PRIMARY_USER_ID);
|
||||
final byte[] storageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
|
||||
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.verifyCredential(PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
|
||||
0, PRIMARY_USER_ID).getResponseCode();
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
|
||||
mService.setLockCredential(PATTERN, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, PASSWORD,
|
||||
PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
|
||||
|
||||
mService.setLockCredentialWithToken(NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
|
||||
handle, TOKEN.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
|
||||
mLocalService.setLockCredentialWithToken(NEWPASSWORD,
|
||||
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, TOKEN.getBytes(),
|
||||
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
|
||||
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
|
||||
NEWPASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
|
||||
@@ -378,8 +379,8 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
throws RemoteException {
|
||||
final String TOKEN = "some-high-entropy-secure-token";
|
||||
enableSyntheticPassword();
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
|
||||
assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
|
||||
}
|
||||
@@ -388,8 +389,8 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
throws RemoteException {
|
||||
final String TOKEN = "some-high-entropy-secure-token";
|
||||
initializeCredentialUnderSP(null, PRIMARY_USER_ID);
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
|
||||
assertTrue(hasSyntheticPassword(PRIMARY_USER_ID));
|
||||
}
|
||||
@@ -404,15 +405,15 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests {
|
||||
PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
|
||||
enableSyntheticPassword();
|
||||
|
||||
long handle = mService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
long handle = mLocalService.addEscrowToken(TOKEN.getBytes(), PRIMARY_USER_ID);
|
||||
// Token not activated immediately since user password exists
|
||||
assertFalse(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertFalse(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
// Activate token (password gets migrated to SP at the same time)
|
||||
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
|
||||
PASSWORD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
|
||||
.getResponseCode());
|
||||
// Verify token is activated
|
||||
assertTrue(mService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
|
||||
}
|
||||
|
||||
public void testPasswordData_serializeDeserialize() {
|
||||
|
||||
Reference in New Issue
Block a user