Skip to content

Commit 0f71ff1

Browse files
daniele-verduccialperozturk96
authored andcommitted
Better fix subfolders in encrypted folders (using existing metadata retrieval function)
Signed-off-by: daniele-verducci <daniele.verducci@nextcloud.com>
1 parent c725437 commit 0f71ff1

1 file changed

Lines changed: 27 additions & 40 deletions

File tree

app/src/main/java/com/nextcloud/utils/e2ee/E2EEKeyInspector.kt

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,18 @@ import com.owncloud.android.datamodel.ArbitraryDataProvider
1414
import com.owncloud.android.datamodel.FileDataStorageManager
1515
import com.owncloud.android.datamodel.OCFile
1616
import com.owncloud.android.datamodel.e2e.v1.encrypted.EncryptedFolderMetadataFileV1
17-
import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFolderMetadataFile
1817
import com.owncloud.android.lib.common.OwnCloudClient
1918
import com.owncloud.android.lib.common.OwnCloudClientFactory
2019
import com.owncloud.android.lib.common.utils.Log_OC
2120
import com.owncloud.android.lib.resources.e2ee.GetMetadataRemoteOperation
22-
import com.owncloud.android.lib.resources.e2ee.MetadataResponse
2321
import com.owncloud.android.lib.resources.status.OCCapability
2422
import com.owncloud.android.lib.resources.users.GetPublicKeyRemoteOperation
2523
import com.owncloud.android.lib.resources.users.GetServerPublicKeyRemoteOperation
2624
import com.owncloud.android.operations.GetCapabilitiesOperation
2725
import com.owncloud.android.ui.dialog.setupEncryption.CertificateValidator
2826
import com.owncloud.android.ui.dialog.setupEncryption.model.DownloadKeyResult
2927
import com.owncloud.android.utils.EncryptionUtils
28+
import com.owncloud.android.utils.EncryptionUtilsV2
3029
import kotlinx.coroutines.Dispatchers
3130
import kotlinx.coroutines.withContext
3231
import org.apache.commons.httpclient.HttpStatus
@@ -89,66 +88,54 @@ class E2EEKeyInspector @Inject constructor(
8988
Log_OC.d(TAG, "checking folder metadata key")
9089

9190
val client = OwnCloudClientFactory.createOwnCloudClient(accountManager.currentAccount, context)
91+
val metadataResult = GetMetadataRemoteOperation(folder.localId).execute(client)
92+
93+
if (!metadataResult.isSuccess) {
94+
return@withContext false
95+
}
9296

9397
val privateKey = arbitraryDataProvider.getValue(accountManager.user, EncryptionUtils.PRIVATE_KEY)
9498
if (privateKey.isEmpty()) {
9599
Log_OC.e(TAG, "user try to decrypt folder with empty private key")
96100
return@withContext false
97101
}
98102

103+
val metadata = metadataResult.resultData
104+
99105
return@withContext if (E2EVersionHelper.isV2Plus(capability)) {
100-
decryptsMetadataV2(client, privateKey, folder)
106+
decryptsMetadataV2(folder, privateKey, client)
101107
} else {
102-
decryptsMetadataV1(client, privateKey, folder)
108+
decryptsMetadataV1(metadata.metadata, privateKey, folder.localId)
103109
}
104110
}
105111

106-
private fun obtainMetadata(client: OwnCloudClient, folder: OCFile): MetadataResponse? {
107-
val metadataResult = GetMetadataRemoteOperation(folder.localId).execute(client)
108-
109-
if (!metadataResult.isSuccess) {
110-
return null
111-
}
112-
113-
return metadataResult.resultData
114-
}
115-
116-
private fun getNearestEncryptedMetadataKey(client: OwnCloudClient, folder: OCFile): String? {
117-
val metadata = obtainMetadata(client, folder) ?: return null
118-
val metadataFile = EncryptionUtils.deserializeJSON(
119-
metadata.metadata,
120-
object : TypeToken<EncryptedFolderMetadataFile>() {}
112+
private fun decryptsMetadataV2(ocFile: OCFile, privateKey: String, client: OwnCloudClient): Boolean {
113+
val userId = client.userId
114+
val metadata = EncryptionUtilsV2().retrieveTopMostMetadata(
115+
ocFile,
116+
storageManager,
117+
client,
118+
userId,
119+
privateKey,
120+
accountManager.user,
121+
context,
122+
arbitraryDataProvider
121123
)
122-
123-
val user = metadataFile.users?.find { it.userId == client.userId }
124-
if (user != null) {
125-
return user.encryptedMetadataKey
126-
}
127-
128-
val parentFolder = storageManager.getFileById(folder.parentId)
129-
if (parentFolder?.isEncrypted == true) {
130-
return getNearestEncryptedMetadataKey(client, parentFolder)
131-
}
132-
133-
return null
134-
}
135-
136-
private fun decryptsMetadataV2(client: OwnCloudClient, privateKey: String, folder: OCFile): Boolean {
137-
val encryptedMetadataKey = getNearestEncryptedMetadataKey(client, folder) ?: return false
124+
val user = metadata.users.find { it.userId == userId }
125+
?: throw IllegalStateException("cannot find current user in metadata")
138126

139127
return try {
140-
EncryptionUtils.decryptStringAsymmetricV2(encryptedMetadataKey, privateKey)
128+
EncryptionUtils.decryptStringAsymmetricV2(user.decryptedMetadataKey, privateKey)
141129
true
142130
} catch (e: Exception) {
143131
Log_OC.w(TAG, "user tried to decrypt folder's metadata with different private key: $e")
144132
false
145133
}
146134
}
147135

148-
private fun decryptsMetadataV1(client: OwnCloudClient, privateKey: String, folder: OCFile): Boolean {
149-
val metadata = obtainMetadata(client, folder) ?: return false
136+
private fun decryptsMetadataV1(serializedMetadata: String, privateKey: String, folderLocalId: Long): Boolean {
150137
val metadataFile = EncryptionUtils.deserializeJSON(
151-
metadata.metadata,
138+
serializedMetadata,
152139
object : TypeToken<EncryptedFolderMetadataFileV1?>() {}
153140
)
154141

@@ -158,7 +145,7 @@ class E2EEKeyInspector @Inject constructor(
158145
privateKey,
159146
arbitraryDataProvider,
160147
accountManager.user,
161-
folder.localId
148+
folderLocalId
162149
)
163150
true
164151
} catch (e: Exception) {

0 commit comments

Comments
 (0)