123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- //
- // CCCrypto.m
- // Crypto Cloud Technology Nextcloud
- //
- // Created by Marino Faggiana on 10/08/16.
- // Copyright (c) 2017 TWS. All rights reserved.
- //
- // Author Marino Faggiana <m.faggiana@twsweb.it>
- //
- // 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 "CCCrypto.h"
- #import "NCBridgeSwift.h"
- @implementation CCCrypto
- //Singleton
- + (id)sharedManager {
- static CCCrypto *CCCrypto = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- CCCrypto = [[self alloc] init];
- });
- return CCCrypto;
- }
- #pragma --------------------------------------------------------------------------------------------
- #pragma mark ===== Encryption function =====
- #pragma --------------------------------------------------------------------------------------------
- // return password
- - (NSString *)getKeyPasscode:(NSString *)uuid
- {
- NSString *key;
- NSString *passcode = [CCUtility getKeyChainPasscodeForUUID:uuid];
-
- if (passcode) key = [AESCrypt encrypt:uuid password:passcode];
- return key;
- }
- - (void)autoInsertPasscodeUUID:(NSString *)uuid text:(NSString *)text
- {
- NSString *key;
- NSString *passcode;
-
- // if return the passcode the UUID it has already entered
- if ([[CCUtility getKeyChainPasscodeForUUID:uuid] length] > 0)
- return;
-
- // verify if the password of the UUID insert is good (OPTIMIZATION)
- passcode = [CCUtility getKeyChainPasscodeForUUID:[CCUtility getUUID]];
- key = [AESCrypt encrypt:uuid password:passcode];
-
- // if the decryption it's ok insert UUID with Passcode in KeyChain
- if([AESCrypt decrypt:text password:key])
- [CCUtility setKeyChainPasscodeForUUID:uuid conPasscode:passcode];
- }
- - (BOOL)verifyPasscode:(NSString *)passcode uuid:(NSString*)uuid text:(NSString *)text
- {
- NSString *key;
-
- key = [AESCrypt encrypt:uuid password:passcode];
- NSString *textDecrypted = [AESCrypt decrypt:text password:key];
-
- if([textDecrypted length]) return true;
- else return false;
- }
- - (BOOL)createFilePlist:(NSString *)fileNamePath title:(NSString *)title len:(NSUInteger)len directory:(BOOL)directory uuid:(NSString *)uuid nameCurrentDevice:(NSString *)nameCurrentDevice icon:(NSString *)icon
- {
- NSMutableDictionary *data;
- NSString *hint = [CCUtility getHint];
-
- // se non ha già l'estensione plist aggiungila
- if([fileNamePath rangeOfString:@".plist"].location == NSNotFound) fileNamePath = [fileNamePath stringByAppendingString:@".plist"];
-
- if ([[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
- data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
- else
- data = [[NSMutableDictionary alloc] init];
-
- [data setObject: [NSNumber numberWithBool:directory] forKey:@"dir"];
- if ([hint length] > 0) [data setObject:[AESCrypt encrypt:hint password:k_UUID_SIM] forKey:@"hint"];
- if ([icon length] > 0) [data setObject:icon forKey:@"icon"];
- [data setObject: [NSString stringWithFormat:@"%li", (unsigned long)len] forKey:@"len"];
- [data setObject: nameCurrentDevice forKey:@"namecurrentdevice"];
- [data setObject: k_versionProtocolPlist forKey:@"protocol"];
- [data setObject: title forKey:@"title"];
- [data setObject: k_metadataType_file forKey:@"type"];
- [data setObject: uuid forKey:@"uuid"];
- [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
-
- return [data writeToFile:fileNamePath atomically:YES];
- }
- - (void)addPlistImage:(NSString *)fileNamePath fileNamePathImage:(NSString *)fileNamePathImage
- {
- NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
-
- if (plist) {
-
- UIImage *image = [UIImage imageWithContentsOfFile:fileNamePathImage];
-
- if (image) {
-
- NSData *dataImage = UIImagePNGRepresentation(image);
-
- NSError *error;
- NSString *passcode = [self getKeyPasscode:[CCUtility getUUID]];
- if (passcode) dataImage = [RNEncryptor encryptData:dataImage withSettings:kRNCryptorAES256Settings password:passcode error:&error];
- else dataImage = nil;
-
- if (dataImage && error == nil) {
-
- [plist setObject:dataImage forKey:@"image"];
- [plist writeToFile:fileNamePath atomically:YES];
- }
- }
- }
- }
- - (BOOL)updateTitleFilePlist:(NSString *)fileName title:(NSString *)title directoryUser:(NSString *)directoryUser
- {
- // if not plist extension add it
- if([fileName rangeOfString:@".plist"].location == NSNotFound) fileName = [fileName stringByAppendingString:@".plist"];
-
- // open file plist
- NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName]];
-
- if (data) {
-
- [data setObject:title forKey:@"title"];
- [data writeToFile:[NSTemporaryDirectory() stringByAppendingString:fileName] atomically:YES];
-
- return YES;
- }
- return NO;
- }
- - (NSString *)createFileDirectoryPlist:(tableMetadata *)metadata
- {
- NSMutableDictionary *data;
-
- NSString *fileName = [self createFilenameEncryptor:metadata.fileNamePrint uuid:metadata.uuid];
- NSString *title = [AESCrypt encrypt:metadata.fileNamePrint password:[self getKeyPasscode:metadata.uuid]];
- NSString *fileNamePath = [NSString stringWithFormat:@"%@%@.plist", NSTemporaryDirectory(), fileName];
- NSString *hint = [CCUtility getHint];
-
- if ([[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
- data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
- else
- data = [[NSMutableDictionary alloc] init];
-
- [data setObject: [NSNumber numberWithBool:true] forKey:@"dir"];
- if ([hint length] > 0) [data setObject: [AESCrypt encrypt:hint password:k_UUID_SIM] forKey:@"hint"];
- [data setObject: @"0" forKey:@"len"];
- [data setObject: metadata.nameCurrentDevice forKey:@"namecurrentdevice"];
- [data setObject: k_versionProtocolPlist forKey:@"protocol"];
- [data setObject: title forKey:@"title"];
- [data setObject: k_metadataType_file forKey:@"type"];
- [data setObject: metadata.uuid forKey:@"uuid"];
- [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
-
- if ([data writeToFile:fileNamePath atomically:YES]) return fileName;
- else return nil;
- }
- - (BOOL)createTemplatesPlist:(NSString *)nameFile title:(NSString *)title uuid:(NSString *)uuid icon:(NSString *)icon model:(NSString *)model dictionary:(NSMutableDictionary*)dictionary
- {
- NSString *encrypted;
- NSString *passcode = [self getKeyPasscode:uuid];
- NSString *fileNamePath = [NSTemporaryDirectory() stringByAppendingString:nameFile];
- NSString *fileCryptoPath = [NSTemporaryDirectory() stringByAppendingString:[CCUtility trasformedFileNamePlistInCrypto:nameFile]];
- NSString *hint = [CCUtility getHint];
-
- NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
-
- for (NSString *key in [dictionary allKeys]) {
- encrypted = [CCUtility stringValueForKey:key conDictionary:dictionary];
- if ([encrypted length] == 0) encrypted = @"";
- else encrypted = [AESCrypt encrypt:encrypted password:passcode];
- [dictionary setObject:encrypted forKey:key];
- }
-
- [data setObject: dictionary forKey:@"field"];
- if ([hint length] > 0) [data setObject: [AESCrypt encrypt:hint password:k_UUID_SIM] forKey:@"hint"];
- [data setObject: icon forKey:@"icon"];
- [data setObject: model forKey:@"model"];
- [data setObject: [CCUtility getNameCurrentDevice] forKey:@"namecurrentdevice"];
- [data setObject: k_versionProtocolPlist forKey:@"protocol"];
- [data setObject: title forKey:@"title"];
- [data setObject: k_metadataType_template forKey:@"type"];
- [data setObject: uuid forKey:@"uuid"];
- [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
- BOOL ritorno = [data writeToFile:fileNamePath atomically:YES];
-
- if (ritorno)
- [CCUtility copyFileAtPath:fileNamePath toPath:fileCryptoPath];
-
- return ritorno;
- }
- - (NSMutableDictionary *)getDictionaryEncrypted:(NSString *)fileName uuid:(NSString *)uuid isLocal:(BOOL)isLocal directoryUser:(NSString *)directoryUser
- {
- NSMutableDictionary *data;
- NSString *clearText;
- NSString *passcode = [self getKeyPasscode:uuid];
- NSString *serverUrl;
-
- if (isLocal) serverUrl = [CCUtility getDirectoryLocal];
- else serverUrl = directoryUser;
-
- NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", serverUrl, fileName];
-
- if (![[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
- return nil;
-
- data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
-
- if (!data)
- return nil;
-
- NSMutableDictionary *dictionary = [data objectForKey:@"field"];
-
- for (NSString *key in [dictionary allKeys]) {
- NSString *valore = [dictionary objectForKey:key];
- if ([valore length]) clearText = [AESCrypt decrypt:valore password:passcode];
- else clearText = @"";
- if ([clearText length]) [dictionary setObject:clearText forKey:key];
- }
-
- return dictionary;
- }
- - (NSString *)getHintFromFile:(NSString *)fileName isLocal:(BOOL)isLocal directoryUser:(NSString *)directoryUser
- {
- NSString *serverUrl;
-
- if (isLocal) serverUrl = [CCUtility getDirectoryLocal];
- else serverUrl = directoryUser;
-
- NSString *filePath = [NSString stringWithFormat:@"%@/%@", serverUrl, fileName];
-
- if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
- return nil;
-
- NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
-
- if (!data)
- return nil;
-
- NSString *hintCryptated = [data objectForKey:@"hint"];
-
- if ([hintCryptated length] > 0) return [AESCrypt decrypt:hintCryptated password:k_UUID_SIM];
- else return nil;
- }
- - (NSString *)createFilenameEncryptor:(NSString *)fileName uuid:(NSString *)uuid
- {
- NSMutableString *cryptoString = [NSMutableString stringWithCapacity: 64];
- NSString *letters = @"0J7pfXHaCPTasxQDFsUDcSDiHJmVjgzsqDUUQU75IPYrT13YKNJpvvEq0hH2uDD06mhNxvb8";
-
- NSString *temp = [NSString stringWithFormat:@"%@|%@|%@", fileName, uuid, uuid];
-
- temp = [temp substringToIndex:64];
- for (int i=0; i<64; i++){
- NSString *numero = [temp substringWithRange:NSMakeRange(i, 1)];
- NSInteger index = [numero integerValue];
- if (index > 0) [cryptoString appendFormat: @"%C", [letters characterAtIndex:index]];
- else [cryptoString appendFormat: @"%C", [letters characterAtIndex:i]];
- }
- return [NSString stringWithFormat:@"%@crypto", cryptoString];
- }
- #pragma --------------------------------------------------------------------------------------------
- #pragma mark ===== Encypt =====
- #pragma---------------------------------------------------------------------------------------------
- - (NSString *)encryptWithCreatePlist:(NSString *)fileName fileNameEncrypted:(NSString*)fileNameEncrypted passcode:(NSString *)passcode directoryUser:(NSString *)directoryUser
- {
- NSString *uuid = [CCUtility getUUID];
- NSString *nameCurrentDevice = [CCUtility getNameCurrentDevice];
- NSString *title = [AESCrypt encrypt:fileName password:passcode];
- NSString *fileNameCrypto = [self createFilenameEncryptor:fileNameEncrypted uuid:uuid];
-
- NSError *error;
- NSUInteger lenData = (NSUInteger)[[[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName] error:nil] fileSize];
- NSUInteger lenEncryptedData;
- @autoreleasepool {
-
- NSData *encryptedData = [RNEncryptor encryptData:[NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName]] withSettings:kRNCryptorAES256Settings password:passcode error:&error];
-
- lenEncryptedData = encryptedData.length;
-
- if (!error && lenEncryptedData > 0)
- [encryptedData writeToFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameCrypto] atomically:YES];
- }
-
- if (error || lenEncryptedData == 0 || lenData == 0) {
-
- [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameEncrypted] error:nil];
-
- NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"_encrypt_error_", nil), fileName, [error localizedDescription]];
-
- NSLog(@"[LOG] Error encrypt file %@ Err. %@", fileName, msg);
-
- return nil;
- }
-
- [self createFilePlist:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameCrypto] title:title len:lenData directory:NO uuid:uuid nameCurrentDevice:nameCurrentDevice icon:nil];
-
- return fileNameCrypto;
- }
- #pragma --------------------------------------------------------------------------------------------
- #pragma mark ===== Decrypt =====
- #pragma---------------------------------------------------------------------------------------------
- - (NSUInteger)decrypt:(NSString *)fileName fileNameDecrypted:(NSString*)fileNameDecrypted fileNamePrint:(NSString *)fileNamePrint password:(NSString *)password directoryUser:(NSString *)directoryUser
- {
- NSError *error;
- NSUInteger len;
-
- @autoreleasepool {
-
- NSData *decryptedData = [RNDecryptor decryptData:[NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.crypt", directoryUser, fileName]] withSettings:kRNCryptorAES256Settings password:password error:&error];
-
- len = decryptedData.length;
-
- if (!error && decryptedData > 0)
- [decryptedData writeToFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameDecrypted] atomically:YES];
- }
- if (error || len == 0) {
-
- [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameDecrypted] error:nil];
-
- NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"_decrypt_error_", nil), fileNamePrint, [error localizedDescription]];
-
- NSLog(@"[LOG] Error decrypt file %@ Err. %@", fileName, msg);
-
- return 0;
- }
- return len;
- }
- #pragma --------------------------------------------------------------------------------------------
- #pragma mark ===== SHA512 =====
- #pragma---------------------------------------------------------------------------------------------
- - (NSString *)createSHA512:(NSString *)string
- {
- const char *cstr = [string cStringUsingEncoding:NSUTF8StringEncoding];
- NSData *data = [NSData dataWithBytes:cstr length:string.length];
- uint8_t digest[CC_SHA512_DIGEST_LENGTH];
- CC_SHA512(data.bytes, (unsigned int)data.length, digest);
- NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
-
- for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
- [output appendFormat:@"%02x", digest[i]];
- return output;
- }
- @end
|