summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java47
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java23
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,