Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.owncloud.android.utils.EncryptionUtils
data class DecryptedMetadata(
val keyChecksums: MutableList<String> = mutableListOf(),
val deleted: Boolean = false,
var counter: Long = 0,
var counter: Long = EncryptionUtils.E2E_V2_INITIAL_COUNTER,
val folders: MutableMap<String, String> = mutableMapOf(),
val files: MutableMap<String, DecryptedFile> = mutableMapOf(),
@Transient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl

try {
// lock folder
token = EncryptionUtils.lockFolder(parent, client);
token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V1_INITIAL_COUNTER);

// get metadata
Pair<Boolean, DecryptedFolderMetadataFileV1> metadataPair = EncryptionUtils.retrieveMetadataV1(parent,
Expand All @@ -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
Expand Down Expand Up @@ -275,7 +275,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl

try {
// lock folder
token = EncryptionUtils.lockFolder(parent, client);
token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V2_INITIAL_COUNTER);

// get metadata
EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -184,7 +188,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor(
metadataExists,
context,
user,
FileDataStorageManager(user, context.contentResolver)
storageManager
)

return Pair(result, delete)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -63,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;
Expand Down Expand Up @@ -296,9 +298,14 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) {
.findFirst()
.ifPresent(file -> {
file.setEncrypted(encrypted);
file.setE2eCounter(0L);
mStorageManager.saveFile(file);
final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(capability);
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) {
notifyItemChanged(position);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2038,10 +2038,16 @@ private void encryptFolder(OCFile folder,
.execute(client);

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);
String token = EncryptionUtils.lockFolder(folder, client, e2eCounter);

OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName());
if (E2EVersionHelper.INSTANCE.isV2Plus(ocCapability)) {
// Update metadata
Pair<Boolean, DecryptedFolderMetadataFile> metadataPair = EncryptionUtils.retrieveMetadata(folder,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -1159,10 +1163,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(),
Expand Down
22 changes: 8 additions & 14 deletions app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -260,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,
Expand Down Expand Up @@ -528,6 +527,7 @@ class EncryptionUtilsV2 {
metadataFile: DecryptedFolderMetadataFile
): DecryptedFolderMetadataFile {
metadataFile.metadata.folders.remove(encryptedFileName)
metadataFile.metadata.counter++

return metadataFile
}
Expand All @@ -536,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)
Expand Down Expand Up @@ -697,7 +698,7 @@ class EncryptionUtilsV2 {
storageManager
)
// lock
val token = EncryptionUtils.lockFolder(folder, client)
val token = EncryptionUtils.lockFolder(folder, client, folder.e2eCounter)

// upload
serializeAndUploadMetadata(
Expand Down Expand Up @@ -1009,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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions gradle/verification-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21501,6 +21501,14 @@
<sha256 value="b4494fe2a8ed059abec25448f98a65e0d1850876a0091e6645607423fb68d9c5" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="com.github.nextcloud" name="android-library" version="9ec469f0cd">
<artifact name="android-library-9ec469f0cd.aar">
<sha256 value="deb6208d5664330a940cb6058c9160f4ae810a7385824b954555fed5e15be292" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
<artifact name="android-library-9ec469f0cd.module">
<sha256 value="40b856a550a4d26cf9bfda6e9ac9a5f117388de5cd7519329e7b5ff64eda8d0c" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="com.github.nextcloud" name="android-library" version="9fdcd0af0ff910086281f32e3b8ef74490671149">
<artifact name="android-library-9fdcd0af0ff910086281f32e3b8ef74490671149.aar">
<sha256 value="57ab4fd7c922875a7e0b5feac20aa27ab5df0fd3b4e042f92ed727c0b6316e81" origin="Generated by Gradle" reason="Artifact is not signed"/>
Expand Down
Loading