mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-23 23:39:14 +00:00
Display a message if all fingerprint slots have been invalidated
This commit is contained in:
parent
576f908e01
commit
a52c5b61c0
4 changed files with 72 additions and 9 deletions
|
@ -15,6 +15,7 @@ import android.widget.TextView;
|
|||
import com.mattprecious.swirl.SwirlView;
|
||||
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
|
@ -30,9 +31,6 @@ import me.impy.aegis.helpers.FingerprintUiHelper;
|
|||
import me.impy.aegis.helpers.AuthHelper;
|
||||
|
||||
public class AuthActivity extends AegisActivity implements FingerprintUiHelper.Callback, SlotCollectionTask.Callback {
|
||||
public static final int RESULT_OK = 0;
|
||||
public static final int RESULT_EXCEPTION = 1;
|
||||
|
||||
private EditText _textPassword;
|
||||
|
||||
private SlotCollection _slots;
|
||||
|
@ -45,6 +43,7 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
|||
setContentView(R.layout.activity_auth);
|
||||
_textPassword = findViewById(R.id.text_password);
|
||||
LinearLayout boxFingerprint = findViewById(R.id.box_fingerprint);
|
||||
LinearLayout boxFingerprintInfo = findViewById(R.id.box_fingerprint_info);
|
||||
TextView textFingerprint = findViewById(R.id.text_fingerprint);
|
||||
|
||||
SwirlView imgFingerprint = null;
|
||||
|
@ -60,6 +59,7 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
|||
// only show the fingerprint controls if the api version is new enough, permission is granted, a scanner is found and a fingerprint slot is found
|
||||
FingerprintManager manager = FingerprintHelper.getManager(this);
|
||||
if (manager != null && _slots.has(FingerprintSlot.class)) {
|
||||
boolean invalidated = false;
|
||||
try {
|
||||
// find a fingerprint slot with an id that matches an alias in the keystore
|
||||
for (FingerprintSlot slot : _slots.findAll(FingerprintSlot.class)) {
|
||||
|
@ -67,15 +67,26 @@ public class AuthActivity extends AegisActivity implements FingerprintUiHelper.C
|
|||
KeyStoreHandle handle = new KeyStoreHandle();
|
||||
if (handle.containsKey(id)) {
|
||||
SecretKey key = handle.getKey(id);
|
||||
// if 'key' is null, it was permanently invalidated
|
||||
if (key == null) {
|
||||
invalidated = true;
|
||||
continue;
|
||||
}
|
||||
_fingerCipher = Slot.createCipher(key, Cipher.DECRYPT_MODE);
|
||||
_fingerHelper = new FingerprintUiHelper(manager, imgFingerprint, textFingerprint, this);
|
||||
boxFingerprint.setVisibility(View.VISIBLE);
|
||||
invalidated = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new UndeclaredThrowableException(e);
|
||||
}
|
||||
|
||||
// display a help message if a matching invalidated keystore entry was found
|
||||
if (invalidated) {
|
||||
boxFingerprintInfo.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
Button button = findViewById(R.id.button_decrypt);
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.widget.ImageView;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
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.RawSlot;
|
||||
|
@ -29,13 +30,19 @@ public class SlotHolder extends RecyclerView.ViewHolder {
|
|||
|
||||
public void setData(Slot slot) {
|
||||
if (slot instanceof PasswordSlot) {
|
||||
_slotName.setText("Password 1");
|
||||
_slotName.setText("Password");
|
||||
_slotImg.setImageResource(R.drawable.ic_create_black_24dp);
|
||||
} else if (slot instanceof FingerprintSlot) {
|
||||
_slotName.setText("Finger 1");
|
||||
_slotName.setText("Finger");
|
||||
_slotImg.setImageResource(R.drawable.ic_fingerprint_black_24dp);
|
||||
try {
|
||||
KeyStoreHandle keyStore = new KeyStoreHandle();
|
||||
if (keyStore.containsKey(slot.getID())) {
|
||||
_slotUsed.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} catch (Exception e) { }
|
||||
} else if (slot instanceof RawSlot) {
|
||||
_slotName.setText("Raw 1");
|
||||
_slotName.setText("Raw");
|
||||
_slotImg.setImageResource(R.drawable.ic_vpn_key_black_24dp);
|
||||
} else {
|
||||
throw new RuntimeException();
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package me.impy.aegis.crypto;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Build;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyPermanentlyInvalidatedException;
|
||||
import android.security.keystore.KeyProperties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import me.impy.aegis.crypto.slots.FingerprintSlot;
|
||||
|
@ -47,7 +52,28 @@ public class KeyStoreHandle {
|
|||
}
|
||||
}
|
||||
|
||||
public SecretKey getKey(String id) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
|
||||
return (SecretKey) _keyStore.getKey(id, null);
|
||||
public SecretKey getKey(String id)
|
||||
throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
|
||||
SecretKey key = (SecretKey) _keyStore.getKey(id, null);
|
||||
|
||||
// try to initialize a dummy cipher
|
||||
// and see if KeyPermanentlyInvalidatedException is thrown
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
try {
|
||||
@SuppressLint("GetInstance")
|
||||
Cipher cipher = Cipher.getInstance(CryptoUtils.CRYPTO_CIPHER_RAW);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
} catch (KeyPermanentlyInvalidatedException e) {
|
||||
return null;
|
||||
} catch (NoSuchPaddingException | InvalidKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public void deleteKey(String id) throws KeyStoreException {
|
||||
_keyStore.deleteEntry(id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="12dp"
|
||||
android:visibility="invisible">
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/img_fingerprint_insert"
|
||||
|
@ -65,5 +65,24 @@
|
|||
android:text="@string/fingerprint_hint"
|
||||
android:textColor="?attr/secondaryText"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/box_fingerprint_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="12dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_info_outline_black_24dp"
|
||||
android:layout_marginEnd="15dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="A fingerprint slot was found, but it appears to have been invalidated by the Android keystore. Go to "Settings -> Key slots" to readd your fingerprint."/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
|
Loading…
Add table
Reference in a new issue