Merge "Disable RecoverableKeyStoreManager for custom lockscreens." into pi-dev
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index 8efce86..1bd5f42 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -148,6 +148,11 @@
             mPlatformKeyManager.invalidatePlatformKey(mUserId, generation);
             return;
         }
+        if (isCustomLockScreen()) {
+            Log.w(TAG, "Unsupported credential type " + mCredentialType + "for user " + mUserId);
+            mRecoverableKeyStoreDb.invalidateKeysForUserIdOnCustomScreenLock(mUserId);
+            return;
+        }
 
         List<Integer> recoveryAgents = mRecoverableKeyStoreDb.getRecoveryAgents(mUserId);
         for (int uid : recoveryAgents) {
@@ -158,6 +163,12 @@
         }
     }
 
+    private boolean isCustomLockScreen() {
+        return mCredentialType != LockPatternUtils.CREDENTIAL_TYPE_NONE
+            && mCredentialType != LockPatternUtils.CREDENTIAL_TYPE_PATTERN
+            && mCredentialType != LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
+    }
+
     private void syncKeysForAgent(int recoveryAgentUid) {
         boolean recreateCurrentVersion = false;
         if (!shoudCreateSnapshot(recoveryAgentUid)) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
index 89ddb6c..2676ee8 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDb.java
@@ -320,6 +320,20 @@
     }
 
     /**
+     * Updates status of old keys to {@code RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE}.
+     */
+    public void invalidateKeysForUserIdOnCustomScreenLock(int userId) {
+        SQLiteDatabase db = mKeyStoreDbHelper.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(KeysEntry.COLUMN_NAME_RECOVERY_STATUS,
+            RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+        String selection =
+            KeysEntry.COLUMN_NAME_USER_ID + " = ?";
+        db.update(KeysEntry.TABLE_NAME, values, selection,
+            new String[] {String.valueOf(userId)});
+    }
+
+    /**
      * Returns the generation ID associated with the platform key of the user with {@code userId}.
      */
     public int getPlatformKeyGenerationId(int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
index e40e3a4..e9289e5 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
@@ -42,11 +42,13 @@
 import android.security.keystore.KeyProperties;
 import android.security.keystore.recovery.KeyDerivationParams;
 import android.security.keystore.recovery.KeyChainSnapshot;
+import android.security.keystore.recovery.RecoveryController;
 import android.security.keystore.recovery.WrappedApplicationKey;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
+import android.util.Log;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverableKeyStoreDb;
 import com.android.server.locksettings.recoverablekeystore.storage.RecoverySnapshotStorage;
 
@@ -516,6 +518,34 @@
                 recoverySnapshotAvailable(TEST_RECOVERY_AGENT_UID2);
     }
 
+    @Test
+    public void run_customLockScreen_RecoveryStatusFailure() throws Exception {
+      mKeySyncTask = new KeySyncTask(
+          mRecoverableKeyStoreDb,
+          mRecoverySnapshotStorage,
+          mSnapshotListenersStorage,
+          TEST_USER_ID,
+          /*credentialType=*/ 3,
+          "12345",
+          /*credentialUpdated=*/ false,
+          mPlatformKeyManager);
+
+      addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS);
+
+      int status =
+          mRecoverableKeyStoreDb
+              .getStatusForAllKeys(TEST_RECOVERY_AGENT_UID)
+              .get(TEST_APP_KEY_ALIAS);
+      assertEquals(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS, status);
+
+      mKeySyncTask.run();
+
+      status = mRecoverableKeyStoreDb
+          .getStatusForAllKeys(TEST_RECOVERY_AGENT_UID)
+          .get(TEST_APP_KEY_ALIAS);
+      assertEquals(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE, status);
+    }
+
     private SecretKey addApplicationKey(int userId, int recoveryAgentUid, String alias)
             throws Exception{
         SecretKey applicationKey = generateKey();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
index dfb2dbf..8b01d97 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
@@ -342,6 +342,30 @@
     }
 
     @Test
+    public void testInvalidateKeysForUserIdOnCustomScreenLock() {
+        int userId = 12;
+        int uid = 1009;
+        int generationId = 6;
+        int status = 120;
+        int status2 = 121;
+        String alias = "test";
+        byte[] nonce = getUtf8Bytes("nonce");
+        byte[] keyMaterial = getUtf8Bytes("keymaterial");
+        WrappedKey wrappedKey = new WrappedKey(nonce, keyMaterial, generationId, status);
+        mRecoverableKeyStoreDb.insertKey(userId, uid, alias, wrappedKey);
+
+        WrappedKey retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias);
+        assertThat(retrievedKey.getRecoveryStatus()).isEqualTo(status);
+
+        mRecoverableKeyStoreDb.setRecoveryStatus(uid, alias, status2);
+        mRecoverableKeyStoreDb.invalidateKeysForUserIdOnCustomScreenLock(userId);
+
+        retrievedKey = mRecoverableKeyStoreDb.getKey(uid, alias);
+        assertThat(retrievedKey.getRecoveryStatus())
+            .isEqualTo(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+    }
+
+    @Test
     public void setRecoveryServicePublicKey_replaceOldKey() throws Exception {
         int userId = 12;
         int uid = 10009;