Marino Faggiana 1 рік тому
батько
коміт
44b31876a6

+ 10 - 11
iOSClient/NCGlobal.swift

@@ -94,16 +94,16 @@ class NCGlobal: NSObject {
 
     // Nextcloud version
     //
-    let nextcloudVersion12: Int                     =  12
-    let nextcloudVersion15: Int                     =  15
-    let nextcloudVersion17: Int                     =  17
-    let nextcloudVersion18: Int                     =  18
-    let nextcloudVersion20: Int                     =  20
-    let nextcloudVersion23: Int                     =  23
-    let nextcloudVersion24: Int                     =  24
-    let nextcloudVersion25: Int                     =  25
-    let nextcloudVersion26: Int                     =  26
-    let nextcloudVersion27: Int                     =  27
+    let nextcloudVersion12: Int                     = 12
+    let nextcloudVersion15: Int                     = 15
+    let nextcloudVersion17: Int                     = 17
+    let nextcloudVersion18: Int                     = 18
+    let nextcloudVersion20: Int                     = 20
+    let nextcloudVersion23: Int                     = 23
+    let nextcloudVersion24: Int                     = 24
+    let nextcloudVersion25: Int                     = 25
+    let nextcloudVersion26: Int                     = 26
+    let nextcloudVersion27: Int                     = 27
 
     // Nextcloud unsupported
     //
@@ -127,7 +127,6 @@ class NCGlobal: NSObject {
 
     // E2EE
     //
-    let e2eeMaxFileSize: UInt64                     = 500000000     // 500 MB
     let e2eePassphraseTest                          = "more over television factory tendency independence international intellectual impress interest sentence pony"
     @objc let e2eeReadVersions                      = ["1.1", "1.2"]
 

+ 142 - 27
iOSClient/Networking/E2EE/NCEndToEndEncryption.m

@@ -567,23 +567,11 @@
 
 - (BOOL)decryptFile:(NSString *)fileName fileNameView:(NSString *)fileNameView ocId:(NSString *)ocId key:(NSString *)key initializationVector:(NSString *)initializationVector authenticationTag:(NSString *)authenticationTag
 {
-    NSMutableData *plainData;
-
-    NSData *cipherData = [[NSFileManager defaultManager] contentsAtPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName]];
-    if (cipherData == nil)
-        return false;
-    
     NSData *keyData = [[NSData alloc] initWithBase64EncodedString:key options:0];
     NSData *initializationVectorData = [[NSData alloc] initWithBase64EncodedString:initializationVector options:0];
     NSData *authenticationTagData = [[NSData alloc] initWithBase64EncodedString:authenticationTag options:0];
 
-    BOOL result = [self decryptData:cipherData plain:&plainData key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
-    if (plainData != nil && result) {
-        [plainData writeToFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] atomically:YES];
-        return true;
-    }
-    
-    return false;
+   return [self decryptFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName] fileNamePlain:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameView] key:keyData keyLen:AES_KEY_128_LENGTH initializationVector:initializationVectorData authenticationTag:authenticationTagData];
 }
 
 // -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -728,7 +716,7 @@
 #pragma mark - AES/GCM/NoPadding
 #
 
-// Encryption NSData using GCM mode
+// Encryption data using GCM mode
 - (BOOL)encryptData:(NSData *)plain cipher:(NSMutableData **)cipher key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData **)authenticationTag
 {
     int status = 0;
@@ -762,31 +750,41 @@
     else if (keyLen == AES_KEY_256_LENGTH)
         status = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
     
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Set IV length. Not necessary if this is 12 bytes (96 bits)
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Initialise key and IV
     status = EVP_EncryptInit_ex (ctx, NULL, NULL, cKey, cIV);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Provide the message to be encrypted, and obtain the encrypted output
     *cipher = [NSMutableData dataWithLength:[plain length]];
     unsigned char * cCipher = [*cipher mutableBytes];
     int cCipherLen = 0;
     status = EVP_EncryptUpdate(ctx, cCipher, &cCipherLen, [plain bytes], (int)[plain length]);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Finalise the encryption
     status = EVP_EncryptFinal_ex(ctx, cCipher, &cCipherLen);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Get the tag
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, (int)sizeof(cTag), cTag);
@@ -795,7 +793,6 @@
     // Append TAG
     [*cipher appendData:*authenticationTag];
 
-    // Free
     EVP_CIPHER_CTX_free(ctx);
     
     return status; // OpenSSL uses 1 for success
@@ -928,8 +925,7 @@
     return status; // OpenSSL uses 1 for success
 }
 
