Skip to content

Commit 71d06dc

Browse files
Merge pull request #16944 from nextcloud/fix/e2ee-key-creation
fix: e2ee key creation
2 parents ca3983e + 8e08bdb commit 71d06dc

9 files changed

Lines changed: 48 additions & 29 deletions

File tree

app/src/main/java/com/owncloud/android/datamodel/e2e/v2/decrypted/DecryptedMetadata.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import com.owncloud.android.utils.EncryptionUtils
1212
data class DecryptedMetadata(
1313
val keyChecksums: MutableList<String> = mutableListOf(),
1414
val deleted: Boolean = false,
15-
var counter: Long = 0,
15+
var counter: Long = EncryptionUtils.E2E_V2_INITIAL_COUNTER,
1616
val folders: MutableMap<String, String> = mutableMapOf(),
1717
val files: MutableMap<String, DecryptedFile> = mutableMapOf(),
1818
@Transient

app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl
137137

138138
try {
139139
// lock folder
140-
token = EncryptionUtils.lockFolder(parent, client);
140+
token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V1_INITIAL_COUNTER);
141141

142142
// get metadata
143143
Pair<Boolean, DecryptedFolderMetadataFileV1> metadataPair = EncryptionUtils.retrieveMetadataV1(parent,
@@ -153,7 +153,7 @@ private RemoteOperationResult encryptedCreateV1(OCFile parent, OwnCloudClient cl
153153

154154
// check if filename already exists
155155
if (isFileExisting(metadata, filename)) {
156-
return new RemoteOperationResult(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS);
156+
return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FOLDER_ALREADY_EXISTS);
157157
}
158158

159159
// generate new random file name, check if it exists in metadata
@@ -275,7 +275,7 @@ private RemoteOperationResult encryptedCreateV2(OCFile parent, OwnCloudClient cl
275275

276276
try {
277277
// lock folder
278-
token = EncryptionUtils.lockFolder(parent, client);
278+
token = EncryptionUtils.lockFolder(parent, client, EncryptionUtils.E2E_V2_INITIAL_COUNTER);
279279

280280
// get metadata
281281
EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2();

app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor(
5959
val isE2EVersionAtLeast2 = (E2EVersionHelper.isV2Plus(capability))
6060

6161
try {
62-
token = EncryptionUtils.lockFolder(parentFolder, client)
62+
token = EncryptionUtils.lockFolder(parentFolder, client, parentFolder.e2eCounter + 1)
6363

6464
return if (isE2EVersionAtLeast2) {
6565
val deleteResult = deleteForV2(client, token)
@@ -176,6 +176,10 @@ class RemoveRemoteEncryptedFileOperation internal constructor(
176176
encryptionUtilsV2.removeFileFromMetadata(fileName, metadata)
177177
}
178178

179+
parentFolder.setE2eCounter(metadata.metadata.counter)
180+
val storageManager = FileDataStorageManager(user, context.contentResolver)
181+
storageManager.saveFile(parentFolder)
182+
179183
encryptionUtilsV2.serializeAndUploadMetadata(
180184
parentFolder,
181185
metadata,
@@ -184,7 +188,7 @@ class RemoveRemoteEncryptedFileOperation internal constructor(
184188
metadataExists,
185189
context,
186190
user,
187-
FileDataStorageManager(user, context.contentResolver)
191+
storageManager
188192
)
189193

190194
return Pair(result, delete)

app/src/main/java/com/owncloud/android/ui/adapter/OCFileListAdapter.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.nextcloud.client.jobs.upload.FileUploadHelper;
3434
import com.nextcloud.client.preferences.AppPreferences;
3535
import com.nextcloud.model.OfflineOperationType;
36+
import com.nextcloud.utils.e2ee.E2EVersionHelper;
3637
import com.nextcloud.utils.extensions.ViewExtensionsKt;
3738
import com.nextcloud.utils.mdm.MDMConfig;
3839
import com.owncloud.android.MainApp;
@@ -63,6 +64,7 @@
6364
import com.owncloud.android.ui.interfaces.OCFileListFragmentInterface;
6465
import com.owncloud.android.ui.preview.PreviewTextFragment;
6566
import com.owncloud.android.utils.DisplayUtils;
67+
import com.owncloud.android.utils.EncryptionUtils;
6668
import com.owncloud.android.utils.FileSortOrder;
6769
import com.owncloud.android.utils.FileStorageUtils;
6870
import com.owncloud.android.utils.MimeTypeUtil;
@@ -296,9 +298,14 @@ public void updateFileEncryptionById(String fileId, boolean encrypted) {
296298
.findFirst()
297299
.ifPresent(file -> {
298300
file.setEncrypted(encrypted);
299-
file.setE2eCounter(0L);
300-
mStorageManager.saveFile(file);
301+
final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(capability);
302+
long e2eCounter = EncryptionUtils.E2E_V1_INITIAL_COUNTER;
303+
if (isE2EEV2) {
304+
e2eCounter = EncryptionUtils.E2E_V2_INITIAL_COUNTER;
305+
}
301306

307+
file.setE2eCounter(e2eCounter);
308+
mStorageManager.saveFile(file);
302309
int position = getItemPosition(file);
303310
if (position != -1) {
304311
notifyItemChanged(position);

app/src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,10 +1944,16 @@ private void encryptFolder(OCFile folder,
19441944
.execute(client);
19451945

19461946
if (remoteOperationResult.isSuccess()) {
1947+
OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName());
1948+
final var isE2EEV2 = E2EVersionHelper.INSTANCE.isV2Plus(ocCapability);
1949+
long e2eCounter = EncryptionUtils.E2E_V1_INITIAL_COUNTER;
1950+
if (isE2EEV2) {
1951+
e2eCounter = EncryptionUtils.E2E_V2_INITIAL_COUNTER;
1952+
}
1953+
19471954
// lock folder
1948-
String token = EncryptionUtils.lockFolder(folder, client);
1955+
String token = EncryptionUtils.lockFolder(folder, client, e2eCounter);
19491956

1950-
OCCapability ocCapability = mContainerActivity.getStorageManager().getCapability(user.getAccountName());
19511957
if (E2EVersionHelper.INSTANCE.isV2Plus(ocCapability)) {
19521958
// Update metadata
19531959
Pair<Boolean, DecryptedFolderMetadataFile> metadataPair = EncryptionUtils.retrieveMetadata(folder,

app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ public final class EncryptionUtils {
129129
@VisibleForTesting
130130
public static final String MIGRATED_FOLDER_IDS = "MIGRATED_FOLDER_IDS";
131131

132+
public static final long E2E_V1_INITIAL_COUNTER = 0L;
133+
public static final long E2E_V2_INITIAL_COUNTER = 1L;
134+
135+
132136
private EncryptionUtils() {
133137
// utility class -> private constructor
134138
}
@@ -1159,10 +1163,6 @@ public static boolean verifySHA512(String hashWithSalt, String compareToken) {
11591163
return hashWithSalt.equals(newHash);
11601164
}
11611165

1162-
public static String lockFolder(ServerFileInterface parentFile, OwnCloudClient client) throws UploadException {
1163-
return lockFolder(parentFile, client, -1);
1164-
}
1165-
11661166
public static String lockFolder(ServerFileInterface parentFile, OwnCloudClient client, long counter) throws UploadException {
11671167
// Lock folder
11681168
LockFileRemoteOperation lockFileOperation = new LockFileRemoteOperation(parentFile.getLocalId(),

app/src/main/java/com/owncloud/android/utils/EncryptionUtilsV2.kt

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ import java.io.BufferedReader
5757
import java.io.ByteArrayOutputStream
5858
import java.io.InputStream
5959
import java.io.InputStreamReader
60-
import java.math.BigInteger
6160
import java.security.MessageDigest
6261
import java.security.PrivateKey
6362
import java.security.cert.X509Certificate
@@ -260,7 +259,7 @@ class EncryptionUtilsV2 {
260259

261260
if (transferredFiledrop) {
262261
// lock folder
263-
val token = EncryptionUtils.lockFolder(ocFile, client)
262+
val token = EncryptionUtils.lockFolder(ocFile, client, ocFile.e2eCounter)
264263

265264
serializeAndUploadMetadata(
266265
ocFile,
@@ -528,6 +527,7 @@ class EncryptionUtilsV2 {
528527
metadataFile: DecryptedFolderMetadataFile
529528
): DecryptedFolderMetadataFile {
530529
metadataFile.metadata.folders.remove(encryptedFileName)
530+
metadataFile.metadata.counter++
531531

532532
return metadataFile
533533
}
@@ -536,6 +536,7 @@ class EncryptionUtilsV2 {
536536
fun removeFileFromMetadata(fileName: String, metadata: DecryptedFolderMetadataFile) {
537537
metadata.metadata.files.remove(fileName)
538538
?: throw IllegalStateException("File $fileName not found in metadata!")
539+
metadata.metadata.counter++
539540
}
540541

541542
@Throws(IllegalStateException::class)
@@ -697,7 +698,7 @@ class EncryptionUtilsV2 {
697698
storageManager
698699
)
699700
// lock
700-
val token = EncryptionUtils.lockFolder(folder, client)
701+
val token = EncryptionUtils.lockFolder(folder, client, folder.e2eCounter)
701702

702703
// upload
703704
serializeAndUploadMetadata(
@@ -1009,17 +1010,10 @@ class EncryptionUtilsV2 {
10091010
return DecryptedFolderMetadataFile(metadata)
10101011
}
10111012

1012-
/**
1013-
* SHA-256 hash of metadata-key
1014-
*/
1015-
@Suppress("MagicNumber")
1016-
fun hashMetadataKey(metadataKey: ByteArray): String {
1017-
val bytes = MessageDigest
1018-
.getInstance("SHA-256")
1019-
.digest(metadataKey)
1020-
1021-
return BigInteger(1, bytes).toString(16).padStart(32, '0')
1022-
}
1013+
fun hashMetadataKey(metadataKey: ByteArray): String = MessageDigest
1014+
.getInstance("SHA-256")
1015+
.digest(metadataKey)
1016+
.joinToString("") { "%02x".format(it) }
10231017

10241018
fun getMessageSignature(cert: String, privateKey: String, metadataFile: EncryptedFolderMetadataFile): String =
10251019
getMessageSignature(

app/src/main/java/com/owncloud/android/utils/crypto/CryptoHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object CryptoHelper {
3434

3535
private const val TRANSFORMATION = "AES/GCM/NoPadding"
3636
private const val GCM_TAG_LENGTH = 16
37-
private const val IV_LENGTH = 16
37+
private const val IV_LENGTH = 12
3838
private const val SALT_LENGTH = 40
3939
private const val GCM_TLEN = GCM_TAG_LENGTH * 8
4040
private val charset = StandardCharsets.UTF_8

gradle/verification-metadata.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21550,6 +21550,14 @@
2155021550
<sha256 value="b4494fe2a8ed059abec25448f98a65e0d1850876a0091e6645607423fb68d9c5" origin="Generated by Gradle" reason="Artifact is not signed"/>
2155121551
</artifact>
2155221552
</component>
21553+
<component group="com.github.nextcloud" name="android-library" version="9ec469f0cd">
21554+
<artifact name="android-library-9ec469f0cd.aar">
21555+
<sha256 value="deb6208d5664330a940cb6058c9160f4ae810a7385824b954555fed5e15be292" origin="Generated by Gradle" reason="Artifact is not signed"/>
21556+
</artifact>
21557+
<artifact name="android-library-9ec469f0cd.module">
21558+
<sha256 value="40b856a550a4d26cf9bfda6e9ac9a5f117388de5cd7519329e7b5ff64eda8d0c" origin="Generated by Gradle" reason="Artifact is not signed"/>
21559+
</artifact>
21560+
</component>
2155321561
<component group="com.github.nextcloud" name="android-library" version="9fdcd0af0ff910086281f32e3b8ef74490671149">
2155421562
<artifact name="android-library-9fdcd0af0ff910086281f32e3b8ef74490671149.aar">
2155521563
<sha256 value="57ab4fd7c922875a7e0b5feac20aa27ab5df0fd3b4e042f92ed727c0b6316e81" origin="Generated by Gradle" reason="Artifact is not signed"/>

0 commit comments

Comments
 (0)