Răsfoiți Sursa

E2ee step2 (#2575)

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* markFolderE2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* markFolderE2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* upload e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* upload e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* upload e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* rename e2ee

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix code

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix code

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* fix delete

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improvements

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* create folder

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* create folder

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* improved code

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* lint

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* coding

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* coding

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add debug

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* add debug

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

* build 3

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>

---------

Signed-off-by: Marino Faggiana <marino@marinofaggiana.com>
Marino Faggiana 1 an în urmă
părinte
comite
536e2840df

+ 1 - 1
Brand/Database.swift

@@ -26,4 +26,4 @@ import Foundation
 // Database Realm
 //
 let databaseName                    = "nextcloud.realm"
-let databaseSchemaVersion: UInt64   = 307
+let databaseSchemaVersion: UInt64   = 311

+ 8 - 2
Nextcloud.xcodeproj/project.pbxproj

@@ -537,6 +537,8 @@
 		F79EC78926316AC4004E59D6 /* NCPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F702F30725EE5D47008F8E80 /* NCPopupViewController.swift */; };
 		F79EDAA326B004980007D134 /* NCPlayerToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79EDA9F26B004980007D134 /* NCPlayerToolBar.swift */; };
 		F79EDAA526B004980007D134 /* NCPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79EDAA126B004980007D134 /* NCPlayer.swift */; };
+		F79FFB262A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */; };
+		F79FFB272A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */; };
 		F7A0D1352591FBC5008F8A13 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; };
 		F7A0D1362591FBC5008F8A13 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; };
 		F7A0D1372591FBC5008F8A13 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extension.swift */; };
@@ -1159,6 +1161,7 @@
 		F79BCEEA270B49C800B5B71F /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
 		F79EDA9F26B004980007D134 /* NCPlayerToolBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPlayerToolBar.swift; sourceTree = "<group>"; };
 		F79EDAA126B004980007D134 /* NCPlayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCPlayer.swift; sourceTree = "<group>"; };
+		F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EEMarkFolder.swift; sourceTree = "<group>"; };
 		F7A0D1342591FBC5008F8A13 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
 		F7A321AB1E9E6AD50069AD1B /* CCAdvanced.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAdvanced.h; sourceTree = "<group>"; };
 		F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCAdvanced.m; sourceTree = "<group>"; };
@@ -2280,6 +2283,7 @@
 				F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */,
 				F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */,
 				F7C30DF9291BCF790017149B /* NCNetworkingE2EECreateFolder.swift */,
+				F79FFB252A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift */,
 				F7C30DFC291BD0B80017149B /* NCNetworkingE2EEDelete.swift */,
 				F7C30DFF291BD2610017149B /* NCNetworkingE2EERename.swift */,
 				F7C30DF5291BC0CA0017149B /* NCNetworkingE2EEUpload.swift */,
@@ -3486,6 +3490,7 @@
 				F7D57C8B26317BDE00DE301D /* NCAccountRequest.swift in Sources */,
 				F7C30DF7291BC0D30017149B /* NCNetworkingE2EEUpload.swift in Sources */,
 				F78A10C229322E8A008499B8 /* NCManageDatabase+Directory.swift in Sources */,
+				F79FFB272A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */,
 				F7D68FCE28CB9051009139F3 /* NCManageDatabase+DashboardWidget.swift in Sources */,
 				AF22B217277D196700DAB0CC /* NCShareExtension+DataSource.swift in Sources */,
 				F76D364728A4F8BF00214537 /* NCActivityIndicator.swift in Sources */,
@@ -3801,6 +3806,7 @@
 				F7864ACC2A78FE73004870E0 /* NCManageDatabase+LocalFile.swift in Sources */,
 				F7F4F11027ECDC4A008676F9 /* UIDevice+Extension.swift in Sources */,
 				F77B0ED11D118A16002130FE /* Acknowledgements.m in Sources */,
+				F79FFB262A97C24A0055EEA4 /* NCNetworkingE2EEMarkFolder.swift in Sources */,
 				F70D8D8124A4A9BF000A5756 /* NCNetworkingProcessUpload.swift in Sources */,
 				F7D96FCC246ED7E200536D73 /* NCNetworkingCheckRemoteUser.swift in Sources */,
 				F7E4D9C422ED929B003675FD /* NCShareCommentsCell.swift in Sources */,
@@ -4661,7 +4667,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 3;
 				DEBUG_INFORMATION_FORMAT = dwarf;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -4726,7 +4732,7 @@
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				COPY_PHASE_STRIP = NO;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 3;
 				DEVELOPMENT_TEAM = NKUJUXUJ3B;
 				ENABLE_STRICT_OBJC_MSGSEND = YES;
 				ENABLE_TESTABILITY = YES;

+ 1 - 1
iOSClient/AppDelegate.swift

@@ -313,7 +313,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         NCPushNotification.shared().pushNotification()
 
         // Unlock E2EE
-        NCNetworkingE2EE.shared.unlockAll(account: account)
+        NCNetworkingE2EE().unlockAll(account: account)
 
         // Start services
         NCService.shared.startRequestServicesServer()

+ 44 - 26
iOSClient/Data/NCManageDatabase+E2EE.swift

@@ -80,7 +80,6 @@ class tableE2eMetadataV2: Object {
 
     @Persisted(primaryKey: true) var primaryKey = ""
     @Persisted var account = ""
-    @Persisted var counter: Int = 0
     @Persisted var deleted: Bool = false
     @Persisted var folders = Map<String, String>()
     @Persisted var keyChecksums = List<String>()
@@ -96,6 +95,22 @@ class tableE2eMetadataV2: Object {
      }
 }
 
