From 241b9a8a58f7b295fbd28bf46e83811607e9fb9d Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Wed, 4 Sep 2024 10:58:38 +0200 Subject: [PATCH 01/18] Bump compile and target SDK to version 34 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 61f2a35b6c..fbb777b74e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -223,7 +223,7 @@ static def getDate() { android { namespace 'org.commcare.dalvik' - compileSdk 33 + compileSdk 34 lintOptions { abortOnError false @@ -250,7 +250,7 @@ android { defaultConfig { minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 34 multiDexEnabled true applicationId 'org.commcare.dalvik' testNamespace 'org.commcare.dalvik.test' From 8b8c4418278d7e503e2c0817fa6afa3c86f34a54 Mon Sep 17 00:00:00 2001 From: Shubham Goyal Date: Mon, 23 Sep 2024 12:19:25 +0200 Subject: [PATCH 02/18] Remove unused cipher pool --- .../models/encryption/CipherPool.java | 59 --------- .../models/legacy/DecryptingCursor.java | 113 ------------------ .../services/CommCareSessionService.java | 27 ----- .../org/commcare/CommCareTestApplication.java | 1 - 4 files changed, 200 deletions(-) delete mode 100755 app/src/org/commcare/models/encryption/CipherPool.java delete mode 100755 app/src/org/commcare/models/legacy/DecryptingCursor.java diff --git a/app/src/org/commcare/models/encryption/CipherPool.java b/app/src/org/commcare/models/encryption/CipherPool.java deleted file mode 100755 index 2283bb2574..0000000000 --- a/app/src/org/commcare/models/encryption/CipherPool.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.commcare.models.encryption; - -import android.util.Log; - -import java.util.HashSet; -import java.util.Stack; - -import javax.crypto.Cipher; - -/** - * @author ctsims - */ -public abstract class CipherPool { - private static final String TAG = CipherPool.class.getSimpleName(); - - private static final int GROWTH_FACTOR = 5; - - private final HashSet issued = new HashSet<>(); - private final Stack free = new Stack<>(); - - //TODO: Pass in factory and finalize all API's rather than - //leaving the class to be anonymous? - public CipherPool() { - - } - - public synchronized final void init() { - grow(); - } - - public synchronized final Cipher borrow() { - if (free.isEmpty()) { - grow(); - Log.d(TAG, "Growing cipher pool. Current size is: " + free.size() + issued.size()); - } - Cipher toLend = free.pop(); - issued.add(toLend); - return toLend; - } - - public synchronized final void remit(Cipher cipher) { - issued.remove(cipher); - free.push(cipher); - } - - private synchronized void grow() { - for (int i = 0; i < GROWTH_FACTOR; ++i) { - free.push(generateNewCipher()); - } - } - - protected abstract Cipher generateNewCipher(); - - public synchronized final void expire() { - //do we want to try to destroy the final object here? - issued.clear(); - free.clear(); - } -} diff --git a/app/src/org/commcare/models/legacy/DecryptingCursor.java b/app/src/org/commcare/models/legacy/DecryptingCursor.java deleted file mode 100755 index 0f3d153d28..0000000000 --- a/app/src/org/commcare/models/legacy/DecryptingCursor.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.commcare.models.legacy; - -import android.database.sqlite.SQLiteCursor; -import android.database.sqlite.SQLiteCursorDriver; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteQuery; - -import org.commcare.models.encryption.CipherPool; -import org.commcare.core.encryption.CryptUtil; -import org.commcare.modern.database.DatabaseHelper; -import org.commcare.modern.models.EncryptedModel; - -import javax.crypto.Cipher; - -/** - * @author ctsims - */ -public class DecryptingCursor extends SQLiteCursor { - final Cipher cipher; - final EncryptedModel model; - final CipherPool pool; - - public DecryptingCursor(SQLiteDatabase db, SQLiteCursorDriver driver, String editTable, SQLiteQuery query, EncryptedModel model, CipherPool pool) { - super(db, driver, editTable, query); - this.model = model; - this.pool = pool; - this.cipher = pool.borrow(); - } - - @Override - public byte[] getBlob(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getBlob(columnIndex); - } else { - return decrypt(columnIndex); - } - } - - @Override - public double getDouble(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getDouble(columnIndex); - } else { - return Double.valueOf(new String(decrypt(columnIndex))); - } - } - - @Override - public float getFloat(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getFloat(columnIndex); - } else { - return Float.valueOf(new String(decrypt(columnIndex))); - } - } - - @Override - public int getInt(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getInt(columnIndex); - } else { - return Integer.valueOf(new String(decrypt(columnIndex))); - } - } - - @Override - public long getLong(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getLong(columnIndex); - } else { - return Long.valueOf(new String(decrypt(columnIndex))); - } - } - - @Override - public short getShort(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getShort(columnIndex); - } else { - return Short.valueOf(new String(decrypt(columnIndex))); - } - } - - @Override - public String getString(int columnIndex) { - if (!isEncrypted(columnIndex)) { - return super.getString(columnIndex); - } else { - return new String(decrypt(columnIndex)); - } - } - - private boolean isEncrypted(int columnIndex) { - String column = this.getColumnName(columnIndex); - if (model.isEncrypted(column)) { - return true; - } - return (column.equals(DatabaseHelper.DATA_COL) && - model.isBlobEncrypted()); - } - - private byte[] decrypt(int columnIndex) { - byte[] data = super.getBlob(columnIndex); - return CryptUtil.decrypt(data, cipher); - } - - - @Override - public void close() { - super.close(); - pool.remit(cipher); - } -} diff --git a/app/src/org/commcare/services/CommCareSessionService.java b/app/src/org/commcare/services/CommCareSessionService.java index 1ed06a1e51..ca9da6d2ca 100644 --- a/app/src/org/commcare/services/CommCareSessionService.java +++ b/app/src/org/commcare/services/CommCareSessionService.java @@ -27,7 +27,6 @@ import org.commcare.interfaces.FormSaveCallback; import org.commcare.models.database.user.DatabaseUserOpenHelper; import org.commcare.models.database.user.UserSandboxUtils; -import org.commcare.models.encryption.CipherPool; import org.commcare.preferences.HiddenPreferences; import org.commcare.sync.FormSubmissionHelper; import org.commcare.tasks.DataSubmissionListener; @@ -83,7 +82,6 @@ public class CommCareSessionService extends Service { public static final ReentrantLock sessionAliveLock = new ReentrantLock(); private Timer maintenanceTimer; - private CipherPool pool; private byte[] key = null; @@ -141,7 +139,6 @@ public CommCareSessionService getService() { public void onCreate() { mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); setSessionLength(); - createCipherPool(); } @Override @@ -154,27 +151,6 @@ public void onTaskRemoved(Intent rootIntent) { } } - public void createCipherPool() { - pool = new CipherPool() { - @Override - public Cipher generateNewCipher() { - synchronized (lock) { - try { - SecretKeySpec spec = new SecretKeySpec(key, "AES"); - Cipher decrypter = Cipher.getInstance("AES"); - decrypter.init(Cipher.DECRYPT_MODE, spec); - - return decrypter; - } catch (NoSuchPaddingException | NoSuchAlgorithmException | - InvalidKeyException e) { - e.printStackTrace(); - } - } - return null; - } - }; - } - @Override public int onStartCommand(Intent intent, int flags, int startId) { // We want this service to continue running until it is explicitly @@ -286,7 +262,6 @@ public void prepareStorage(byte[] symetricKey, UserKeyRecord record) { synchronized (lock) { this.userKeyRecordUUID = record.getUuid(); this.key = symetricKey; - pool.init(); if (userDatabase != null && userDatabase.isOpen()) { userDatabase.close(); } @@ -488,8 +463,6 @@ public void closeServiceResources() { maintenanceTimer.cancel(); } logoutStartedAt = -1; - - pool.expire(); endHeartbeatLifecycle(); } } diff --git a/app/unit-tests/src/org/commcare/CommCareTestApplication.java b/app/unit-tests/src/org/commcare/CommCareTestApplication.java index eb38ef32cb..368a3cc496 100644 --- a/app/unit-tests/src/org/commcare/CommCareTestApplication.java +++ b/app/unit-tests/src/org/commcare/CommCareTestApplication.java @@ -201,7 +201,6 @@ public void startUserSession(byte[] symetricKey, UserKeyRecord record, boolean r // manually create/setup session service because robolectric doesn't // really support services CommCareSessionService ccService = startRoboCommCareService(); - ccService.createCipherPool(); ccService.prepareStorage(symetricKey, record); User user = getUserFromDb(ccService, record); if (user == null && cachedUserPassword != null) { From b93b72ec39a60bff9ef8229b0f891bd6fbd3e1f6 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Tue, 29 Oct 2024 09:55:59 +0200 Subject: [PATCH 03/18] Bump AGP version to version 8.1.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e0a5d687a1..3eb760f227 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.0.1' + classpath 'com.android.tools.build:gradle:8.1.1' classpath 'com.google.gms:google-services:4.3.14' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" From 000fef69264515ad470749e6b1a158e03b7f861a Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 14 Nov 2024 14:36:54 +0200 Subject: [PATCH 04/18] Set foreground service type --- app/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 2c45970177..4121c7a076 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -38,6 +38,7 @@ + From e8879bc95264ec2592a09f1665709c65209fe465 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 14 Nov 2024 14:37:38 +0200 Subject: [PATCH 05/18] Set exported attribute to receivers --- app/AndroidManifest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/AndroidManifest.xml b/app/AndroidManifest.xml index 4121c7a076..81c9f0aed9 100644 --- a/app/AndroidManifest.xml +++ b/app/AndroidManifest.xml @@ -374,7 +374,9 @@ - +