-
-// Decryption using GCM mode
+// Decryption data using GCM mode
 - (BOOL)decryptData:(NSData *)cipher plain:(NSMutableData **)plain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
 {    
     int status = 0;
@@ -964,31 +960,41 @@
     else if (keyLen == AES_KEY_256_LENGTH)
         status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
     
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Set IV length. Not necessary if this is 12 bytes (96 bits)
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Initialise key and IV
     status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Provide the message to be decrypted, and obtain the plaintext output
     *plain = [NSMutableData dataWithLength:([cipher length])];
     int cPlainLen = 0;
     unsigned char * cPlain = [*plain mutableBytes];
     status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [cipher bytes], (int)([cipher length]));
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Tag is the last 16 bytes
     status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
-    if (status <= 0)
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
         return NO;
+    }
     
     // Finalise the encryption
     EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
@@ -999,6 +1005,115 @@
     return status; // OpenSSL uses 1 for success
 }
 
+// Decryption file using GCM mode
+- (BOOL)decryptFile:(NSString *)fileName fileNamePlain:(NSString *)fileNamePlain key:(NSData *)key keyLen:(int)keyLen initializationVector:(NSData *)initializationVector authenticationTag:(NSData *)authenticationTag
+{
+    int status = 0;
+    int len = 0;
+
+    // set up key
+    len = keyLen;
+    unsigned char cKey[len];
+    bzero(cKey, sizeof(cKey));
+    [key getBytes:cKey length:len];
+
+    // set up ivec
+    len = (int)[initializationVector length];
+    unsigned char cIV[len];
+    bzero(cIV, sizeof(cIV));
+    [initializationVector getBytes:cIV length:len];
+
+    // set up tag
+    len = (int)[authenticationTag length];;
+    unsigned char cTag[len];
+    bzero(cTag, sizeof(cTag));
+    [authenticationTag getBytes:cTag length:len];
+
+    // Create and initialise the context
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+    if (!ctx)
+        return NO;
+
+    // Initialise the decryption operation
+    if (keyLen == AES_KEY_128_LENGTH)
+        status = EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
+    else if (keyLen == AES_KEY_256_LENGTH)
+        status = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
+
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Set IV length. Not necessary if this is 12 bytes (96 bits)
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)sizeof(cIV), NULL);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    // Initialise key and IV
+    status = EVP_DecryptInit_ex(ctx, NULL, NULL, cKey, cIV);
+    if (status <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        return NO;
+    }
+
+    NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:fileName];
+    [inStream open];
+    NSOutputStream *outStream = [NSOutputStream outputStreamToFileAtPath:fileNamePlain append:false];
+    [outStream open];
+
+    Byte buffer[streamBuffer];
+    NSInteger totalNumberOfBytesWritten = 0;
+
+    int cPlainLen = 0;
+    unsigned char *cPlain;
+
+    while ([inStream hasBytesAvailable]) {
+
+        NSInteger bytesRead = [inStream read:buffer maxLength:streamBuffer];
+
+        if (bytesRead > 0) {
+
+            cPlain = [[NSMutableData dataWithLength:bytesRead] mutableBytes];
+            status = EVP_DecryptUpdate(ctx, cPlain, &cPlainLen, [[NSData dataWithBytes:buffer length:bytesRead] bytes], (int)bytesRead);
+            if (status <= 0) {
+                [inStream close];
+                [outStream close];
+                EVP_CIPHER_CTX_free(ctx);
+                return NO;
+            }
+
+            if ([outStream hasSpaceAvailable]) {
+                totalNumberOfBytesWritten = [outStream write:cPlain maxLength:cPlainLen];
+                if (totalNumberOfBytesWritten != cPlainLen) {
+                    [inStream close];
+                    [outStream close];
+                    EVP_CIPHER_CTX_free(ctx);
+                    return NO;
+                }
+            }
+        }
+    }
+
+    [inStream close];
+    [outStream close];
+
+    // Tag is the last 16 bytes
+    status = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)sizeof(cTag), cTag);
+    if (status <= 0)
+        return NO;
+
+    // Finalise the encryption
+    EVP_DecryptFinal_ex(ctx,NULL, &cPlainLen);
+
+    // Free
+    EVP_CIPHER_CTX_free(ctx);
+
+    return status; // OpenSSL uses 1 for success
+}
+
 #
 #pragma mark - Utility
 #

+ 0 - 7
iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

@@ -54,13 +54,6 @@ class NCNetworkingE2EEUpload: NSObject {
         let ocIdTemp = metadata.ocId
         let errorCreateEncrypted = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_e2e_error_create_encrypted_")
 
-        // Verify max size
-        if metadata.size > NCGlobal.shared.e2eeMaxFileSize {
-            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": metadata.ocId, "error": NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "E2E Error file too big")])
-            return NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "E2E Error file too big")
-        }
-
         // 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