Skip to content

Commit 2488b6b

Browse files
committed
Fix crash after screenlock changed
e.g. after (un)enroll fingerprints
1 parent 756418d commit 2488b6b

File tree

7 files changed

+68
-24
lines changed

7 files changed

+68
-24
lines changed

app/src/main/java/org/sorz/lab/tinykeepass/BaseActivity.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
import org.sorz.lab.tinykeepass.auth.FingerprintDialogFragment;
1414
import org.sorz.lab.tinykeepass.auth.SecureStringStorage;
15-
import org.sorz.lab.tinykeepass.keepass.KeePassStorage;
1615
import org.sorz.lab.tinykeepass.keepass.OpenKeePassTask;
1716

17+
import java.security.KeyException;
1818
import java.util.List;
1919
import java.util.function.Consumer;
2020

@@ -28,7 +28,8 @@
2828
public abstract class BaseActivity extends AppCompatActivity
2929
implements FingerprintDialogFragment.OnFragmentInteractionListener {
3030
private final static String TAG = MainActivity.class.getName();
31-
private final static int REQUEST_CONFIRM_DEVICE_CREDENTIAL = 0;
31+
private final static int REQUEST_CONFIRM_DEVICE_CREDENTIAL = 100;
32+
private final static int REQUEST_SETUP_DATABASE = 101;
3233

3334
private SharedPreferences preferences;
3435
private KeyguardManager keyguardManager;
@@ -57,6 +58,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
5758
else
5859
onKeyAuthFailed.accept(getString(R.string.fail_to_auth));
5960
break;
61+
case REQUEST_SETUP_DATABASE:
62+
if (resultCode == RESULT_OK)
63+
getKey();
64+
else
65+
onKeyAuthFailed.accept(getString(R.string.fail_to_decrypt));
66+
break;
6067
default:
6168
super.onActivityResult(requestCode, resultCode, data);
6269
}
@@ -79,6 +86,13 @@ protected void getDatabaseKeys(Consumer<List<String>> onKeyRetrieved,
7986
getKey();
8087
}
8188

89+
@Override
90+
public void onKeyException(KeyException e) {
91+
// Key is invalided, have to reconfigure passwords.
92+
Intent intent = new Intent(this, DatabaseSetupActivity.class);
93+
startActivityForResult(intent, REQUEST_SETUP_DATABASE);
94+
}
95+
8296
private void getKey() {
8397
int authMethod = preferences.getInt("key-auth-method", 0);
8498
switch (authMethod) {
@@ -93,6 +107,8 @@ private void getKey() {
93107
getString(R.string.auth_key_title),
94108
getString(R.string.auth_key_description));
95109
startActivityForResult(intent, REQUEST_CONFIRM_DEVICE_CREDENTIAL);
110+
} catch (KeyException e) {
111+
onKeyException(e);
96112
} catch (SecureStringStorage.SystemException e) {
97113
throw new RuntimeException(e);
98114
}

app/src/main/java/org/sorz/lab/tinykeepass/DatabaseSetupActivity.java

+14-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.sorz.lab.tinykeepass.auth.SecureStringStorage;
2525

2626
import java.lang.ref.WeakReference;
27+
import java.security.KeyException;
2728
import java.util.ArrayList;
2829
import java.util.List;
2930

@@ -247,16 +248,14 @@ private void saveKeys(Cipher cipher) {
247248
strings.add(editMasterPassword.getText().toString());
248249
strings.add(editAuthPassword.getText().toString());
249250
secureStringStorage.put(cipher, strings);
250-
} catch (SecureStringStorage.SystemException e) {
251-
throw new RuntimeException("cannot get save keys", e);
252251
} catch (UserNotAuthenticatedException e) {
253-
Log.e(TAG, "cannot get cipher from system", e);
254-
cancelSubmit();
255-
return;
252+
Log.e(TAG, "cannot get cipher from system", e);
253+
cancelSubmit();
254+
return;
255+
} catch (SecureStringStorage.SystemException | KeyException e) {
256+
throw new RuntimeException("cannot get save keys", e);
256257
}
257-
Intent intent = new Intent(this, MainActivity.class);
258-
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
259-
startActivity(new Intent(this, MainActivity.class));
258+
setResult(RESULT_OK);
260259
finish();
261260
}
262261

@@ -297,6 +296,13 @@ public void onFingerprintSuccess(Cipher cipher) {
297296
saveKeys(cipher);
298297
}
299298

299+
@Override
300+
public void onKeyException(KeyException e) {
301+
// The key are new added here (by calling `secureStringStorage.generateNewKey()`),
302+
// so no KeyException happen here.
303+
throw new IllegalStateException(e);
304+
}
305+
300306

