Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c1ee524 authored by Robert Berry's avatar Robert Berry
Browse files

Back PlatformKeyManager with database

It was previously using SharedPreferences

Test: adb shell am instrument -w -e package com.android.server.locksettings.recoverablekeystore com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I76a75edb93a3feca645e49162c0d8b3e9485385b
parent 13eec469
Loading
Loading
Loading
Loading
+15 −25
Original line number Diff line number Diff line
@@ -18,16 +18,14 @@ package com.android.server.locksettings.recoverablekeystore;

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;
@@ -64,8 +62,6 @@ public class PlatformKeyManager {

    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";
@@ -74,7 +70,7 @@ public class PlatformKeyManager {

    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";
@@ -92,17 +88,14 @@ public class PlatformKeyManager {
     *
     * @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;
    }
@@ -112,11 +105,11 @@ public class PlatformKeyManager {
            int userId,
            Context context,
            KeyStoreProxy keyStore,
            SharedPreferences sharedPreferences) {
            RecoverableKeyStoreDb database) {
        mUserId = userId;
        mKeyStore = keyStore;
        mContext = context;
        mSharedPreferences = sharedPreferences;
        mDatabase = database;
    }

    /**
@@ -127,7 +120,11 @@ public class PlatformKeyManager {
     * @hide
     */
    public int getGenerationId() {
        return mSharedPreferences.getInt(getGenerationIdKey(), 1);
        int generationId = mDatabase.getPlatformKeyGenerationId(mUserId);
        if (generationId == -1) {
            return 1;
        }
        return generationId;
    }

    /**
@@ -150,9 +147,9 @@ public class PlatformKeyManager {
     * @hide
     */
    public void regenerate() throws NoSuchAlgorithmException, KeyStoreException {
        int generationId = getGenerationId();
        generateAndLoadKey(generationId + 1);
        setGenerationId(generationId + 1);
        int nextId = getGenerationId() + 1;
        generateAndLoadKey(nextId);
        setGenerationId(nextId);
    }

    /**
@@ -252,14 +249,7 @@ public class PlatformKeyManager {
     * 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);
    }

    /**
+13 −7
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import android.support.test.InstrumentationRegistry;
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;
@@ -45,6 +47,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.io.File;
import java.security.KeyStore;
import java.util.List;

@@ -52,9 +55,9 @@ 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;
@@ -63,18 +66,20 @@ public class PlatformKeyManagerTest {
    @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");
@@ -83,7 +88,8 @@ public class PlatformKeyManagerTest {

    @After
    public void tearDown() {
        mSharedPreferences.edit().clear().commit();
        mRecoverableKeyStoreDb.close();
        mDatabaseFile.delete();
    }

    @Test