package com.beemdevelopment.aegis; import android.view.View; import androidx.annotation.Nullable; import androidx.test.espresso.UiController; import androidx.test.espresso.ViewAction; import androidx.test.platform.app.InstrumentationRegistry; import com.beemdevelopment.aegis.crypto.CryptoUtils; import com.beemdevelopment.aegis.crypto.SCryptParameters; import com.beemdevelopment.aegis.otp.OtpInfo; import com.beemdevelopment.aegis.vault.VaultEntry; import com.beemdevelopment.aegis.vault.VaultFileCredentials; import com.beemdevelopment.aegis.vault.VaultManager; import com.beemdevelopment.aegis.vault.VaultRepository; import com.beemdevelopment.aegis.vault.VaultRepositoryException; import com.beemdevelopment.aegis.vault.slots.PasswordSlot; import com.beemdevelopment.aegis.vault.slots.SlotException; import com.beemdevelopment.aegis.vectors.VaultEntries; import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Rule; import java.lang.reflect.InvocationTargetException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.List; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.inject.Inject; import dagger.hilt.android.testing.HiltAndroidRule; public abstract class AegisTest { public static final String VAULT_PASSWORD = "test"; public static final String VAULT_BACKUP_PASSWORD = "something"; @Rule public HiltAndroidRule hiltRule = new HiltAndroidRule(this); @Inject protected VaultManager _vaultManager; @Inject protected Preferences _prefs; @Before public void init() { hiltRule.inject(); } protected AegisApplicationBase getApp() { return (AegisApplicationBase) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); } protected VaultRepository initEncryptedVault() { VaultFileCredentials creds = generateCredentials(); return initVault(creds, VaultEntries.get()); } protected VaultRepository initEmptyEncryptedVault() { VaultFileCredentials creds = generateCredentials(); return initVault(creds, null); } protected VaultRepository initPlainVault() { return initVault(null, VaultEntries.get()); } private VaultRepository initVault(@Nullable VaultFileCredentials creds, @Nullable List entries) { VaultRepository vault; try { vault = _vaultManager.initNew(creds); } catch (VaultRepositoryException e) { throw new RuntimeException(e); } if (entries != null) { for (VaultEntry entry : entries) { _vaultManager.getVault().addEntry(entry); } } try { _vaultManager.save(); } catch (VaultRepositoryException e) { throw new RuntimeException(e); } _prefs.setIntroDone(true); return vault; } protected VaultFileCredentials generateCredentials() { PasswordSlot slot = new PasswordSlot(); byte[] salt = CryptoUtils.generateSalt(); SCryptParameters scryptParams = new SCryptParameters( CryptoUtils.CRYPTO_SCRYPT_N, CryptoUtils.CRYPTO_SCRYPT_r, CryptoUtils.CRYPTO_SCRYPT_p, salt ); VaultFileCredentials creds = new VaultFileCredentials(); try { SecretKey key = slot.deriveKey(VAULT_PASSWORD.toCharArray(), scryptParams); slot.setKey(creds.getKey(), CryptoUtils.createEncryptCipher(key)); } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | SlotException e) { throw new RuntimeException(e); } creds.getSlots().add(slot); return creds; } protected static VaultEntry generateEntry(Class type, String name, String issuer) { return generateEntry(type, name, issuer, 20); } protected static VaultEntry generateEntry(Class type, String name, String issuer, int secretLength) { byte[] secret = CryptoUtils.generateRandomBytes(secretLength); OtpInfo info; try { info = type.getConstructor(byte[].class).newInstance(secret); } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); } return new VaultEntry(info, name, issuer); } // source: https://stackoverflow.com/a/30338665 protected static ViewAction clickChildViewWithId(final int id) { return new ViewAction() { @Override public Matcher getConstraints() { return null; } @Override public String getDescription() { return "Click on a child view with specified id."; } @Override public void perform(UiController uiController, View view) { View v = view.findViewById(id); v.performClick(); } }; } }