Decrypt the database on a separate thread and show a progress dialog

pull/41/head
Alexander Bakker 7 years ago
parent 277d76e467
commit d922be3912

@ -35,7 +35,7 @@ import me.impy.aegis.crypto.slots.SlotIntegrityException;
import me.impy.aegis.finger.FingerprintUiHelper;
import me.impy.aegis.helpers.AuthHelper;
public class AuthActivity extends AppCompatActivity implements FingerprintUiHelper.Callback {
public class AuthActivity extends AppCompatActivity implements FingerprintUiHelper.Callback, SlotCollectionTask.Callback {
public static final int RESULT_OK = 0;
public static final int RESULT_EXCEPTION = 1;
@ -82,7 +82,8 @@ public class AuthActivity extends AppCompatActivity implements FingerprintUiHelp
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
trySlots(PasswordSlot.class);
char[] password = AuthHelper.getPassword(_textPassword, true);
trySlots(PasswordSlot.class, password);
}
});
}
@ -100,48 +101,19 @@ public class AuthActivity extends AppCompatActivity implements FingerprintUiHelp
builder.create().show();
}
private MasterKey decryptPasswordSlot(PasswordSlot slot) throws Exception {
char[] password = AuthHelper.getPassword(_textPassword, true);
SecretKey key = slot.deriveKey(password);
CryptoUtils.zero(password);
Cipher cipher = Slot.createCipher(key, Cipher.DECRYPT_MODE);
return _slots.decrypt(slot, cipher);
}
private MasterKey decryptFingerSlot(FingerprintSlot slot) throws Exception {
return _slots.decrypt(slot, _fingerCipher);
}
private <T extends Slot> void trySlots(Class<T> type) {
try {
if (!_slots.has(type)) {
throw new RuntimeException();
}
MasterKey masterKey = null;
for (Slot slot : _slots.findAll(type)) {
try {
if (slot instanceof PasswordSlot) {
masterKey = decryptPasswordSlot((PasswordSlot) slot);
} else if (slot instanceof FingerprintSlot) {
masterKey = decryptFingerSlot((FingerprintSlot) slot);
} else {
throw new RuntimeException();
}
break;
} catch (SlotIntegrityException e) { }
}
if (masterKey == null) {
throw new SlotIntegrityException();
}
setKey(masterKey);
} catch (SlotIntegrityException e) {
showError();
} catch (Exception e) {
throw new UndeclaredThrowableException(e);
}
/*DerivationTask task = new DerivationTask(this);
DerivationTask.Params params = new DerivationTask.Params() {{
Slots = _slots;
Slot = (PasswordSlot) slot;
Password = AuthHelper.getPassword(_textPassword, true);
}};
masterKey = task.execute(params).get();*/
private <T extends Slot> void trySlots(Class<T> type, Object obj) {
new SlotCollectionTask<T>(type, this, this).execute(new SlotCollectionTask.Params(){{
Slots = _slots;
Obj = obj;
}});
}
private void setKey(MasterKey key) {
@ -177,11 +149,20 @@ public class AuthActivity extends AppCompatActivity implements FingerprintUiHelp
@Override
public void onAuthenticated() {
trySlots(FingerprintSlot.class);
trySlots(FingerprintSlot.class, _fingerCipher);
}
@Override
public void onError() {
}
@Override
public void onTaskFinished(MasterKey key) {
if (key != null) {
setKey(key);
} else {
showError();
}
}
}

@ -32,7 +32,6 @@ import java.lang.reflect.UndeclaredThrowableException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Objects;
import me.impy.aegis.crypto.MasterKey;

@ -0,0 +1,91 @@
package me.impy.aegis;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import java.lang.reflect.UndeclaredThrowableException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import me.impy.aegis.crypto.CryptoUtils;
import me.impy.aegis.crypto.MasterKey;
import me.impy.aegis.crypto.slots.FingerprintSlot;
import me.impy.aegis.crypto.slots.PasswordSlot;
import me.impy.aegis.crypto.slots.Slot;
import me.impy.aegis.crypto.slots.SlotCollection;
import me.impy.aegis.crypto.slots.SlotIntegrityException;
public class SlotCollectionTask<T extends Slot> extends AsyncTask<SlotCollectionTask.Params, Void, MasterKey> {
private Callback _cb;
private Class<T> _type;
private ProgressDialog _dialog;
public SlotCollectionTask(Class<T> type, Context context, Callback cb) {
_cb = cb;
_type = type;
_dialog = new ProgressDialog(context);
}
@Override
protected MasterKey doInBackground(SlotCollectionTask.Params... args) {
SlotCollectionTask.Params params = args[0];
try {
if (!params.Slots.has(_type)) {
throw new RuntimeException();
}
MasterKey masterKey = null;
for (Slot slot : params.Slots.findAll(_type)) {
try {
if (slot instanceof PasswordSlot) {
char[] password = (char[])params.Obj;
SecretKey key = ((PasswordSlot)slot).deriveKey(password);
CryptoUtils.zero(password);
Cipher cipher = Slot.createCipher(key, Cipher.DECRYPT_MODE);
masterKey = params.Slots.decrypt(slot, cipher);
} else if (slot instanceof FingerprintSlot) {
masterKey = params.Slots.decrypt(slot, (Cipher)params.Obj);
} else {
throw new RuntimeException();
}
break;
} catch (SlotIntegrityException e) { }
}
if (masterKey == null) {
throw new SlotIntegrityException();
}
return masterKey;
} catch (SlotIntegrityException e) {
return null;
} catch (Exception e) {
throw new UndeclaredThrowableException(e);
}
}
@Override
protected void onPreExecute() {
_dialog.setMessage("Decrypting database");
_dialog.show();
}
@Override
protected void onPostExecute(MasterKey masterKey) {
if (_dialog.isShowing()) {
_dialog.dismiss();
}
_cb.onTaskFinished(masterKey);
}
static class Params {
public SlotCollection Slots;
public Object Obj;
}
interface Callback {
void onTaskFinished(MasterKey key);
}
}
Loading…
Cancel
Save