+class tableE2eCounterV2: Object {
+
+    @Persisted(primaryKey: true) var primaryKey: String
+    @Persisted var account: String
+    @Persisted var counter: Int
+    @Persisted var ocIdServerUrl: String
+
+    convenience init(account: String, ocIdServerUrl: String, counter: Int) {
+        self.init()
+        self.account = account
+        self.ocIdServerUrl = ocIdServerUrl
+        self.primaryKey = account + ocIdServerUrl
+        self.counter = counter
+     }
+}
+
 class tableE2eUsersV2: Object {
 
     @Persisted(primaryKey: true) var primaryKey = ""
@@ -381,30 +396,7 @@ extension NCManageDatabase {
         return nil
     }
 
-    func incrementCounterE2eMetadataV2(account: String, serverUrl: String, ocIdServerUrl: String, version: String) -> tableE2eMetadataV2? {
-
-        do {
-            let realm = try Realm()
-            try realm.write {
-                if let result = realm.objects(tableE2eMetadataV2.self).filter("account == %@ && ocIdServerUrl == %@", account, ocIdServerUrl).first {
-                    result.counter += 1
-                } else {
-                    let object = tableE2eMetadataV2.init(account: account, ocIdServerUrl: ocIdServerUrl)
-                    object.serverUrl = serverUrl
-                    object.counter = 1
-                    object.version = version
-                    realm.add(object, update: .all)
-                }
-            }
-            return realm.objects(tableE2eMetadataV2.self).filter("account == %@ && ocIdServerUrl == %@", account, ocIdServerUrl).first
-        } catch let error {
-            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
-        }
-
-        return nil
-    }
-
-    func addE2eMetadataV2(account: String, serverUrl: String, ocIdServerUrl: String, keyChecksums: [String]?, deleted: Bool, counter: Int, folders: [String: String]?, version: String) {
+    func addE2eMetadataV2(account: String, serverUrl: String, ocIdServerUrl: String, keyChecksums: [String]?, deleted: Bool, folders: [String: String]?, version: String) {
 
         do {
             let realm = try Realm()
@@ -414,7 +406,6 @@ extension NCManageDatabase {
                     object.keyChecksums.append(objectsIn: keyChecksums)
                 }
                 object.deleted = deleted
-                object.counter = counter
                 let foldersDictionary = object.folders
                 if let folders {
                     for folder in folders {
@@ -429,4 +420,31 @@ extension NCManageDatabase {
             NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
         }
     }
+
+    func updateCounterE2eMetadataV2(account: String, ocIdServerUrl: String, counter: Int) {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            try realm.write {
+                let object = tableE2eCounterV2.init(account: account, ocIdServerUrl: ocIdServerUrl, counter: counter)
+                realm.add(object, update: .all)
+            }
+        } catch let error {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not write to database: \(error)")
+        }
+    }
+
+    func getCounterE2eMetadataV2(account: String, ocIdServerUrl: String) -> Int? {
+
+        do {
+            let realm = try Realm()
+            realm.refresh()
+            return realm.objects(tableE2eCounterV2.self).filter("account == %@ && ocIdServerUrl == %@", account, ocIdServerUrl).first?.counter
+        } catch let error as NSError {
+            NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
+        }
+
+        return nil
+    }
 }

+ 3 - 0
iOSClient/Data/NCManageDatabase.swift

@@ -34,6 +34,8 @@ class NCManageDatabase: NSObject {
         return instance
     }()
 
+    let serialQueue = DispatchQueue(label: "realmSerialQueue")
+
     override init() {
 
         let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroups)
@@ -207,6 +209,7 @@ class NCManageDatabase: NSObject {
         self.clearTable(tableE2eMetadata.self, account: account)
         self.clearTable(tableE2eMetadataV2.self, account: account)
         self.clearTable(tableE2eUsersV2.self, account: account)
+        self.clearTable(tableE2eCounterV2.self, account: account)
         self.clearTable(tableExternalSites.self, account: account)
         self.clearTable(tableGPS.self, account: nil)
         self.clearTable(TableGroupfolders.self, account: account)

+ 9 - 3
iOSClient/Extensions/UIAlertController+Extension.swift

@@ -38,9 +38,15 @@ extension UIAlertController {
             guard let fileNameFolder = alertController.textFields?.first?.text else { return }
             if markE2ee {
                 Task {
-                    let error = await NCNetworkingE2EECreateFolder.shared.createFolderAndMarkE2EE(fileName: fileNameFolder, serverUrl: serverUrl, account: urlBase.account, userId: urlBase.userId, createFolder: true)
-                    if error != .success {
-                        NCContentPresenter.shared.showError(error: error)
+
+                    let createFolderResults = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrl + "/" + fileNameFolder)
+                    if createFolderResults.error == .success {
+                        let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: urlBase.account, fileName: fileNameFolder, serverUrl: serverUrl, userId: urlBase.userId, withPush: true)
+                        if error != .success {
+                            NCContentPresenter.shared.showError(error: error)
+                        }
+                    } else {
+                        NCContentPresenter.shared.showError(error: createFolderResults.error)
                     }
                 }
             } else {

+ 4 - 6
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -413,13 +413,10 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
               serverUrl == self.serverUrl,
               let account = userInfo["account"] as? String,
               account == appDelegate.account,
-              let e2ee = userInfo["e2ee"] as? Bool,
               let withPush = userInfo["withPush"] as? Bool
         else { return }
 
-        if e2ee {
-            reloadDataSourceNetwork(isForced: true)
-        } else if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
+        if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) {
             reloadDataSource()
             if withPush {
                 pushMetadata(metadata)
@@ -1060,7 +1057,8 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
             if let metadataFolder = metadataFolder {
                 tableDirectory = NCManageDatabase.shared.setDirectory(serverUrl: self.serverUrl, richWorkspace: metadataFolder.richWorkspace, account: account)
             }
-            if isForced || tableDirectory?.etag != metadataFolder?.etag || metadataFolder?.e2eEncrypted ?? false {
+
+            if isForced || tableDirectory?.etag != metadataFolder?.etag || metadataFolder?.e2eEncrypted ?? true {
                 NCNetworking.shared.readFolder(serverUrl: self.serverUrl, account: self.appDelegate.account) { _, metadataFolder, metadatas, metadatasUpdate, _, metadatasDelete, error in
                     guard error == .success else {
                         completion(tableDirectory, nil, nil, nil, error)
@@ -1071,7 +1069,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
                     if let metadataFolder = metadataFolder, metadataFolder.e2eEncrypted, CCUtility.isEnd(toEndEnabled: self.appDelegate.account) {
                         NextcloudKit.shared.getE2EEMetadata(fileId: metadataFolder.ocId, e2eToken: nil) { _, e2eMetadata, signature, _, error in
                             if error == .success, let e2eMetadata = e2eMetadata {
-                                let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: signature, serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, ownerId: metadataFolder.ownerId)
+                                let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: signature, serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
                                 if error == .success {
                                     self.reloadDataSource()
                                 } else {

+ 2 - 2
iOSClient/Menu/NCCollectionViewCommon+Menu.swift

@@ -145,7 +145,7 @@ extension NCCollectionViewCommon {
         }
 
         //
-        // SET FOLDER E2EE -- IF > (ONLY ROOT) metadata.serverUrl == serverUrlHome,
+        // SET FOLDER E2EE
         //
         if metadata.isDirectoySettableE2EE {
             actions.append(
@@ -155,7 +155,7 @@ extension NCCollectionViewCommon {
                     order: 30,
                     action: { _ in
                         Task {
-                            let error = await NCNetworkingE2EECreateFolder.shared.createFolderAndMarkE2EE(fileName: metadata.fileName, serverUrl: metadata.serverUrl, account: metadata.account, userId: metadata.userId, createFolder: false)
+                            let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: metadata.account, fileName: metadata.fileName, serverUrl: metadata.serverUrl, userId: metadata.userId, withPush: false)
                             if error != .success {
                                 NCContentPresenter.shared.showError(error: error)
                             }

+ 1 - 1
iOSClient/Menu/NCShare+Menu.swift

@@ -65,7 +65,7 @@ extension NCShare {
                     Task {
                         if let metadata = self.metadata, metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
                             let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-                            let error = await NCNetworkingE2EE.shared.uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: nil, removeUserId: share.shareWith)
+                            let error = await NCNetworkingE2EE().uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: nil, removeUserId: share.shareWith)
                             if error != .success {
                                 NCContentPresenter.shared.showError(error: error)
                                 return

+ 4 - 1
iOSClient/NCGlobal.swift

@@ -236,6 +236,9 @@ class NCGlobal: NSObject {
     @objc let errorE2EELock: Int                    = -98008
     @objc let errorE2EEEncryptFile: Int             = -98009
     @objc let errorE2EEEncryptPayloadFile: Int      = -98010
+    @objc let errorE2EECounter: Int                 = -98011
+    @objc let errorE2EEGenerateKey: Int             = -98012
+    @objc let errorE2EEEncodedKey: Int              = -98013
 
     // Constants to identify the different permissions of a file
     //
@@ -357,7 +360,7 @@ class NCGlobal: NSObject {
 
     let notificationCenterProgressTask                          = "progressTask"                    // userInfo: account, ocId, serverUrl, status, chunk, e2eEncrypted, progress, totalBytes, totalBytesExpected
 
-    let notificationCenterCreateFolder                          = "createFolder"                    // userInfo: ocId, serverUrl, account, e2ee, withPush
+    let notificationCenterCreateFolder                          = "createFolder"                    // userInfo: ocId, serverUrl, account, withPush
     let notificationCenterDeleteFile                            = "deleteFile"                      // userInfo: [ocId], [indexPath], onlyLocalCache, error, hud?
     let notificationCenterMoveFile                              = "moveFile"                        // userInfo: [ocId], [indexPath], error, hud?
     let notificationCenterCopyFile                              = "copyFile"                        // userInfo: [ocId], [indexPath], error, hud?

+ 3 - 3
iOSClient/Networking/E2EE/NCEndToEndEncryption.m

@@ -1170,7 +1170,7 @@
     if (contentInfo == nil)
         return nil;
 
-    CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
+    // DEBUG CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
     PEM_write_bio_CMS(printBIO, contentInfo);
 
     BIO *i2dCmsBioOut = BIO_new(BIO_s_mem());
@@ -1204,7 +1204,7 @@
     BIO *publicKeyBIO = BIO_new_mem_buf(publicKeyUTF8, -1);
     EVP_PKEY *pkey = PEM_read_bio_PUBKEY(publicKeyBIO, NULL, NULL, NULL);
 
-    CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
+    // DEBUG CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
 
     BOOL verifyResult = CMS_verify(contentInfo, NULL, NULL, dataBIO, NULL, CMS_DETACHED | CMS_NO_SIGNER_CERT_VERIFY);
 
@@ -1256,7 +1256,7 @@
     BIO *cmsBIO = BIO_new_mem_buf(cmsContent.bytes, (int)cmsContent.length);
 
     CMS_ContentInfo *contentInfo = d2i_CMS_bio(cmsBIO, NULL);
-    CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
+    // DEBUG CMS_ContentInfo_print_ctx(printBIO, contentInfo, 0, NULL);
 
     BOOL verifyResult = CMS_verify(contentInfo, NULL, NULL, dataBIO, NULL, CMS_DETACHED | CMS_NO_SIGNER_CERT_VERIFY);
 

+ 8 - 8
iOSClient/Networking/E2EE/NCEndToEndMetadata.swift

@@ -30,10 +30,10 @@ class NCEndToEndMetadata: NSObject {
     // MARK: Encode JSON Metadata Bridge
     // --------------------------------------------------------------------------------------------
 
-    func encodeMetadata(account: String, serverUrl: String, userId: String, addUserId: String? = nil, addCertificate: String? = nil, removeUserId: String? = nil) -> (metadata: String?, signature: String?, error: NKError) {
+    func encodeMetadata(account: String, serverUrl: String, userId: String, addUserId: String? = nil, addCertificate: String? = nil, removeUserId: String? = nil) -> (metadata: String?, signature: String?, counter: Int, error: NKError) {
 
         guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
+            return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
         }
 
         if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV12 && NCGlobal.shared.e2eeVersions.contains(NCGlobal.shared.e2eeVersionV12) {
@@ -41,7 +41,7 @@ class NCEndToEndMetadata: NSObject {
         } else if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 && NCGlobal.shared.e2eeVersions.contains(NCGlobal.shared.e2eeVersionV20) {
             return encodeMetadataV20(account: account, serverUrl: serverUrl, ocIdServerUrl: directory.ocId, userId: userId, addUserId: addUserId, addCertificate: addCertificate, removeUserId: removeUserId)
         } else {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEVersion, errorDescription: "Server E2EE version " + NCGlobal.shared.capabilityE2EEApiVersion + ", not compatible"))
+            return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEVersion, errorDescription: "Server E2EE version " + NCGlobal.shared.capabilityE2EEApiVersion + ", not compatible"))
         }
     }
 
@@ -49,20 +49,20 @@ class NCEndToEndMetadata: NSObject {
     // MARK: Decode JSON Metadata Bridge
     // --------------------------------------------------------------------------------------------
 
-    func decodeMetadata(_ json: String, signature: String?, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+    func decodeMetadata(_ metadata: String, signature: String?, serverUrl: String, account: String, urlBase: String, userId: String) -> NKError {
 
-        guard let data = json.data(using: .utf8), let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
+        guard let data = metadata.data(using: .utf8), let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
             return (NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: "_e2e_error_"))
         }
 
         data.printJson()
 
         if (try? JSONDecoder().decode(E2eeV1.self, from: data)) != nil && NCGlobal.shared.e2eeVersions.contains(NCGlobal.shared.e2eeVersionV11) {
-            return decodeMetadataV1(json, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId)
+            return decodeMetadataV1(metadata, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId)
         } else if (try? JSONDecoder().decode(E2eeV12.self, from: data)) != nil && NCGlobal.shared.e2eeVersions.contains(NCGlobal.shared.e2eeVersionV12) {
-            return decodeMetadataV12(json, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId, ownerId: ownerId)
+            return decodeMetadataV12(metadata, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId)
         } else if (try? JSONDecoder().decode(E2eeV20.self, from: data)) != nil && NCGlobal.shared.e2eeVersions.contains(NCGlobal.shared.e2eeVersionV20) {
-            return decodeMetadataV20(json, signature: signature, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId, ownerId: ownerId)
+            return decodeMetadataV20(metadata, signature: signature, serverUrl: serverUrl, account: account, ocIdServerUrl: directory.ocId, urlBase: urlBase, userId: userId)
         } else {
             return NKError(errorCode: NCGlobal.shared.errorE2EEVersion, errorDescription: "Server E2EE version " + NCGlobal.shared.capabilityE2EEApiVersion + ", not compatible")
         }

+ 6 - 6
iOSClient/Networking/E2EE/NCEndToEndMetadataV1.swift

@@ -86,7 +86,7 @@ extension NCEndToEndMetadata {
     // MARK: Ecode JSON Metadata V1.2
     // --------------------------------------------------------------------------------------------
 
-    func encodeMetadataV12(account: String, serverUrl: String, ocIdServerUrl: String) -> (metadata: String?, signature: String?, error: NKError) {
+    func encodeMetadataV12(account: String, serverUrl: String, ocIdServerUrl: String) -> (metadata: String?, signature: String?, counter: Int, error: NKError) {
 
         let encoder = JSONEncoder()
         var metadataKey: String = ""
@@ -133,7 +133,7 @@ extension NCEndToEndMetadata {
                     }
                     fileNameIdentifiers.append(e2eEncryption.fileNameIdentifier)
                 } catch let error {
-                    return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
+                    return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
                 }
             }
 
@@ -160,7 +160,7 @@ extension NCEndToEndMetadata {
                         filedrop.updateValue(record, forKey: e2eEncryption.fileNameIdentifier)
                     }
                 } catch let error {
-                    return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
+                    return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
                 }
             }
         }
@@ -183,9 +183,9 @@ extension NCEndToEndMetadata {
             if NCManageDatabase.shared.getE2eMetadata(account: account, serverUrl: serverUrl) == nil {
                 NCManageDatabase.shared.setE2eMetadata(account: account, serverUrl: serverUrl, metadataKey: metadataKey, version: metadataVersion)
             }
-            return (jsonString, nil, NKError())
+            return (jsonString, nil, 0, NKError())
         } catch let error {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
+            return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
         }
     }
 
@@ -193,7 +193,7 @@ extension NCEndToEndMetadata {
     // MARK: Decode JSON Metadata V1.2
     // --------------------------------------------------------------------------------------------
 
-    func decodeMetadataV12(_ json: String, serverUrl: String, account: String, ocIdServerUrl: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+    func decodeMetadataV12(_ json: String, serverUrl: String, account: String, ocIdServerUrl: String, urlBase: String, userId: String) -> NKError {
 
         guard let data = json.data(using: .utf8) else {
             return NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: "_e2e_error_")

+ 75 - 48
iOSClient/Networking/E2EE/NCEndToEndMetadataV20.swift

@@ -99,11 +99,11 @@ extension NCEndToEndMetadata {
     // MARK: Ecode JSON Metadata V2.0
     // --------------------------------------------------------------------------------------------
 
-    func encodeMetadataV20(account: String, serverUrl: String, ocIdServerUrl: String, userId: String, addUserId: String?, addCertificate: String?, removeUserId: String?) -> (metadata: String?, signature: String?, error: NKError) {
+    func encodeMetadataV20(account: String, serverUrl: String, ocIdServerUrl: String, userId: String, addUserId: String?, addCertificate: String?, removeUserId: String?) -> (metadata: String?, signature: String?, counter: Int, error: NKError) {
 
         guard let keyGenerated = NCEndToEndEncryption.sharedManager()?.generateKey() as? Data,
               let directoryTop = NCUtility.shared.getDirectoryE2EETop(serverUrl: serverUrl, account: account) else {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
+            return (nil, nil, 0, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
         }
 
         let isDirectoryTop = NCUtility.shared.isDirectoryE2EETop(account: account, serverUrl: serverUrl)
@@ -112,6 +112,7 @@ extension NCEndToEndMetadata {
         var usersCodable: [E2eeV20.Users] = []
         var filedropCodable: [String: E2eeV20.Filedrop] = [:]
         var folders: [String: String] = [:]
+        var counter: Int = 1
 
         func addUser(userId: String?, certificate: String?) {
 
@@ -158,8 +159,8 @@ extension NCEndToEndMetadata {
             }
         }
 
-        guard let e2eMetadataV2 = NCManageDatabase.shared.incrementCounterE2eMetadataV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, version: NCGlobal.shared.e2eeVersionV20) else {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_"))
+        if let resultCounter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl) {
+            counter = resultCounter + 1
         }
 
         // Create ciphertext
@@ -175,7 +176,7 @@ extension NCEndToEndMetadata {
             }
         }
 
-        let ciphertext = E2eeV20.ciphertext(counter: e2eMetadataV2.counter, deleted: false, keyChecksums: keyChecksums, files: filesCodable, folders: folders)
+        let ciphertext = E2eeV20.ciphertext(counter: counter, deleted: false, keyChecksums: keyChecksums, files: filesCodable, folders: folders)
         var authenticationTag: NSString?
         var initializationVector: NSString?
 
@@ -185,7 +186,7 @@ extension NCEndToEndMetadata {
             let ciphertext = NCEndToEndEncryption.sharedManager().encryptPayloadFile(jsonZip, key: metadataKey, initializationVector: &initializationVector, authenticationTag: &authenticationTag)
 
             guard var ciphertext, let initializationVector = initializationVector as? String, let authenticationTag = authenticationTag as? String else {
-                return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEEncryptPayloadFile, errorDescription: "_e2e_error_"))
+                return (nil, nil, counter, NKError(errorCode: NCGlobal.shared.errorE2EEEncryptPayloadFile, errorDescription: "_e2e_error_"))
             }
 
             // Add initializationVector [ANDROID]
@@ -198,10 +199,11 @@ extension NCEndToEndMetadata {
 
             let e2eeJson = String(data: e2eeData, encoding: .utf8)
             let signature = createSignature(account: account, userId: userId, metadata: metadataCodable, users: usersCodable, version: NCGlobal.shared.e2eeVersionV20, certificate: CCUtility.getEndToEndCertificate(account))
-            return (e2eeJson, signature, NKError())
+
+            return (e2eeJson, signature, counter, NKError())
 
         } catch let error {
-            return (nil, nil, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
+            return (nil, nil, counter, NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription))
         }
     }
 
@@ -209,7 +211,7 @@ extension NCEndToEndMetadata {
     // MARK: Decode JSON Metadata V2.0
     // --------------------------------------------------------------------------------------------
 
-    func decodeMetadataV20(_ json: String, signature: String?, serverUrl: String, account: String, ocIdServerUrl: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+    func decodeMetadataV20(_ json: String, signature: String?, serverUrl: String, account: String, ocIdServerUrl: String, urlBase: String, userId: String) -> NKError {
 
         guard let data = json.data(using: .utf8),
               let directoryTop = NCUtility.shared.getDirectoryE2EETop(serverUrl: serverUrl, account: account) else {
@@ -298,52 +300,77 @@ extension NCEndToEndMetadata {
                let decryptedMetadataKey = tableE2eUsersV2.decryptedMetadataKey {
 
                 // SIGNATURE CHECK
-                if let signature,
-                    !verifySignature(account: account, signature: signature, userId: tableE2eUsersV2.userId, metadata: metadata, users: users, version: version, certificate: tableE2eUsersV2.certificate) {
+                guard let signature,
+                      verifySignature(account: account, signature: signature, userId: tableE2eUsersV2.userId, metadata: metadata, users: users, version: version, certificate: tableE2eUsersV2.certificate) else {
                     return NKError(errorCode: NCGlobal.shared.errorE2EEKeyVerifySignature, errorDescription: "_e2e_error_")
+
                 }
 
                 // CIPHERTEXT
-                if let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag) {
-                    if decrypted.isGzipped {
-                        do {
-                            let data = try decrypted.gunzipped()
-                            if let jsonText = String(data: data, encoding: .utf8) {
-                                print(jsonText)
-                            }
-
-                            let json = try JSONDecoder().decode(E2eeV20.ciphertext.self, from: data)
-
-                            // Checksums check
-                            if let keyChecksums = json.keyChecksums,
-                                let hash = NCEndToEndEncryption.sharedManager().createSHA256(decryptedMetadataKey),
-                                !keyChecksums.contains(hash) {
-                                return NKError(errorCode: NCGlobal.shared.errorE2EEKeyChecksums, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
-                            }
-
-                            NCManageDatabase.shared.addE2eMetadataV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, keyChecksums: json.keyChecksums, deleted: json.deleted ?? false, counter: json.counter, folders: json.folders, version: version)
-
-                            if let files = json.files {
-                                for file in files {
-                                    addE2eEncryption(fileNameIdentifier: file.key, filename: file.value.filename, authenticationTag: file.value.authenticationTag, key: file.value.key, initializationVector: file.value.nonce, metadataKey: metadataKey, mimetype: file.value.mimetype, blob: "files")
-                                }
-                            }
-
-                            if let folders = json.folders {
-                                for folder in folders {
-                                    addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: metadataKey, initializationVector: metadata.nonce, metadataKey: metadataKey, mimetype: "httpd/unix-directory", blob: "folders")
-                                }
-                            }
-
-                        } catch let error {
-                            return NKError(error: error)
-                        }
-                    } else {
-                        return NKError(errorCode: NCGlobal.shared.errorE2EEKeyCiphertext, errorDescription: "_e2e_error_")
+                guard let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: metadataKey, initializationVector: metadata.nonce, authenticationTag: metadata.authenticationTag),
+                      decrypted.isGzipped else {
+                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyCiphertext, errorDescription: "_e2e_error_")
+                }
+
+                let data = try decrypted.gunzipped()
+                if let jsonText = String(data: data, encoding: .utf8) {
+                    print(jsonText)
+                }
+
+                let json = try JSONDecoder().decode(E2eeV20.ciphertext.self, from: data)
+
+                // Check "checksums"
+                guard let keyChecksums = json.keyChecksums,
+                      let hash = NCEndToEndEncryption.sharedManager().createSHA256(decryptedMetadataKey),
+                      keyChecksums.contains(hash) else {
+                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyChecksums, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+                }
+
+                print("\n\nCOUNTER -------------------------------")
+                print("Counter: \(json.counter)")
+
+                // Check "counter"
+                if let resultCounter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl) {
+                    print("Counter saved: \(resultCounter)")
+                    if json.counter > resultCounter {
+                        return NKError(errorCode: NCGlobal.shared.errorE2EECounter, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
                     }
                 } else {
-                    return NKError(errorCode: NCGlobal.shared.errorE2EEKeyCiphertext, errorDescription: "_e2e_error_")
+                    print("Counter RESET")
+                    NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl, counter: json.counter)
                 }
+
+                // Check "deleted"
+                if let deleted = json.deleted, deleted {
+                    // TODO: We need to check deleted, id yes ???
+                }
+
+                NCManageDatabase.shared.addE2eMetadataV2(account: account, serverUrl: serverUrl, ocIdServerUrl: ocIdServerUrl, keyChecksums: json.keyChecksums, deleted: json.deleted ?? false, folders: json.folders, version: version)
+
+                if let files = json.files {
+                    print("\nFILES ---------------------------------\n")
+                    for file in files {
+                        addE2eEncryption(fileNameIdentifier: file.key, filename: file.value.filename, authenticationTag: file.value.authenticationTag, key: file.value.key, initializationVector: file.value.nonce, metadataKey: metadataKey, mimetype: file.value.mimetype, blob: "files")
+
+                        print("filename: \(file.value.filename)")
+                        print("fileNameIdentifier: \(file.key)")
+                        print("mimetype: \(file.value.mimetype)")
+                        print("\n")
+                    }
+                }
+
+                if let folders = json.folders {
+                    print("FOLDERS--------------------------------\n")
+                    for folder in folders {
+                        addE2eEncryption(fileNameIdentifier: folder.key, filename: folder.value, authenticationTag: metadata.authenticationTag, key: metadataKey, initializationVector: metadata.nonce, metadataKey: metadataKey, mimetype: "httpd/unix-directory", blob: "folders")
+
+                        print("filename: \(folder.value)")
+                        print("fileNameIdentifier: \(folder.key)")
+                        print("\n")
+                    }
+                }
+
+                print("---------------------------------------\n\n")
             }
         } catch let error {
             return NKError(errorCode: NCGlobal.shared.errorE2EEJSon, errorDescription: error.localizedDescription)

+ 101 - 29
iOSClient/Networking/E2EE/NCNetworkingE2EE.swift

@@ -19,17 +19,10 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-import UIKit
-import OpenSSL
+import Foundation
 import NextcloudKit
-import CFNetwork
-import Alamofire
 
 class NCNetworkingE2EE: NSObject {
-    public static let shared: NCNetworkingE2EE = {
-        let instance = NCNetworkingE2EE()
-        return instance
-    }()
 
     func generateRandomIdentifier() -> String {
 
@@ -38,10 +31,13 @@ class NCNetworkingE2EE: NSObject {
         return UUID
     }
 
-    func uploadMetadata(account: String, serverUrl: String, userId: String, addUserId: String?, removeUserId: String?) async -> (NKError) {
+    func uploadMetadata(account: String, serverUrl: String, userId: String, addUserId: String?, removeUserId: String?) async -> NKError {
 
-        var error = NKError()
         var addCertificate: String?
+        var method = "POST"
+        guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
+        }
 
         if let addUserId {
             let results = await NextcloudKit.shared.getE2EECertificate(user: addUserId)
@@ -52,24 +48,99 @@ class NCNetworkingE2EE: NSObject {
             }
         }
 
-        let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId, addUserId: addUserId, addCertificate: addCertificate, removeUserId: removeUserId)
-        guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata, let signature = resultsEncode.signature else { return resultsEncode.error }
+        // LOCK
+        //
+        let resultsLock = await lock(account: account, serverUrl: serverUrl)
+        guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else {
+            return resultsLock.error
+        }
+
+        // METHOD
+        //
+        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
+        if resultsGetE2EEMetadata.error == .success {
+            method = "PUT"
+        } else if resultsGetE2EEMetadata.error.errorCode != NCGlobal.shared.errorResourceNotFound {
+            return resultsGetE2EEMetadata.error
+        }
+
+        // UPLOAD METADATA
+        //
+        let uploadMetadataError = await uploadMetadata(account: account,
+                                                       serverUrl: serverUrl,
+                                                       ocIdServerUrl: directory.ocId,
+                                                       fileId: fileId,
+                                                       userId: userId,
+                                                       e2eToken: e2eToken,
+                                                       method: method,
+                                                       addUserId: addUserId,
+                                                       addCertificate: addCertificate,
+                                                       removeUserId: removeUserId)
+        guard uploadMetadataError == .success else {
+            await unlock(account: account, serverUrl: serverUrl)
+            return uploadMetadataError
+        }
+
+        // UNLOCK
+        //
+        await unlock(account: account, serverUrl: serverUrl)
+
+        return NKError()
+    }
+
+    func downloadMetadata(account: String,
+                          serverUrl: String,
+                          urlBase: String,
+                          userId: String,
+                          fileId: String,
+                          e2eToken: String) async -> NKError {
+
+        let resultsGetE2EEMetadata = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
+        guard resultsGetE2EEMetadata.error == .success, let e2eMetadata = resultsGetE2EEMetadata.e2eMetadata else {
+            return resultsGetE2EEMetadata.error
+        }
+
+        let resultsDecodeMetadataError = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: resultsGetE2EEMetadata.signature, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId)
+        guard resultsDecodeMetadataError == .success else {
+            return resultsDecodeMetadataError
+        }
+
+        return NKError()
+    }
+
+    func uploadMetadata(account: String,
+                        serverUrl: String,
+                        ocIdServerUrl: String,
+                        fileId: String,
+                        userId: String,
+                        e2eToken: String,
+                        method: String,
+                        addUserId: String? = nil,
+                        addCertificate: String? = nil,
+                        removeUserId: String? = nil) async -> NKError {
+
+        let resultsEncodeMetadata = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId, addCertificate: addCertificate, removeUserId: removeUserId)
+        guard resultsEncodeMetadata.error == .success, let e2eMetadata = resultsEncodeMetadata.metadata else {
+            return resultsEncodeMetadata.error
+        }
+
+        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncodeMetadata.signature, method: method)
+        guard putE2EEMetadataResults.error == .success else {
+            return putE2EEMetadataResults.error
+        }
 
-        let results = await NCNetworkingE2EE.shared.lock(account: account, serverUrl: serverUrl)
-        error = results.error
-        if error == .success, let e2eToken = results.e2eToken, let fileId = results.fileId {
-            let results = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: signature, method: "PUT")
-            error = results.error
+        // COUNTER
+        //
+        if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
+            NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: ocIdServerUrl, counter: resultsEncodeMetadata.counter)
         }
 
-        await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
-        return error
+        return NKError()
     }
 
     func lock(account: String, serverUrl: String) async -> (fileId: String?, e2eToken: String?, error: NKError) {
 
         var e2eToken: String?
-        let e2EEApiVersion = NCGlobal.shared.capabilityE2EEApiVersion
         var e2eCounter = "0"
 
         guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
@@ -80,16 +151,17 @@ class NCNetworkingE2EE: NSObject {
             e2eToken = tableLock.e2eToken
         }
 
-        if e2EEApiVersion == NCGlobal.shared.e2eeVersionV20, let result = NCManageDatabase.shared.getE2eMetadataV2(account: account, ocIdServerUrl: directory.ocId) {
-            e2eCounter = "\(result.counter)"
+        if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20, var counter = NCManageDatabase.shared.getCounterE2eMetadataV2(account: account, ocIdServerUrl: directory.ocId) {
+            counter += 1
+            e2eCounter = "\(counter)"
         }
 
-        let lockE2EEFolderResults = await NextcloudKit.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: "POST")
-        if lockE2EEFolderResults.error == .success, let e2eToken = lockE2EEFolderResults.e2eToken {
+        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, e2eCounter: e2eCounter, method: "POST")
+        if resultsLockE2EEFolder.error == .success, let e2eToken = resultsLockE2EEFolder.e2eToken {
             NCManageDatabase.shared.setE2ETokenLock(account: account, serverUrl: serverUrl, fileId: directory.fileId, e2eToken: e2eToken)
         }
 
-        return (directory.fileId, lockE2EEFolderResults.e2eToken, lockE2EEFolderResults.error)
+        return (directory.fileId, resultsLockE2EEFolder.e2eToken, resultsLockE2EEFolder.error)
     }
 
     func unlock(account: String, serverUrl: String) async {
@@ -98,8 +170,8 @@ class NCNetworkingE2EE: NSObject {
             return
         }
 
-        let lockE2EEFolderResults = await NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, e2eCounter: nil, method: "DELETE")
-        if lockE2EEFolderResults.error == .success {
+        let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, e2eCounter: nil, method: "DELETE")
+        if resultsLockE2EEFolder.error == .success {
             NCManageDatabase.shared.deleteE2ETokenLock(account: account, serverUrl: serverUrl)
         }
 
@@ -111,8 +183,8 @@ class NCNetworkingE2EE: NSObject {
 
         Task {
             for result in NCManageDatabase.shared.getE2EAllTokenLock(account: account) {
-                let lockE2EEFolderResults = await NextcloudKit.shared.lockE2EEFolder(fileId: result.fileId, e2eToken: result.e2eToken, e2eCounter: nil, method: "DELETE")
-                if lockE2EEFolderResults.error == .success {
+                let resultsLockE2EEFolder = await NextcloudKit.shared.lockE2EEFolder(fileId: result.fileId, e2eToken: result.e2eToken, e2eCounter: nil, method: "DELETE")
+                if resultsLockE2EEFolder.error == .success {
                     NCManageDatabase.shared.deleteE2ETokenLock(account: account, serverUrl: result.serverUrl)
                 }
             }

+ 95 - 134
iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift

@@ -27,162 +27,123 @@ import Alamofire
 import Foundation
 
 class NCNetworkingE2EECreateFolder: NSObject {
-    public static let shared: NCNetworkingE2EECreateFolder = {
-        let instance = NCNetworkingE2EECreateFolder()
-        return instance
-    }()
 
-    func createFolderAndMarkE2EE(fileName: String, serverUrl: String, account: String, userId: String, createFolder: Bool) async -> NKError {
+    let networkingE2EE = NCNetworkingE2EE()
 
-        let serverUrlFileName = serverUrl + "/" + fileName
-        var error = NKError()
+    func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String, withPush: Bool) async -> NKError {
 
-        // CREATE FOLDER
-        if createFolder {
-            let createFolderResults = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName)
-            if createFolderResults.error != .success { return createFolderResults.error }
+        let fileNameIdentifier = networkingE2EE.generateRandomIdentifier()
+        let serverUrlFileName = serverUrl + "/" + fileNameIdentifier
+        let fileNameFolder = NCUtilityFileSystem.shared.createFileName(CCUtility.removeForbiddenCharactersServer(fileName)!, serverUrl: serverUrl, account: account)
+        if fileNameFolder.isEmpty {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
 
-        let readFileOrFolderResults = await NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0")
-        error = readFileOrFolderResults.error
-        if error == .success, let file = readFileOrFolderResults.files.first {
-
-            // MARK: AS E2EE
-            let markE2EEFolderResults = await NextcloudKit.shared.markE2EEFolder(fileId: file.fileId, delete: false)
-            if markE2EEFolderResults.error != .success { return markE2EEFolderResults.error }
-
-            file.e2eEncrypted = true
-            let isDirectoryE2EE = NCUtility.shared.isDirectoryE2EE(file: file)
-            guard let metadata = NCManageDatabase.shared.addMetadata(NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryE2EE)) else {
-                return error
-            }
-            NCManageDatabase.shared.addDirectory(encrypted: true, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
-            NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, serverUrlFileName))
-
-            // LOCK
-            let lockResults = await NCNetworkingE2EE.shared.lock(account: account, serverUrl: serverUrlFileName)
-            if lockResults.error != .success { return lockResults.error }
-
-            let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrlFileName, userId: userId)
-            guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
+        guard let directory = NCManageDatabase.shared.getTableDirectory(predicate:  NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) else {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+        }
 
-            let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: file.fileId, e2eToken: lockResults.e2eToken!, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: "POST")
-            error = putE2EEMetadataResults.error
+        func sendE2ee(e2eToken: String, fileId: String) async -> NKError {
 
-            // UNLOCK
-            await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrlFileName)
+            var key: NSString?
+            var initializationVector: NSString?
+            var method = "POST"
 
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl": serverUrl])
-        }
+            // DOWNLOAD METADATA
+            //
+            let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: account, serverUrl: serverUrl, urlBase: urlBase, userId: userId, fileId: fileId, e2eToken: e2eToken)
+            if errorDownloadMetadata == .success {
+                method = "PUT"
+            } else if errorDownloadMetadata.errorCode != NCGlobal.shared.errorResourceNotFound {
+                return errorDownloadMetadata
+            }
 
-        return error
-    }
+            NCEndToEndEncryption.sharedManager()?.encodedkey(&key, initializationVector: &initializationVector)
+            guard let key = key as? String, let initializationVector = initializationVector as? String else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEEncodedKey, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            }
 
-    func createFolder(fileName: String, serverUrl: String, account: String, urlBase: String, userId: String, withPush: Bool) async -> (NKError) {
-
-        var fileNameFolder = CCUtility.removeForbiddenCharactersServer(fileName)!
-        var serverUrlFileName = ""
-        var fileNameIdentifier = ""
-        var ocId: String?
-        var error = NKError()
-
-        fileNameFolder = NCUtilityFileSystem.shared.createFileName(fileNameFolder, serverUrl: serverUrl, account: account)
-        if fileNameFolder.isEmpty { return error }
-        fileNameIdentifier = NCNetworkingE2EE.shared.generateRandomIdentifier()
-        serverUrlFileName = serverUrl + "/" + fileNameIdentifier
-
-        // ** Lock **
-        let lockResults = await NCNetworkingE2EE.shared.lock(account: account, serverUrl: serverUrl)
-
-        error = lockResults.error
-        if error == .success, let e2eToken = lockResults.e2eToken, let fileIdLock = lockResults.fileId {
-
-            let createFolderResults = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, options: NKRequestOptions(customHeader: ["e2e-token": e2eToken]))
-            error = createFolderResults.error
-            ocId = createFolderResults.ocId
-            if error == .success, let fileId = NCUtility.shared.ocIdToFileId(ocId: ocId) {
-                // Mark folder as E2EE
-                let markE2EEFolderResults = await NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: false)
-                error = markE2EEFolderResults.error
-                if error == .success {
-                    error = await createE2Ee(e2eToken: e2eToken, fileIdLock: fileIdLock, account: account, fileNameFolder: fileNameFolder, fileNameIdentifier: fileNameIdentifier, serverUrl: serverUrl, ocIdServerUrl: ocId!, urlBase: urlBase, userId: userId)
+            let object = tableE2eEncryption.init(account: account, ocIdServerUrl: directory.ocId, fileNameIdentifier: fileNameIdentifier)
+            object.blob = "folders"
+            if let results = NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) {
+                object.metadataKey = results.metadataKey
+                object.metadataKeyIndex = results.metadataKeyIndex
+            } else {
+                guard let key = NCEndToEndEncryption.sharedManager()?.generateKey() as NSData? else {
+                    return NKError(errorCode: NCGlobal.shared.errorE2EEGenerateKey, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
                 }
+                object.metadataKey = key.base64EncodedString()
+                object.metadataKeyIndex = 0
             }
+            object.authenticationTag = ""
+            object.fileName = fileNameFolder
+            object.key = key
+            object.initializationVector = initializationVector
+            object.mimeType = "httpd/unix-directory"
+            object.serverUrl = serverUrl
+            NCManageDatabase.shared.addE2eEncryption(object)
+
+            // UPLOAD METADATA
+            //
+            let uploadMetadataError = await networkingE2EE.uploadMetadata(account: account,
+                                                                          serverUrl: serverUrl,
+                                                                          ocIdServerUrl: directory.ocId,
+                                                                          fileId: fileId,
+                                                                          userId: userId,
+                                                                          e2eToken: e2eToken,
+                                                                          method: method)
+
+            return uploadMetadataError
         }
 
-        // ** Unlock **
-        await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
-
-        if error == .success, let ocId = ocId {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": ocId, "serverUrl": serverUrl, "account": account, "e2ee": true, "withPush": withPush])
+        // LOCK
+        //
+        let resultsLock = await networkingE2EE.lock(account: account, serverUrl: serverUrl)
+        guard let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId, resultsLock.error == .success else {
+            return NKError(errorCode: NCGlobal.shared.errorE2EELock, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
-        return error
-    }
-
-    private func createE2Ee(e2eToken: String, fileIdLock: String, account: String, fileNameFolder: String, fileNameIdentifier: String, serverUrl: String, ocIdServerUrl: String, urlBase: String, userId: String) async -> (NKError) {
 
-        var key: NSString?
-        var initializationVector: NSString?
-        var method = "POST"
-
-        // Get last metadata
-        let results = await NextcloudKit.shared.getE2EEMetadata(fileId: fileIdLock, e2eToken: e2eToken)
-        if results.error == .success, let e2eMetadata = results.e2eMetadata {
-            let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: results.signature, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, ownerId: nil)
-            if error != .success { return error }
-            method = "PUT"
+        // SEND NEW METADATA
+        //
+        let sendE2eeError = await sendE2ee(e2eToken: e2eToken, fileId: fileId)
+        guard sendE2eeError == .success else {
+            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            return sendE2eeError
         }
 
-        // Add new metadata
-        NCEndToEndEncryption.sharedManager()?.encodedkey(&key, initializationVector: &initializationVector)
-
-        let object = tableE2eEncryption.init(account: account, ocIdServerUrl: ocIdServerUrl, fileNameIdentifier: fileNameIdentifier)
-        object.blob = "folders"
-        object.authenticationTag = ""
-        object.fileName = fileNameFolder
-        object.key = key! as String
-        object.initializationVector = initializationVector! as String
-        if let result = NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) {
-            object.metadataKey = result.metadataKey
-            object.metadataKeyIndex = result.metadataKeyIndex
-        } else {
-            object.metadataKey = (NCEndToEndEncryption.sharedManager()?.generateKey()?.base64EncodedString(options: []))! as String // AES_KEY_128_LENGTH
-            object.metadataKeyIndex = 0
+        // CREATE FOLDER
+        //
+        let resultsCreateFolder = await NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, options: NKRequestOptions(customHeader: ["e2e-token": e2eToken]))
+        guard resultsCreateFolder.error == .success, let ocId = resultsCreateFolder.ocId, let fileId = NCUtility.shared.ocIdToFileId(ocId: ocId) else {
+            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            return resultsCreateFolder.error
         }
-        object.mimeType = "httpd/unix-directory"
-        object.serverUrl = serverUrl
-        NCManageDatabase.shared.addE2eEncryption(object)
-
-        let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId)
-        guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
-
-        // send metadata
-        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileIdLock, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: method)
-        return putE2EEMetadataResults.error
-    }
-
-    func markE2EEFolder(account: String, serverUrl: String, fileId: String, ocId: String, userId: String) async -> (NKError) {
-
-        let markE2EEFolderResult = await NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: false)
-        if markE2EEFolderResult.error != .success { return markE2EEFolderResult.error }
 
-        NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl))
-        NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, serverUrlTo: nil, etag: nil, ocId: nil, fileId: nil, encrypted: true, richWorkspace: nil, account: account)
-        NCManageDatabase.shared.setMetadataEncrypted(ocId: ocId, encrypted: true)
-
-        // LOCK
-        let lockResults = await NCNetworkingE2EE.shared.lock(account: account, serverUrl: serverUrl)
-        if lockResults.error != .success { return lockResults.error }
-
-        let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: account, serverUrl: serverUrl, userId: userId)
-        guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
-
-        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: lockResults.e2eToken!, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: "POST")
-        let error = putE2EEMetadataResults.error
+        // MARK FOLDER AS E2EE
+        //
+        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: fileId, delete: false)
+        guard resultsMarkE2EEFolder.error == .success  else {
+            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            return resultsMarkE2EEFolder.error
+        }
 
         // UNLOCK
-        await NCNetworkingE2EE.shared.unlock(account: account, serverUrl: serverUrl)
+        //
+        await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+
+        //
+        //
+        let resultsReadFileOrFolder = await NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0")
+        guard resultsReadFileOrFolder.error == .success, let file = resultsReadFileOrFolder.files.first else {
+            await networkingE2EE.unlock(account: account, serverUrl: serverUrl)
+            return resultsReadFileOrFolder.error
+        }
+        let metadata = NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: true)
+        NCManageDatabase.shared.addMetadata(metadata)
+        NCManageDatabase.shared.addDirectory(encrypted: true, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
+
+        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": ocId, "serverUrl": serverUrl, "account": account, "withPush": withPush])
 
-        return error
+        return NKError()
     }
 }

+ 43 - 42
iOSClient/Networking/E2EE/NCNetworkingE2EEDelete.swift

@@ -19,61 +19,62 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-import UIKit
-import OpenSSL
-import NextcloudKit
-import CFNetwork
-import Alamofire
 import Foundation
+import NextcloudKit
 
 class NCNetworkingE2EEDelete: NSObject {
-    public static let shared: NCNetworkingE2EEDelete = {
-        let instance = NCNetworkingE2EEDelete()
-        return instance
-    }()
-
-    func delete(metadata: tableMetadata) async -> (NKError) {
-
-        var error = NKError()
 
-        func sendE2EMetadata(e2eToken: String, fileId: String) async -> (NKError) {
+    let networkingE2EE = NCNetworkingE2EE()
 
-            // Get last metadata
-            let results = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
-            guard results.error == .success, let e2eMetadata = results.e2eMetadata else {
-                return NKError(errorCode: NCGlobal.shared.errorE2EEKeyEncodeMetadata, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
-            }
+    func delete(metadata: tableMetadata) async -> NKError {
 
-            let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: results.signature, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if error != .success { return error }
-
-            // delete
-            NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", metadata.account, metadata.serverUrl, metadata.fileName))
+        guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
+        }
 
-            let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: metadata.account, serverUrl: metadata.serverUrl, userId: metadata.userId)
-            guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
+        // LOCK
+        //
+        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { return resultsLock.error }
 
-            // Send metadata
-            let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: "PUT")
-            return putE2EEMetadataResults.error
+        // DELETE FILE
+        //
+        let deleteMetadataPlainError = await NCNetworking.shared.deleteMetadataPlain(metadata, customHeader: ["e2e-token": e2eToken])
+        guard deleteMetadataPlainError == .success else {
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return deleteMetadataPlainError
         }
 
-        // ** Lock **
-        let lockResults = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        // DOWNLOAD METADATA
+        //
+        let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+        guard errorDownloadMetadata == .success else {
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return errorDownloadMetadata
+        }
 
-        error = lockResults.error
-        if error == .success, let e2eToken = lockResults.e2eToken, let fileId = lockResults.fileId {
+        // UPDATE DB
+        //
+        NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileNameIdentifier == %@", metadata.account, metadata.serverUrl, metadata.fileName))
 
-            let deleteMetadataPlainError = await NCNetworking.shared.deleteMetadataPlain(metadata, customHeader: ["e2e-token": e2eToken])
-            error = deleteMetadataPlainError
-            if error == .success {
-                let sendE2EMetadataError = await sendE2EMetadata(e2eToken: e2eToken, fileId: fileId)
-                error = sendE2EMetadataError
-            }
+        // UPLOAD METADATA
+        //
+        let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
+                                                                      serverUrl: metadata.serverUrl,
+                                                                      ocIdServerUrl: directory.ocId,
+                                                                      fileId: fileId,
+                                                                      userId: metadata.userId,
+                                                                      e2eToken: e2eToken,
+                                                                      method: "PUT")
+        guard uploadMetadataError == .success else {
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return uploadMetadataError
         }
 
-        // ** Unlock **
-        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
-        return error
+        // UNLOCK
+        //
+        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+
+        return NKError()
     }
 }

+ 55 - 0
iOSClient/Networking/E2EE/NCNetworkingE2EEMarkFolder.swift

@@ -0,0 +1,55 @@
+//
+//  NCNetworkingE2EEMarkFolder.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 24/08/23.
+//  Copyright © 2022 Marino Faggiana. All rights reserved.
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+import Foundation
+import NextcloudKit
+
+class NCNetworkingE2EEMarkFolder: NSObject {
+
+    func markFolderE2ee(account: String, fileName: String, serverUrl: String, userId: String, withPush: Bool) async -> NKError {
+
+        let serverUrlFileName = serverUrl + "/" + fileName
+
+        let resultsReadFileOrFolder = await NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0")
+        guard resultsReadFileOrFolder.error == .success, let file = resultsReadFileOrFolder.files.first else { return resultsReadFileOrFolder.error }
+
+        let resultsMarkE2EEFolder = await NextcloudKit.shared.markE2EEFolder(fileId: file.fileId, delete: false)
+        guard resultsMarkE2EEFolder.error == .success else { return resultsMarkE2EEFolder.error }
+
+        file.e2eEncrypted = true
+        guard let metadata = NCManageDatabase.shared.addMetadata(NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: false)) else {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
+        }
+        NCManageDatabase.shared.addDirectory(encrypted: true, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
+        NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, serverUrlFileName))
+        if NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
+            NCManageDatabase.shared.updateCounterE2eMetadataV2(account: account, ocIdServerUrl: metadata.ocId, counter: 0)
+        }
+
+        if withPush {
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId, "serverUrl": serverUrl, "account": account, "withPush": withPush])
+        } else {
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeStatusFolderE2EE, userInfo: ["serverUrl": serverUrl])
+        }
+
+        return NKError()
+    }
+}

+ 53 - 56
iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift

@@ -19,76 +19,73 @@
 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //
 
-import UIKit
-import OpenSSL
 import NextcloudKit
-import CFNetwork
-import Alamofire
 import Foundation
 
 class NCNetworkingE2EERename: NSObject {
-    public static let shared: NCNetworkingE2EERename = {
-        let instance = NCNetworkingE2EERename()
-        return instance
-    }()
 
-    func rename(metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath) async -> (NKError) {
-
-        var error = NKError()
-
-        func sendE2EMetadata(e2eToken: String, fileId: String) async -> (NKError) {
-
-            // Get last metadata
-            let results = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
-            guard results.error == .success, let e2eMetadata = results.e2eMetadata else {
-                return results.error
-            }
-
-            error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: results.signature, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if error != .success { return error }
-
-            // rename
-            NCManageDatabase.shared.renameFileE2eEncryption(account: metadata.account, serverUrl: metadata.serverUrl, fileNameIdentifier: metadata.fileName, newFileName: fileNameNew, newFileNamePath: CCUtility.returnFileNamePath(fromFileName: fileNameNew, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account))
-
-            let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: metadata.account, serverUrl: metadata.serverUrl, userId: metadata.userId)
-            guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
-
-            // send metadata
-            let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: "PUT")
-            return putE2EEMetadataResults.error
-        }
+    let networkingE2EE = NCNetworkingE2EE()
+    
+    func rename(metadata: tableMetadata, fileNameNew: String, indexPath: IndexPath) async -> NKError {
 
         // verify if exists the new fileName
         if NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, fileNameNew)) != nil {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_file_already_exists_")
         }
-
-        // ** Lock **
-        let lockResults = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
-
-        error = lockResults.error
-        if error == .success, let e2eToken = lockResults.e2eToken, let fileId = lockResults.fileId {
-
-            let sendE2EMetadataError = await sendE2EMetadata(e2eToken: e2eToken, fileId: fileId)
-            error = sendE2EMetadataError
-            if error == .success {
-                NCManageDatabase.shared.setMetadataFileNameView(serverUrl: metadata.serverUrl, fileName: metadata.fileName, newFileNameView: fileNameNew, account: metadata.account)
-                // Move file system
-                let atPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId) + "/" + metadata.fileNameView
-                let toPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId) + "/" + fileNameNew
-                do {
-                    try FileManager.default.moveItem(atPath: atPath, toPath: toPath)
-                } catch { }
-            }
+        guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
+            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: "_e2e_error_")
         }
 