301307
private static class FetchTask extends FetchDatabaseTask {
302308
private final WeakReference<DatabaseSetupActivity> activity;

app/src/main/java/org/sorz/lab/tinykeepass/MainActivity.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
public class MainActivity extends BaseActivity {
1515
private final static String TAG = MainActivity.class.getName();
16+
private final static int REQUEST_SETUP_DATABASE = 1;
1617

1718
@Override
1819
protected void onCreate(Bundle savedInstanceState) {
@@ -25,7 +26,6 @@ protected void onCreate(Bundle savedInstanceState) {
2526

2627
if (!hasDatabaseConfigured(this)) {
2728
doConfigureDatabase();
28-
finish();
2929
} else {
3030
doUnlockDatabase();
3131
}
@@ -51,6 +51,19 @@ public void onDestroy() {
5151
KeePassStorage.set(this, null);
5252
}
5353

54+
@Override
55+
public void onActivityResult(int requestCode, int resultCode, Intent data) {
56+
switch (requestCode) {
57+
case REQUEST_SETUP_DATABASE:
58+
if (resultCode == RESULT_OK)
59+
doUnlockDatabase();
60+
break;
61+
default:
62+
super.onActivityResult(requestCode, resultCode, data);
63+
break;
64+
}
65+
}
66+
5467
public void doUnlockDatabase() {
5568
if (KeePassStorage.get(this) != null) {
5669
showEntryList();
@@ -70,7 +83,8 @@ public void doLockDatabase() {
7083

7184
public void doConfigureDatabase() {
7285
KeePassStorage.set(this, null);
73-
startActivity(new Intent(this, DatabaseSetupActivity.class));
86+
Intent intent = new Intent(this, DatabaseSetupActivity.class);
87+
startActivityForResult(intent, REQUEST_SETUP_DATABASE);
7488
}
7589

7690
public void doSyncDatabase() {

app/src/main/java/org/sorz/lab/tinykeepass/auth/FingerprintDialogFragment.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
import org.sorz.lab.tinykeepass.R;
1212

13+
import java.security.KeyException;
14+
1315
import javax.crypto.Cipher;
1416

1517

@@ -83,7 +85,13 @@ public void onDetach() {
8385
@Override
8486
public void onResume() {
8587
super.onResume();
86-
fingerprintUiHelper.start(getArguments().getInt(ARGS_CIPHER_MODE));
88+
try {
89+
fingerprintUiHelper.start(getArguments().getInt(ARGS_CIPHER_MODE));
90+
} catch (KeyException e) {
91+
if (listener != null)
92+
listener.onKeyException(e);
93+
dismiss();
94+
}
8795
}
8896

8997
@Override
@@ -103,5 +111,6 @@ public void onCancel(DialogInterface dialog) {
103111
public interface OnFragmentInteractionListener {
104112
void onFingerprintCancel();
105113
void onFingerprintSuccess(Cipher cipher);
114+
void onKeyException(KeyException e);
106115
}
107116
}

app/src/main/java/org/sorz/lab/tinykeepass/auth/FingerprintUiHelper.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import org.sorz.lab.tinykeepass.R;
1212

13+
import java.security.KeyException;
1314
import java.util.function.Consumer;
1415

1516
import javax.crypto.Cipher;
@@ -46,7 +47,7 @@ public FingerprintUiHelper(Context context, View view, Consumer<Cipher> finishHa
4647
"and textFingerprintStatus");
4748
}
4849

49-
public void start(int cipherMode) {
50+
public void start(int cipherMode) throws KeyException {
5051
Cipher cipher;
5152
try {
5253
SecureStringStorage storage = new SecureStringStorage(context);
@@ -60,7 +61,7 @@ public void start(int cipherMode) {
6061
default:
6162
throw new UnsupportedOperationException("not support such cipher mode");
6263
}
63-
} catch (UserNotAuthenticatedException | SecureStringStorage.SystemException e) {
64+
} catch (SecureStringStorage.SystemException e) {
6465
throw new RuntimeException("cannot get cipher", e);
6566
}
6667
FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);

app/src/main/java/org/sorz/lab/tinykeepass/auth/SecureStringStorage.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import java.io.IOException;
1818
import java.io.UTFDataFormatException;
1919
import java.security.InvalidAlgorithmParameterException;
20-
import java.security.InvalidKeyException;
20+
import java.security.KeyException;
2121
import java.security.KeyStore;
2222
import java.security.KeyStoreException;
2323
import java.security.NoSuchAlgorithmException;
@@ -80,8 +80,7 @@ public void generateNewKey(boolean auth, int authSecs) throws SystemException {
8080
keyGenerator.generateKey();
8181
}
8282

83-
private Cipher getCipher(int mode, byte[] iv) throws SystemException,
84-
UserNotAuthenticatedException {
83+
private Cipher getCipher(int mode, byte[] iv) throws SystemException, KeyException {
8584
try {
8685
SecretKey key = (SecretKey) keyStore.getKey(KEY_ALIAS, null);
8786
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
@@ -92,21 +91,19 @@ private Cipher getCipher(int mode, byte[] iv) throws SystemException,
9291
cipher.init(mode, key);
9392
}
9493
return cipher;
95-
} catch (UserNotAuthenticatedException e) {
94+
} catch (KeyException e) {
9695
throw e;
9796
} catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException
98-
| NoSuchPaddingException | InvalidAlgorithmParameterException
99-
| InvalidKeyException e) {
97+
| NoSuchPaddingException | InvalidAlgorithmParameterException e) {
10098
throw new SystemException(e);
10199
}
102100
}
103101

104-
public Cipher getEncryptCipher() throws UserNotAuthenticatedException, SystemException {
102+
public Cipher getEncryptCipher() throws KeyException, SystemException {
105103
return getCipher(Cipher.ENCRYPT_MODE, null);
106104
}
107105

108-
public Cipher getDecryptCipher()
109-
throws UserNotAuthenticatedException, SystemException {
106+
public Cipher getDecryptCipher() throws KeyException, SystemException {
110107
String iv = preferences.getString(PREF_IV_NAME, null);
111108
if (iv == null)
112109
return null;

app/src/main/java/org/sorz/lab/tinykeepass/autofill/AuthActivity.java

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.sorz.lab.tinykeepass.search.SearchIndex;
1515
import org.sorz.lab.tinykeepass.keepass.KeePassStorage;
1616

17+
import java.security.KeyException;
1718
import java.util.Objects;
1819
import java.util.stream.Stream;
1920

0 commit comments

Comments
 (0)