Marino Faggiana 1 year ago
parent
commit
5abd6fe7c7

+ 25 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -651,6 +651,8 @@
 		F7F4F10C27ECDBDB008676F9 /* Inconsolata-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F7F4F10427ECDBDB008676F9 /* Inconsolata-Regular.ttf */; };
 		F7F4F11027ECDC4A008676F9 /* UIDevice+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F4F10F27ECDC4A008676F9 /* UIDevice+Extension.swift */; };
 		F7F4F11227ECDC52008676F9 /* UIFont+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F4F11127ECDC52008676F9 /* UIFont+Extension.swift */; };
+		F7F623B52A5EF4D30022D3D4 /* Gzip in Frameworks */ = {isa = PBXBuildFile; productRef = F7F623B42A5EF4D30022D3D4 /* Gzip */; };
+		F7F623B72A5EFA0C0022D3D4 /* Gzip in Frameworks */ = {isa = PBXBuildFile; productRef = F7F623B62A5EFA0C0022D3D4 /* Gzip */; };
 		F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; };
 		F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; };
 		F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F9D1BA25397CE000D9BFF5 /* NCViewer.swift */; };
@@ -1424,6 +1426,7 @@
 				F73ADD2126554F8E0069EA0D /* SwiftEntryKit in Frameworks */,
 				F7EBCDCF277B81FF00A4EF67 /* UICKeyChainStore in Frameworks */,
 				F70821D829E59E6D001CA2D7 /* TagListView in Frameworks */,
+				F7F623B72A5EFA0C0022D3D4 /* Gzip in Frameworks */,
 				F72D7EB7263B1207000B3DFC /* MarkdownKit in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -1477,6 +1480,7 @@
 				F70B86752642CE3B00ED5349 /* FirebaseCrashlytics in Frameworks */,
 				F7A1050E29E587AF00FFD92B /* TagListView in Frameworks */,
 				F76DA969277B77EA0082465B /* DropDown in Frameworks */,
+				F7F623B52A5EF4D30022D3D4 /* Gzip in Frameworks */,
 				F75EAED826D2552E00F4320E /* MarqueeLabel in Frameworks */,
 				F710FC7A277B7D0000AA9FBF /* Realm in Frameworks */,
 				F72DA9B425F53E4E00B87DB1 /* SwiftRichString in Frameworks */,
@@ -2762,6 +2766,7 @@
 				F72CD01127A7E92400E59476 /* JGProgressHUD */,
 				F72AD70E28C24BA1006CB92D /* NextcloudKit */,
 				F70821D729E59E6D001CA2D7 /* TagListView */,
+				F7F623B62A5EFA0C0022D3D4 /* Gzip */,
 			);
 			productName = "Share Ext";
 			productReference = F7CE8AFB1DC1F8D8009CAE48 /* Share.appex */;
@@ -2862,6 +2867,7 @@
 				F787AC08298BCB4A0001BB00 /* SVGKitSwift */,
 				F7A1050D29E587AF00FFD92B /* TagListView */,
 				F31F69632A2F929600162F76 /* PreviewSnapshots */,
+				F7F623B42A5EF4D30022D3D4 /* Gzip */,
 			);
 			productName = "Crypto Cloud";
 			productReference = F7CE8AFA1DC1F8D8009CAE48 /* Nextcloud.app */;
@@ -3036,6 +3042,7 @@
 				F31F694B2A2F6EFA00162F76 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
 				F31F69622A2F929600162F76 /* XCRemoteSwiftPackageReference "swiftui-preview-snapshots" */,
 				F31F69672A2F92F000162F76 /* XCRemoteSwiftPackageReference "SnapshotTestingHEIC" */,
+				F7F623B32A5EF4D30022D3D4 /* XCRemoteSwiftPackageReference "GzipSwift" */,
 			);
 			productRefGroup = F7F67B9F1A24D27800EE80DA;
 			projectDirPath = "";
@@ -5045,6 +5052,14 @@
 				minimumVersion = 10.1.1;
 			};
 		};
+		F7F623B32A5EF4D30022D3D4 /* XCRemoteSwiftPackageReference "GzipSwift" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/1024jp/GzipSwift";
+			requirement = {
+				kind = upToNextMajorVersion;
+				minimumVersion = 6.0.0;
+			};
+		};
 /* End XCRemoteSwiftPackageReference section */
 
 /* Begin XCSwiftPackageProductDependency section */
