Aegis/app/src/main/java/me/impy/aegis/IntroActivity.java

147 lines
5.2 KiB
Java
Raw Normal View History

package me.impy.aegis;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import agency.tango.materialintroscreen.MaterialIntroActivity;
import agency.tango.materialintroscreen.MessageButtonBehaviour;
import agency.tango.materialintroscreen.SlideFragmentBuilder;
import me.impy.aegis.crypto.CryptResult;
import me.impy.aegis.crypto.MasterKey;
import me.impy.aegis.crypto.slots.PasswordSlot;
import me.impy.aegis.crypto.slots.SlotCollection;
import me.impy.aegis.db.Database;
import me.impy.aegis.db.DatabaseFile;
public class IntroActivity extends MaterialIntroActivity {
public static final int RESULT_OK = 0;
public static final int RESULT_EXCEPTION = 1;
private CustomAuthenticatedSlide authenticatedSlide;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
2017-08-06 21:45:27 +02:00
hideBackButton();
addSlide(new SlideFragmentBuilder()
2017-08-02 21:29:27 +02:00
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.intro_shield)
.title("Welcome")
.description("Aegis is a brand new open source(!) authenticator app which generates tokens for your accounts.")
.build());
addSlide(new SlideFragmentBuilder()
2017-08-02 21:29:27 +02:00
.backgroundColor(R.color.colorAccent)
.buttonsColor(R.color.colorPrimary)
.neededPermissions(new String[]{Manifest.permission.CAMERA})
.image(R.drawable.intro_scanner)
.title("Permissions")
.description("Aegis needs permission to your camera in order to function properly. This is needed to scan QR codes.")
.build(),
new MessageButtonBehaviour(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
}, "Permission granted"));
addSlide(new CustomAuthenticationSlide());
authenticatedSlide = new CustomAuthenticatedSlide();
addSlide(authenticatedSlide);
addSlide(new SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.drawable.intro_shield)
.title("All done!")
.description("Aegis has been set up and is ready to go.")
.build());
}
private void setException(Exception e) {
Intent result = new Intent();
result.putExtra("exception", e);
setResult(RESULT_OK, result);
}
@Override
public void onFinish() {
super.onFinish();
// create the database and database file
Database database = new Database();
DatabaseFile databaseFile = new DatabaseFile();
2017-08-06 21:45:27 +02:00
int cryptType = authenticatedSlide.getCryptType();
// generate the master key
MasterKey masterKey = null;
if (cryptType != CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
try {
masterKey = MasterKey.generate();
} catch (Exception e) {
setException(e);
return;
}
}
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
SlotCollection slots = databaseFile.getSlots();
PasswordSlot slot = new PasswordSlot();
Cipher cipher = authenticatedSlide.getCipher(slot, Cipher.ENCRYPT_MODE);
masterKey.encryptSlot(slot, cipher);
slots.add(slot);
} catch (Exception e) {
setException(e);
return;
}
}
if (cryptType != CustomAuthenticationSlide.CRYPT_TYPE_FINGER) {
// TODO
}
// finally, save the database
try {
byte[] bytes = database.serialize();
2017-08-06 21:45:27 +02:00
if (cryptType == CustomAuthenticationSlide.CRYPT_TYPE_NONE) {
databaseFile.setContent(bytes);
} else {
CryptResult result = masterKey.encrypt(bytes);
databaseFile.setContent(result.Data);
databaseFile.setCryptParameters(result.Parameters);
}
databaseFile.save(getApplicationContext());
} catch (Exception e) {
setException(e);
return;
}
// send the master key back to the main activity
Intent result = new Intent();
result.putExtra("key", masterKey);
setResult(RESULT_OK, result);
// skip the intro from now on
// TODO: show the intro if we can't find any database files
SharedPreferences prefs = this.getSharedPreferences("me.impy.aegis", Context.MODE_PRIVATE);
prefs.edit().putBoolean("passedIntro", true).apply();
}
}