summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java45
2 files changed, 55 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index fda6cdf33e0c..33e767fe1a8f 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -519,11 +519,11 @@ public class RecoverableKeyStoreManager {
byte[] locallyEncryptedKey;
try {
// TODO: Remove the extraneous logging here
- Log.e(TAG, constructLoggingMessage("sessionEntry.getKeyClaimant()",
+ Log.d(TAG, constructLoggingMessage("sessionEntry.getKeyClaimant()",
sessionEntry.getKeyClaimant()));
- Log.e(TAG, constructLoggingMessage("sessionEntry.getVaultParams()",
+ Log.d(TAG, constructLoggingMessage("sessionEntry.getVaultParams()",
sessionEntry.getVaultParams()));
- Log.e(TAG, constructLoggingMessage("encryptedClaimResponse", encryptedClaimResponse));
+ Log.d(TAG, constructLoggingMessage("encryptedClaimResponse", encryptedClaimResponse));
locallyEncryptedKey = KeySyncUtils.decryptRecoveryClaimResponse(
sessionEntry.getKeyClaimant(),
sessionEntry.getVaultParams(),
@@ -543,9 +543,9 @@ public class RecoverableKeyStoreManager {
try {
// TODO: Remove the extraneous logging here
- Log.e(TAG, constructLoggingMessage("sessionEntry.getLskfHash()",
+ Log.d(TAG, constructLoggingMessage("sessionEntry.getLskfHash()",
sessionEntry.getLskfHash()));
- Log.e(TAG, constructLoggingMessage("locallyEncryptedKey", locallyEncryptedKey));
+ Log.d(TAG, constructLoggingMessage("locallyEncryptedKey", locallyEncryptedKey));
return KeySyncUtils.decryptRecoveryKey(sessionEntry.getLskfHash(), locallyEncryptedKey);
} catch (InvalidKeyException e) {
Log.e(TAG, "Got InvalidKeyException during decrypting recovery key", e);
@@ -585,8 +585,8 @@ public class RecoverableKeyStoreManager {
try {
// TODO: Remove the extraneous logging here
- Log.e(TAG, constructLoggingMessage("recoveryKey", recoveryKey));
- Log.e(TAG, constructLoggingMessage("encryptedKeyMaterial", encryptedKeyMaterial));
+ Log.d(TAG, constructLoggingMessage("recoveryKey", recoveryKey));
+ Log.d(TAG, constructLoggingMessage("encryptedKeyMaterial", encryptedKeyMaterial));
byte[] keyMaterial =
KeySyncUtils.decryptApplicationKey(recoveryKey, encryptedKeyMaterial);
keyMaterialByAlias.put(alias, keyMaterial);
@@ -600,13 +600,16 @@ public class RecoverableKeyStoreManager {
throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED,
"Failed to recover key with alias '" + alias + "': " + e.getMessage());
} catch (AEADBadTagException e) {
- // TODO: Remove the extraneous logging here
Log.e(TAG, "Got AEADBadTagException during decrypting application key with alias: "
+ alias, e);
- throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED,
- "Failed to recover key with alias '" + alias + "': " + e.getMessage());
+ // Ignore the exception to continue to recover the other application keys.
}
}
+ if (keyMaterialByAlias.isEmpty()) {
+ Log.e(TAG, "Failed to recover any of the application keys.");
+ throw new ServiceSpecificException(ERROR_DECRYPTION_FAILED,
+ "Failed to recover any of the application keys.");
+ }
return keyMaterialByAlias;
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 473a813c3838..2343deec020b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -125,6 +125,7 @@ public class RecoverableKeyStoreManagerTest {
private static final byte[] RECOVERY_RESPONSE_HEADER =
"V1 reencrypted_recovery_key".getBytes(StandardCharsets.UTF_8);
private static final String TEST_ALIAS = "nick";
+ private static final String TEST_ALIAS2 = "bob";
private static final int RECOVERABLE_KEY_SIZE_BYTES = 32;
private static final int GENERATION_ID = 1;
private static final byte[] NONCE = getUtf8Bytes("nonce");
@@ -424,7 +425,7 @@ public class RecoverableKeyStoreManagerTest {
}
@Test
- public void recoverKeys_throwsIfFailedToDecryptAnApplicationKey() throws Exception {
+ public void recoverKeys_throwsIfFailedToDecryptAllApplicationKeys() throws Exception {
mRecoverableKeyStoreManager.startRecoverySession(
TEST_SESSION_ID,
TEST_PUBLIC_KEY,
@@ -442,7 +443,7 @@ public class RecoverableKeyStoreManagerTest {
keyClaimant, TEST_SECRET, TEST_VAULT_PARAMS, recoveryKey);
WrappedApplicationKey badApplicationKey = new WrappedApplicationKey(
TEST_ALIAS,
- randomBytes(32));
+ encryptedApplicationKey(randomRecoveryKey(), randomBytes(32)));
try {
mRecoverableKeyStoreManager.recoverKeys(
@@ -451,7 +452,7 @@ public class RecoverableKeyStoreManagerTest {
/*applicationKeys=*/ ImmutableList.of(badApplicationKey));
fail("should have thrown");
} catch (ServiceSpecificException e) {
- assertThat(e.getMessage()).startsWith("Failed to recover key with alias 'nick'");
+ assertThat(e.getMessage()).startsWith("Failed to recover any of the application keys");
}
}
@@ -487,6 +488,44 @@ public class RecoverableKeyStoreManagerTest {
}
@Test
+ public void recoverKeys_worksOnOtherApplicationKeysIfOneDecryptionFails() throws Exception {
+ mRecoverableKeyStoreManager.startRecoverySession(
+ TEST_SESSION_ID,
+ TEST_PUBLIC_KEY,
+ TEST_VAULT_PARAMS,
+ TEST_VAULT_CHALLENGE,
+ ImmutableList.of(new KeyChainProtectionParams(
+ TYPE_LOCKSCREEN,
+ UI_FORMAT_PASSWORD,
+ KeyDerivationParams.createSha256Params(TEST_SALT),
+ TEST_SECRET)));
+ byte[] keyClaimant = mRecoverySessionStorage.get(Binder.getCallingUid(), TEST_SESSION_ID)
+ .getKeyClaimant();
+ SecretKey recoveryKey = randomRecoveryKey();
+ byte[] encryptedClaimResponse = encryptClaimResponse(
+ keyClaimant, TEST_SECRET, TEST_VAULT_PARAMS, recoveryKey);
+
+ byte[] applicationKeyBytes1 = randomBytes(32);
+ byte[] applicationKeyBytes2 = randomBytes(32);
+
+ WrappedApplicationKey applicationKey1 = new WrappedApplicationKey(
+ TEST_ALIAS,
+ // Use a different recovery key here, so the decryption will fail
+ encryptedApplicationKey(randomRecoveryKey(), applicationKeyBytes1));
+ WrappedApplicationKey applicationKey2 = new WrappedApplicationKey(
+ TEST_ALIAS2,
+ encryptedApplicationKey(recoveryKey, applicationKeyBytes2));
+
+ Map<String, byte[]> recoveredKeys = mRecoverableKeyStoreManager.recoverKeys(
+ TEST_SESSION_ID,
+ encryptedClaimResponse,
+ ImmutableList.of(applicationKey1, applicationKey2));
+
+ assertThat(recoveredKeys).hasSize(1);
+ assertThat(recoveredKeys.get(TEST_ALIAS2)).isEqualTo(applicationKeyBytes2);
+ }
+
+ @Test
public void setSnapshotCreatedPendingIntent() throws Exception {
int uid = Binder.getCallingUid();
PendingIntent intent = PendingIntent.getBroadcast(