From eadf32d09906fbf34e027df502b0946b987ec911 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 10:30:15 +0200 Subject: [PATCH 01/11] wip Signed-off-by: alperozturk96 --- app/src/main/java/com/owncloud/android/datamodel/OCFile.java | 1 + .../android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt | 3 ++- .../owncloud/android/operations/CreateFolderOperation.java | 4 ++-- .../android/operations/RemoveRemoteEncryptedFileOperation.kt | 2 +- .../com/owncloud/android/ui/adapter/OCFileListAdapter.java | 2 +- .../com/owncloud/android/ui/fragment/OCFileListFragment.java | 2 +- .../main/java/com/owncloud/android/utils/EncryptionUtils.java | 4 ---- .../main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt | 4 ++-- .../java/com/owncloud/android/utils/crypto/CryptoHelper.kt | 2 +- 9 files changed, 11 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java index 7aaf0e05924f..4d2d2a6cc893 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -46,6 +46,7 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterface { + public final static long FIRST_E2EE_COUNTER = 1L; public final static String PERMISSION_CAN_RESHARE = "R"; public final static String PERMISSION_SHARED = "S"; public final static String PERMISSION_MOUNTED = "M"; diff --git a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt index 7401571217c6..87a9801db105 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt +++ b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt @@ -7,12 +7,13 @@ */ package com.owncloud.android.datamodel.e2e.v2.decrypted +import com.owncloud.android.datamodel.OCFile import com.owncloud.android.utils.EncryptionUtils data class DecryptedMetadata( val keyChecksums: MutableList = mutableListOf(), val deleted: Boolean = false, - var counter: Long = 0, + var counter: Long = OCFile.FIRST_E2EE_COUNTER, val folders: MutableMap = mutableMapOf(), val files: MutableMap = mutableMapOf(), @Transient diff --git a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java index 795331f6c1d1..1a2324a6ea05 100644 --- a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java @@ -137,7 +137,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client); + token = EncryptionUtils.lockFolder(parent, client, OCFile.FIRST_E2EE_COUNTER); // get metadata Pair metadataPair = EncryptionUtils.retrieveMetadataV1(parent, @@ -275,7 +275,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client); + token = EncryptionUtils.lockFolder(parent, client, OCFile.FIRST_E2EE_COUNTER); // get metadata EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2(); diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index e1b47c58e381..10fa22d411d4 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -59,7 +59,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor( val isE2EVersionAtLeast2 = (E2EVersionHelper.isV2Plus(capability)) try { - token = EncryptionUtils.lockFolder(parentFolder, client) + token = EncryptionUtils.lockFolder(parentFolder, client, parentFolder.e2eCounter + 1) return if (isE2EVersionAtLeast2) { val deleteResult = deleteForV2(client, token) diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index 4e0c11632045..afc589f49ca8 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -296,7 +296,7 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) { .findFirst() .ifPresent(file -> { file.setEncrypted(encrypted); - file.setE2eCounter(0L); + file.setE2eCounter(OCFile.FIRST_E2EE_COUNTER); mStorageManager.saveFile(file); int position = getItemPosition(file); diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index d1b66e00c37a..c35605089dff 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -2039,7 +2039,7 @@ private void encryptFolder(OCFile folder, if (remoteOperationResult.isSuccess()) { // lock folder - String token = EncryptionUtils.lockFolder(folder, client); + String token = EncryptionUtils.lockFolder(folder, client, OCFile.FIRST_E2EE_COUNTER); OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName()); if (E2EVersionHelper.INSTANCE.isV2Plus(ocCapability)) { diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java index 078bc598b357..595aecdafa94 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java @@ -1159,10 +1159,6 @@ public static boolean verifySHA512(String hashWithSalt, String compareToken) { return hashWithSalt.equals(newHash); } - public static String lockFolder(ServerFileInterface parentFile, OwnCloudClient client) throws UploadException { - return lockFolder(parentFile, client, -1); - } - public static String lockFolder(ServerFileInterface parentFile, OwnCloudClient client, long counter) throws UploadException { // Lock folder LockFileRemoteOperation lockFileOperation = new LockFileRemoteOperation(parentFile.getLocalId(), diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index 63d7616d920a..07dfc2f3fe0d 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -260,7 +260,7 @@ class EncryptionUtilsV2 { if (transferredFiledrop) { // lock folder - val token = EncryptionUtils.lockFolder(ocFile, client) + val token = EncryptionUtils.lockFolder(ocFile, client, ocFile.e2eCounter) serializeAndUploadMetadata( ocFile, @@ -697,7 +697,7 @@ class EncryptionUtilsV2 { storageManager ) // lock - val token = EncryptionUtils.lockFolder(folder, client) + val token = EncryptionUtils.lockFolder(folder, client, folder.e2eCounter) // upload serializeAndUploadMetadata( diff --git a/app/src/main/java/com/owncloud/android/utils/crypto/CryptoHelper.kt b/app/src/main/java/com/owncloud/android/utils/crypto/CryptoHelper.kt index 6e76ae379538..8228a29a1fa2 100644 --- a/app/src/main/java/com/owncloud/android/utils/crypto/CryptoHelper.kt +++ b/app/src/main/java/com/owncloud/android/utils/crypto/CryptoHelper.kt @@ -34,7 +34,7 @@ object CryptoHelper { private const val TRANSFORMATION = "AES/GCM/NoPadding" private const val GCM_TAG_LENGTH = 16 - private const val IV_LENGTH = 16 + private const val IV_LENGTH = 12 private const val SALT_LENGTH = 40 private const val GCM_TLEN = GCM_TAG_LENGTH * 8 private val charset = StandardCharsets.UTF_8 From 22c3c61b423ab129edead89ae902405e3bcb2749 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 10:39:11 +0200 Subject: [PATCH 02/11] wip Signed-off-by: alperozturk96 --- .../operations/RemoveRemoteEncryptedFileOperation.kt | 8 ++++++-- .../java/com/owncloud/android/utils/EncryptionUtilsV2.kt | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index 10fa22d411d4..0238acba8161 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -176,6 +176,10 @@ class RemoveRemoteEncryptedFileOperation internal constructor( encryptionUtilsV2.removeFileFromMetadata(fileName, metadata) } + parentFolder.setE2eCounter(metadata.metadata.counter) + val storageManager = FileDataStorageManager(user, context.contentResolver) + storageManager.saveFile(parentFolder) + encryptionUtilsV2.serializeAndUploadMetadata( parentFolder, metadata, @@ -184,7 +188,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor( metadataExists, context, user, - FileDataStorageManager(user, context.contentResolver) + storageManager ) return Pair(result, delete) @@ -195,4 +199,4 @@ class RemoveRemoteEncryptedFileOperation internal constructor( private const val REMOVE_READ_TIMEOUT = 30000 private const val REMOVE_CONNECTION_TIMEOUT = 5000 } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index 07dfc2f3fe0d..b3b538e9035d 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -528,6 +528,7 @@ class EncryptionUtilsV2 { metadataFile: DecryptedFolderMetadataFile ): DecryptedFolderMetadataFile { metadataFile.metadata.folders.remove(encryptedFileName) + metadataFile.metadata.counter++ return metadataFile } @@ -536,6 +537,7 @@ class EncryptionUtilsV2 { fun removeFileFromMetadata(fileName: String, metadata: DecryptedFolderMetadataFile) { metadata.metadata.files.remove(fileName) ?: throw IllegalStateException("File $fileName not found in metadata!") + metadata.metadata.counter++ } @Throws(IllegalStateException::class) @@ -1046,4 +1048,4 @@ class EncryptionUtilsV2 { private val TAG = EncryptionUtils::class.java.simpleName private const val PEM_LINE_LENGTH = 64 } -} +} \ No newline at end of file From 72e4547d7614ba35ad7165b1e421928da638177c Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 11:31:48 +0200 Subject: [PATCH 03/11] wip Signed-off-by: alperozturk96 --- .../main/java/com/owncloud/android/datamodel/OCFile.java | 9 ++++++++- .../datamodel/e2e/v2/decrypted/DecryptedMetadata.kt | 2 +- .../android/operations/CreateFolderOperation.java | 4 ++-- .../owncloud/android/ui/adapter/OCFileListAdapter.java | 5 +++-- .../owncloud/android/ui/fragment/OCFileListFragment.java | 6 ++++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java index 4d2d2a6cc893..e56d1d77b0ce 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -46,7 +46,6 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterface { - public final static long FIRST_E2EE_COUNTER = 1L; public final static String PERMISSION_CAN_RESHARE = "R"; public final static String PERMISSION_SHARED = "S"; public final static String PERMISSION_MOUNTED = "M"; @@ -1176,4 +1175,12 @@ public boolean hasValidParentId() { return getParentId() != 0; } } + + public static long getFirstE2EECounter(boolean useV2) { + if (useV2) { + return 1L; + } else { + return -1; + } + } } diff --git a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt index 87a9801db105..10f3bd3617de 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt +++ b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt @@ -13,7 +13,7 @@ import com.owncloud.android.utils.EncryptionUtils data class DecryptedMetadata( val keyChecksums: MutableList = mutableListOf(), val deleted: Boolean = false, - var counter: Long = OCFile.FIRST_E2EE_COUNTER, + var counter: Long = OCFile.getFirstE2EECounter(true), val folders: MutableMap = mutableMapOf(), val files: MutableMap = mutableMapOf(), @Transient diff --git a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java index 1a2324a6ea05..fdfd438ee7ba 100644 --- a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java @@ -137,7 +137,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client, OCFile.FIRST_E2EE_COUNTER); + token = EncryptionUtils.lockFolder(parent, client, OCFile.getFirstE2EECounter(false)); // get metadata Pair metadataPair = EncryptionUtils.retrieveMetadataV1(parent, @@ -275,7 +275,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client, OCFile.FIRST_E2EE_COUNTER); + token = EncryptionUtils.lockFolder(parent, client, OCFile.getFirstE2EECounter(true)); // get metadata EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2(); diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index afc589f49ca8..3f5bca54573c 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -33,6 +33,7 @@ import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.preferences.AppPreferences; import com.nextcloud.model.OfflineOperationType; +import com.nextcloud.utils.e2ee.E2EVersionHelper; import com.nextcloud.utils.extensions.ViewExtensionsKt; import com.nextcloud.utils.mdm.MDMConfig; import com.owncloud.android.MainApp; @@ -296,9 +297,9 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) { .findFirst() .ifPresent(file -> { file.setEncrypted(encrypted); - file.setE2eCounter(OCFile.FIRST_E2EE_COUNTER); + final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(capability); + file.setE2eCounter(OCFile.getFirstE2EECounter(isE2EEV2)); mStorageManager.saveFile(file); - int position = getItemPosition(file); if (position != -1) { notifyItemChanged(position); diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index c35605089dff..8224b9f77dca 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -2038,10 +2038,12 @@ private void encryptFolder(OCFile folder, .execute(client); if (remoteOperationResult.isSuccess()) { + OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName()); + final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(ocCapability); + // lock folder - String token = EncryptionUtils.lockFolder(folder, client, OCFile.FIRST_E2EE_COUNTER); + String token = EncryptionUtils.lockFolder(folder, client, OCFile.getFirstE2EECounter(isE2EEV2)); - OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName()); if (E2EVersionHelper.INSTANCE.isV2Plus(ocCapability)) { // Update metadata Pair metadataPair = EncryptionUtils.retrieveMetadata(folder, From b2a471c4bba972a035263b297ba2979361496e05 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 14:57:14 +0200 Subject: [PATCH 04/11] wip Signed-off-by: alperozturk96 --- app/src/main/java/com/owncloud/android/datamodel/OCFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java index e56d1d77b0ce..87c5383d437e 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -1180,7 +1180,7 @@ public static long getFirstE2EECounter(boolean useV2) { if (useV2) { return 1L; } else { - return -1; + return 0L; } } } From 4b87485c7aaec39d553709d6a41db865e8492960 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 15:02:31 +0200 Subject: [PATCH 05/11] wip Signed-off-by: alperozturk96 # Conflicts: # gradle/libs.versions.toml --- gradle/verification-metadata.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 8865a73a3faa..5b29c92d57a5 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -21501,6 +21501,14 @@ + + + + + + + + From 8334780c7b761592ea0755ec4e953a3f10b0ceab Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 15:03:41 +0200 Subject: [PATCH 06/11] wip Signed-off-by: alperozturk96 --- .../android/operations/RemoveRemoteEncryptedFileOperation.kt | 2 +- .../main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index 0238acba8161..2bd1042ae4e9 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -199,4 +199,4 @@ class RemoveRemoteEncryptedFileOperation internal constructor( private const val REMOVE_READ_TIMEOUT = 30000 private const val REMOVE_CONNECTION_TIMEOUT = 5000 } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index b3b538e9035d..88c634b0a35c 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -1048,4 +1048,4 @@ class EncryptionUtilsV2 { private val TAG = EncryptionUtils::class.java.simpleName private const val PEM_LINE_LENGTH = 64 } -} \ No newline at end of file +} From 26ddb772a5c6db90550b1a68c9cfcac9163e2863 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 10:30:15 +0200 Subject: [PATCH 07/11] wip Signed-off-by: alperozturk96 --- app/src/main/java/com/owncloud/android/datamodel/OCFile.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java index 87c5383d437e..55ddd8c68aae 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -46,6 +46,7 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterface { + public final static long FIRST_E2EE_COUNTER = 1L; public final static String PERMISSION_CAN_RESHARE = "R"; public final static String PERMISSION_SHARED = "S"; public final static String PERMISSION_MOUNTED = "M"; From d6951b8f88d50c13437b40c8f0c2879d6a0f19ba Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 10:39:11 +0200 Subject: [PATCH 08/11] wip Signed-off-by: alperozturk96 --- .../android/operations/RemoveRemoteEncryptedFileOperation.kt | 2 +- .../main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index 2bd1042ae4e9..0238acba8161 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -199,4 +199,4 @@ class RemoveRemoteEncryptedFileOperation internal constructor( private const val REMOVE_READ_TIMEOUT = 30000 private const val REMOVE_CONNECTION_TIMEOUT = 5000 } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index 88c634b0a35c..b3b538e9035d 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -1048,4 +1048,4 @@ class EncryptionUtilsV2 { private val TAG = EncryptionUtils::class.java.simpleName private const val PEM_LINE_LENGTH = 64 } -} +} \ No newline at end of file From 0aefe7122506bf31fb5ecd12afd6ef76ada62946 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 30 Apr 2026 15:03:41 +0200 Subject: [PATCH 09/11] wip Signed-off-by: alperozturk96 --- .../android/operations/RemoveRemoteEncryptedFileOperation.kt | 2 +- .../main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt index 0238acba8161..2bd1042ae4e9 100644 --- a/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt +++ b/app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt @@ -199,4 +199,4 @@ class RemoveRemoteEncryptedFileOperation internal constructor( private const val REMOVE_READ_TIMEOUT = 30000 private const val REMOVE_CONNECTION_TIMEOUT = 5000 } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index b3b538e9035d..88c634b0a35c 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -1048,4 +1048,4 @@ class EncryptionUtilsV2 { private val TAG = EncryptionUtils::class.java.simpleName private const val PEM_LINE_LENGTH = 64 } -} \ No newline at end of file +} From a157d2ed9057dbceabbacfd0ba88df06fbe4fe3c Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 7 May 2026 14:50:34 +0200 Subject: [PATCH 10/11] fix checksum generation Signed-off-by: alperozturk96 --- .../owncloud/android/utils/EncryptionUtilsV2.kt | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt index 88c634b0a35c..2a697c1e2bef 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -57,7 +57,6 @@ import java.io.BufferedReader import java.io.ByteArrayOutputStream import java.io.InputStream import java.io.InputStreamReader -import java.math.BigInteger import java.security.MessageDigest import java.security.PrivateKey import java.security.cert.X509Certificate @@ -1011,17 +1010,10 @@ class EncryptionUtilsV2 { return DecryptedFolderMetadataFile(metadata) } - /** - * SHA-256 hash of metadata-key - */ - @Suppress("MagicNumber") - fun hashMetadataKey(metadataKey: ByteArray): String { - val bytes = MessageDigest - .getInstance("SHA-256") - .digest(metadataKey) - - return BigInteger(1, bytes).toString(16).padStart(32, '0') - } + fun hashMetadataKey(metadataKey: ByteArray): String = MessageDigest + .getInstance("SHA-256") + .digest(metadataKey) + .joinToString("") { "%02x".format(it) } fun getMessageSignature(cert: String, privateKey: String, metadataFile: EncryptedFolderMetadataFile): String = getMessageSignature( From f81b82c829f6552a9c539756a340fe94c24b71ea Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Fri, 8 May 2026 10:38:09 +0200 Subject: [PATCH 11/11] wip Signed-off-by: alperozturk96 --- .../main/java/com/owncloud/android/datamodel/OCFile.java | 9 --------- .../datamodel/e2e/v2/decrypted/DecryptedMetadata.kt | 3 +-- .../android/operations/CreateFolderOperation.java | 6 +++--- .../owncloud/android/ui/adapter/OCFileListAdapter.java | 8 +++++++- .../owncloud/android/ui/fragment/OCFileListFragment.java | 6 +++++- .../java/com/owncloud/android/utils/EncryptionUtils.java | 4 ++++ 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java index 55ddd8c68aae..7aaf0e05924f 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -46,7 +46,6 @@ public class OCFile implements Parcelable, Comparable, ServerFileInterface { - public final static long FIRST_E2EE_COUNTER = 1L; public final static String PERMISSION_CAN_RESHARE = "R"; public final static String PERMISSION_SHARED = "S"; public final static String PERMISSION_MOUNTED = "M"; @@ -1176,12 +1175,4 @@ public boolean hasValidParentId() { return getParentId() != 0; } } - - public static long getFirstE2EECounter(boolean useV2) { - if (useV2) { - return 1L; - } else { - return 0L; - } - } } diff --git a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt index 10f3bd3617de..532f4c7dcf63 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt +++ b/app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt @@ -7,13 +7,12 @@ */ package com.owncloud.android.datamodel.e2e.v2.decrypted -import com.owncloud.android.datamodel.OCFile import com.owncloud.android.utils.EncryptionUtils data class DecryptedMetadata( val keyChecksums: MutableList = mutableListOf(), val deleted: Boolean = false, - var counter: Long = OCFile.getFirstE2EECounter(true), + var counter: Long = EncryptionUtils.E2E_V2_INITIAL_COUNTER, val folders: MutableMap = mutableMapOf(), val files: MutableMap = mutableMapOf(), @Transient diff --git a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java index fdfd438ee7ba..af0ed63b794f 100644 --- a/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java @@ -137,7 +137,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client, OCFile.getFirstE2EECounter(false)); + token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V1_INITIAL_COUNTER); // get metadata Pair metadataPair = EncryptionUtils.retrieveMetadataV1(parent, @@ -153,7 +153,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl // check if filename already exists if (isFileExisting(metadata, filename)) { - return new RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS); + return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS); } // generate new random file name, check if it exists in metadata @@ -275,7 +275,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl try { // lock folder - token = EncryptionUtils.lockFolder(parent, client, OCFile.getFirstE2EECounter(true)); + token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V2_INITIAL_COUNTER); // get metadata EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2(); diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java index 3f5bca54573c..a2c7616dda3c 100644 --- a/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java @@ -64,6 +64,7 @@ import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface; import com.owncloud.android.ui.preview.PreviewTextFragment; import com.owncloud.android.utils.DisplayUtils; +import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.FileSortOrder; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.MimeTypeUtil; @@ -298,7 +299,12 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) { .ifPresent(file -> { file.setEncrypted(encrypted); final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(capability); - file.setE2eCounter(OCFile.getFirstE2EECounter(isE2EEV2)); + long e2eCounter = EncryptionUtils.E2E_V1_INITIAL_COUNTER; + if (isE2EEV2) { + e2eCounter = EncryptionUtils.E2E_V2_INITIAL_COUNTER; + } + + file.setE2eCounter(e2eCounter); mStorageManager.saveFile(file); int position = getItemPosition(file); if (position != -1) { diff --git a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java index 8224b9f77dca..289c26509383 100644 --- a/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -2040,9 +2040,13 @@ private void encryptFolder(OCFile folder, if (remoteOperationResult.isSuccess()) { OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName()); final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(ocCapability); + long e2eCounter = EncryptionUtils.E2E_V1_INITIAL_COUNTER; + if (isE2EEV2) { + e2eCounter = EncryptionUtils.E2E_V2_INITIAL_COUNTER; + } // lock folder - String token = EncryptionUtils.lockFolder(folder, client, OCFile.getFirstE2EECounter(isE2EEV2)); + String token = EncryptionUtils.lockFolder(folder, client, e2eCounter); if (E2EVersionHelper.INSTANCE.isV2Plus(ocCapability)) { // Update metadata diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java index 595aecdafa94..027775b60666 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java @@ -129,6 +129,10 @@ public final class EncryptionUtils { @VisibleForTesting public static final String MIGRATED_FOLDER_IDS = "MIGRATED_FOLDER_IDS"; + public static final long E2E_V1_INITIAL_COUNTER = 0L; + public static final long E2E_V2_INITIAL_COUNTER = 1L; + + private EncryptionUtils() { // utility class -> private constructor }