@@ -5398,6 +5413,16 @@
 			package = F7ED547A25EEA65400956C55 /* XCRemoteSwiftPackageReference "QRCodeReader" */;
 			productName = QRCodeReader;
 		};
+		F7F623B42A5EF4D30022D3D4 /* Gzip */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = F7F623B32A5EF4D30022D3D4 /* XCRemoteSwiftPackageReference "GzipSwift" */;
+			productName = Gzip;
+		};
+		F7F623B62A5EFA0C0022D3D4 /* Gzip */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = F7F623B32A5EF4D30022D3D4 /* XCRemoteSwiftPackageReference "GzipSwift" */;
+			productName = Gzip;
+		};
 /* End XCSwiftPackageProductDependency section */
 	};
 	rootObject = F7F67BA01A24D27800EE80DA /* Project object */;

+ 3 - 3
iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

@@ -1075,11 +1075,11 @@ 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) { account, e2eMetadata, _, data, error in
                             if error == .success, let e2eMetadata = e2eMetadata {
-                                let result = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, ownerId: metadataFolder.ownerId)
-                                if result.error == .success {
+                                let error = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: self.serverUrl, account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, ownerId: metadataFolder.ownerId)
+                                if error == .success {
                                     self.reloadDataSource()
                                 } else {
-                                    NCContentPresenter.shared.showError(error: result.error)
+                                    NCContentPresenter.shared.showError(error: error)
                                 }
                             } else if error.errorCode != NCGlobal.shared.errorResourceNotFound {
                                 NCContentPresenter.shared.showError(error: NKError(errorCode: NCGlobal.shared.errorDecodeMetadata, errorDescription: "_e2e_error_decode_metadata_"))

+ 82 - 30
iOSClient/Networking/E2EE/NCEndToEndMetadata.swift

@@ -119,6 +119,14 @@ class NCEndToEndMetadata: NSObject {
         let version: String
     }
 
+    struct PlainUsers {
+        let userId: String
+        let certificate: String
+        let metadataKey: String
+        let filedropKey: String
+    }
+
+
     // --------------------------------------------------------------------------------------------
     // MARK: Encode JSON Metadata V2.0
     // --------------------------------------------------------------------------------------------
@@ -232,9 +240,10 @@ class NCEndToEndMetadata: NSObject {
     // MARK: Decode JSON Metadata Bridge
     // --------------------------------------------------------------------------------------------
 
-    func decoderMetadata(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> (version: Double, metadataKey: String, error: NKError) {
+    func decoderMetadata(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+
         guard let data = json.data(using: .utf8) else {
-            return (0, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON"))
+            return (NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON"))
         }
 
         data.printJson()
@@ -248,7 +257,7 @@ class NCEndToEndMetadata: NSObject {
         } else if (try? decoder.decode(E2eeV20.self, from: data)) != nil {
             return decoderMetadataV20(json, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, ownerId: ownerId)
         } else {
-            return (0, "", NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "Server E2EE version " + NCGlobal.shared.capabilityE2EEApiVersion + ", not compatible"))
+            return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "Server E2EE version " + NCGlobal.shared.capabilityE2EEApiVersion + ", not compatible")
         }
     }
 
@@ -256,15 +265,16 @@ class NCEndToEndMetadata: NSObject {
     // MARK: Decode JSON Metadata V2.0
     // --------------------------------------------------------------------------------------------
 
-    func decoderMetadataV20(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> (version: Double, metadataKey: String, error: NKError) {
+    func decoderMetadataV20(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+
         guard let data = json.data(using: .utf8) else {
-            return (0, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON"))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON")
         }
 
         let decoder = JSONDecoder()
         let privateKey = CCUtility.getEndToEndPrivateKey(account)
         var metadataVersion: Double = 0
-        var metadataKey = ""
+        var plainUsers: [PlainUsers] = []
 
         do {
             let json = try decoder.decode(E2eeV20.self, from: data)
@@ -274,19 +284,59 @@ class NCEndToEndMetadata: NSObject {
             let filedrop = json.filedrop
             metadataVersion = Double(json.version) ?? 0
 
-            let ciphertextData = Data(base64Encoded: metadata.ciphertext)
+            //
+            // users
+            //
+
+            for user in users {
 
-            NCEndToEndEncryption.sharedManager().verifySignatureCMS(data, data: nil, publicKey: CCUtility.getEndToEndPublicKey(account), userId: userId)
+                var metadataKey = ""
+                var filedropKey = ""
 
+                if let encryptedMetadataKey = user.encryptedMetadataKey {
+                    let data = Data(base64Encoded: encryptedMetadataKey)
+                    if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(data, privateKey: privateKey) {
+                        metadataKey = decrypted.base64EncodedString()
+                    }
+                }
 
-            if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(ciphertextData, privateKey: privateKey),
-                let keyData = Data(base64Encoded: decrypted),
-                let key = String(data: keyData, encoding: .utf8) {
-                metadataKey = key
-            } else {
-                return (metadataVersion, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt metadataKey"))
+                if let encryptedFiledropKey = user.encryptedFiledropKey {
+                    let data = Data(base64Encoded: encryptedFiledropKey)
+                    if let decrypted = NCEndToEndEncryption.sharedManager().decryptAsymmetricData(data, privateKey: privateKey) {
+                        filedropKey = decrypted.base64EncodedString()
+                    }
+                }
+
+                plainUsers.append(PlainUsers(userId: user.userId, certificate: user.certificate, metadataKey: metadataKey, filedropKey: filedropKey))
             }
 
+            //
+            // metadata
+            //
+
+            if let plainUser = plainUsers.first(where: { $0.userId == userId }) {
+                if let decrypted = NCEndToEndEncryption.sharedManager().decryptPayloadFile(metadata.ciphertext, key: plainUser.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)
+                            }
+                            if let json = try JSONSerialization.jsonObject(with: data) as? [String: AnyObject] {
+                                let keyChecksums = json["keyChecksums"]
+                                let deleted = json["deleted"]
+                                let folders = json["folders"]
+                                let files = json["files"]
+                                print("")
+                            }
+                        } catch let error {
+                            print("Serious internal error in decoding metadata (" + error.localizedDescription + ")")
+                        }
+                    } else {
+                        print("Serious internal error in decoding metadata")
+                    }
+                }
+            }
 
             /* TEST CMS
 
@@ -303,19 +353,20 @@ class NCEndToEndMetadata: NSObject {
              */
 
         } catch let error {
-            return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription)
         }
 
-        return (metadataVersion, metadataKey, NKError())
+        return NKError()
     }
 
     // --------------------------------------------------------------------------------------------
     // MARK: Decode JSON Metadata V1.1
     // --------------------------------------------------------------------------------------------
 
-    func decoderMetadataV1(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String) -> (version: Double, metadataKey: String, error: NKError) {
+    func decoderMetadataV1(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String) -> NKError {
+
         guard let data = json.data(using: .utf8) else {
-            return (0, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON"))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON")
         }
 
         let decoder = JSONDecoder()
@@ -351,7 +402,7 @@ class NCEndToEndMetadata: NSObject {
             //
             if let tableE2eMetadata = NCManageDatabase.shared.getE2eMetadata(account: account, serverUrl: serverUrl) {
                 if tableE2eMetadata.version > metadataVersion {
-                    return (metadataVersion, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error verify version \(tableE2eMetadata.version)"))
+                    return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error verify version \(tableE2eMetadata.version)")
                 }
             }
 
@@ -408,25 +459,26 @@ class NCEndToEndMetadata: NSObject {
                             }
 
                         } catch let error {
-                            return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt file: " + error.localizedDescription))
+                            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt file: " + error.localizedDescription)
                         }
                     }
                 }
             }
         } catch let error {
-            return (metadataVersion, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription)
         }
 
-        return (metadataVersion, "", NKError())
+        return NKError()
     }
 
     // --------------------------------------------------------------------------------------------
     // MARK: Decode JSON Metadata V1.2
     // --------------------------------------------------------------------------------------------
 
-    func decoderMetadataV12(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> (version: Double, metadataKey: String, error: NKError) {
+    func decoderMetadataV12(_ json: String, serverUrl: String, account: String, urlBase: String, userId: String, ownerId: String?) -> NKError {
+
         guard let data = json.data(using: .utf8) else {
-            return (0, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON"))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decoding JSON")
         }
 
         let decoder = JSONDecoder()
@@ -454,7 +506,7 @@ class NCEndToEndMetadata: NSObject {
                 let key = String(data: keyData, encoding: .utf8) {
                 metadataKey = key
             } else {
-                return (metadataVersion, "", NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt metadataKey"))
+                return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt metadataKey")
             }
 
             // DATA
@@ -512,7 +564,7 @@ class NCEndToEndMetadata: NSObject {
                             }
 
                         } catch let error {
-                            return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt file: " + error.localizedDescription))
+                            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt file: " + error.localizedDescription)
                         }
                     }
                 }
@@ -574,7 +626,7 @@ class NCEndToEndMetadata: NSObject {
                             }
 
                         } catch let error {
-                            return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt filedrop: " + error.localizedDescription))
+                            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error decrypt filedrop: " + error.localizedDescription)
                         }
                     }
                 }
@@ -584,12 +636,12 @@ class NCEndToEndMetadata: NSObject {
             let passphrase = CCUtility.getEndToEndPassphrase(account).replacingOccurrences(of: " ", with: "")
             let checksum = NCEndToEndEncryption.sharedManager().createSHA256(passphrase + fileNameIdentifiers.sorted().joined() + metadata.metadataKey)
             if metadata.checksum != checksum {
-                return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error checksum"))
+                return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: "Error checksum")
             }
         } catch let error {
-            return (metadataVersion, metadataKey, NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription))
+            return NKError(errorCode: NCGlobal.shared.errorE2EE, errorDescription: error.localizedDescription)
         }
 