-        // ** Unlock **
-        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        // LOCK
+        //
+        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        guard resultsLock.error == .success, let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId else { return resultsLock.error }
+
+        // DOWNLOAD METADATA
+        //
+        let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+        guard errorDownloadMetadata == .success else {
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return errorDownloadMetadata
+        }
 
-        if error == .success {
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "indexPath": indexPath])
+        // DB RENAME
+        //
+        NCManageDatabase.shared.renameFileE2eEncryption(account: metadata.account, serverUrl: metadata.serverUrl, fileNameIdentifier: metadata.fileName, newFileName: fileNameNew, newFileNamePath: CCUtility.returnFileNamePath(fromFileName: fileNameNew, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, account: metadata.account))
+
+
+        // UPLOAD METADATA
+        //
+        let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
+                                                                      serverUrl: metadata.serverUrl,
+                                                                      ocIdServerUrl: directory.ocId,
+                                                                      fileId: fileId,
+                                                                      userId: metadata.userId,
+                                                                      e2eToken: e2eToken,
+                                                                      method: "PUT")
+        guard uploadMetadataError == .success else {
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return uploadMetadataError
         }
 
-        return error
+        // UPDATE DB
+        //
+        NCManageDatabase.shared.setMetadataFileNameView(serverUrl: metadata.serverUrl, fileName: metadata.fileName, newFileNameView: fileNameNew, account: metadata.account)
+
+        // MOVE FILE SYSTEM
+        //
+        let atPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId) + "/" + metadata.fileNameView
+        let toPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId) + "/" + fileNameNew
+        do {
+            try FileManager.default.moveItem(atPath: atPath, toPath: toPath)
+        } catch { }
+
+        // UNLOCK
+        //
+        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        
+        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterRenameFile, userInfo: ["ocId": metadata.ocId, "account": metadata.account, "indexPath": indexPath])
+
+        return NKError()
     }
 }

