You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1017 lines
30 KiB

7 years ago
3 years ago
7 years ago
3 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. //
  2. // PEPSession.m
  3. // pEpiOSAdapter
  4. //
  5. // Created by Volker Birk on 08.07.15.
  6. // Copyright (c) 2015 pp. All rights reserved.
  7. //
  8. #import "PEPInternalSession.h"
  9. #import <PEPObjCTypeUtils/PEPObjCTypeUtils.h>
  10. #import "PEPConstants.h"
  11. #import "PEPObjCAdapter.h"
  12. #import "PEPObjCAdapter+Internal.h"
  13. #import "PEPLanguage.h"
  14. #import "PEPCSVScanner.h"
  15. #import "NSArray+Take.h"
  16. #import "PEPIdentity.h"
  17. #import "PEPMessage.h"
  18. #import "NSError+PEP+Internal.h"
  19. #import "PEPAutoPointer.h"
  20. #import "NSNumber+PEPRating.h"
  21. #import "PEPSync.h"
  22. #import "PEPSync_Internal.h" // for [PEPSync createSession:]
  23. #import "PEPInternalConstants.h"
  24. #import "PEPPassphraseCache.h"
  25. #import "PEPInternalSession+PassphraseCache.h"
  26. #import "NSString+NormalizePassphrase.h"
  27. #import "PEPIdentity+Reset.h"
  28. #import "key_reset.h"
  29. @implementation PEPInternalSession
  30. - (_Nullable instancetype)init
  31. {
  32. self = [super init];
  33. if (self) {
  34. [PEPInternalSession setupTrustWordsDB];
  35. // Get an engine session from PEPSync, because its creation requires callbacks
  36. // that PEPSync is responsible for.
  37. _session = [PEPSync createSession:nil];
  38. // [PEPSync createSession:] has already logged any errors.
  39. if (!_session) {
  40. return nil;
  41. }
  42. }
  43. return self;
  44. }
  45. - (void)dealloc
  46. {
  47. if (_session != nil) {
  48. release(_session);
  49. }
  50. }
  51. #pragma mark - CONFIG
  52. - (void)configUnEncryptedSubjectEnabled:(BOOL)enabled;
  53. {
  54. config_unencrypted_subject(self.session, enabled);
  55. }
  56. #pragma mark - INTERNAL
  57. + (void)setupTrustWordsDB
  58. {
  59. static dispatch_once_t once;
  60. dispatch_once(&once, ^{
  61. [PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]];
  62. });
  63. }
  64. #pragma mark - API
  65. void decryptMessageFree(message *src, message *dst, stringlist_t *extraKeys)
  66. {
  67. free_message(src);
  68. free_message(dst);
  69. free_stringlist(extraKeys);
  70. }
  71. - (PEPMessage * _Nullable)decryptMessage:(PEPMessage * _Nonnull)theMessage
  72. flags:(PEPDecryptFlags * _Nullable)flags
  73. rating:(PEPRating * _Nullable)rating
  74. extraKeys:(PEPStringList * _Nullable * _Nullable)extraKeys
  75. status:(PEPStatus * _Nullable)status
  76. error:(NSError * _Nullable * _Nullable)error
  77. {
  78. if (rating) {
  79. *rating = PEPRatingUndefined;
  80. }
  81. message *_src = [theMessage toStruct];
  82. __block message *_dst = NULL;
  83. __block stringlist_t *theKeys = NULL;
  84. __block PEPDecryptFlags theFlags = 0;
  85. if (flags) {
  86. theFlags = *flags;
  87. }
  88. if (extraKeys && [*extraKeys count]) {
  89. theKeys = [*extraKeys toStringList];
  90. }
  91. __block PEPRating internalRating = PEPRatingUndefined;
  92. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  93. return decrypt_message(session,
  94. _src,
  95. &_dst,
  96. &theKeys,
  97. (PEP_rating *) &internalRating,
  98. (PEP_decrypt_flags *) &theFlags);
  99. }];
  100. if (status) {
  101. *status = theStatus;
  102. }
  103. if ([NSError setError:error fromPEPStatus:theStatus]) {
  104. decryptMessageFree(_src, _dst, theKeys);
  105. return nil;
  106. }
  107. if (flags) {
  108. *flags = theFlags;
  109. }
  110. PEPMessage *dst_;
  111. if (_dst) {
  112. dst_ = [PEPMessage fromStruct:_dst];
  113. } else {
  114. dst_ = [PEPMessage fromStruct:_src];
  115. }
  116. if (theFlags & PEP_decrypt_flag_untrusted_server) {
  117. [theMessage overWriteFromStruct:_src];
  118. }
  119. if (extraKeys) {
  120. *extraKeys = [NSArray arrayFromStringlist:theKeys];
  121. }
  122. decryptMessageFree(_src, _dst, theKeys);
  123. if (rating) {
  124. *rating = internalRating;
  125. }
  126. return dst_;
  127. }
  128. - (BOOL)reEvaluateMessage:(PEPMessage * _Nonnull)theMessage
  129. xKeyList:(PEPStringList * _Nullable)xKeyList
  130. rating:(PEPRating * _Nonnull)rating
  131. status:(PEPStatus * _Nullable)status
  132. error:(NSError * _Nullable * _Nullable)error
  133. {
  134. message *_src = [theMessage toStruct];
  135. stringlist_t *theKeys = NULL;
  136. if ([xKeyList count]) {
  137. theKeys = [xKeyList toStringList];
  138. }
  139. PEPRating originalRating = *rating;
  140. __block PEPRating resultRating = PEPRatingUndefined;
  141. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  142. PEP_STATUS tmpStatus = re_evaluate_message_rating(session,
  143. _src,
  144. theKeys,
  145. (PEP_rating) originalRating,
  146. (PEP_rating *) &resultRating);
  147. *rating = resultRating;
  148. return tmpStatus;
  149. }];
  150. free_message(_src);
  151. free_stringlist(theKeys);
  152. if (status) {
  153. *status = theStatus;
  154. }
  155. if ([NSError setError:error fromPEPStatus:theStatus]) {
  156. return NO;
  157. } else {
  158. return YES;
  159. }
  160. }
  161. - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage
  162. extraKeys:(PEPStringList * _Nullable)extraKeys
  163. encFormat:(PEPEncFormat)encFormat
  164. status:(PEPStatus * _Nullable)status
  165. error:(NSError * _Nullable * _Nullable)error
  166. {
  167. // Don't change the original
  168. PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage];
  169. __block PEP_encrypt_flags_t flags = 0;
  170. __block message *_src = [[messageCopy removeEmptyRecipients] toStruct];
  171. __block message *_dst = NULL;
  172. __block stringlist_t *_keys = [extraKeys toStringList];
  173. PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  174. return encrypt_message(session,
  175. _src,
  176. _keys,
  177. &_dst,
  178. (PEP_enc_format) encFormat,
  179. flags);
  180. }];
  181. if (status) {
  182. *status = theStatus;
  183. }
  184. if ([NSError setError:error fromPEPStatus:theStatus]) {
  185. return nil;
  186. }
  187. PEPMessage *dst_;
  188. if (_dst) {
  189. dst_ = [PEPMessage fromStruct:_dst];
  190. }
  191. else {
  192. dst_ = [PEPMessage fromStruct:_src];
  193. }
  194. free_message(_src);
  195. free_message(_dst);
  196. free_stringlist(_keys);
  197. return dst_;
  198. }
  199. - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)message
  200. extraKeys:(PEPStringList * _Nullable)extraKeys
  201. status:(PEPStatus * _Nullable)status
  202. error:(NSError * _Nullable * _Nullable)error
  203. {
  204. return [self
  205. encryptMessage:message
  206. extraKeys:extraKeys
  207. encFormat:PEPEncFormatPEP
  208. status:status
  209. error:error];
  210. }
  211. - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage
  212. forSelf:(PEPIdentity * _Nonnull)ownIdentity
  213. extraKeys:(PEPStringList * _Nullable)extraKeys
  214. status:(PEPStatus * _Nullable)status
  215. error:(NSError * _Nullable * _Nullable)error
  216. {
  217. // Don't change the original
  218. PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage];
  219. __block PEP_encrypt_flags_t flags = 0;
  220. __block message *_src = [[messageCopy removeEmptyRecipients] toStruct];
  221. __block pEp_identity *ident = [ownIdentity toStruct];
  222. __block message *_dst = NULL;
  223. __block stringlist_t *keysStringList = [extraKeys toStringList];
  224. PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  225. return encrypt_message_for_self(session,
  226. ident,
  227. _src,
  228. keysStringList,
  229. &_dst,
  230. PEP_enc_PGP_MIME,
  231. flags);
  232. }];
  233. free_stringlist(keysStringList);
  234. if (status) {
  235. *status = theStatus;
  236. }
  237. if ([NSError setError:error fromPEPStatus:theStatus]) {
  238. return nil;
  239. }
  240. PEPMessage *dst_;
  241. if (_dst) {
  242. dst_ = [PEPMessage fromStruct:_dst];
  243. }
  244. else {
  245. dst_ = [PEPMessage fromStruct:_src];
  246. }
  247. free_message(_src);
  248. free_message(_dst);
  249. free_identity(ident);
  250. return dst_;
  251. }
  252. - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage
  253. toFpr:(NSString * _Nonnull)toFpr
  254. encFormat:(PEPEncFormat)encFormat
  255. flags:(PEPDecryptFlags)flags
  256. status:(PEPStatus * _Nullable)status
  257. error:(NSError * _Nullable * _Nullable)error
  258. {
  259. // Don't change the original
  260. PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage];
  261. message *src = [[messageCopy removeEmptyRecipients] toStruct];
  262. __block message *dst = NULL;
  263. PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  264. return encrypt_message_and_add_priv_key(session,
  265. src,
  266. &dst,
  267. [[toFpr precomposedStringWithCanonicalMapping] UTF8String],
  268. (PEP_enc_format) encFormat,
  269. flags);
  270. }];
  271. if (status) {
  272. *status = theStatus;
  273. }
  274. if ([NSError setError:error fromPEPStatus:theStatus]) {
  275. return nil;
  276. }
  277. if (dst) {
  278. // As long as dst is non-nil, the result is also non-nil
  279. PEPMessage *result = [PEPMessage fromStruct:dst];
  280. return result;
  281. }
  282. return nil;
  283. }
  284. - (NSNumber * _Nullable)outgoingRatingForMessage:(PEPMessage * _Nonnull)theMessage
  285. error:(NSError * _Nullable * _Nullable)error
  286. {
  287. message *_msg = [theMessage toStruct];
  288. __block PEPRating rating = PEPRatingUndefined;
  289. PEPStatus status = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  290. return outgoing_message_rating(session, _msg, (PEP_rating *) &rating);
  291. }];
  292. free_message(_msg);
  293. if ([NSError setError:error fromPEPStatus:status]) {
  294. return nil;
  295. }
  296. return [NSNumber numberWithPEPRating:rating];
  297. }
  298. - (NSNumber * _Nullable)outgoingRatingPreviewForMessage:(PEPMessage * _Nonnull)theMessage
  299. error:(NSError * _Nullable * _Nullable)error
  300. {
  301. message *_msg = [theMessage toStruct];
  302. PEPRating rating = PEPRatingUndefined;
  303. PEPStatus status = (PEPStatus) outgoing_message_rating_preview(_session,
  304. _msg,
  305. (PEP_rating *) &rating);
  306. free_message(_msg);
  307. if ([NSError setError:error fromPEPStatus:status]) {
  308. return nil;
  309. }
  310. return [NSNumber numberWithPEPRating:rating];
  311. }
  312. - (NSNumber * _Nullable)ratingForIdentity:(PEPIdentity * _Nonnull)identity
  313. error:(NSError * _Nullable * _Nullable)error
  314. {
  315. pEp_identity *ident = [identity toStruct];
  316. __block PEPRating rating = PEPRatingUndefined;
  317. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  318. return identity_rating(session, ident, (PEP_rating *) &rating);
  319. }];
  320. free_identity(ident);
  321. if ([NSError setError:error fromPEPStatus:status]) {
  322. return nil;
  323. }
  324. return [NSNumber numberWithPEPRating:rating];
  325. }
  326. - (NSArray<NSString *> * _Nullable)trustwordsForFingerprint:(NSString * _Nonnull)fingerprint
  327. languageID:(NSString * _Nonnull)languageID
  328. shortened:(BOOL)shortened
  329. error:(NSError * _Nullable * _Nullable)error
  330. {
  331. NSMutableArray *array = [NSMutableArray array];
  332. for (int i = 0; i < [fingerprint length]; i += 4) {
  333. if (shortened && i >= 20)
  334. break;
  335. NSString *str = [fingerprint substringWithRange:NSMakeRange(i, 4)];
  336. unsigned int value;
  337. [[NSScanner scannerWithString:str] scanHexInt:&value];
  338. PEPAutoPointer *word = [PEPAutoPointer new];
  339. __block size_t size;
  340. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  341. return trustword(session,
  342. value,
  343. [[languageID precomposedStringWithCanonicalMapping]
  344. UTF8String],
  345. word.charPointerPointer,
  346. &size);
  347. }];
  348. if ([NSError setError:error fromPEPStatus:status]) {
  349. return nil;
  350. }
  351. [array addObject:[NSString stringWithUTF8String:word.charPointer]];
  352. }
  353. return array;
  354. }
  355. - (BOOL)mySelf:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error
  356. {
  357. pEp_identity *ident = [identity toStruct];
  358. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  359. return myself(session, ident);
  360. }];
  361. if ([NSError setError:error fromPEPStatus:status]) {
  362. free_identity(ident);
  363. return NO;
  364. }
  365. [identity reset];
  366. [identity overWriteFromStruct:ident];
  367. free_identity(ident);
  368. return YES;
  369. }
  370. - (BOOL)updateIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error
  371. {
  372. if (identity.isOwn) {
  373. return [self mySelf:identity error:error];
  374. } else {
  375. pEp_identity *ident = [identity toStruct];
  376. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  377. return update_identity(session, ident);
  378. }];
  379. if ([NSError setError:error fromPEPStatus:status]) {
  380. free_identity(ident);
  381. return NO;
  382. }
  383. [identity reset];
  384. [identity overWriteFromStruct:ident];
  385. free_identity(ident);
  386. return YES;
  387. }
  388. }
  389. - (BOOL)trustPersonalKey:(PEPIdentity * _Nonnull)identity
  390. error:(NSError * _Nullable * _Nullable)error
  391. {
  392. pEp_identity *ident = [identity toStruct];
  393. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  394. return trust_personal_key(session, ident);
  395. }];
  396. if ([NSError setError:error fromPEPStatus:status]) {
  397. free_identity(ident);
  398. return NO;
  399. }
  400. free_identity(ident);
  401. return YES;
  402. }
  403. - (BOOL)keyMistrusted:(PEPIdentity *)identity error:(NSError * _Nullable * _Nullable)error
  404. {
  405. pEp_identity *ident = [identity toStruct];
  406. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  407. return key_mistrusted(session, ident);
  408. }];
  409. if ([NSError setError:error fromPEPStatus:status]) {
  410. free_identity(ident);
  411. return NO;
  412. }
  413. free_identity(ident);
  414. return YES;
  415. }
  416. - (BOOL)keyResetTrust:(PEPIdentity * _Nonnull)identity
  417. error:(NSError * _Nullable * _Nullable)error
  418. {
  419. __block pEp_identity *ident = [identity toStruct];
  420. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  421. return key_reset_trust(session, ident);
  422. }];
  423. if ([NSError setError:error fromPEPStatus:theStatus]) {
  424. free_identity(ident);
  425. return NO;
  426. }
  427. free_identity(ident);
  428. return YES;
  429. }
  430. - (BOOL)enableSyncForIdentity:(PEPIdentity * _Nonnull)identity
  431. error:(NSError * _Nullable * _Nullable)error
  432. {
  433. if (!identity.isOwn) {
  434. [NSError setError:error fromPEPStatus:PEPStatusIllegalValue];
  435. return NO;
  436. }
  437. pEp_identity *ident = [identity toStruct];
  438. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  439. return enable_identity_for_sync(session, ident);
  440. }];
  441. if ([NSError setError:error fromPEPStatus:status]) {
  442. free_identity(ident);
  443. return NO;
  444. }
  445. free_identity(ident);
  446. return YES;
  447. }
  448. - (BOOL)disableSyncForIdentity:(PEPIdentity * _Nonnull)identity
  449. error:(NSError * _Nullable * _Nullable)error
  450. {
  451. if (!identity.isOwn) {
  452. [NSError setError:error fromPEPStatus:PEPStatusIllegalValue];
  453. return NO;
  454. }
  455. pEp_identity *ident = [identity toStruct];
  456. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  457. return disable_identity_for_sync(session, ident);
  458. }];
  459. if ([NSError setError:error fromPEPStatus:theStatus]) {
  460. free_identity(ident);
  461. return NO;
  462. }
  463. free_identity(ident);
  464. return YES;
  465. }
  466. - (NSArray<PEPIdentity *> * _Nullable)importKey:(NSString * _Nonnull)keydata
  467. error:(NSError * _Nullable * _Nullable)error
  468. {
  469. __block identity_list *identList = NULL;
  470. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  471. return import_key(session,
  472. [[keydata precomposedStringWithCanonicalMapping] UTF8String],
  473. [keydata length], &identList);
  474. }];
  475. if ([NSError setError:error fromPEPStatus:status]) {
  476. free(identList);
  477. return nil;
  478. }
  479. NSArray *idents = [NSArray arrayFromIdentityList:identList];
  480. free(identList);
  481. return idents;
  482. }
  483. - (BOOL)logTitle:(NSString * _Nonnull)title
  484. entity:(NSString * _Nonnull)entity
  485. description:(NSString * _Nullable)description
  486. comment:(NSString * _Nullable)comment
  487. error:(NSError * _Nullable * _Nullable)error
  488. {
  489. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  490. return log_event(session,
  491. [[title precomposedStringWithCanonicalMapping]
  492. UTF8String],
  493. [[entity precomposedStringWithCanonicalMapping]
  494. UTF8String],
  495. [[description precomposedStringWithCanonicalMapping]
  496. UTF8String],
  497. [[comment precomposedStringWithCanonicalMapping]
  498. UTF8String]);
  499. }];
  500. if ([NSError setError:error fromPEPStatus:status]) {
  501. return NO;
  502. } else {
  503. return YES;
  504. }
  505. }
  506. - (NSString * _Nullable)getLogWithError:(NSError * _Nullable * _Nullable)error
  507. {
  508. __block char *theChars = NULL;
  509. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  510. return get_crashdump_log(session, 0, &theChars);
  511. }];
  512. if ([NSError setError:error fromPEPStatus:status]) {
  513. return nil;
  514. }
  515. if (theChars) {
  516. return [NSString stringWithUTF8String:theChars];
  517. } else {
  518. [NSError setError:error fromPEPStatus:(PEPStatus) PEP_UNKNOWN_ERROR];
  519. return nil;
  520. }
  521. }
  522. - (NSString * _Nullable)getTrustwordsIdentity1:(PEPIdentity * _Nonnull)identity1
  523. identity2:(PEPIdentity * _Nonnull)identity2
  524. language:(NSString * _Nullable)language
  525. full:(BOOL)full
  526. error:(NSError * _Nullable * _Nullable)error
  527. {
  528. pEp_identity *ident1 = [identity1 toStruct];
  529. pEp_identity *ident2 = [identity2 toStruct];
  530. PEPAutoPointer *trustwords = [PEPAutoPointer new];
  531. __block size_t sizeWritten = 0;
  532. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  533. return get_trustwords(session, ident1, ident2,
  534. [[language precomposedStringWithCanonicalMapping]
  535. UTF8String],
  536. trustwords.charPointerPointer, &sizeWritten, full);
  537. }];
  538. free_identity(ident1);
  539. free_identity(ident2);
  540. NSString *result = nil;
  541. if (![NSError setError:error fromPEPStatus:status]) {
  542. result = [NSString stringWithUTF8String:trustwords.charPointer];
  543. }
  544. return result;
  545. }
  546. - (NSString * _Nullable)getTrustwordsFpr1:(NSString * _Nonnull)fpr1
  547. fpr2:(NSString * _Nonnull)fpr2
  548. language:(NSString * _Nullable)language
  549. full:(BOOL)full
  550. error:(NSError * _Nullable * _Nullable)error
  551. {
  552. const char *_fpr1 = [fpr1 UTF8String]; // fprs are NFC normalized anyway
  553. const char *_fpr2 = [fpr2 UTF8String];
  554. PEPAutoPointer *trustwords = [PEPAutoPointer new];
  555. __block size_t sizeWritten = 0;
  556. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  557. return get_trustwords_for_fprs(session, _fpr1, _fpr2,
  558. [[language precomposedStringWithCanonicalMapping]
  559. UTF8String],
  560. trustwords.charPointerPointer, &sizeWritten, full);
  561. }];
  562. NSString *result = nil;
  563. if (![NSError setError:error fromPEPStatus:status]) {
  564. result = [NSString stringWithUTF8String:trustwords.charPointer];
  565. }
  566. return result;
  567. }
  568. - (NSArray<PEPLanguage *> * _Nullable)languageListWithError:(NSError * _Nullable * _Nullable)error
  569. {
  570. PEPAutoPointer *chLangs = [PEPAutoPointer new];
  571. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  572. return get_languagelist(session, chLangs.charPointerPointer);
  573. }];
  574. if ([NSError setError:error fromPEPStatus:status]) {
  575. return nil;
  576. }
  577. NSString *parserInput = [NSString stringWithUTF8String:chLangs.charPointer];
  578. NSMutableArray<NSString *> *tokens = [NSMutableArray array];
  579. PEPCSVScanner *scanner = [[PEPCSVScanner alloc] initWithString:parserInput];
  580. while (YES) {
  581. NSString *token = [scanner nextString];
  582. if (!token) {
  583. break;
  584. }
  585. [tokens addObject:token];
  586. }
  587. NSArray *theTokens = [NSArray arrayWithArray:tokens];
  588. NSMutableArray<PEPLanguage *> *langs = [NSMutableArray new];
  589. while (YES) {
  590. ArrayTake *take = [theTokens takeOrNil:3];
  591. if (!take) {
  592. break;
  593. }
  594. NSArray *elements = take.elements;
  595. PEPLanguage *lang = [[PEPLanguage alloc]
  596. initWithCode:[elements objectAtIndex:0]
  597. name:[elements objectAtIndex:1]
  598. sentence:[elements objectAtIndex:2]];
  599. [langs addObject:lang];
  600. theTokens = take.rest;
  601. }
  602. return [NSArray arrayWithArray:langs];
  603. }
  604. static NSDictionary *ratingToString;
  605. static NSDictionary *stringToRating;
  606. + (void)initialize
  607. {
  608. NSDictionary *ratingToStringIntern =
  609. @{
  610. [NSNumber numberWithInteger:PEPRatingCannotDecrypt]: @"cannot_decrypt",
  611. [NSNumber numberWithInteger:PEPRatingHaveNoKey]: @"have_no_key",
  612. [NSNumber numberWithInteger:PEPRatingUnencrypted]: @"unencrypted",
  613. [NSNumber numberWithInteger:PEPRatingUnreliable]: @"unreliable",
  614. [NSNumber numberWithInteger:PEPRatingReliable]: @"reliable",
  615. [NSNumber numberWithInteger:PEPRatingTrusted]: @"trusted",
  616. [NSNumber numberWithInteger:PEPRatingTrustedAndAnonymized]: @"trusted_and_anonymized",
  617. [NSNumber numberWithInteger:PEPRatingFullyAnonymous]: @"fully_anonymous",
  618. [NSNumber numberWithInteger:PEPRatingMistrust]: @"mistrust",
  619. [NSNumber numberWithInteger:PEPRatingB0rken]: @"b0rken",
  620. [NSNumber numberWithInteger:PEPRatingUnderAttack]: @"under_attack",
  621. [NSNumber numberWithInteger:PEPRatingUndefined]: kUndefined,
  622. };
  623. NSMutableDictionary *stringToRatingMutable = [NSMutableDictionary
  624. dictionaryWithCapacity:
  625. ratingToStringIntern.count];
  626. for (NSNumber *ratingNumber in ratingToStringIntern.allKeys) {
  627. NSString *ratingName = [ratingToStringIntern objectForKey:ratingNumber];
  628. [stringToRatingMutable setObject:ratingNumber forKey:ratingName];
  629. }
  630. ratingToString = ratingToStringIntern;
  631. stringToRating = [NSDictionary dictionaryWithDictionary:stringToRatingMutable];
  632. }
  633. - (PEPRating)ratingFromString:(NSString * _Nonnull)string
  634. {
  635. NSNumber *num = [stringToRating objectForKey:string];
  636. if (num != nil) {
  637. return (PEPRating) [num integerValue];
  638. } else {
  639. return PEPRatingUndefined;
  640. }
  641. }
  642. - (NSString * _Nonnull)stringFromRating:(PEPRating)rating
  643. {
  644. NSString *stringRating = [ratingToString objectForKey:[NSNumber numberWithInteger:rating]];
  645. if (stringRating) {
  646. return stringRating;
  647. } else {
  648. return kUndefined;
  649. }
  650. }
  651. - (NSNumber * _Nullable)isPEPUser:(PEPIdentity * _Nonnull)identity
  652. error:(NSError * _Nullable * _Nullable)error
  653. {
  654. pEp_identity *ident = [identity toStruct];
  655. __block bool isPEP;
  656. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  657. return is_pEp_user(session, ident, &isPEP);
  658. }];
  659. free_identity(ident);
  660. if ([NSError setError:error fromPEPStatus:status]) {
  661. return nil;
  662. } else {
  663. return [NSNumber numberWithBool:isPEP];
  664. }
  665. }
  666. - (BOOL)setOwnKey:(PEPIdentity * _Nonnull)identity fingerprint:(NSString * _Nonnull)fingerprint
  667. error:(NSError * _Nullable * _Nullable)error
  668. {
  669. pEp_identity *ident = [identity toStruct];
  670. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  671. return set_own_key(session,
  672. ident,
  673. [[fingerprint precomposedStringWithCanonicalMapping]
  674. UTF8String]);
  675. }];
  676. free_identity(ident);
  677. if ([NSError setError:error fromPEPStatus:status]) {
  678. return NO;
  679. } else {
  680. return YES;
  681. }
  682. }
  683. - (void)configurePassiveModeEnabled:(BOOL)enabled
  684. {
  685. config_passive_mode(_session, enabled);
  686. }
  687. - (BOOL)setFlags:(PEPIdentityFlags)flags
  688. forIdentity:(PEPIdentity *)identity
  689. error:(NSError * _Nullable * _Nullable)error
  690. {
  691. pEp_identity *ident = [identity toStruct];
  692. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  693. return set_identity_flags(session, ident, flags);
  694. }];
  695. if ([NSError setError:error fromPEPStatus:status]) {
  696. free_identity(ident);
  697. return NO;
  698. } else {
  699. [identity reset];
  700. [identity overWriteFromStruct:ident];
  701. free_identity(ident);
  702. return YES;
  703. }
  704. }
  705. - (BOOL)deliverHandshakeResult:(PEPSyncHandshakeResult)result
  706. identitiesSharing:(NSArray<PEPIdentity *> * _Nullable)identitiesSharing
  707. error:(NSError * _Nullable * _Nullable)error;
  708. {
  709. identity_list *identitiesSharingData = NULL;
  710. if (identitiesSharing) {
  711. identitiesSharingData = [identitiesSharing toIdentityList];
  712. }
  713. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  714. return deliverHandshakeResult(session,
  715. (sync_handshake_result) result,
  716. identitiesSharingData);
  717. }];
  718. free(identitiesSharingData);
  719. if ([NSError setError:error fromPEPStatus:status]) {
  720. return NO;
  721. } else {
  722. return YES;
  723. }
  724. }
  725. - (BOOL)trustOwnKeyIdentity:(PEPIdentity * _Nonnull)identity
  726. error:(NSError * _Nullable * _Nullable)error
  727. {
  728. pEp_identity *ident = [identity toStruct];
  729. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  730. return trust_own_key(session, ident);
  731. }];
  732. free_identity(ident);
  733. if ([NSError setError:error fromPEPStatus:status]) {
  734. return NO;
  735. } else {
  736. return YES;
  737. }
  738. }
  739. - (PEPColor)colorFromRating:(PEPRating)rating
  740. {
  741. return (PEPColor) color_from_rating((PEP_rating) rating);
  742. }
  743. - (BOOL)keyReset:(PEPIdentity * _Nonnull)identity
  744. fingerprint:(NSString * _Nullable)fingerprint
  745. error:(NSError * _Nullable * _Nullable)error
  746. {
  747. pEp_identity *ident = [identity toStruct];
  748. const char *fpr = [[fingerprint precomposedStringWithCanonicalMapping] UTF8String];
  749. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  750. return key_reset_user(session, ident->user_id, fpr);
  751. }];
  752. free_identity(ident);
  753. if ([NSError setError:error fromPEPStatus:theStatus]) {
  754. return NO;
  755. } else {
  756. return YES;
  757. }
  758. }
  759. - (BOOL)leaveDeviceGroup:(NSError * _Nullable * _Nullable)error
  760. {
  761. PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  762. return leave_device_group(session);
  763. }];
  764. if ([NSError setError:error fromPEPStatus:status]) {
  765. return NO;
  766. } else {
  767. return YES;
  768. }
  769. }
  770. - (BOOL)keyResetAllOwnKeysError:(NSError * _Nullable * _Nullable)error
  771. {
  772. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  773. return key_reset_all_own_keys(self.session);
  774. }];
  775. if ([NSError setError:error fromPEPStatus:theStatus]) {
  776. return NO;
  777. } else {
  778. return YES;
  779. }
  780. }
  781. - (BOOL)configurePassphrase:(NSString * _Nonnull)passphrase
  782. error:(NSError * _Nullable * _Nullable)error
  783. {
  784. if (error) {
  785. *error = nil;
  786. }
  787. NSString *normalizedPassphrase = [passphrase normalizedPassphraseWithError:error];
  788. if (normalizedPassphrase == nil) {
  789. return NO;
  790. }
  791. [self.passphraseCache addPassphrase:normalizedPassphrase];
  792. PEP_STATUS status = config_passphrase(_session, [normalizedPassphrase UTF8String]);
  793. if ([NSError setError:error fromPEPStatus:(PEPStatus) status]) {
  794. return NO;
  795. }
  796. [PEPSync.sharedInstance handleNewPassphraseConfigured];
  797. return YES;
  798. }
  799. - (PEPPassphraseCache * _Nonnull)passphraseCache
  800. {
  801. return [PEPPassphraseCache sharedInstance];
  802. }
  803. - (BOOL)disableAllSyncChannels:(NSError * _Nullable * _Nullable)error
  804. {
  805. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) {
  806. return disable_all_sync_channels(self.session);
  807. }];
  808. if ([NSError setError:error fromPEPStatus:theStatus]) {
  809. return NO;
  810. } else {
  811. return YES;
  812. }
  813. }
  814. @end