mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-16 06:53:01 +00:00
Derive passwords on a separate thread in the intro
Also, show a progress dialog while waiting
This commit is contained in:
parent
5df20ef525
commit
0afc1b3a97
4 changed files with 116 additions and 43 deletions
|
@ -101,14 +101,6 @@ public class AuthActivity extends AppCompatActivity implements FingerprintUiHelp
|
|||
builder.create().show();
|
||||
}
|
||||
|
||||
/*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;
|
||||
|
|
|
@ -22,10 +22,7 @@ import java.lang.reflect.UndeclaredThrowableException;
|
|||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import me.impy.aegis.crypto.CryptoUtils;
|
||||
import me.impy.aegis.crypto.KeyStoreHandle;
|
||||
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.finger.FingerprintUiHelper;
|
||||
import me.impy.aegis.helpers.AuthHelper;
|
||||
|
@ -60,18 +57,12 @@ public class CustomAuthenticatedSlide extends Fragment implements FingerprintUiH
|
|||
return _cryptType;
|
||||
}
|
||||
|
||||
public Cipher getCipher(Slot slot) throws Exception {
|
||||
if (slot instanceof PasswordSlot) {
|
||||
char[] password = AuthHelper.getPassword(_textPassword, true);
|
||||
byte[] salt = CryptoUtils.generateSalt();
|
||||
SecretKey key = ((PasswordSlot)slot).deriveKey(password, salt, CryptoUtils.CRYPTO_SCRYPT_N, CryptoUtils.CRYPTO_SCRYPT_r, CryptoUtils.CRYPTO_SCRYPT_p);
|
||||
CryptoUtils.zero(password);
|
||||
return Slot.createCipher(key, Cipher.ENCRYPT_MODE);
|
||||
} else if (slot instanceof FingerprintSlot) {
|
||||
return _fingerCipher;
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
public char[] getPassword() {
|
||||
return AuthHelper.getPassword(_textPassword, true);
|
||||
}
|
||||
|
||||
public Cipher getFingerCipher() {
|
||||
return _fingerCipher;
|
||||
}
|
||||
|
||||
public void setBgColor(int color) {
|
||||
|
|
57
app/src/main/java/me/impy/aegis/DerivationTask.java
Normal file
57
app/src/main/java/me/impy/aegis/DerivationTask.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package me.impy.aegis;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import me.impy.aegis.crypto.CryptoUtils;
|
||||
import me.impy.aegis.crypto.slots.PasswordSlot;
|
||||
|
||||
public class DerivationTask extends AsyncTask<DerivationTask.Params, Void, SecretKey> {
|
||||
private Callback _cb;
|
||||
private ProgressDialog _dialog;
|
||||
|
||||
public DerivationTask(Context context, Callback cb) {
|
||||
_cb = cb;
|
||||
_dialog = new ProgressDialog(context);
|
||||
_dialog.setCancelable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SecretKey doInBackground(DerivationTask.Params... args) {
|
||||
DerivationTask.Params params = args[0];
|
||||
try {
|
||||
byte[] salt = CryptoUtils.generateSalt();
|
||||
SecretKey key = params.Slot.deriveKey(params.Password, salt, CryptoUtils.CRYPTO_SCRYPT_N, CryptoUtils.CRYPTO_SCRYPT_r, CryptoUtils.CRYPTO_SCRYPT_p);
|
||||
CryptoUtils.zero(params.Password);
|
||||
return key;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
_dialog.setMessage("Deriving key from password");
|
||||
_dialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(SecretKey key) {
|
||||
if (_dialog.isShowing()) {
|
||||
_dialog.dismiss();
|
||||
}
|
||||
_cb.onTaskFinished(key);
|
||||
}
|
||||
|
||||
static class Params {
|
||||
public PasswordSlot Slot;
|
||||
public char[] Password;
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
void onTaskFinished(SecretKey key);
|
||||
}
|
||||
}
|
|
@ -12,16 +12,19 @@ import com.github.paolorotolo.appintro.AppIntroFragment;
|
|||
import com.github.paolorotolo.appintro.model.SliderPage;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import me.impy.aegis.crypto.CryptResult;
|
||||
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.db.Database;
|
||||
import me.impy.aegis.db.DatabaseFile;
|
||||
|
||||
public class IntroActivity extends AppIntro {
|
||||
public class IntroActivity extends AppIntro implements DerivationTask.Callback {
|
||||
public static final int RESULT_OK = 0;
|
||||
public static final int RESULT_EXCEPTION = 1;
|
||||
|
||||
|
@ -29,6 +32,11 @@ public class IntroActivity extends AppIntro {
|
|||
private CustomAuthenticationSlide _authenticationSlide;
|
||||
private Fragment _endSlide;
|
||||
|
||||
private Database _database;
|
||||
private DatabaseFile _databaseFile;
|
||||
private PasswordSlot _passwordSlot;
|
||||
private Cipher _passwordCipher;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -65,6 +73,10 @@ public class IntroActivity extends AppIntro {
|
|||
endSliderPage.setBgColor(getResources().getColor(R.color.colorPrimary));
|
||||
_endSlide = AppIntroFragment.newInstance(endSliderPage);
|
||||
addSlide(_endSlide);
|
||||
|
||||
// create the database and database file
|
||||
_database = new Database();
|
||||
_databaseFile = new DatabaseFile();
|
||||
}
|
||||
|
||||
private void setException(Exception e) {
|
||||
|
@ -76,10 +88,17 @@ public class IntroActivity extends AppIntro {
|
|||
|
||||
@Override
|
||||
public void onSlideChanged(Fragment oldFragment, Fragment newFragment) {
|
||||
// skip to the last slide if no encryption will be used
|
||||
if (oldFragment == _authenticationSlide && newFragment != _endSlide) {
|
||||
Intent intent = getIntent();
|
||||
int cryptType = intent.getIntExtra("cryptType", CustomAuthenticationSlide.CRYPT_TYPE_INVALID);
|
||||
Intent intent = getIntent();
|
||||
int cryptType = intent.getIntExtra("cryptType", CustomAuthenticationSlide.CRYPT_TYPE_INVALID);
|
||||
|
||||
if (newFragment == _endSlide && cryptType != CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
|
||||
_passwordSlot = new PasswordSlot();
|
||||
new DerivationTask(this, this).execute(new DerivationTask.Params() {{
|
||||
Slot = _passwordSlot;
|
||||
Password = _authenticatedSlide.getPassword();
|
||||
}});
|
||||
} else if (oldFragment == _authenticationSlide && newFragment != _endSlide) {
|
||||
// skip to the last slide if no encryption will be used
|
||||
if (cryptType == CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
|
||||
// TODO: no magic indices
|
||||
getPager().setCurrentItem(5);
|
||||
|
@ -91,10 +110,6 @@ public class IntroActivity extends AppIntro {
|
|||
public void onDonePressed(Fragment currentFragment) {
|
||||
super.onDonePressed(currentFragment);
|
||||
|
||||
// create the database and database file
|
||||
Database database = new Database();
|
||||
DatabaseFile databaseFile = new DatabaseFile();
|
||||
|
||||
int cryptType = _authenticatedSlide.getCryptType();
|
||||
|
||||
// generate the master key
|
||||
|
@ -108,15 +123,20 @@ public class IntroActivity extends AppIntro {
|
|||
}
|
||||
}
|
||||
|
||||
SlotCollection slots = databaseFile.getSlots();
|
||||
SlotCollection slots = _databaseFile.getSlots();
|
||||
if (cryptType != CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
|
||||
try {
|
||||
// encrypt the master key with a key derived from the user's password
|
||||
// and add it to the list of slots
|
||||
PasswordSlot slot = new PasswordSlot();
|
||||
Cipher cipher = _authenticatedSlide.getCipher(slot);
|
||||
slots.encrypt(slot, masterKey, cipher);
|
||||
slots.add(slot);
|
||||
if (_passwordSlot == null || _passwordCipher == null) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
try {
|
||||
slots.encrypt(_passwordSlot, masterKey, _passwordCipher);
|
||||
slots.add(_passwordSlot);
|
||||
} catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
setException(e);
|
||||
return;
|
||||
|
@ -128,7 +148,7 @@ public class IntroActivity extends AppIntro {
|
|||
// encrypt the master key with the fingerprint key
|
||||
// and add it to the list of slots
|
||||
FingerprintSlot slot = new FingerprintSlot();
|
||||
Cipher cipher = _authenticatedSlide.getCipher(slot);
|
||||
Cipher cipher = _authenticatedSlide.getFingerCipher();
|
||||
slots.encrypt(slot, masterKey, cipher);
|
||||
slots.add(slot);
|
||||
} catch (Exception e) {
|
||||
|
@ -139,15 +159,15 @@ public class IntroActivity extends AppIntro {
|
|||
|
||||
// finally, save the database
|
||||
try {
|
||||
byte[] bytes = database.serialize();
|
||||
byte[] bytes = _database.serialize();
|
||||
if (cryptType == CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
|
||||
databaseFile.setContent(bytes);
|
||||
_databaseFile.setContent(bytes);
|
||||
} else {
|
||||
CryptResult result = masterKey.encrypt(bytes);
|
||||
databaseFile.setContent(result.Data);
|
||||
databaseFile.setCryptParameters(result.Parameters);
|
||||
_databaseFile.setContent(result.Data);
|
||||
_databaseFile.setCryptParameters(result.Parameters);
|
||||
}
|
||||
databaseFile.save(getApplicationContext());
|
||||
_databaseFile.save(getApplicationContext());
|
||||
} catch (Exception e) {
|
||||
setException(e);
|
||||
return;
|
||||
|
@ -163,4 +183,17 @@ public class IntroActivity extends AppIntro {
|
|||
prefs.edit().putBoolean("passedIntro", true).apply();
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskFinished(SecretKey key) {
|
||||
if (key != null) {
|
||||
try {
|
||||
_passwordCipher = Slot.createCipher(key, Cipher.ENCRYPT_MODE);
|
||||
} catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
} else {
|
||||
setException(new NullPointerException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue