import android.app.KeyguardManager;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Environment;
import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyProtection;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
-import java.io.File;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
private static final String KEY_ALGORITHM = "AES";
private static final int KEY_SIZE_BITS = 256;
- private static final String SHARED_PREFS_KEY_GENERATION_ID = "generationId";
- private static final String SHARED_PREFS_PATH = "/system/recoverablekeystore/platform_keys.xml";
private static final String KEY_ALIAS_PREFIX =
"com.android.server.locksettings.recoverablekeystore/platform/";
private static final String ENCRYPT_KEY_ALIAS_SUFFIX = "encrypt";
private final Context mContext;
private final KeyStoreProxy mKeyStore;
- private final SharedPreferences mSharedPreferences;
+ private final RecoverableKeyStoreDb mDatabase;
private final int mUserId;
private static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
*
* @hide
*/
- public static PlatformKeyManager getInstance(Context context, int userId)
+ public static PlatformKeyManager getInstance(Context context, RecoverableKeyStoreDb database, int userId)
throws KeyStoreException, NoSuchAlgorithmException, InsecureUserException {
context = context.getApplicationContext();
- File sharedPreferencesFile = new File(
- Environment.getDataDirectory().getAbsoluteFile(), SHARED_PREFS_PATH);
- sharedPreferencesFile.mkdirs();
PlatformKeyManager keyManager = new PlatformKeyManager(
userId,
context,
new KeyStoreProxyImpl(getAndLoadAndroidKeyStore()),
- context.getSharedPreferences(sharedPreferencesFile, Context.MODE_PRIVATE));
+ database);
keyManager.init();
return keyManager;
}
int userId,
Context context,
KeyStoreProxy keyStore,
- SharedPreferences sharedPreferences) {
+ RecoverableKeyStoreDb database) {
mUserId = userId;
mKeyStore = keyStore;
mContext = context;
- mSharedPreferences = sharedPreferences;
+ mDatabase = database;
}
/**
* @hide
*/
public int getGenerationId() {
- return mSharedPreferences.getInt(getGenerationIdKey(), 1);
+ int generationId = mDatabase.getPlatformKeyGenerationId(mUserId);
+ if (generationId == -1) {
+ return 1;
+ }
+ return generationId;
}
/**
* @hide
*/
public void regenerate() throws NoSuchAlgorithmException, KeyStoreException {
- int generationId = getGenerationId();
- generateAndLoadKey(generationId + 1);
- setGenerationId(generationId + 1);
+ int nextId = getGenerationId() + 1;
+ generateAndLoadKey(nextId);
+ setGenerationId(nextId);
}
/**
* Sets the current generation ID to {@code generationId}.
*/
private void setGenerationId(int generationId) {
- mSharedPreferences.edit().putInt(getGenerationIdKey(), generationId).commit();
- }
-
- /**
- * Returns the current user's generation ID key in the shared preferences.
- */
- private String getGenerationIdKey() {
- return SHARED_PREFS_KEY_GENERATION_ID + "/" + mUserId;
+ mDatabase.setPlatformKeyGenerationId(mUserId, generationId);
}
/**
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.File;
import java.security.KeyStore;
import java.util.List;
@RunWith(AndroidJUnit4.class)
public class PlatformKeyManagerTest {
+ private static final String DATABASE_FILE_NAME = "recoverablekeystore.db";
private static final int USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS = 15;
private static final int USER_ID_FIXTURE = 42;
- private static final String TEST_SHARED_PREFS_NAME = "PlatformKeyManagerTestPrefs";
@Mock private Context mContext;
@Mock private KeyStoreProxy mKeyStoreProxy;
@Captor private ArgumentCaptor<KeyStore.ProtectionParameter> mProtectionParameterCaptor;
@Captor private ArgumentCaptor<KeyStore.Entry> mEntryArgumentCaptor;
- private SharedPreferences mSharedPreferences;
+ private RecoverableKeyStoreDb mRecoverableKeyStoreDb;
+ private File mDatabaseFile;
+
private PlatformKeyManager mPlatformKeyManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- Context testContext = InstrumentationRegistry.getTargetContext();
- mSharedPreferences = testContext.getSharedPreferences(
- TEST_SHARED_PREFS_NAME, Context.MODE_PRIVATE);
+ Context context = InstrumentationRegistry.getTargetContext();
+ mDatabaseFile = context.getDatabasePath(DATABASE_FILE_NAME);
+ mRecoverableKeyStoreDb = RecoverableKeyStoreDb.newInstance(context);
mPlatformKeyManager = new PlatformKeyManager(
- USER_ID_FIXTURE, mContext, mKeyStoreProxy, mSharedPreferences);
+ USER_ID_FIXTURE, mContext, mKeyStoreProxy, mRecoverableKeyStoreDb);
when(mContext.getSystemService(anyString())).thenReturn(mKeyguardManager);
when(mContext.getSystemServiceName(any())).thenReturn("test");
@After
public void tearDown() {
- mSharedPreferences.edit().clear().commit();
+ mRecoverableKeyStoreDb.close();
+ mDatabaseFile.delete();
}
@Test