+ 98 - 89
iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

@@ -37,71 +37,127 @@ extension uploadE2EEDelegate {
 }
 
 class NCNetworkingE2EEUpload: NSObject {
-    public static let shared: NCNetworkingE2EEUpload = {
-        let instance = NCNetworkingE2EEUpload()
-        return instance
-    }()
 
-    func upload(metadata: tableMetadata, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> (NKError) {
+    let networkingE2EE = NCNetworkingE2EE()
 
-        var metadata = tableMetadata.init(value: metadata)
+    func upload(metadata: tableMetadata, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> NKError {
+
+        var metadata = metadata
         let ocIdTemp = metadata.ocId
 
-        // Create metadata for upload
         if let result = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileNameView == %@ AND ocId != %@", metadata.serverUrl, metadata.fileNameView, metadata.ocId)) {
             metadata.fileName = result.fileName
         } else {
-            metadata.fileName = NCNetworkingE2EE.shared.generateRandomIdentifier()
+            metadata.fileName = networkingE2EE.generateRandomIdentifier()
         }
         metadata.session = NextcloudKit.shared.nkCommonInstance.sessionIdentifierUpload
         metadata.sessionError = ""
-        guard let result = NCManageDatabase.shared.addMetadata(metadata) else {
-            return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
-
-        }
-        guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
+        guard let result = NCManageDatabase.shared.addMetadata(metadata),
+              let directory = NCManageDatabase.shared.getTableDirectory(predicate:  NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
             return NKError(errorCode: NCGlobal.shared.errorUnexpectedResponseFromDB, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            
         }
         metadata = result
 
-        // ** Lock **
-        let lockResults = await NCNetworkingE2EE.shared.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        func sendE2ee(e2eToken: String, fileId: String) async -> NKError {
+
+            var key: NSString?, initializationVector: NSString?, authenticationTag: NSString?
+            var method = "POST"
+
+            // ENCRYPT FILE
+            //
+            if NCEndToEndEncryption.sharedManager()?.encryptFile(metadata.fileNameView, fileNameIdentifier: metadata.fileName, directory: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), key: &key, initializationVector: &initializationVector, authenticationTag: &authenticationTag) == false {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEEncryptFile, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            }
+            guard let key = key as? String, let initializationVector = initializationVector as? String else {
+                return NKError(errorCode: NCGlobal.shared.errorE2EEEncodedKey, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            }
+
+            // DOWNLOAD METADATA
+            //
+            let errorDownloadMetadata = await networkingE2EE.downloadMetadata(account: metadata.account, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId, fileId: fileId, e2eToken: e2eToken)
+            if errorDownloadMetadata == .success {
+                method = "PUT"
+            } else if errorDownloadMetadata.errorCode != NCGlobal.shared.errorResourceNotFound {
+                return errorDownloadMetadata
+            }
+
+            // CREATE E2E METADATA
+            //
+            NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, metadata.fileNameView))
+            let object = tableE2eEncryption.init(account: metadata.account, ocIdServerUrl: directory.ocId, fileNameIdentifier: metadata.fileName)
+            if let results = NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
+                object.metadataKey = results.metadataKey
+                object.metadataKeyIndex = results.metadataKeyIndex
+            } else {
+                guard let key = NCEndToEndEncryption.sharedManager()?.generateKey() as NSData? else {
+                    return NKError(errorCode: NCGlobal.shared.errorE2EEGenerateKey, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+                }
+                object.metadataKey = key.base64EncodedString()
+                object.metadataKeyIndex = 0
+            }
+            object.authenticationTag = authenticationTag! as String
+            object.fileName = metadata.fileNameView
+            object.key = key
+            object.initializationVector = initializationVector
+            object.mimeType = metadata.contentType
+            object.serverUrl = metadata.serverUrl
+            NCManageDatabase.shared.addE2eEncryption(object)
+
+            // UPLOAD METADATA
+            //
+            let uploadMetadataError = await networkingE2EE.uploadMetadata(account: metadata.account,
+                                                                          serverUrl: metadata.serverUrl,
+                                                                          ocIdServerUrl: directory.ocId,
+                                                                          fileId: fileId,
+                                                                          userId: metadata.userId,
+                                                                          e2eToken: e2eToken,
+                                                                          method: method)
+
+            return uploadMetadataError
+        }
 
-        guard let e2eToken = lockResults.e2eToken, let fileId = lockResults.fileId, lockResults.error == .success else {
+
+        // LOCK
+        //
+        let resultsLock = await networkingE2EE.lock(account: metadata.account, serverUrl: metadata.serverUrl)
+        guard let e2eToken = resultsLock.e2eToken, let fileId = resultsLock.fileId, resultsLock.error == .success else {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
             NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": NKError(errorCode: NCGlobal.shared.errorE2EELock, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))])
             return NKError(errorCode: NCGlobal.shared.errorE2EELock, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
         }
 
-        // Send e2e metadata
-        let createE2EeError = await createE2Ee(metadata: metadata, e2eToken: e2eToken, ocIdServerUrl: directory.ocId, fileId: fileId)
-        guard createE2EeError == .success else {
-            // ** Unlock **
-            await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        // SEND NEW METADATA
+        //
+        let sendE2eeError = await sendE2ee(e2eToken: e2eToken, fileId: fileId)
+        guard sendE2eeError == .success else {
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp))
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": createE2EeError])
-            return createE2EeError
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": sendE2eeError])
+            await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+            return sendE2eeError
         }
 
-        // Send file
-        let sendFileResults = await sendFile(metadata: metadata, e2eToken: e2eToken, uploadE2EEDelegate: uploadE2EEDelegate)
-
-        // ** Unlock **
-        await NCNetworkingE2EE.shared.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        // UPLOAD
+        //
+        let resultsSendFile = await sendFile(metadata: metadata, e2eToken: e2eToken, uploadE2EEDelegate: uploadE2EEDelegate)
 
-        if let afError = sendFileResults.afError, afError.isExplicitlyCancelledError {
+        // UNLOCK
+        //
+        await networkingE2EE.unlock(account: metadata.account, serverUrl: metadata.serverUrl)
+        
+        if let afError = resultsSendFile.afError, afError.isExplicitlyCancelledError {
 
             CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId))
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": sendFileResults.error])
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": resultsSendFile.error])
 
-        } else if sendFileResults.error == .success, let ocId = sendFileResults.ocId {
+        } else if resultsSendFile.error == .success, let ocId = resultsSendFile.ocId {
 
             NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
             NCUtilityFileSystem.shared.moveFileInBackground(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), toPath: CCUtility.getDirectoryProviderStorageOcId(ocId))
 
-            metadata.date = sendFileResults.date ?? NSDate()
-            metadata.etag = sendFileResults.etag ?? ""
+            metadata.date = resultsSendFile.date ?? NSDate()
+            metadata.etag = resultsSendFile.etag ?? ""
             metadata.ocId = ocId
             metadata.chunk = 0
 
@@ -113,65 +169,18 @@ class NCNetworkingE2EEUpload: NSObject {
             NCManageDatabase.shared.addMetadata(metadata)
             NCManageDatabase.shared.addLocalFile(metadata: metadata)
             NCUtility.shared.createImageFrom(fileNameView: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile)
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": sendFileResults.error])
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": resultsSendFile.error])
 
         } else {
 
-            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: sendFileResults.error.errorDescription, sessionTaskIdentifier: 0, status: NCGlobal.shared.metadataStatusUploadError)
-            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": sendFileResults.error])
-        }
-
-        return(sendFileResults.error)
-    }
-
-    private func createE2Ee(metadata: tableMetadata, e2eToken: String, ocIdServerUrl: String, fileId: String) async -> (NKError) {
-
-        var key: NSString?, initializationVector: NSString?, authenticationTag: NSString?
-        var method = "POST"
-
-        if NCEndToEndEncryption.sharedManager()?.encryptFile(metadata.fileNameView, fileNameIdentifier: metadata.fileName, directory: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), key: &key, initializationVector: &initializationVector, authenticationTag: &authenticationTag) == false {
-            return NKError(errorCode: NCGlobal.shared.errorE2EEEncryptFile, errorDescription: NSLocalizedString("_e2e_error_", comment: ""))
+            NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: resultsSendFile.error.errorDescription, sessionTaskIdentifier: 0, status: NCGlobal.shared.metadataStatusUploadError)
+            NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterUploadedFile, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "fileName": metadata.fileName, "ocIdTemp": ocIdTemp, "error": resultsSendFile.error])
         }
 
