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..87c5383d437e 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/OCFile.java +++ b/app/src/main/java/com/owncloud/android/datamodel/OCFile.java @@ -1175,4 +1175,12 @@ 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 7401571217c6..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 @@ -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.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 795331f6c1d1..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); + 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); + token = EncryptionUtils.lockFolder(parent, client, OCFile.getFirstE2EECounter(true)); // 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..2bd1042ae4e9 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) @@ -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) 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..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(0L); + 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 b0f6c533a4ea..ee60b9310b44 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 @@ -1940,10 +1940,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); + 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, 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..0e4ddbb3fc60 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java @@ -17,6 +17,7 @@ import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.nextcloud.client.account.User; +import com.nextcloud.common.SessionTimeOutKt; import com.nextcloud.utils.e2ee.E2EVersionHelper; import com.owncloud.android.R; import com.owncloud.android.datamodel.ArbitraryDataProvider; @@ -42,7 +43,6 @@ import com.owncloud.android.lib.resources.e2ee.StoreMetadataRemoteOperation; import com.owncloud.android.lib.resources.e2ee.StoreMetadataV2RemoteOperation; import com.owncloud.android.lib.resources.e2ee.UnlockFileRemoteOperation; -import com.owncloud.android.lib.resources.e2ee.UnlockFileV1RemoteOperation; import com.owncloud.android.lib.resources.e2ee.UpdateMetadataRemoteOperation; import com.owncloud.android.lib.resources.e2ee.UpdateMetadataV2RemoteOperation; import com.owncloud.android.lib.resources.files.model.ServerFileInterface; @@ -1159,14 +1159,11 @@ 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(), - counter); + counter, + SessionTimeOutKt.getDefaultSessionTimeOut()); RemoteOperationResult lockFileOperationResult = lockFileOperation.execute(client); if (lockFileOperationResult.isSuccess() && @@ -1366,7 +1363,7 @@ public static RemoteOperationResult unlockFolder(ServerFileInterface paren public static RemoteOperationResult unlockFolderV1(ServerFileInterface parentFolder, OwnCloudClient client, String token) { if (token != null) { - return new UnlockFileV1RemoteOperation(parentFolder.getLocalId(), token).execute(client); + return new UnlockFileRemoteOperation(parentFolder.getLocalId(), token, SessionTimeOutKt.getDefaultSessionTimeOut(), false).execute(client); } else { return new RemoteOperationResult<>(new Exception("No token available")); } 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 e87ef399d635..1818bb52556b 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt @@ -259,7 +259,7 @@ class EncryptionUtilsV2 { if (transferredFiledrop) { // lock folder - val token = EncryptionUtils.lockFolder(ocFile, client) + val token = EncryptionUtils.lockFolder(ocFile, client, ocFile.e2eCounter) serializeAndUploadMetadata( ocFile, @@ -527,6 +527,7 @@ class EncryptionUtilsV2 { metadataFile: DecryptedFolderMetadataFile ): DecryptedFolderMetadataFile { metadataFile.metadata.folders.remove(encryptedFileName) + metadataFile.metadata.counter++ return metadataFile } @@ -535,6 +536,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) @@ -781,7 +783,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 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cca111a669e8..775a8304254f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ androidCommonLibraryVersion = "0.33.2" androidGifDrawableVersion = "1.2.31" androidImageCropperVersion = "4.7.0" -androidLibraryVersion ="20e8cd17191f337d34b2ed97e0ac61e84a0bfc39" +androidLibraryVersion ="9ec469f0cd" androidPluginVersion = "9.2.0" androidsvgVersion = "1.4" androidxMediaVersion = "1.5.1" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index c7804dce66d7..b960908bdfaf 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -21526,6 +21526,14 @@ + + + + + + + +