Skip to content

Commit 2a9cfb6

Browse files
authored
Merge pull request #14 from OutSystems/fix/RMET-1182/cipher-database-errors
RMET-1182 ::: Fix - Ciphered Database Errors
2 parents eb3d32b + 69702f5 commit 2a9cfb6

File tree

3 files changed

+43
-31
lines changed

3 files changed

+43
-31
lines changed

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
2.6.8-OS11 - 2022-04-12
5+
------------------
6+
7+
- Fix: Fix for the error messages: Keystore operation failed, User not authenticated, Key not yet valid. (RMET-1182)
8+
9+
410
2.6.8-OS9 - 2022-01-28
511
------------------
612

src/android/RSA.java

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import android.security.KeyPairGeneratorSpec;
66
import android.security.keystore.KeyGenParameterSpec;
77
import android.security.keystore.KeyInfo;
8+
import android.security.keystore.KeyNotYetValidException;
89
import android.security.keystore.KeyPermanentlyInvalidatedException;
910
import android.security.keystore.KeyProperties;
11+
import android.security.keystore.UserNotAuthenticatedException;
1012
import android.util.Log;
1113

1214
import java.math.BigInteger;
@@ -44,17 +46,12 @@ public static byte[] decrypt(byte[] encrypted, String alias) throws Exception {
4446

4547
public static void createKeyPair(Context ctx, String alias) throws Exception {
4648
synchronized (LOCK) {
47-
Calendar notBefore = Calendar.getInstance();
4849

49-
//this back dates the date of the key in order to avoid some timezone issues found during use with some devices
50-
notBefore.add(Calendar.HOUR_OF_DAY, -26);
51-
Calendar notAfter = Calendar.getInstance();
52-
notAfter.add(Calendar.YEAR, 100);
5350
String principalString = String.format("CN=%s, OU=%s", alias, ctx.getPackageName());
5451

55-
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M){
52+
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
5653
KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, KEYSTORE_PROVIDER);
57-
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_DECRYPT)
54+
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT)
5855
.setUserAuthenticationRequired(true)
5956
//the value used for the validity is 31 days a big number to ensure the keys are always usable after a authentication done by the user
6057
.setUserAuthenticationValidityDurationSeconds(60*60*24*31)
@@ -64,11 +61,7 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
6461
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
6562
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
6663
.setRandomizedEncryptionRequired(true)
67-
.setKeyValidityStart(notBefore.getTime())
68-
.setKeyValidityEnd(notAfter.getTime());
69-
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
70-
builder.setInvalidatedByBiometricEnrollment(false);
71-
}
64+
.setInvalidatedByBiometricEnrollment(false);
7265
KeyGenParameterSpec spec = builder.build();
7366
generator.initialize(spec);
7467
generator.generateKeyPair();
@@ -80,8 +73,6 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
8073
.setAlias(alias)
8174
.setSubject(new X500Principal(principalString))
8275
.setSerialNumber(BigInteger.ONE)
83-
.setStartDate(notBefore.getTime())
84-
.setEndDate(notAfter.getTime())
8576
.setEncryptionRequired()
8677
.setKeySize(2048)
8778
.setKeyType("RSA")
@@ -90,8 +81,6 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
9081
kpGenerator.initialize(spec);
9182
kpGenerator.generateKeyPair();
9283
}
93-
94-
9584
}
9685
}
9786

@@ -121,7 +110,7 @@ private static void initCipher(Cipher cipher, int cipherMode, String alias) thro
121110
}
122111
}
123112

124-
public static boolean isEntryAvailable(String alias) {
113+
public static boolean isEntryAvailable(String alias) throws UserNotAuthenticatedException {
125114
KeyStore.PrivateKeyEntry entry;
126115

127116
synchronized (LOCK) {
@@ -141,6 +130,10 @@ public static boolean isEntryAvailable(String alias) {
141130
initCipher(tempCipher, Cipher.ENCRYPT_MODE, alias);
142131
initCipher(tempCipher, Cipher.DECRYPT_MODE, alias);
143132
return true; // Key is usable
133+
} catch (UserNotAuthenticatedException e) {
134+
throw e;
135+
} catch (KeyNotYetValidException e) {
136+
return false;
144137
} catch (KeyPermanentlyInvalidatedException e) {
145138
// Key is never usable again, so might as well consider it's not available
146139
// This will let a new one be used in its place

src/android/SecureStorage.java

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,27 @@ private boolean init(CordovaArgs args, CallbackContext callbackContext) throws J
217217
}
218218
}
219219

220+
try {
220221

221-
if (!isDeviceSecure()) {
222-
// Lock screen that requires authentication is not defined
223-
Log.e(TAG, MSG_DEVICE_NOT_SECURE);
224-
callbackContext.error(MSG_DEVICE_NOT_SECURE);
222+
if (!isDeviceSecure()) {
223+
// Lock screen that requires authentication is not defined
224+
Log.e(TAG, MSG_DEVICE_NOT_SECURE);
225+
callbackContext.error(MSG_DEVICE_NOT_SECURE);
225226

226-
} else if (!RSA.isEntryAvailable(alias)) {
227-
// Key for alias does not exist
228-
handleLockScreen(IntentRequestType.INIT, service, callbackContext);
227+
} else if (!RSA.isEntryAvailable(alias)) {
228+
// Key for alias does not exist
229+
handleLockScreen(IntentRequestType.INIT, service, callbackContext);
229230

230-
} else {
231-
// No actions are required to init correctly
232-
initSuccess(callbackContext);
231+
} else {
232+
// No actions are required to init correctly
233+
initSuccess(callbackContext);
234+
}
235+
236+
} catch (UserNotAuthenticatedException e) {
237+
//
238+
handleLockScreen(IntentRequestType.INIT, service, callbackContext);
233239
}
240+
234241
return true;
235242
}
236243

@@ -597,11 +604,17 @@ public void run() {
597604
Log.v(TAG, "Completed request is of init action");
598605

599606
String alias = service2alias(service);
600-
if (!RSA.isEntryAvailable(alias)) {
601-
//Solves Issue #96. The RSA key may have been deleted by changing the lock type.
602-
getStorage(service).clear();
603-
RSA.createKeyPair(getContext(), alias);
607+
608+
try {
609+
if (!RSA.isEntryAvailable(alias)) {
610+
//Solves Issue #96. The RSA key may have been deleted by changing the lock type.
611+
getStorage(service).clear();
612+
RSA.createKeyPair(getContext(), alias);
613+
}
614+
} catch (UserNotAuthenticatedException e) {
615+
Log.v(TAG, "Authentication validity expired, request a new login.");
604616
}
617+
605618
}
606619

607620
Log.v(TAG, "init returned success");

0 commit comments

Comments
 (0)