-        // Get last metadata
-        let results = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
-        if results.error == .success, let e2eMetadata = results.e2eMetadata {
-            let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: results.signature, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if error != .success { return error }
-            method = "PUT"
-        }
-
-        // [REPLACE]
-        NCManageDatabase.shared.deleteE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, metadata.fileNameView))
-
-        // Add new metadata
-        let object = tableE2eEncryption.init(account: metadata.account, ocIdServerUrl: ocIdServerUrl, fileNameIdentifier: metadata.fileName)
-        if let result = NCManageDatabase.shared.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
-            object.metadataKey = result.metadataKey
-            object.metadataKeyIndex = result.metadataKeyIndex
-        } else {
-            let key = NCEndToEndEncryption.sharedManager()?.generateKey() as NSData?
-            object.metadataKey = key!.base64EncodedString()
-            object.metadataKeyIndex = 0
-        }
-        object.authenticationTag = authenticationTag! as String
-        object.fileName = metadata.fileNameView
-        object.key = key! as String
-        object.initializationVector = initializationVector! as String
-        object.mimeType = metadata.contentType
-        object.serverUrl = metadata.serverUrl
-        NCManageDatabase.shared.addE2eEncryption(object)
-
-        let resultsEncode = NCEndToEndMetadata().encodeMetadata(account: metadata.account, serverUrl: metadata.serverUrl, userId: metadata.userId)
-        guard resultsEncode.error == .success, let e2eMetadata = resultsEncode.metadata else { return resultsEncode.error }
-
-        // send metadata
-        let putE2EEMetadataResults = await NextcloudKit.shared.putE2EEMetadata(fileId: fileId, e2eToken: e2eToken, e2eMetadata: e2eMetadata, signature: resultsEncode.signature, method: method)
-
-        return putE2EEMetadataResults.error
+        return (resultsSendFile.error)
     }
 
