From 5ab36d72a41d8862935368b2fc4fb3afca2c939a Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Sun, 20 Nov 2022 15:05:11 +0100 Subject: [PATCH] Add a test for password and backup password changes --- .../com/beemdevelopment/aegis/AegisTest.java | 2 + .../aegis/BackupExportTest.java | 80 ++++++++++++++++--- .../SecurityPreferencesFragment.java | 7 +- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java index e3ec9d48..d4566bca 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/AegisTest.java @@ -41,7 +41,9 @@ import dagger.hilt.android.testing.HiltAndroidRule; public abstract class AegisTest { public static final String VAULT_PASSWORD = "test"; + public static final String VAULT_PASSWORD_CHANGED = "test2"; public static final String VAULT_BACKUP_PASSWORD = "something"; + public static final String VAULT_BACKUP_PASSWORD_CHANGED = "something2"; @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); diff --git a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java index 04babe67..36615f44 100644 --- a/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java +++ b/app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java @@ -184,6 +184,64 @@ public class BackupExportTest extends AegisTest { readVault(file, VAULT_BACKUP_PASSWORD); } + @Test + public void testChangeBackupPassword() throws SlotIntegrityException { + initEncryptedVault(); + setSeparateBackupExportPassword(); + + onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click())); + onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_backup_password_change_title)), click())); + onView(withId(R.id.text_password)).perform(typeText(VAULT_BACKUP_PASSWORD_CHANGED), closeSoftKeyboard()); + onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_BACKUP_PASSWORD_CHANGED), closeSoftKeyboard()); + onView(withId(android.R.id.button1)).perform(click()); + onView(isRoot()).perform(pressBack()); + + VaultFileCredentials creds = _vaultManager.getVault().getCredentials(); + assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1); + assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1); + + for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) { + verifyPasswordSlotChange(creds, slot, VAULT_BACKUP_PASSWORD, VAULT_BACKUP_PASSWORD_CHANGED); + } + + for (PasswordSlot slot : creds.getSlots().findRegularPasswordSlots()) { + decryptPasswordSlot(slot, VAULT_PASSWORD); + } + + openExportDialog(); + File file = doExport(); + readVault(file, VAULT_BACKUP_PASSWORD_CHANGED); + } + + @Test + public void testChangePasswordHavingBackupPassword() throws SlotIntegrityException { + initEncryptedVault(); + setSeparateBackupExportPassword(); + + onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_section_security_title)), click())); + onView(withId(androidx.preference.R.id.recycler_view)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(R.string.pref_set_password_title)), click())); + onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD_CHANGED), closeSoftKeyboard()); + onView(withId(R.id.text_password_confirm)).perform(typeText(VAULT_PASSWORD_CHANGED), closeSoftKeyboard()); + onView(withId(android.R.id.button1)).perform(click()); + onView(isRoot()).perform(pressBack()); + + VaultFileCredentials creds = _vaultManager.getVault().getCredentials(); + assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1); + assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1); + + for (PasswordSlot slot : creds.getSlots().findRegularPasswordSlots()) { + verifyPasswordSlotChange(creds, slot, VAULT_PASSWORD, VAULT_PASSWORD_CHANGED); + } + + for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) { + decryptPasswordSlot(slot, VAULT_BACKUP_PASSWORD); + } + + openExportDialog(); + File file = doExport(); + readVault(file, VAULT_BACKUP_PASSWORD); + } + private void setSeparateBackupExportPassword() { VaultFileCredentials creds = _vaultManager.getVault().getCredentials(); assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1); @@ -200,18 +258,22 @@ public class BackupExportTest extends AegisTest { assertEquals(creds.getSlots().findRegularPasswordSlots().size(), 1); assertEquals(creds.getSlots().findBackupPasswordSlots().size(), 1); for (PasswordSlot slot : creds.getSlots().findBackupPasswordSlots()) { - assertThrows(SlotIntegrityException.class, () -> decryptPasswordSlot(slot, VAULT_PASSWORD)); - MasterKey masterKey; - try { - masterKey = decryptPasswordSlot(slot, VAULT_BACKUP_PASSWORD); - } catch (SlotIntegrityException e) { - throw new RuntimeException("Unable to decrypt password slot", e); - } - - assertArrayEquals(creds.getKey().getBytes(), masterKey.getBytes()); + verifyPasswordSlotChange(creds, slot, VAULT_PASSWORD, VAULT_BACKUP_PASSWORD); } } + private void verifyPasswordSlotChange(VaultFileCredentials creds, PasswordSlot slot, String oldPassword, String newPassword) { + assertThrows(SlotIntegrityException.class, () -> decryptPasswordSlot(slot, oldPassword)); + MasterKey masterKey; + try { + masterKey = decryptPasswordSlot(slot, newPassword); + } catch (SlotIntegrityException e) { + throw new RuntimeException("Unable to decrypt password slot", e); + } + + assertArrayEquals(creds.getKey().getBytes(), masterKey.getBytes()); + } + private File doExport() { File file = getExportFileUri(); Intent resultData = new Intent(); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java index 5c7f2e46..68318d74 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java @@ -24,7 +24,6 @@ import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.preferences.SwitchPreference; import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask; import com.beemdevelopment.aegis.vault.VaultFileCredentials; -import com.beemdevelopment.aegis.vault.VaultRepository; import com.beemdevelopment.aegis.vault.VaultRepositoryException; import com.beemdevelopment.aegis.vault.slots.BiometricSlot; import com.beemdevelopment.aegis.vault.slots.PasswordSlot; @@ -337,9 +336,9 @@ public class SecurityPreferencesFragment extends PreferencesFragment { slot.setKey(creds.getKey(), cipher); // remove the old master password slot - PasswordSlot oldSlot = creds.getSlots().find(PasswordSlot.class); - if (oldSlot != null) { - slots.remove(oldSlot); + List passSlots = creds.getSlots().findRegularPasswordSlots(); + if (passSlots.size() != 0) { + slots.remove(passSlots.get(0)); } // add the new master password slot