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.

1009 lines
32 KiB

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