-    private func sendFile(metadata: tableMetadata, e2eToken: String, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> (ocId: String?, etag: String?, date: NSDate?, afError: AFError?, error: NKError) {
+    private func sendFile(metadata: tableMetadata, e2eToken: String, uploadE2EEDelegate: uploadE2EEDelegate? = nil) async -> (ocId: String?, etag: String?, date: NSDate? ,afError: AFError?, error: NKError) {
 
         if metadata.chunk > 0 {
 
@@ -180,8 +189,8 @@ class NCNetworkingE2EEUpload: NSObject {
                     uploadE2EEDelegate?.start()
                 } progressHandler: { totalBytesExpected, totalBytes, fractionCompleted in
                     uploadE2EEDelegate?.uploadE2EEProgress(totalBytesExpected, totalBytes, fractionCompleted)
-                } completion: { _, file, afError, error in
-                    continuation.resume(returning: (ocId: file?.ocId, etag: file?.etag, date: file?.date, afError: afError, error: error))
+                } completion: { account, file, afError, error in
+                    continuation.resume(returning: (ocId: file?.ocId, etag: file?.etag, date: file?.date ,afError: afError, error: error))
                 }
             })
 
@@ -193,8 +202,8 @@ class NCNetworkingE2EEUpload: NSObject {
                     uploadE2EEDelegate?.start()
                 } progressHandler: { totalBytesExpected, totalBytes, fractionCompleted in
                     uploadE2EEDelegate?.uploadE2EEProgress(totalBytesExpected, totalBytes, fractionCompleted)
-                } completion: { _, ocId, etag, date, _, _, afError, error in
-                    continuation.resume(returning: (ocId: ocId, etag: etag, date: date, afError: afError, error: error))
+                } completion: { account, ocId, etag, date, size, allHeaderFields, afError, error in
+                    continuation.resume(returning: (ocId: ocId, etag: etag, date: date ,afError: afError, error: error))
                 }
             })
         }