-        return (metadataVersion, metadataKey, NKError())
+        return NKError()
     }
 }

+ 2 - 2
iOSClient/Networking/E2EE/NCNetworkingE2EECreateFolder.swift

@@ -133,8 +133,8 @@ class NCNetworkingE2EECreateFolder: NSObject {
         // Get last metadata
         let getE2EEMetadataResults = await NextcloudKit.shared.getE2EEMetadata(fileId: fileIdLock, e2eToken: e2eToken)
         if getE2EEMetadataResults.error == .success, let e2eMetadata = getE2EEMetadataResults.e2eMetadata {
-            let result = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, ownerId: nil)
-            if result.error != .success { return result.error }
+            let error = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: serverUrl, account: account, urlBase: urlBase, userId: userId, ownerId: nil)
+            if error != .success { return error }
             method = "PUT"
         }
 

+ 2 - 2
iOSClient/Networking/E2EE/NCNetworkingE2EEDelete.swift

@@ -51,8 +51,8 @@ class NCNetworkingE2EEDelete: NSObject {
                 return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: NSLocalizedString("_e2e_error_encode_metadata_", comment: ""))
             }
 
-            let result = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if result.error != .success { return result.error }
+            let error = NCEndToEndMetadata().decoderMetadata(e2eMetadata, 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))

+ 2 - 2
iOSClient/Networking/E2EE/NCNetworkingE2EERename.swift

@@ -48,8 +48,8 @@ class NCNetworkingE2EERename: NSObject {
                 return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: NSLocalizedString("_e2e_error_encode_metadata_", comment: ""))
             }
 
-            let result = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if result.error != .success { return result.error }
+            error = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
+            if error != .success { return error }
 
             // rename
             NCManageDatabase.shared.renameFileE2eEncryption(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))

+ 2 - 2
iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

@@ -140,8 +140,8 @@ class NCNetworkingE2EEUpload: NSObject {
         // Get last metadata
         let getE2EEMetadataResults = await NextcloudKit.shared.getE2EEMetadata(fileId: fileId, e2eToken: e2eToken)
         if getE2EEMetadataResults.error == .success, let e2eMetadata = getE2EEMetadataResults.e2eMetadata {
-            let result = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
-            if result.error != .success { return result.error }
+            let error = NCEndToEndMetadata().decoderMetadata(e2eMetadata, serverUrl: metadata.serverUrl, account: metadata.account, urlBase: metadata.urlBase, userId: metadata.userId, ownerId: metadata.ownerId)
+            if error != .success { return error }
             method = "PUT"
         }