diff options
2 files changed, 50 insertions, 20 deletions
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 819b62b20ee4..662ffc814390 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java @@ -158,9 +158,17 @@ public class KeySyncTask implements Runnable { } private void syncKeysForAgent(int recoveryAgentUid) { + boolean recreateCurrentVersion = false; if (!shoudCreateSnapshot(recoveryAgentUid)) { - Log.d(TAG, "Key sync not needed."); - return; + recreateCurrentVersion = + (mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid) != null) + && (mRecoverySnapshotStorage.get(recoveryAgentUid) == null); + if (recreateCurrentVersion) { + Log.d(TAG, "Recreating most recent snapshot"); + } else { + Log.d(TAG, "Key sync not needed."); + return; + } } if (!mSnapshotListenersStorage.hasListener(recoveryAgentUid)) { @@ -253,23 +261,21 @@ public class KeySyncTask implements Runnable { Log.e(TAG,"Could not encrypt with recovery key", e); return; } - // TODO: store raw data in RecoveryServiceMetadataEntry and generate Parcelables later - // TODO: use Builder. - KeyChainProtectionParams metadata = new KeyChainProtectionParams( - /*userSecretType=*/ TYPE_LOCKSCREEN, - /*lockScreenUiFormat=*/ getUiFormat(mCredentialType, mCredential), - /*keyDerivationParams=*/ KeyDerivationParams.createSha256Params(salt), - /*secret=*/ new byte[0]); + KeyChainProtectionParams metadata = new KeyChainProtectionParams.Builder() + .setUserSecretType(TYPE_LOCKSCREEN) + .setLockScreenUiFormat(getUiFormat(mCredentialType, mCredential)) + .setKeyDerivationParams(KeyDerivationParams.createSha256Params(salt)) + .setSecret(new byte[0]) + .build(); + ArrayList<KeyChainProtectionParams> metadataList = new ArrayList<>(); metadataList.add(metadata); - int snapshotVersion = incrementSnapshotVersion(recoveryAgentUid); - // If application keys are not updated, snapshot will not be created on next unlock. mRecoverableKeyStoreDb.setShouldCreateSnapshot(mUserId, recoveryAgentUid, false); mRecoverySnapshotStorage.put(recoveryAgentUid, new KeyChainSnapshot.Builder() - .setSnapshotVersion(snapshotVersion) + .setSnapshotVersion(getSnapshotVersion(recoveryAgentUid, recreateCurrentVersion)) .setMaxAttempts(TRUSTED_HARDWARE_MAX_ATTEMPTS) .setCounterId(counterId) .setTrustedHardwarePublicKey(SecureBox.encodePublicKey(publicKey)) @@ -283,9 +289,14 @@ public class KeySyncTask implements Runnable { } @VisibleForTesting - int incrementSnapshotVersion(int recoveryAgentUid) { + int getSnapshotVersion(int recoveryAgentUid, boolean recreateCurrentVersion) { Long snapshotVersion = mRecoverableKeyStoreDb.getSnapshotVersion(mUserId, recoveryAgentUid); - snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion + 1; + if (recreateCurrentVersion) { + // version shouldn't be null at this moment. + snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion; + } else { + snapshotVersion = snapshotVersion == null ? 1 : snapshotVersion + 1; + } mRecoverableKeyStoreDb.setSnapshotVersion(mUserId, recoveryAgentUid, snapshotVersion); return snapshotVersion.intValue(); @@ -413,10 +424,10 @@ public class KeySyncTask implements Runnable { Map<String, byte[]> encryptedApplicationKeys) { ArrayList<WrappedApplicationKey> keyEntries = new ArrayList<>(); for (String alias : encryptedApplicationKeys.keySet()) { - keyEntries.add( - new WrappedApplicationKey( - alias, - encryptedApplicationKeys.get(alias))); + keyEntries.add(new WrappedApplicationKey.Builder() + .setAlias(alias) + .setEncryptedKeyMaterial(encryptedApplicationKeys.get(alias)) + .build()); } return keyEntries; } 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 c94f227f6961..ce5ee138cc3d 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 @@ -327,8 +327,7 @@ public class KeySyncTaskTest { mRecoverableKeyStoreDb.setRecoveryServicePublicKey( TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic()); when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true); - SecretKey applicationKey = - addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS); + addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS); mKeySyncTask.run(); @@ -343,6 +342,26 @@ public class KeySyncTaskTest { } @Test + public void run_recreatesMissingSnapshot() throws Exception { + mRecoverableKeyStoreDb.setRecoveryServicePublicKey( + TEST_USER_ID, TEST_RECOVERY_AGENT_UID, mKeyPair.getPublic()); + when(mSnapshotListenersStorage.hasListener(TEST_RECOVERY_AGENT_UID)).thenReturn(true); + addApplicationKey(TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_APP_KEY_ALIAS); + + mKeySyncTask.run(); + + KeyChainSnapshot keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); + assertThat(keyChainSnapshot.getSnapshotVersion()).isEqualTo(1); // default value; + + mRecoverySnapshotStorage.remove(TEST_RECOVERY_AGENT_UID); // corrupt snapshot. + + mKeySyncTask.run(); + + keyChainSnapshot = mRecoverySnapshotStorage.get(TEST_RECOVERY_AGENT_UID); + assertThat(keyChainSnapshot.getSnapshotVersion()).isEqualTo(1); // Same version + } + + @Test public void run_setsCorrectTypeForPassword() throws Exception { mKeySyncTask = new KeySyncTask( mRecoverableKeyStoreDb, |