Browse Source

e2e encryptFileName

Marino Faggiana 7 years ago
parent
commit
a74053e260

+ 6 - 4
iOSClient/Database/NCDatabase.swift

@@ -113,18 +113,19 @@ class tableDirectory: Object {
 
 class tableE2eEncryption: Object {
     
+    @objc dynamic var account = ""
     @objc dynamic var authenticationTag = ""
-    @objc dynamic var fileID = ""
-    @objc dynamic var filename = ""
+    @objc dynamic var fileName = ""
     @objc dynamic var fileNameEncrypted = ""
     @objc dynamic var key = ""
     @objc dynamic var initializationVector = ""
     @objc dynamic var metadataKey: Int = 0
-    @objc dynamic var mimetype = ""
+    @objc dynamic var mimeType = ""
+    @objc dynamic var serverUrl = ""
     @objc dynamic var version: Int = 0
     
     override static func primaryKey() -> String {
-        return "fileID"
+        return "fileNameEncrypted"
     }
 }
 
@@ -239,6 +240,7 @@ class tableQueueUpload: Object {
     @objc dynamic var date = NSDate()
     @objc dynamic var encrypted: Bool = false
     @objc dynamic var fileName = ""
+    @objc dynamic var fileNameEncrypted = ""
     @objc dynamic var lock: Bool = false
     @objc dynamic var priority: Int = 0
     @objc dynamic var selector = ""

+ 25 - 2
iOSClient/Database/NCManageDatabase.swift

@@ -57,10 +57,13 @@ class NCManageDatabase: NSObject {
         let config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: 12,
+            schemaVersion: 15,
             
-            // 11 : Add Object e2eEncryption
+            // 11 : Add object tableE2eEncryption
             // 12 : Add encrypted on tableQueueDownload, tableQueueUpload
+            // 13 : Add account on object tableE2eEncryption
+            // 14 : Add fileNameEncrypted on tableQueueUpload
+            // 15 : remove fileID add serverUrl and change primary key for fileNameEncrypted on tableE2eEncryption (change fields name)
             
             migrationBlock: { migration, oldSchemaVersion in
                 // We haven’t migrated anything yet, so oldSchemaVersion == 0
@@ -606,6 +609,21 @@ class NCManageDatabase: NSObject {
         return result.versionMajor
     }
 
+    @objc func getEndToEndEncryptionVersion() -> Float {
+        
+        guard let tableAccount = self.getAccountActive() else {
+            return 0
+        }
+        
+        let realm = try! Realm()
+        
+        guard let result = realm.objects(tableCapabilities.self).filter("account = %@", tableAccount.account).first else {
+            return 0
+        }
+        
+        return Float(result.endToEndEncryptionVersion)!
+    }
+    
     @objc func compareServerVersion(_ versionCompare: String) -> Int {
         
         guard let tableAccount = self.getAccountActive() else {
@@ -1828,6 +1846,7 @@ class NCManageDatabase: NSObject {
         
         let metadataNet = CCMetadataNet()
         
+        metadataNet.account = result.account
         metadataNet.encrypted = result.encrypted
         metadataNet.fileID = result.fileID
         metadataNet.selector = result.selector
@@ -1898,6 +1917,7 @@ class NCManageDatabase: NSObject {
                         addObject.assetLocalIdentifier = metadataNet.assetLocalIdentifier
                         addObject.encrypted = metadataNet.encrypted
                         addObject.fileName = metadataNet.fileName
+                        addObject.fileNameEncrypted = metadataNet.fileNameEncrypted
                         addObject.selector = metadataNet.selector
                         
                         if let selectorPost = metadataNet.selectorPost {
@@ -1942,6 +1962,7 @@ class NCManageDatabase: NSObject {
                         addObject.assetLocalIdentifier = metadataNet.assetLocalIdentifier
                         addObject.encrypted = metadataNet.encrypted
                         addObject.fileName = metadataNet.fileName
+                        addObject.fileNameEncrypted = metadataNet.fileNameEncrypted
                         addObject.selector = metadataNet.selector
                         
                         if let selectorPost = metadataNet.selectorPost {
@@ -1978,9 +1999,11 @@ class NCManageDatabase: NSObject {
         
         let metadataNet = CCMetadataNet()
         
+        metadataNet.account = result.account
         metadataNet.assetLocalIdentifier = result.assetLocalIdentifier
         metadataNet.encrypted = result.encrypted
         metadataNet.fileName = result.fileName
+        metadataNet.fileNameEncrypted = result.fileNameEncrypted
         metadataNet.priority = result.priority
         metadataNet.selector = result.selector
         metadataNet.selectorPost = result.selectorPost

+ 4 - 6
iOSClient/Main/CCMain.m

@@ -1595,7 +1595,7 @@
     BOOL useSubFolder = [[arguments objectAtIndex:2] boolValue];
     NSString *session = [arguments objectAtIndex:3];
     
-    NSString *fileName;
+    
     NSString *autoUploadPath = [[NCManageDatabase sharedInstance] getAccountAutoUploadPath:app.activeUrl];
     NSString *directoryID = [[NCManageDatabase sharedInstance] getDirectoryID:serverUrl];
     if (!directoryID) return;
@@ -1612,11 +1612,7 @@
     
     for (PHAsset *asset in assets) {
         
-        if (isEncrypted) {
-            fileName = [CCUtility generateEncryptedFileName];
-        } else {
-            fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameMask keyFileNameType:k_keyFileNameType];
-        }
+        NSString *fileName = [CCUtility createFileName:[asset valueForKey:@"filename"] fileDate:asset.creationDate fileType:asset.mediaType keyFileName:k_keyFileNameMask keyFileNameType:k_keyFileNameType];
         
         NSDate *assetDate = asset.creationDate;
         NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
@@ -1650,6 +1646,8 @@
             metadataNet.assetLocalIdentifier = asset.localIdentifier;
             metadataNet.encrypted = isEncrypted;
             metadataNet.fileName = fileName;
+            if (isEncrypted)
+                metadataNet.fileNameEncrypted = [CCUtility generateEncryptedFileName];
             metadataNet.session = session;
             metadataNet.selector = selectorReadFileUploadFile;
             metadataNet.serverUrl = serverUrl;

+ 1 - 0
iOSClient/Networking/CCNetworking.h

@@ -109,6 +109,7 @@
 @property (nonatomic, strong) NSString *expirationTime;
 @property (nonatomic, strong) NSString *fileID;
 @property (nonatomic, strong) NSString *fileName;
+@property (nonatomic, strong) NSString *fileNameEncrypted;
 @property (nonatomic, strong) NSString *fileNameTo;
 @property (nonatomic, strong) NSString *key;
 @property (nonatomic, strong) NSString *keyCipher;

+ 48 - 7
iOSClient/Networking/CCNetworking.m

@@ -22,7 +22,7 @@
 //
 
 #import "CCNetworking.h"
-
+#import "NCEndToEndEncryption.h"
 #import "AppDelegate.h"
 #import "CCCertificate.h"
 #import "NSDate+ISO8601.h"
@@ -764,7 +764,6 @@
         if (assetMediaType == PHAssetMediaTypeImage) {
         
             __block PHAsset *asset = result[0];
-            __block NSError *error = nil;
             
             PHImageRequestOptions *options = [PHImageRequestOptions new];
             options.networkAccessAllowed = YES; // iCloud
@@ -772,19 +771,23 @@
             [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                 
                 tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive];
+                BOOL result = YES;
+                NSError *error = nil;
 
                 if ([dataUTI isEqualToString:@"public.heic"] && tableAccount.autoUploadFormatCompatibility) {
                     
                     UIImage *image = [UIImage imageWithData:imageData];
-                    NSData *imageDataJPEG = UIImageJPEGRepresentation(image, 1.0);
+                    imageData = UIImageJPEGRepresentation(image, 1.0);
                     NSString *fileNameJPEG = [[metadataNet.fileName lastPathComponent] stringByDeletingPathExtension];
                     metadataNet.fileName = [fileNameJPEG stringByAppendingString:@".jpg"];
                     
-                    [imageDataJPEG writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] options:NSDataWritingAtomic error:&error];
+                    if (!metadataNet.encrypted)
+                        [imageData writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] options:NSDataWritingAtomic error:&error];
                     
                 } else {
                     
-                    [imageData writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] options:NSDataWritingAtomic error:&error];
+                    if (!metadataNet.encrypted)
+                        [imageData writeToFile:[NSString stringWithFormat:@"%@/%@", _directoryUser, metadataNet.fileName] options:NSDataWritingAtomic error:&error];
                 }
                 
                 if (error) {
@@ -796,9 +799,43 @@
                 
                 } else {
                     
-                    // OOOOOK
+                    // *** ENCRYPTED ***
+                    if (metadataNet.encrypted) {
+                        
+                        NSString *key;
+                        NSString *initializationVector;
+                        NSString *authenticationTag;
+                        
+                        result = [[NCEndToEndEncryption sharedManager] encryptFileName:metadataNet.fileName directoryUser: _directoryUser data:imageData key:&key initializationVector:&initializationVector authenticationTag:&authenticationTag];
+                        
+                        // Write to DB
+                        if (result) {
+                            
+                            tableE2eEncryption *addObject = [tableE2eEncryption new];
+                            
+                            addObject.account = metadataNet.account;
+                            addObject.authenticationTag = authenticationTag;
+                            addObject.fileName = metadataNet.fileName;
+                            addObject.fileNameEncrypted = metadataNet.fileNameEncrypted;
+                            addObject.key = key;
+                            addObject.initializationVector = initializationVector;
+                            addObject.mimeType =  @"";
+                            addObject.serverUrl = metadataNet.serverUrl;
+                            addObject.version = [[NCManageDatabase sharedInstance] getEndToEndEncryptionVersion];
+                            
+                            (void)[[NCManageDatabase sharedInstance] adde2eEncryption:addObject];
+                        }                        
+                    }
+                    
                     dispatch_async(dispatch_get_main_queue(), ^{
-                        [self upload:metadataNet.fileName serverUrl:metadataNet.serverUrl assetLocalIdentifier:metadataNet.assetLocalIdentifier session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:delegate];
+                        if (result) {
+                            // OOOOOK
+                            [self upload:metadataNet.fileName serverUrl:metadataNet.serverUrl assetLocalIdentifier:metadataNet.assetLocalIdentifier session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:delegate];
+                        } else {
+                            // ERROR
+                            if ([delegate respondsToSelector:@selector(uploadFileFailure:fileID:serverUrl:selector:message:errorCode:)])
+                                [delegate uploadFileFailure:metadataNet fileID:nil serverUrl:metadataNet.serverUrl selector:metadataNet.selector message:[NSString stringWithFormat:@"Image request encrypted failed [%@]", error.description] errorCode:error.code];
+                        }
                     });
                 }
             }];
@@ -828,6 +865,9 @@
                         
                         if (AVAssetExportSessionStatusCompleted == exportSession.status) {
                             
+                            // *** ENCRYPTED ***
+                            
+                            
                             // OOOOOOK
                             dispatch_async(dispatch_get_main_queue(), ^{
                                 [self upload:metadataNet.fileName serverUrl:metadataNet.serverUrl assetLocalIdentifier:metadataNet.assetLocalIdentifier session:metadataNet.session taskStatus:metadataNet.taskStatus selector:metadataNet.selector selectorPost:metadataNet.selectorPost errorCode:metadataNet.errorCode delegate:delegate];
@@ -1550,6 +1590,7 @@
     [metadataNet setExpirationTime: self.expirationTime];
     [metadataNet setFileID: self.fileID];
     [metadataNet setFileName: self.fileName];
+    [metadataNet setFileNameEncrypted: self.fileNameEncrypted];
     [metadataNet setFileNameTo: self.fileNameTo];
     [metadataNet setKey: self.key];
     [metadataNet setKeyCipher: self.keyCipher];

+ 2 - 0
iOSClient/Security/NCEndToEndEncryption.h

@@ -29,6 +29,8 @@
 
 + (instancetype)sharedManager;
 
+- (BOOL)encryptFileName:(NSString *)fileName directoryUser:(NSString *)directoryUser data:(NSData *)data key:(NSString **)key initializationVector:(NSString **)initializationVector authenticationTag:(NSString **)authenticationTag;
+
 //- (void)encryptMetadata:(tableMetadata *)metadata activeUrl:(NSString *)activeUrl;
 //- (NSString *)decryptMetadata:(NSString *)cipher key:(NSString *)key iv:(NSString *)iv tag:(NSString *)tag;
 

+ 18 - 7
iOSClient/Security/NCEndToEndEncryption.m

@@ -540,24 +540,35 @@ cleanup:
     return outString;
 }
 
-- (NSString *)encryptFileName:(NSString *)fileName fileID:(NSString *)fileID activeUrl:(NSString *)activeUrl
+- (BOOL)encryptFileName:(NSString *)fileName directoryUser:(NSString *)directoryUser data:(NSData *)data key:(NSString **)key initializationVector:(NSString **)initializationVector authenticationTag:(NSString **)authenticationTag
 {
     NSMutableData *cipherData;
     NSData *tagData;
-    NSString* authenticationTag;
-
-    NSData *plainData = [[NSFileManager defaultManager] contentsAtPath:[NSString stringWithFormat:@"%@/%@", activeUrl, fileID]];
+    NSData *plainData;
+    
+    if (data) {
+        plainData = data;
+    } else {
+        plainData = [[NSFileManager defaultManager] contentsAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName]];
+    }
+    
     NSData *keyData = [self generateKey:AES_KEY_128_LENGTH];
     NSData *ivData = [self generateIV:AES_IVEC_LENGTH];
     
     BOOL result = [self encryptData:plainData cipherData:&cipherData keyData:keyData keyLen:AES_KEY_128_LENGTH ivData:ivData tagData:&tagData];
     
     if (cipherData != nil && result) {
-        [cipherData writeToFile:[NSString stringWithFormat:@"%@/%@.dms", activeUrl, fileID] atomically:YES];
-        authenticationTag = [tagData base64EncodedStringWithOptions:0];
+        
+        [cipherData writeToFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName] atomically:YES];
+        
+        *key = [keyData base64EncodedStringWithOptions:0];
+        *initializationVector = [ivData base64EncodedStringWithOptions:0];
+        *authenticationTag = [tagData base64EncodedStringWithOptions:0];
+
+        return true;
     }
     
-    return nil;
+    return false;
 }
 
 /*

+ 1 - 1
iOSClient/Security/NCEntoToEndInterface.swift

@@ -462,7 +462,7 @@ class NCEntoToEndInterface : NSObject, OCNetworkingDelegate  {
         // Create "files"
         for recordE2eEncryption in recordsE2eEncryption {
             
-            let plainEncrypted = recordE2eEncryption.key+"|"+recordE2eEncryption.filename+"|"+recordE2eEncryption.mimetype+"|"+",\(recordE2eEncryption.version)"
+            let plainEncrypted = recordE2eEncryption.key+"|"+recordE2eEncryption.fileName+"|"+recordE2eEncryption.mimeType+"|"+",\(recordE2eEncryption.version)"
             guard let encryptedData = NCEndToEndEncryption.sharedManager().encryptAsymmetricString(plainEncrypted, publicKey: publicKey) else {
                 
                 appDelegate.messageNotification("E2E encore metadata", description: "Serious internal error in creation \"encrypted\" key", visible: true, delay: TimeInterval(k_dismissAfterSecond), type: TWMessageBarMessageType.error, errorCode: 0)