+ 14 - 14
iOSClient/Networking/NCNetworking.swift

@@ -412,7 +412,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         if metadata.isDirectoryE2EE {
 #if !EXTENSION_FILE_PROVIDER_EXTENSION && !EXTENSION_WIDGET
             Task {
-                let error = await NCNetworkingE2EEUpload.shared.upload(metadata: metadata, uploadE2EEDelegate: uploadE2EEDelegate)
+                let error = await NCNetworkingE2EEUpload().upload(metadata: metadata, uploadE2EEDelegate: uploadE2EEDelegate)
                 completion(error)
             }
 #endif
@@ -1153,7 +1153,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         if isDirectoryEncrypted {
 #if !EXTENSION
             Task {
-                let error = await NCNetworkingE2EECreateFolder.shared.createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, withPush: withPush)
+                let error = await NCNetworkingE2EECreateFolder().createFolder(fileName: fileName, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, withPush: withPush)
                 completion(error)
             }
 #endif
@@ -1192,7 +1192,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
                         NCManageDatabase.shared.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: fileNameFolderUrl, account: account)
                     }
                     if let metadata = NCManageDatabase.shared.getMetadataFromOcId(metadataFolder?.ocId) {
-                        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "e2ee": false, "withPush": withPush])
+                        NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl, "account": metadata.account, "withPush": withPush])
                     }
                 }
                 completion(error)
