CCCrypto.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. //
  2. // CCCrypto.m
  3. // Crypto Cloud Technology Nextcloud
  4. //
  5. // Created by Marino Faggiana on 10/08/16.
  6. // Copyright (c) 2014 TWS. All rights reserved.
  7. //
  8. // Author Marino Faggiana <m.faggiana@twsweb.it>
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. #import "CCCrypto.h"
  24. @implementation CCCrypto
  25. #pragma --------------------------------------------------------------------------------------------
  26. #pragma mark ===== Encryption function =====
  27. #pragma --------------------------------------------------------------------------------------------
  28. // return password
  29. - (NSString *)getKeyPasscode:(NSString *)uuid
  30. {
  31. NSString *key;
  32. NSString *passcode = [CCUtility getKeyChainPasscodeForUUID:uuid];
  33. if (passcode) key = [AESCrypt encrypt:uuid password:passcode];
  34. return key;
  35. }
  36. - (void)autoInsertPasscodeUUID:(NSString *)uuid text:(NSString *)text
  37. {
  38. NSString *key;
  39. NSString *passcode;
  40. // if return the passcode the UUID it has already entered
  41. if ([CCUtility getKeyChainPasscodeForUUID:uuid]) return;
  42. // verify if the password of the UUID insert is good (OPTIMIZATION)
  43. passcode = [CCUtility getKeyChainPasscodeForUUID:[CCUtility getUUID]];
  44. key = [AESCrypt encrypt:uuid password:passcode];
  45. // if the decryption it's ok insert UUID with Passcode in KeyChain
  46. if([AESCrypt decrypt:text password:key]) [CCUtility setKeyChainPasscodeForUUID:uuid conPasscode:passcode];
  47. }
  48. - (BOOL)verifyPasscode:(NSString *)passcode uuid:(NSString*)uuid text:(NSString *)text
  49. {
  50. NSString *key;
  51. key = [AESCrypt encrypt:uuid password:passcode];
  52. NSString *textDecrypted = [AESCrypt decrypt:text password:key];
  53. if([textDecrypted length]) return true;
  54. else return false;
  55. }
  56. - (BOOL)createFilePlist:(NSString *)fileNamePath title:(NSString *)title len:(NSUInteger)len directory:(BOOL)directory uuid:(NSString *)uuid nameCurrentDevice:(NSString *)nameCurrentDevice icon:(NSString *)icon
  57. {
  58. NSMutableDictionary *data;
  59. NSString *hint = [CCUtility getHint];
  60. // se non ha già l'estensione plist aggiungila
  61. if([fileNamePath rangeOfString:@".plist"].location == NSNotFound) fileNamePath = [fileNamePath stringByAppendingString:@".plist"];
  62. if ([[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
  63. data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
  64. else
  65. data = [[NSMutableDictionary alloc] init];
  66. [data setObject: [NSNumber numberWithBool:directory] forKey:@"dir"];
  67. if ([hint length] > 0) [data setObject:[AESCrypt encrypt:hint password:UUID_SIM] forKey:@"hint"];
  68. if ([icon length] > 0) [data setObject:icon forKey:@"icon"];
  69. [data setObject: [NSString stringWithFormat:@"%li", (unsigned long)len] forKey:@"len"];
  70. [data setObject: nameCurrentDevice forKey:@"namecurrentdevice"];
  71. [data setObject: versionProtocolPlist forKey:@"protocol"];
  72. [data setObject: title forKey:@"title"];
  73. [data setObject: k_metadataType_file forKey:@"type"];
  74. [data setObject: uuid forKey:@"uuid"];
  75. [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
  76. return [data writeToFile:fileNamePath atomically:YES];
  77. }
  78. - (void)addPlistImage:(NSString *)fileNamePath fileNamePathImage:(NSString *)fileNamePathImage
  79. {
  80. NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
  81. if (plist) {
  82. UIImage *image = [UIImage imageWithContentsOfFile:fileNamePathImage];
  83. if (image) {
  84. NSData *dataImage = UIImagePNGRepresentation(image);
  85. NSError *error;
  86. NSString *passcode = [self getKeyPasscode:[CCUtility getUUID]];
  87. if (passcode) dataImage = [RNEncryptor encryptData:dataImage withSettings:kRNCryptorAES256Settings password:passcode error:&error];
  88. else dataImage = nil;
  89. if (dataImage && error == nil) {
  90. [plist setObject:dataImage forKey:@"image"];
  91. [plist writeToFile:fileNamePath atomically:YES];
  92. }
  93. }
  94. }
  95. }
  96. - (BOOL)updateTitleFilePlist:(NSString *)fileName title:(NSString *)title directoryUser:(NSString *)directoryUser
  97. {
  98. // if not plist extension add it
  99. if([fileName rangeOfString:@".plist"].location == NSNotFound) fileName = [fileName stringByAppendingString:@".plist"];
  100. // open file plist
  101. NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName]];
  102. if (data) {
  103. [data setObject:title forKey:@"title"];
  104. [data writeToFile:[NSTemporaryDirectory() stringByAppendingString:fileName] atomically:YES];
  105. return YES;
  106. }
  107. return NO;
  108. }
  109. - (NSString *)createFileDirectoryPlist:(CCMetadata *)metadata
  110. {
  111. NSMutableDictionary *data;
  112. NSString *fileName = [self createFilenameEncryptor:metadata.fileNamePrint uuid:metadata.uuid];
  113. NSString *title = [AESCrypt encrypt:metadata.fileNamePrint password:[self getKeyPasscode:metadata.uuid]];
  114. NSString *fileNamePath = [NSString stringWithFormat:@"%@%@.plist", NSTemporaryDirectory(), fileName];
  115. NSString *hint = [CCUtility getHint];
  116. if ([[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
  117. data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
  118. else
  119. data = [[NSMutableDictionary alloc] init];
  120. [data setObject: [NSNumber numberWithBool:true] forKey:@"dir"];
  121. if ([hint length] > 0) [data setObject: [AESCrypt encrypt:hint password:UUID_SIM] forKey:@"hint"];
  122. [data setObject: @"0" forKey:@"len"];
  123. [data setObject: metadata.nameCurrentDevice forKey:@"namecurrentdevice"];
  124. [data setObject: versionProtocolPlist forKey:@"protocol"];
  125. [data setObject: title forKey:@"title"];
  126. [data setObject: k_metadataType_file forKey:@"type"];
  127. [data setObject: metadata.uuid forKey:@"uuid"];
  128. [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
  129. if ([data writeToFile:fileNamePath atomically:YES]) return fileName;
  130. else return nil;
  131. }
  132. - (BOOL)createTemplatesPlist:(NSString *)nameFile title:(NSString *)title uuid:(NSString *)uuid icon:(NSString *)icon model:(NSString *)model dictionary:(NSMutableDictionary*)dictionary
  133. {
  134. NSString *encrypted;
  135. NSString *passcode = [self getKeyPasscode:uuid];
  136. NSString *fileNamePath = [NSTemporaryDirectory() stringByAppendingString:nameFile];
  137. NSString *fileCryptoPath = [NSTemporaryDirectory() stringByAppendingString:[CCUtility trasformedFileNamePlistInCrypto:nameFile]];
  138. NSString *hint = [CCUtility getHint];
  139. NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
  140. for (NSString *key in [dictionary allKeys]) {
  141. encrypted = [CCUtility stringValueForKey:key conDictionary:dictionary];
  142. if ([encrypted length] == 0) encrypted = @"";
  143. else encrypted = [AESCrypt encrypt:encrypted password:passcode];
  144. [dictionary setObject:encrypted forKey:key];
  145. }
  146. [data setObject: dictionary forKey:@"field"];
  147. if ([hint length] > 0) [data setObject: [AESCrypt encrypt:hint password:UUID_SIM] forKey:@"hint"];
  148. [data setObject: icon forKey:@"icon"];
  149. [data setObject: model forKey:@"model"];
  150. [data setObject: [CCUtility getNameCurrentDevice] forKey:@"namecurrentdevice"];
  151. [data setObject: versionProtocolPlist forKey:@"protocol"];
  152. [data setObject: title forKey:@"title"];
  153. [data setObject: k_metadataType_model forKey:@"type"];
  154. [data setObject: uuid forKey:@"uuid"];
  155. [data setObject: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] forKey:@"version"];
  156. BOOL ritorno = [data writeToFile:fileNamePath atomically:YES];
  157. if (ritorno)
  158. [CCUtility copyFileAtPath:fileNamePath toPath:fileCryptoPath];
  159. return ritorno;
  160. }
  161. - (NSMutableDictionary *)getDictionaryEncrypted:(NSString *)fileName uuid:(NSString *)uuid isLocal:(BOOL)isLocal directoryUser:(NSString *)directoryUser
  162. {
  163. NSMutableDictionary *data;
  164. NSString *clearText;
  165. NSString *passcode = [self getKeyPasscode:uuid];
  166. NSString *serverUrl;
  167. if (isLocal) serverUrl = [CCUtility getDirectoryLocal];
  168. else serverUrl = directoryUser;
  169. NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@", serverUrl, fileName];
  170. if (![[NSFileManager defaultManager] fileExistsAtPath:fileNamePath])
  171. return nil;
  172. data = [[NSMutableDictionary alloc] initWithContentsOfFile:fileNamePath];
  173. if (!data)
  174. return nil;
  175. NSMutableDictionary *dictionary = [data objectForKey:@"field"];
  176. for (NSString *key in [dictionary allKeys]) {
  177. NSString *valore = [dictionary objectForKey:key];
  178. if ([valore length]) clearText = [AESCrypt decrypt:valore password:passcode];
  179. else clearText = @"";
  180. if ([clearText length]) [dictionary setObject:clearText forKey:key];
  181. }
  182. return dictionary;
  183. }
  184. - (NSString *)getHintFromFile:(NSString *)fileName isLocal:(BOOL)isLocal directoryUser:(NSString *)directoryUser
  185. {
  186. NSString *serverUrl;
  187. if (isLocal) serverUrl = [CCUtility getDirectoryLocal];
  188. else serverUrl = directoryUser;
  189. NSString *filePath = [NSString stringWithFormat:@"%@/%@", serverUrl, fileName];
  190. if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
  191. return nil;
  192. NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
  193. if (!data)
  194. return nil;
  195. NSString *hintCryptated = [data objectForKey:@"hint"];
  196. if ([hintCryptated length] > 0) return [AESCrypt decrypt:hintCryptated password:UUID_SIM];
  197. else return nil;
  198. }
  199. - (NSString *)createFilenameEncryptor:(NSString *)fileName uuid:(NSString *)uuid
  200. {
  201. NSMutableString *cryptoString = [NSMutableString stringWithCapacity: 64];
  202. NSString *letters = @"0J7pfXHaCPTasxQDFsUDcSDiHJmVjgzsqDUUQU75IPYrT13YKNJpvvEq0hH2uDD06mhNxvb8";
  203. NSString *temp = [NSString stringWithFormat:@"%@|%@|%@", fileName, uuid, uuid];
  204. temp = [temp substringToIndex:64];
  205. for (int i=0; i<64; i++){
  206. NSString *numero = [temp substringWithRange:NSMakeRange(i, 1)];
  207. NSInteger index = [numero integerValue];
  208. if (index > 0) [cryptoString appendFormat: @"%C", [letters characterAtIndex:index]];
  209. else [cryptoString appendFormat: @"%C", [letters characterAtIndex:i]];
  210. }
  211. return [NSString stringWithFormat:@"%@crypto", cryptoString];
  212. }
  213. #pragma --------------------------------------------------------------------------------------------
  214. #pragma mark ===== Encypt =====
  215. #pragma---------------------------------------------------------------------------------------------
  216. - (NSString *)encryptWithCreatePlist:(NSString *)fileName fileNameEncrypted:(NSString*)fileNameEncrypted passcode:(NSString *)passcode directoryUser:(NSString *)directoryUser
  217. {
  218. NSString *uuid = [CCUtility getUUID];
  219. NSString *nameCurrentDevice = [CCUtility getNameCurrentDevice];
  220. NSString *title = [AESCrypt encrypt:fileName password:passcode];
  221. NSString *fileNameCrypto = [self createFilenameEncryptor:fileNameEncrypted uuid:uuid];
  222. NSError *error;
  223. NSUInteger lenData = (NSUInteger)[[[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName] error:nil] fileSize];
  224. NSUInteger lenEncryptedData;
  225. @autoreleasepool {
  226. NSData *encryptedData = [RNEncryptor encryptData:[NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileName]] withSettings:kRNCryptorAES256Settings password:passcode error:&error];
  227. lenEncryptedData = encryptedData.length;
  228. if (!error && lenEncryptedData > 0)
  229. [encryptedData writeToFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameCrypto] atomically:YES];
  230. }
  231. if (error || lenEncryptedData == 0 || lenData == 0) {
  232. [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameEncrypted] error:nil];
  233. NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"_encrypt_error_", nil), fileName, [error localizedDescription]];
  234. NSLog(@"[LOG] Error encrypt file %@ Err. %@", fileName, msg);
  235. return nil;
  236. }
  237. [self createFilePlist:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameCrypto] title:title len:lenData directory:NO uuid:uuid nameCurrentDevice:nameCurrentDevice icon:nil];
  238. return fileNameCrypto;
  239. }
  240. #pragma --------------------------------------------------------------------------------------------
  241. #pragma mark ===== Decrypt =====
  242. #pragma---------------------------------------------------------------------------------------------
  243. - (NSUInteger)decrypt:(NSString *)fileName fileNameDecrypted:(NSString*)fileNameDecrypted fileNamePrint:(NSString *)fileNamePrint password:(NSString *)password directoryUser:(NSString *)directoryUser
  244. {
  245. NSError *error;
  246. NSUInteger len;
  247. @autoreleasepool {
  248. NSData *decryptedData = [RNDecryptor decryptData:[NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.crypt", directoryUser, fileName]] withSettings:kRNCryptorAES256Settings password:password error:&error];
  249. len = decryptedData.length;
  250. if (!error && decryptedData > 0)
  251. [decryptedData writeToFile:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameDecrypted] atomically:YES];
  252. }
  253. if (error || len == 0) {
  254. [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@", directoryUser, fileNameDecrypted] error:nil];
  255. NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"_decrypt_error_", nil), fileNamePrint, [error localizedDescription]];
  256. NSLog(@"[LOG] Error decrypt file %@ Err. %@", fileName, msg);
  257. return 0;
  258. }
  259. return len;
  260. }
  261. @end