Merge "Update RecoveryController to use KeyStore grant API."
This commit is contained in:
committed by
Android (Google) Code Review
commit
63e027d040
@@ -26,9 +26,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keystore.AndroidKeyStoreProvider;
|
||||
|
||||
import com.android.internal.widget.ILockSettings;
|
||||
|
||||
import java.security.Key;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -113,9 +117,11 @@ public class RecoveryController {
|
||||
|
||||
|
||||
private final ILockSettings mBinder;
|
||||
private final KeyStore mKeyStore;
|
||||
|
||||
private RecoveryController(ILockSettings binder) {
|
||||
private RecoveryController(ILockSettings binder, KeyStore keystore) {
|
||||
mBinder = binder;
|
||||
mKeyStore = keystore;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +139,7 @@ public class RecoveryController {
|
||||
public static RecoveryController getInstance(Context context) {
|
||||
ILockSettings lockSettings =
|
||||
ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"));
|
||||
return new RecoveryController(lockSettings);
|
||||
return new RecoveryController(lockSettings, KeyStore.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,6 +436,7 @@ public class RecoveryController {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
* Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable
|
||||
* key store. Returns the raw material of the key.
|
||||
*
|
||||
@@ -444,7 +451,6 @@ public class RecoveryController {
|
||||
public byte[] generateAndStoreKey(@NonNull String alias, byte[] account)
|
||||
throws InternalRecoveryServiceException, LockScreenRequiredException {
|
||||
try {
|
||||
// TODO: add account
|
||||
return mBinder.generateAndStoreKey(alias);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
@@ -456,6 +462,72 @@ public class RecoveryController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable
|
||||
* key store. Returns {@link javax.crypto.SecretKey}.
|
||||
*
|
||||
* @param alias The key alias.
|
||||
* @param account The account associated with the key.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
* @throws LockScreenRequiredException if the user has not set a lock screen. This is required
|
||||
* to generate recoverable keys, as the snapshots are encrypted using a key derived from the
|
||||
* lock screen.
|
||||
* @hide
|
||||
*/
|
||||
public Key generateKey(@NonNull String alias, byte[] account)
|
||||
throws InternalRecoveryServiceException, LockScreenRequiredException {
|
||||
// TODO: update RecoverySession.recoverKeys
|
||||
try {
|
||||
String grantAlias = mBinder.generateKey(alias, account);
|
||||
if (grantAlias == null) {
|
||||
return null;
|
||||
}
|
||||
Key result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
|
||||
mKeyStore,
|
||||
grantAlias,
|
||||
KeyStore.UID_SELF);
|
||||
return result;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (UnrecoverableKeyException e) {
|
||||
throw new InternalRecoveryServiceException("Access to newly generated key failed for");
|
||||
} catch (ServiceSpecificException e) {
|
||||
if (e.errorCode == ERROR_INSECURE_USER) {
|
||||
throw new LockScreenRequiredException(e.getMessage());
|
||||
}
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key called {@code alias} from the recoverable key store.
|
||||
*
|
||||
* @param alias The key alias.
|
||||
* @return The key.
|
||||
* @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
|
||||
* service.
|
||||
* @throws UnrecoverableKeyException if key is permanently invalidated or not found.
|
||||
* @hide
|
||||
*/
|
||||
public @Nullable Key getKey(@NonNull String alias)
|
||||
throws InternalRecoveryServiceException, UnrecoverableKeyException {
|
||||
try {
|
||||
String grantAlias = mBinder.getKey(alias);
|
||||
if (grantAlias == null) {
|
||||
return null;
|
||||
}
|
||||
return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
|
||||
mKeyStore,
|
||||
grantAlias,
|
||||
KeyStore.UID_SELF);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw wrapUnexpectedServiceSpecificException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key called {@code alias} from the recoverable key store.
|
||||
*
|
||||
|
||||
@@ -66,6 +66,8 @@ interface ILockSettings {
|
||||
void initRecoveryService(in String rootCertificateAlias, in byte[] signedPublicKeyList);
|
||||
KeyChainSnapshot getKeyChainSnapshot();
|
||||
byte[] generateAndStoreKey(String alias);
|
||||
String generateKey(String alias, in byte[] account);
|
||||
String getKey(String alias);
|
||||
void removeKey(String alias);
|
||||
void setSnapshotCreatedPendingIntent(in PendingIntent intent);
|
||||
Map getRecoverySnapshotVersions();
|
||||
|
||||
@@ -383,8 +383,8 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
return KeyStore.getInstance();
|
||||
}
|
||||
|
||||
public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
|
||||
return RecoverableKeyStoreManager.getInstance(mContext);
|
||||
public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) {
|
||||
return RecoverableKeyStoreManager.getInstance(mContext, keyStore);
|
||||
}
|
||||
|
||||
public IStorageManager getStorageManager() {
|
||||
@@ -413,7 +413,7 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
mInjector = injector;
|
||||
mContext = injector.getContext();
|
||||
mKeyStore = injector.getKeyStore();
|
||||
mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
|
||||
mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore);
|
||||
mHandler = injector.getHandler();
|
||||
mStrongAuth = injector.getStrongAuth();
|
||||
mActivityManager = injector.getActivityManager();
|
||||
@@ -2064,6 +2064,16 @@ public class LockSettingsService extends ILockSettings.Stub {
|
||||
return mRecoverableKeyStoreManager.generateAndStoreKey(alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateKey(@NonNull String alias, byte[] account) throws RemoteException {
|
||||
return mRecoverableKeyStoreManager.generateKey(alias, account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey(@NonNull String alias) throws RemoteException {
|
||||
return mRecoverableKeyStoreManager.getKey(alias);
|
||||
}
|
||||
|
||||
private static final String[] VALID_SETTINGS = new String[] {
|
||||
LockPatternUtils.LOCKOUT_PERMANENT_KEY,
|
||||
LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.android.server.locksettings.recoverablekeystore;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
|
||||
/**
|
||||
@@ -27,6 +30,7 @@ import java.security.UnrecoverableKeyException;
|
||||
*/
|
||||
public class KeyStoreProxyImpl implements KeyStoreProxy {
|
||||
|
||||
private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
|
||||
private final KeyStore mKeyStore;
|
||||
|
||||
/**
|
||||
@@ -57,4 +61,21 @@ public class KeyStoreProxyImpl implements KeyStoreProxy {
|
||||
public void deleteEntry(String alias) throws KeyStoreException {
|
||||
mKeyStore.deleteEntry(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns AndroidKeyStore-provided {@link KeyStore}, having already invoked
|
||||
* {@link KeyStore#load(KeyStore.LoadStoreParameter)}.
|
||||
*
|
||||
* @throws KeyStoreException if there was a problem getting or initializing the key store.
|
||||
*/
|
||||
public static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
|
||||
KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
|
||||
try {
|
||||
keyStore.load(/*param=*/ null);
|
||||
} catch (CertificateException | IOException | NoSuchAlgorithmException e) {
|
||||
// Should never happen.
|
||||
throw new KeyStoreException("Unable to load keystore.", e);
|
||||
}
|
||||
return keyStore;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,21 +37,23 @@ import android.security.keystore.recovery.KeyChainProtectionParams;
|
||||
import android.security.keystore.recovery.KeyChainSnapshot;
|
||||
import android.security.keystore.recovery.RecoveryController;
|
||||
import android.security.keystore.recovery.WrappedApplicationKey;
|
||||
import android.security.KeyStore;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.HexDump;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.ApplicationKeyStorage;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
@@ -82,18 +84,23 @@ public class RecoverableKeyStoreManager {
|
||||
private final RecoverableKeyGenerator mRecoverableKeyGenerator;
|
||||
private final RecoverySnapshotStorage mSnapshotStorage;
|
||||
private final PlatformKeyManager mPlatformKeyManager;
|
||||
private final KeyStore mKeyStore;
|
||||
private final ApplicationKeyStorage mApplicationKeyStorage;
|
||||
|
||||
/**
|
||||
* Returns a new or existing instance.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static synchronized RecoverableKeyStoreManager getInstance(Context context) {
|
||||
public static synchronized RecoverableKeyStoreManager
|
||||
getInstance(Context context, KeyStore keystore) {
|
||||
if (mInstance == null) {
|
||||
RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(context);
|
||||
PlatformKeyManager platformKeyManager;
|
||||
ApplicationKeyStorage applicationKeyStorage;
|
||||
try {
|
||||
platformKeyManager = PlatformKeyManager.getInstance(context, db);
|
||||
applicationKeyStorage = ApplicationKeyStorage.getInstance(keystore);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// Impossible: all algorithms must be supported by AOSP
|
||||
throw new RuntimeException(e);
|
||||
@@ -103,12 +110,14 @@ public class RecoverableKeyStoreManager {
|
||||
|
||||
mInstance = new RecoverableKeyStoreManager(
|
||||
context.getApplicationContext(),
|
||||
keystore,
|
||||
db,
|
||||
new RecoverySessionStorage(),
|
||||
Executors.newSingleThreadExecutor(),
|
||||
new RecoverySnapshotStorage(),
|
||||
new RecoverySnapshotListenersStorage(),
|
||||
platformKeyManager);
|
||||
platformKeyManager,
|
||||
applicationKeyStorage);
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
@@ -116,19 +125,23 @@ public class RecoverableKeyStoreManager {
|
||||
@VisibleForTesting
|
||||
RecoverableKeyStoreManager(
|
||||
Context context,
|
||||
KeyStore keystore,
|
||||
RecoverableKeyStoreDb recoverableKeyStoreDb,
|
||||
RecoverySessionStorage recoverySessionStorage,
|
||||
ExecutorService executorService,
|
||||
RecoverySnapshotStorage snapshotStorage,
|
||||
RecoverySnapshotListenersStorage listenersStorage,
|
||||
PlatformKeyManager platformKeyManager) {
|
||||
PlatformKeyManager platformKeyManager,
|
||||
ApplicationKeyStorage applicationKeyStorage) {
|
||||
mContext = context;
|
||||
mKeyStore = keystore;
|
||||
mDatabase = recoverableKeyStoreDb;
|
||||
mRecoverySessionStorage = recoverySessionStorage;
|
||||
mExecutorService = executorService;
|
||||
mListenersStorage = listenersStorage;
|
||||
mSnapshotStorage = snapshotStorage;
|
||||
mPlatformKeyManager = platformKeyManager;
|
||||
mApplicationKeyStorage = applicationKeyStorage;
|
||||
|
||||
try {
|
||||
mRecoverableKeyGenerator = RecoverableKeyGenerator.newInstance(mDatabase);
|
||||
@@ -406,6 +419,7 @@ public class RecoverableKeyStoreManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
* Generates a key named {@code alias} in the recoverable store for the calling uid. Then
|
||||
* returns the raw key material.
|
||||
*
|
||||
@@ -450,9 +464,55 @@ public class RecoverableKeyStoreManager {
|
||||
boolean wasRemoved = mDatabase.removeKey(uid, alias);
|
||||
if (wasRemoved) {
|
||||
mDatabase.setShouldCreateSnapshot(userId, uid, true);
|
||||
mApplicationKeyStorage.deleteEntry(userId, uid, alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a key named {@code alias} in caller's namespace.
|
||||
* The key is stored in system service keystore namespace.
|
||||
*
|
||||
* @return grant alias, which caller can use to access the key.
|
||||
*/
|
||||
public String generateKey(@NonNull String alias, byte[] account) throws RemoteException {
|
||||
int uid = Binder.getCallingUid();
|
||||
int userId = UserHandle.getCallingUserId();
|
||||
|
||||
PlatformEncryptionKey encryptionKey;
|
||||
try {
|
||||
encryptionKey = mPlatformKeyManager.getEncryptKey(userId);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// Impossible: all algorithms must be supported by AOSP
|
||||
throw new RuntimeException(e);
|
||||
} catch (KeyStoreException | UnrecoverableKeyException e) {
|
||||
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
|
||||
} catch (InsecureUserException e) {
|
||||
throw new ServiceSpecificException(ERROR_INSECURE_USER, e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] secretKey =
|
||||
mRecoverableKeyGenerator.generateAndStoreKey(encryptionKey, userId, uid, alias);
|
||||
mApplicationKeyStorage.setSymmetricKeyEntry(userId, uid, alias, secretKey);
|
||||
String grantAlias = mApplicationKeyStorage.getGrantAlias(userId, uid, alias);
|
||||
return grantAlias;
|
||||
} catch (KeyStoreException | InvalidKeyException | RecoverableKeyStorageException e) {
|
||||
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key named {@code alias} in caller's namespace.
|
||||
*
|
||||
* @return grant alias, which caller can use to access the key.
|
||||
*/
|
||||
public String getKey(@NonNull String alias) throws RemoteException {
|
||||
int uid = Binder.getCallingUid();
|
||||
int userId = UserHandle.getCallingUserId();
|
||||
String grantAlias = mApplicationKeyStorage.getGrantAlias(userId, uid, alias);
|
||||
return grantAlias;
|
||||
}
|
||||
|
||||
private byte[] decryptRecoveryKey(
|
||||
RecoverySessionStorage.Entry sessionEntry, byte[] encryptedClaimResponse)
|
||||
throws RemoteException, ServiceSpecificException {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.server.locksettings.recoverablekeystore.storage;
|
||||
|
||||
import static android.security.keystore.RecoveryController.ERROR_SERVICE_INTERNAL_ERROR;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.security.Credentials;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyProperties;
|
||||
import android.security.keystore.KeyProtection;
|
||||
import android.security.keystore.recovery.KeyChainSnapshot;
|
||||
import android.security.KeyStore;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.locksettings.recoverablekeystore.KeyStoreProxy;
|
||||
import com.android.server.locksettings.recoverablekeystore.KeyStoreProxyImpl;
|
||||
|
||||
import java.security.KeyStore.SecretKeyEntry;
|
||||
import java.security.KeyStoreException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Storage for Application keys in LockSettings service KeyStore namespace.
|
||||
*
|
||||
* <p> Uses KeyStore's grant mechanism to make keys usable by application process without
|
||||
* revealing key material
|
||||
*/
|
||||
public class ApplicationKeyStorage {
|
||||
private static final String APPLICATION_KEY_ALIAS_PREFIX =
|
||||
"com.android.server.locksettings.recoverablekeystore/application/";
|
||||
|
||||
KeyStoreProxy mKeyStore;
|
||||
KeyStore mKeystoreService;
|
||||
|
||||
public static ApplicationKeyStorage getInstance(KeyStore keystoreService)
|
||||
throws KeyStoreException {
|
||||
return new ApplicationKeyStorage(
|
||||
new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore()),
|
||||
keystoreService);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
ApplicationKeyStorage(KeyStoreProxy keyStore, KeyStore keystoreService) {
|
||||
mKeyStore = keyStore;
|
||||
mKeystoreService = keystoreService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns grant alias, valid in Applications namespace.
|
||||
*/
|
||||
public @Nullable String getGrantAlias(int userId, int uid, String alias) {
|
||||
// Aliases used by {@link KeyStore} are different than used by public API.
|
||||
// {@code USER_PRIVATE_KEY} prefix is used secret keys.
|
||||
String keystoreAlias = Credentials.USER_PRIVATE_KEY + getInternalAlias(userId, uid, alias);
|
||||
return mKeystoreService.grant(keystoreAlias, uid);
|
||||
}
|
||||
|
||||
public void setSymmetricKeyEntry(int userId, int uid, String alias, byte[] secretKey)
|
||||
throws KeyStoreException {
|
||||
try {
|
||||
mKeyStore.setEntry(
|
||||
getInternalAlias(userId, uid, alias),
|
||||
new SecretKeyEntry(
|
||||
new SecretKeySpec(secretKey, KeyProperties.KEY_ALGORITHM_AES)),
|
||||
new KeyProtection.Builder(
|
||||
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
||||
.build());
|
||||
} catch (KeyStoreException e) {
|
||||
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteEntry(int userId, int uid, String alias) {
|
||||
try {
|
||||
mKeyStore.deleteEntry(getInternalAlias(userId, uid, alias));
|
||||
} catch (KeyStoreException e) {
|
||||
throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alias in locksettins service's KeyStore namespace used for given application key.
|
||||
*
|
||||
* <p>These IDs look as follows:
|
||||
* {@code com.security.recoverablekeystore/application/<userId>/<uid>/<alias>}
|
||||
*
|
||||
* @param userId The ID of the user
|
||||
* @param uid The uid
|
||||
* @param alias - alias in application's namespace
|
||||
* @return The alias.
|
||||
*/
|
||||
private String getInternalAlias(int userId, int uid, String alias) {
|
||||
return APPLICATION_KEY_ALIAS_PREFIX + userId + "/" + uid + "/" + alias;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import android.Manifest;
|
||||
import android.os.Binder;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.os.UserHandle;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keystore.AndroidKeyStoreSecretKey;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyProperties;
|
||||
@@ -49,6 +50,7 @@ import android.support.test.filters.SmallTest;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.ApplicationKeyStorage;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverySessionStorage;
|
||||
import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
|
||||
@@ -135,6 +137,8 @@ public class RecoverableKeyStoreManagerTest {
|
||||
@Mock private RecoverySnapshotListenersStorage mMockListenersStorage;
|
||||
@Mock private KeyguardManager mKeyguardManager;
|
||||
@Mock private PlatformKeyManager mPlatformKeyManager;
|
||||
@Mock private KeyStore mKeyStore;
|
||||
@Mock private ApplicationKeyStorage mApplicationKeyStorage;
|
||||
|
||||
private RecoverableKeyStoreDb mRecoverableKeyStoreDb;
|
||||
private File mDatabaseFile;
|
||||
@@ -164,12 +168,14 @@ public class RecoverableKeyStoreManagerTest {
|
||||
|
||||
mRecoverableKeyStoreManager = new RecoverableKeyStoreManager(
|
||||
mMockContext,
|
||||
mKeyStore,
|
||||
mRecoverableKeyStoreDb,
|
||||
mRecoverySessionStorage,
|
||||
Executors.newSingleThreadExecutor(),
|
||||
mRecoverySnapshotStorage,
|
||||
mMockListenersStorage,
|
||||
mPlatformKeyManager);
|
||||
mPlatformKeyManager,
|
||||
mApplicationKeyStorage);
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
Reference in New Issue
Block a user