@@ -1300,14 +1300,14 @@ class NCNetworking: NSObject, NKCommonDelegate {
         if metadata.isDirectoryE2EE {
 #if !EXTENSION
             if let metadataLive = metadataLive {
-                let error = await NCNetworkingE2EEDelete.shared.delete(metadata: metadataLive)
+                let error = await NCNetworkingE2EEDelete().delete(metadata: metadataLive)
                 if error == .success {
-                    return await NCNetworkingE2EEDelete.shared.delete(metadata: metadata)
+                    return await NCNetworkingE2EEDelete().delete(metadata: metadata)
                 } else {
                     return error
                 }
             } else {
-                return await NCNetworkingE2EEDelete.shared.delete(metadata: metadata)
+                return await NCNetworkingE2EEDelete().delete(metadata: metadata)
             }
 #else
             return NKError()
@@ -1326,7 +1326,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         }
     }
 
-    func deleteMetadataPlain(_ metadata: tableMetadata, customHeader: [String: String]? = nil) async -> (NKError) {
+    func deleteMetadataPlain(_ metadata: tableMetadata, customHeader: [String: String]? = nil) async -> NKError {
 
         // verify permission
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanDelete)
@@ -1448,15 +1448,15 @@ class NCNetworking: NSObject, NKCommonDelegate {
 #if !EXTENSION
             Task {
                 if let metadataLive = metadataLive {
-                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadataLive, fileNameNew: fileNameNew, indexPath: indexPath)
+                    let error = await NCNetworkingE2EERename().rename(metadata: metadataLive, fileNameNew: fileNameNew, indexPath: indexPath)
                     if error == .success {
-                        let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
+                        let error = await NCNetworkingE2EERename().rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
                         DispatchQueue.main.async { completion(error) }
                     } else {
                         DispatchQueue.main.async { completion(error) }
                     }
                 } else {
-                    let error = await NCNetworkingE2EERename.shared.rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
+                    let error = await NCNetworkingE2EERename().rename(metadata: metadata, fileNameNew: fileNameNew, indexPath: indexPath)
                     DispatchQueue.main.async { completion(error) }
                 }
             }
@@ -1543,7 +1543,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     // MARK: - WebDav Move
 
-    func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
+    func moveMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
         if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
             let error = await moveMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
@@ -1556,7 +1556,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         return await moveMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
     }
 
-    private func moveMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
+    private func moveMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {
@@ -1579,7 +1579,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
 
     // MARK: - WebDav Copy
 
-    func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
+    func copyMetadata(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
         if let metadataLive = NCManageDatabase.shared.getMetadataLivePhoto(metadata: metadata) {
             let error = await copyMetadataPlain(metadataLive, serverUrlTo: serverUrlTo, overwrite: overwrite)
@@ -1592,7 +1592,7 @@ class NCNetworking: NSObject, NKCommonDelegate {
         return await copyMetadataPlain(metadata, serverUrlTo: serverUrlTo, overwrite: overwrite)
     }
 
-    private func copyMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> (NKError) {
+    private func copyMetadataPlain(_ metadata: tableMetadata, serverUrlTo: String, overwrite: Bool) async -> NKError {
 
         let permission = NCUtility.shared.permissionsContainsString(metadata.permissions, permissions: NCGlobal.shared.permissionCanRename)
         if !(metadata.permissions == "") && !permission {

+ 1 - 1
iOSClient/Networking/NCService.swift

@@ -48,7 +48,7 @@ class NCService: NSObject {
                 getAvatar(tableAccount: tableAccount)
                 requestServerCapabilities()
                 requestDashboardWidget()
-                NCNetworkingE2EE.shared.unlockAll(account: tableAccount.account)
+                NCNetworkingE2EE().unlockAll(account: tableAccount.account)
             }
         }
     }

+ 1 - 1
iOSClient/Share/Advanced/NCShareAdvancePermission.swift

@@ -49,7 +49,7 @@ class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDeleg
             if isNewShare {
                 if metadata.e2eEncrypted && NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
                     let serverUrl = metadata.serverUrl + "/" + metadata.fileName
-                    let error = await NCNetworkingE2EE.shared.uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: share.shareWith, removeUserId: nil)
+                    let error = await NCNetworkingE2EE().uploadMetadata(account: metadata.account, serverUrl: serverUrl, userId: metadata.userId, addUserId: share.shareWith, removeUserId: nil)
                     if error != .success {
                         NCContentPresenter.shared.showError(error: error)
                         return