From 8cedc313cf71177806b18ed59cd8287e0c04a68c Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Sat, 27 Mar 2021 10:54:26 +0100 Subject: [PATCH 01/10] Upgrade version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b828daf6b..7d994024e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { applicationId "com.kunzisoft.keepass" minSdkVersion 15 targetSdkVersion 30 - versionCode = 66 + versionCode = 67 versionName = "2.9.15" multiDexEnabled true From 17029ce67cf605186a4406ac6cb956abcfd5dcac Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 12:42:53 +0200 Subject: [PATCH 02/10] Fix bad padding exception --- .../main/java/com/kunzisoft/encrypt/CipherFactory.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt b/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt index c2830f814..588d97eba 100644 --- a/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt +++ b/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt @@ -7,6 +7,7 @@ import java.security.InvalidAlgorithmParameterException import java.security.InvalidKeyException import java.security.NoSuchAlgorithmException import java.security.Security +import javax.crypto.BadPaddingException import javax.crypto.Cipher import javax.crypto.NoSuchPaddingException import javax.crypto.spec.IvParameterSpec @@ -39,7 +40,16 @@ object CipherFactory { @Throws(NoSuchAlgorithmException::class, NoSuchPaddingException::class, InvalidKeyException::class, InvalidAlgorithmParameterException::class) fun getTwofish(opmode: Int, key: ByteArray, IV: ByteArray): Cipher { - val cipher: Cipher = Cipher.getInstance("Twofish/CBC/PKCS7PADDING") + val cipher: Cipher = try { + Cipher.getInstance("Twofish/CBC/PKCS7PADDING") + } catch (e: BadPaddingException) { + // Retry with other padding if don't work + if (opmode == Cipher.ENCRYPT_MODE) { + Cipher.getInstance("Twofish/CBC/ZeroBytePadding") + } else { + Cipher.getInstance("Twofish/CBC/NoPadding") + } + } cipher.init(opmode, SecretKeySpec(key, "AES"), IvParameterSpec(IV)) return cipher } From 51df8e7bb1a57b8048ba6e56d33aa277702d1b9b Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 12:52:12 +0200 Subject: [PATCH 03/10] Try to fix rare bug --- .../activities/FileDatabaseSelectActivity.kt | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt index 48b2ae293..83dd275b1 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt @@ -162,27 +162,31 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), // Observe list of databases databaseFilesViewModel.databaseFilesLoaded.observe(this) { databaseFiles -> - when (databaseFiles.databaseFileAction) { - DatabaseFilesViewModel.DatabaseFileAction.NONE -> { - mAdapterDatabaseHistory?.replaceAllDatabaseFileHistoryList(databaseFiles.databaseFileList) - } - DatabaseFilesViewModel.DatabaseFileAction.ADD -> { - databaseFiles.databaseFileToActivate?.let { databaseFileToAdd -> - mAdapterDatabaseHistory?.addDatabaseFileHistory(databaseFileToAdd) + try { + when (databaseFiles.databaseFileAction) { + DatabaseFilesViewModel.DatabaseFileAction.NONE -> { + mAdapterDatabaseHistory?.replaceAllDatabaseFileHistoryList(databaseFiles.databaseFileList) } - GroupActivity.launch(this@FileDatabaseSelectActivity, - PreferencesUtil.enableReadOnlyDatabase(this@FileDatabaseSelectActivity)) - } - DatabaseFilesViewModel.DatabaseFileAction.UPDATE -> { - databaseFiles.databaseFileToActivate?.let { databaseFileToUpdate -> - mAdapterDatabaseHistory?.updateDatabaseFileHistory(databaseFileToUpdate) - } - } - DatabaseFilesViewModel.DatabaseFileAction.DELETE -> { - databaseFiles.databaseFileToActivate?.let { databaseFileToDelete -> - mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileToDelete) + DatabaseFilesViewModel.DatabaseFileAction.ADD -> { + databaseFiles.databaseFileToActivate?.let { databaseFileToAdd -> + mAdapterDatabaseHistory?.addDatabaseFileHistory(databaseFileToAdd) + } + GroupActivity.launch(this@FileDatabaseSelectActivity, + PreferencesUtil.enableReadOnlyDatabase(this@FileDatabaseSelectActivity)) + } + DatabaseFilesViewModel.DatabaseFileAction.UPDATE -> { + databaseFiles.databaseFileToActivate?.let { databaseFileToUpdate -> + mAdapterDatabaseHistory?.updateDatabaseFileHistory(databaseFileToUpdate) + } + } + DatabaseFilesViewModel.DatabaseFileAction.DELETE -> { + databaseFiles.databaseFileToActivate?.let { databaseFileToDelete -> + mAdapterDatabaseHistory?.deleteDatabaseFileHistory(databaseFileToDelete) + } } } + } catch (e: Exception) { + Log.e(TAG, "Unable to observe database action", e) } databaseFilesViewModel.consumeAction() } From 75399454652f7a8296b011d69c560efb08509e42 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:01:31 +0200 Subject: [PATCH 04/10] Capture exception when error when launching database action --- .../action/ProgressDatabaseTaskProvider.kt | 22 ++++++++++++++----- app/src/main/res/values/strings.xml | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/database/action/ProgressDatabaseTaskProvider.kt b/app/src/main/java/com/kunzisoft/keepass/database/action/ProgressDatabaseTaskProvider.kt index a9b2aad79..61caf5494 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/action/ProgressDatabaseTaskProvider.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/action/ProgressDatabaseTaskProvider.kt @@ -25,7 +25,10 @@ import android.content.Context.BIND_NOT_FOREGROUND import android.net.Uri import android.os.Bundle import android.os.IBinder +import android.util.Log +import android.widget.Toast import androidx.fragment.app.FragmentActivity +import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment.Companion.DATABASE_CHANGED_DIALOG_TAG import com.kunzisoft.keepass.app.database.CipherDatabaseEntity @@ -251,11 +254,16 @@ class ProgressDatabaseTaskProvider(private val activity: FragmentActivity) { } private fun start(bundle: Bundle? = null, actionTask: String) { - activity.stopService(intentDatabaseTask) - if (bundle != null) - intentDatabaseTask.putExtras(bundle) - intentDatabaseTask.action = actionTask - activity.startService(intentDatabaseTask) + try { + activity.stopService(intentDatabaseTask) + if (bundle != null) + intentDatabaseTask.putExtras(bundle) + intentDatabaseTask.action = actionTask + activity.startService(intentDatabaseTask) + } catch (e: Exception) { + Log.e(TAG, "Unable to perform database action", e) + Toast.makeText(activity, R.string.error_start_database_action, Toast.LENGTH_LONG).show() + } } /* @@ -591,4 +599,8 @@ class ProgressDatabaseTaskProvider(private val activity: FragmentActivity) { } , ACTION_DATABASE_SAVE) } + + companion object { + private val TAG = ProgressDatabaseTaskProvider::class.java.name + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d88a2fd90..a12c2ef0e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -142,6 +142,7 @@ An error occurred while uploading the file data. The file data already exists. An error occurred while removing the file data. + An error occurred while performing an action on the database. Field name Field value Could not find file. Try reopening it from your file browser. From 7d53607f49f82fea5d9c7be82782eaffb43c38e3 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:07:55 +0200 Subject: [PATCH 05/10] Capture exception when launching cipher action --- .../keepass/app/database/CipherDatabaseAction.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/app/database/CipherDatabaseAction.kt b/app/src/main/java/com/kunzisoft/keepass/app/database/CipherDatabaseAction.kt index eec183cda..f49d8a1d9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/app/database/CipherDatabaseAction.kt +++ b/app/src/main/java/com/kunzisoft/keepass/app/database/CipherDatabaseAction.kt @@ -25,6 +25,7 @@ import android.content.Intent import android.content.ServiceConnection import android.net.Uri import android.os.IBinder +import android.util.Log import com.kunzisoft.keepass.services.AdvancedUnlockNotificationService import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.utils.SingletonHolderParameter @@ -76,7 +77,11 @@ class CipherDatabaseAction(context: Context) { mServiceConnection!!, Context.BIND_ABOVE_CLIENT) if (mBinder == null) { - applicationContext.startService(mIntentAdvancedUnlockService) + try { + applicationContext.startService(mIntentAdvancedUnlockService) + } catch (e: Exception) { + Log.e(TAG, "Unable to start cipher action", e) + } } } } @@ -173,5 +178,7 @@ class CipherDatabaseAction(context: Context) { ).execute() } - companion object : SingletonHolderParameter(::CipherDatabaseAction) + companion object : SingletonHolderParameter(::CipherDatabaseAction) { + private val TAG = CipherDatabaseAction::class.java.name + } } \ No newline at end of file From 73156cc33707c8b50c2740cef15c1b6946f54316 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:09:22 +0200 Subject: [PATCH 06/10] Fix clipboard null exception --- .../main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt b/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt index ea9a979bd..7c7ac123f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/timeout/ClipboardHelper.kt @@ -67,7 +67,7 @@ class ClipboardHelper(private val context: Context) { fun getClipboard(context: Context): CharSequence { if (getClipboardManager()?.hasPrimaryClip() == true) { val data = getClipboardManager()?.primaryClip - if (data!!.itemCount > 0) { + if (data != null && data.itemCount > 0) { val text = data.getItemAt(0).coerceToText(context) if (text != null) { return text From f9f59a6eb150a88dfc36fed1f88a797ae71f83d9 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:49:49 +0200 Subject: [PATCH 07/10] Replace serializable UUID by Parcelable UUID --- .../keepass/database/element/icon/IconImageCustom.kt | 11 ++++++----- .../keepass/database/element/node/NodeIdUUID.kt | 5 +++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageCustom.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageCustom.kt index efc039ee4..514222fe9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageCustom.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageCustom.kt @@ -20,6 +20,7 @@ package com.kunzisoft.keepass.database.element.icon import android.os.Parcel +import android.os.ParcelUuid import android.os.Parcelable import com.kunzisoft.keepass.database.element.database.DatabaseVersioned import java.util.* @@ -37,17 +38,17 @@ class IconImageCustom : Parcelable, IconImageDraw { } constructor(parcel: Parcel) { - uuid = parcel.readSerializable() as UUID + uuid = parcel.readParcelable(ParcelUuid::class.java.classLoader)?.uuid ?: DatabaseVersioned.UUID_ZERO + } + + override fun writeToParcel(dest: Parcel, flags: Int) { + dest.writeParcelable(ParcelUuid(uuid), flags) } override fun describeContents(): Int { return 0 } - override fun writeToParcel(dest: Parcel, flags: Int) { - dest.writeSerializable(uuid) - } - override fun hashCode(): Int { val prime = 31 var result = 1 diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/node/NodeIdUUID.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/node/NodeIdUUID.kt index 9ccbfcbae..06eecf05c 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/node/NodeIdUUID.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/node/NodeIdUUID.kt @@ -20,6 +20,7 @@ package com.kunzisoft.keepass.database.element.node import android.os.Parcel +import android.os.ParcelUuid import android.os.Parcelable import java.util.* @@ -35,12 +36,12 @@ class NodeIdUUID : NodeId { } constructor(parcel: Parcel) { - id = parcel.readSerializable() as UUID + id = parcel.readParcelable(ParcelUuid::class.java.classLoader)?.uuid ?: id } override fun writeToParcel(dest: Parcel, flags: Int) { super.writeToParcel(dest, flags) - dest.writeSerializable(id) + dest.writeParcelable(ParcelUuid(id), flags) } override fun equals(other: Any?): Boolean { From 1063dc2b63abc60554cdb2bd2c4b654c7ff1f7c4 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:57:30 +0200 Subject: [PATCH 08/10] Add TODO SparseArray --- .../kunzisoft/keepass/database/element/binary/BinaryCache.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/binary/BinaryCache.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/binary/BinaryCache.kt index 46e4c84a0..d41509cb0 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/binary/BinaryCache.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/binary/BinaryCache.kt @@ -27,7 +27,7 @@ class BinaryCache { } } - // Similar to file storage but much faster + // Similar to file storage but much faster TODO SparseArray private val byteArrayList = HashMap() fun getByteArray(key: String): KeyByteArray { From 151b7a323ddefc31f5a84b143912b8cdae33654f Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 13:58:30 +0200 Subject: [PATCH 09/10] Upgrade version code --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 7d994024e..4f36d745b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { applicationId "com.kunzisoft.keepass" minSdkVersion 15 targetSdkVersion 30 - versionCode = 67 + versionCode = 68 versionName = "2.9.15" multiDexEnabled true From 2b359cc5924dd0c526bef374c412d7d0d80e771e Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Mon, 29 Mar 2021 21:00:10 +0200 Subject: [PATCH 10/10] Remove unused code --- .../main/java/com/kunzisoft/encrypt/CipherFactory.kt | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt b/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt index 588d97eba..c2830f814 100644 --- a/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt +++ b/crypto/src/main/java/com/kunzisoft/encrypt/CipherFactory.kt @@ -7,7 +7,6 @@ import java.security.InvalidAlgorithmParameterException import java.security.InvalidKeyException import java.security.NoSuchAlgorithmException import java.security.Security -import javax.crypto.BadPaddingException import javax.crypto.Cipher import javax.crypto.NoSuchPaddingException import javax.crypto.spec.IvParameterSpec @@ -40,16 +39,7 @@ object CipherFactory { @Throws(NoSuchAlgorithmException::class, NoSuchPaddingException::class, InvalidKeyException::class, InvalidAlgorithmParameterException::class) fun getTwofish(opmode: Int, key: ByteArray, IV: ByteArray): Cipher { - val cipher: Cipher = try { - Cipher.getInstance("Twofish/CBC/PKCS7PADDING") - } catch (e: BadPaddingException) { - // Retry with other padding if don't work - if (opmode == Cipher.ENCRYPT_MODE) { - Cipher.getInstance("Twofish/CBC/ZeroBytePadding") - } else { - Cipher.getInstance("Twofish/CBC/NoPadding") - } - } + val cipher: Cipher = Cipher.getInstance("Twofish/CBC/PKCS7PADDING") cipher.init(opmode, SecretKeySpec(key, "AES"), IvParameterSpec(IV)) return cipher }