// // PEPSession.m // pEpiOSAdapter // // Created by Volker Birk on 08.07.15. // Copyright (c) 2015 p≡p. All rights reserved. // #import "PEPInternalSession.h" #import #import "PEPConstants.h" #import "PEPObjCAdapter.h" #import "PEPObjCAdapter+Internal.h" #import "PEPLanguage.h" #import "PEPCSVScanner.h" #import "NSArray+Take.h" #import "PEPIdentity.h" #import "PEPMessage.h" #import "PEPAutoPointer.h" #import "NSNumber+PEPRating.h" #import "PEPSync.h" #import "PEPSync_Internal.h" // for [PEPSync createSession:] #import "PEPInternalConstants.h" #import "PEPPassphraseCache.h" #import "PEPInternalSession+PassphraseCache.h" #import "NSString+NormalizePassphrase.h" #import "PEPIdentity+Reset.h" #import "key_reset.h" @implementation PEPInternalSession - (_Nullable instancetype)init { self = [super init]; if (self) { [PEPInternalSession setupTrustWordsDB]; // Get an engine session from PEPSync, because its creation requires callbacks // that PEPSync is responsible for. _session = [PEPSync createSession:nil]; // [PEPSync createSession:] has already logged any errors. if (!_session) { return nil; } } return self; } - (void)dealloc { if (_session != nil) { release(_session); } } #pragma mark - CONFIG - (void)configUnEncryptedSubjectEnabled:(BOOL)enabled; { config_unencrypted_subject(self.session, enabled); } #pragma mark - INTERNAL + (void)setupTrustWordsDB { static dispatch_once_t once; dispatch_once(&once, ^{ [PEPObjCAdapter setupTrustWordsDB:[NSBundle bundleForClass:[self class]]]; }); } void decryptMessageFree(message *src, message *dst, stringlist_t *extraKeys) { free_message(src); free_message(dst); free_stringlist(extraKeys); } #pragma mark - API - (PEPMessage * _Nullable)decryptMessage:(PEPMessage * _Nonnull)theMessage flags:(PEPDecryptFlags * _Nullable)flags extraKeys:(PEPStringList * _Nullable * _Nullable)extraKeys status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { message *src = [PEPObjCTypeConversionUtil structFromPEPMessage:theMessage]; __block message *dst = NULL; __block stringlist_t *theKeys = NULL; __block PEPDecryptFlags theFlags = 0; if (flags) { theFlags = *flags; } if (extraKeys && [*extraKeys count]) { theKeys = [PEPObjCTypeConversionUtil arrayToStringList:*extraKeys]; } // Note: According to the engine docs for decrypt_message_2, the destination // message will be NULL on error, and the source message rating will be set regardless. // Since we derive our returned messages from either the destination message or source, // we'll have a correct rating in the returned result regardless. PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return decrypt_message_2(session, src, &dst, &theKeys, (PEP_decrypt_flags *) &theFlags); }]; if (status) { *status = theStatus; } if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { decryptMessageFree(src, dst, theKeys); return nil; } if (flags) { *flags = theFlags; } PEPMessage *dstMessage; if (dst) { // Decryption was successful dstMessage = [PEPObjCTypeConversionUtil pEpMessagefromStruct:dst]; } else { dstMessage = [PEPObjCTypeConversionUtil pEpMessagefromStruct:src]; } if (theFlags & PEP_decrypt_flag_src_modified) { [PEPObjCTypeConversionUtil overWritePEPMessageObject:theMessage withValuesFromStruct:src]; } if (extraKeys) { *extraKeys = [PEPObjCTypeConversionUtil arrayFromStringlist:theKeys]; } decryptMessageFree(src, dst, theKeys); return dstMessage; } - (BOOL)reEvaluateMessage:(PEPMessage * _Nonnull)theMessage xKeyList:(PEPStringList * _Nullable)xKeyList rating:(PEPRating * _Nonnull)rating status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { message *_src = [PEPObjCTypeConversionUtil structFromPEPMessage:theMessage]; stringlist_t *theKeys = NULL; if ([xKeyList count]) { theKeys = [PEPObjCTypeConversionUtil arrayToStringList:xKeyList]; } PEPRating originalRating = *rating; __block PEPRating resultRating = PEPRatingUndefined; PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { PEP_STATUS tmpStatus = re_evaluate_message_rating(session, _src, theKeys, (PEP_rating) originalRating, (PEP_rating *) &resultRating); *rating = resultRating; return tmpStatus; }]; free_message(_src); free_stringlist(theKeys); if (status) { *status = theStatus; } if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return NO; } else { return YES; } } - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage extraKeys:(PEPStringList * _Nullable)extraKeys encFormat:(PEPEncFormat)encFormat status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { // Don't change the original PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage]; __block PEP_encrypt_flags_t flags = 0; __block message *_src = [PEPObjCTypeConversionUtil structFromPEPMessage:[PEPObjCTypeConversionUtil pEpMessageWithEmptyRecipientsRemovedFromPEPMessage:messageCopy]]; __block message *_dst = NULL; __block stringlist_t *_keys = [PEPObjCTypeConversionUtil arrayToStringList:extraKeys]; PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return encrypt_message(session, _src, _keys, &_dst, (PEP_enc_format) encFormat, flags); }]; if (status) { *status = theStatus; } if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return nil; } PEPMessage *dst_; if (_dst) { dst_ = [PEPObjCTypeConversionUtil pEpMessagefromStruct:_dst]; } else { dst_ = [PEPObjCTypeConversionUtil pEpMessagefromStruct:_src]; } free_message(_src); free_message(_dst); free_stringlist(_keys); return dst_; } - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)message extraKeys:(PEPStringList * _Nullable)extraKeys status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { return [self encryptMessage:message extraKeys:extraKeys encFormat:PEPEncFormatPEP status:status error:error]; } - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage forSelf:(PEPIdentity * _Nonnull)ownIdentity extraKeys:(PEPStringList * _Nullable)extraKeys status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { // Don't change the original PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage]; __block PEP_encrypt_flags_t flags = 0; __block message *_src = [PEPObjCTypeConversionUtil structFromPEPMessage:[PEPObjCTypeConversionUtil pEpMessageWithEmptyRecipientsRemovedFromPEPMessage:messageCopy]]; __block pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:ownIdentity]; __block message *_dst = NULL; __block stringlist_t *keysStringList = [PEPObjCTypeConversionUtil arrayToStringList:extraKeys]; PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return encrypt_message_for_self(session, ident, _src, keysStringList, &_dst, PEP_enc_PGP_MIME, flags); }]; free_stringlist(keysStringList); if (status) { *status = theStatus; } if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return nil; } PEPMessage *dst_; if (_dst) { dst_ = [PEPObjCTypeConversionUtil pEpMessagefromStruct:_dst]; } else { dst_ = [PEPObjCTypeConversionUtil pEpMessagefromStruct:_src]; } free_message(_src); free_message(_dst); free_identity(ident); return dst_; } - (PEPMessage * _Nullable)encryptMessage:(PEPMessage * _Nonnull)theMessage toFpr:(NSString * _Nonnull)toFpr encFormat:(PEPEncFormat)encFormat flags:(PEPDecryptFlags)flags status:(PEPStatus * _Nullable)status error:(NSError * _Nullable * _Nullable)error { // Don't change the original PEPMessage *messageCopy = [[PEPMessage alloc] initWithMessage:theMessage]; message *src = [PEPObjCTypeConversionUtil structFromPEPMessage:[PEPObjCTypeConversionUtil pEpMessageWithEmptyRecipientsRemovedFromPEPMessage:messageCopy]]; __block message *dst = NULL; PEPStatus theStatus = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return encrypt_message_and_add_priv_key(session, src, &dst, [[toFpr precomposedStringWithCanonicalMapping] UTF8String], (PEP_enc_format) encFormat, flags); }]; if (status) { *status = theStatus; } if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return nil; } if (dst) { // As long as dst is non-nil, the result is also non-nil PEPMessage *result = [PEPObjCTypeConversionUtil pEpMessagefromStruct:dst]; return result; } return nil; } - (NSNumber * _Nullable)outgoingRatingForMessage:(PEPMessage * _Nonnull)theMessage error:(NSError * _Nullable * _Nullable)error { message *_msg = [PEPObjCTypeConversionUtil structFromPEPMessage:theMessage]; __block PEPRating rating = PEPRatingUndefined; PEPStatus status = [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return outgoing_message_rating(session, _msg, (PEP_rating *) &rating); }]; free_message(_msg); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } return [NSNumber numberWithPEPRating:rating]; } - (NSNumber * _Nullable)outgoingRatingPreviewForMessage:(PEPMessage * _Nonnull)theMessage error:(NSError * _Nullable * _Nullable)error { message *_msg = [PEPObjCTypeConversionUtil structFromPEPMessage:theMessage]; PEPRating rating = PEPRatingUndefined; PEPStatus status = (PEPStatus) outgoing_message_rating_preview(_session, _msg, (PEP_rating *) &rating); free_message(_msg); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } return [NSNumber numberWithPEPRating:rating]; } - (NSNumber * _Nullable)ratingForIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; __block PEPRating rating = PEPRatingUndefined; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return identity_rating(session, ident, (PEP_rating *) &rating); }]; free_identity(ident); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } return [NSNumber numberWithPEPRating:rating]; } - (NSArray * _Nullable)trustwordsForFingerprint:(NSString * _Nonnull)fingerprint languageID:(NSString * _Nonnull)languageID shortened:(BOOL)shortened error:(NSError * _Nullable * _Nullable)error { NSMutableArray *array = [NSMutableArray array]; for (int i = 0; i < [fingerprint length]; i += 4) { if (shortened && i >= 20) break; NSString *str = [fingerprint substringWithRange:NSMakeRange(i, 4)]; unsigned int value; [[NSScanner scannerWithString:str] scanHexInt:&value]; PEPAutoPointer *word = [PEPAutoPointer new]; __block size_t size; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return trustword(session, value, [[languageID precomposedStringWithCanonicalMapping] UTF8String], word.charPointerPointer, &size); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } [array addObject:[NSString stringWithUTF8String:word.charPointer]]; } return array; } - (BOOL)mySelf:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return myself(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } [identity reset]; [PEPObjCTypeConversionUtil overWritePEPIdentityObject:identity withValuesFromStruct:ident]; free_identity(ident); return YES; } - (BOOL)updateIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { if (identity.isOwn) { return [self mySelf:identity error:error]; } else { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return update_identity(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } [identity reset]; [PEPObjCTypeConversionUtil overWritePEPIdentityObject:identity withValuesFromStruct:ident]; free_identity(ident); return YES; } } - (BOOL)trustPersonalKey:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return trust_personal_key(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } free_identity(ident); return YES; } - (BOOL)keyMistrusted:(PEPIdentity *)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return key_mistrusted(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } free_identity(ident); return YES; } - (BOOL)keyResetTrust:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { __block pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return key_reset_trust(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { free_identity(ident); return NO; } free_identity(ident); return YES; } - (BOOL)enableSyncForIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { if (!identity.isOwn) { [PEPStatusNSErrorUtil setError:error fromPEPStatus:PEPStatusIllegalValue]; return NO; } pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return enable_identity_for_sync(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } free_identity(ident); return YES; } - (BOOL)disableSyncForIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { if (!identity.isOwn) { [PEPStatusNSErrorUtil setError:error fromPEPStatus:PEPStatusIllegalValue]; return NO; } pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return disable_identity_for_sync(session, ident); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { free_identity(ident); return NO; } free_identity(ident); return YES; } - (NSArray * _Nullable)importKey:(NSString * _Nonnull)keydata error:(NSError * _Nullable * _Nullable)error { __block identity_list *identList = NULL; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return import_key(session, [[keydata precomposedStringWithCanonicalMapping] UTF8String], [keydata length], &identList); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free(identList); return nil; } NSArray *idents = [PEPObjCTypeConversionUtil arrayFromIdentityList:identList]; free(identList); return idents; } - (BOOL)logTitle:(NSString * _Nonnull)title entity:(NSString * _Nonnull)entity description:(NSString * _Nullable)description comment:(NSString * _Nullable)comment error:(NSError * _Nullable * _Nullable)error { PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return log_event(session, [[title precomposedStringWithCanonicalMapping] UTF8String], [[entity precomposedStringWithCanonicalMapping] UTF8String], [[description precomposedStringWithCanonicalMapping] UTF8String], [[comment precomposedStringWithCanonicalMapping] UTF8String]); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return NO; } else { return YES; } } - (NSString * _Nullable)getLogWithError:(NSError * _Nullable * _Nullable)error { __block char *theChars = NULL; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return get_crashdump_log(session, 0, &theChars); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } if (theChars) { return [NSString stringWithUTF8String:theChars]; } else { [PEPStatusNSErrorUtil setError:error fromPEPStatus:(PEPStatus) PEP_UNKNOWN_ERROR]; return nil; } } - (NSString * _Nullable)getTrustwordsIdentity1:(PEPIdentity * _Nonnull)identity1 identity2:(PEPIdentity * _Nonnull)identity2 language:(NSString * _Nullable)language full:(BOOL)full error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident1 = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity1]; pEp_identity *ident2 = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity2]; PEPAutoPointer *trustwords = [PEPAutoPointer new]; __block size_t sizeWritten = 0; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return get_trustwords(session, ident1, ident2, [[language precomposedStringWithCanonicalMapping] UTF8String], trustwords.charPointerPointer, &sizeWritten, full); }]; free_identity(ident1); free_identity(ident2); NSString *result = nil; if (![PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { result = [NSString stringWithUTF8String:trustwords.charPointer]; } return result; } - (NSString * _Nullable)getTrustwordsFpr1:(NSString * _Nonnull)fpr1 fpr2:(NSString * _Nonnull)fpr2 language:(NSString * _Nullable)language full:(BOOL)full error:(NSError * _Nullable * _Nullable)error { const char *_fpr1 = [fpr1 UTF8String]; // fprs are NFC normalized anyway const char *_fpr2 = [fpr2 UTF8String]; PEPAutoPointer *trustwords = [PEPAutoPointer new]; __block size_t sizeWritten = 0; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return get_trustwords_for_fprs(session, _fpr1, _fpr2, [[language precomposedStringWithCanonicalMapping] UTF8String], trustwords.charPointerPointer, &sizeWritten, full); }]; NSString *result = nil; if (![PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { result = [NSString stringWithUTF8String:trustwords.charPointer]; } return result; } - (NSArray * _Nullable)languageListWithError:(NSError * _Nullable * _Nullable)error { PEPAutoPointer *chLangs = [PEPAutoPointer new]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return get_languagelist(session, chLangs.charPointerPointer); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } NSString *parserInput = [NSString stringWithUTF8String:chLangs.charPointer]; NSMutableArray *tokens = [NSMutableArray array]; PEPCSVScanner *scanner = [[PEPCSVScanner alloc] initWithString:parserInput]; while (YES) { NSString *token = [scanner nextString]; if (!token) { break; } [tokens addObject:token]; } NSArray *theTokens = [NSArray arrayWithArray:tokens]; NSMutableArray *langs = [NSMutableArray new]; while (YES) { ArrayTake *take = [theTokens takeOrNil:3]; if (!take) { break; } NSArray *elements = take.elements; PEPLanguage *lang = [[PEPLanguage alloc] initWithCode:[elements objectAtIndex:0] name:[elements objectAtIndex:1] sentence:[elements objectAtIndex:2]]; [langs addObject:lang]; theTokens = take.rest; } return [NSArray arrayWithArray:langs]; } static NSDictionary *ratingToString; static NSDictionary *stringToRating; + (void)initialize { NSDictionary *ratingToStringIntern = @{ [NSNumber numberWithInteger:PEPRatingCannotDecrypt]: @"cannot_decrypt", [NSNumber numberWithInteger:PEPRatingHaveNoKey]: @"have_no_key", [NSNumber numberWithInteger:PEPRatingUnencrypted]: @"unencrypted", [NSNumber numberWithInteger:PEPRatingUnreliable]: @"unreliable", [NSNumber numberWithInteger:PEPRatingReliable]: @"reliable", [NSNumber numberWithInteger:PEPRatingTrusted]: @"trusted", [NSNumber numberWithInteger:PEPRatingTrustedAndAnonymized]: @"trusted_and_anonymized", [NSNumber numberWithInteger:PEPRatingFullyAnonymous]: @"fully_anonymous", [NSNumber numberWithInteger:PEPRatingMistrust]: @"mistrust", [NSNumber numberWithInteger:PEPRatingB0rken]: @"b0rken", [NSNumber numberWithInteger:PEPRatingUnderAttack]: @"under_attack", [NSNumber numberWithInteger:PEPRatingUndefined]: kUndefined, }; NSMutableDictionary *stringToRatingMutable = [NSMutableDictionary dictionaryWithCapacity: ratingToStringIntern.count]; for (NSNumber *ratingNumber in ratingToStringIntern.allKeys) { NSString *ratingName = [ratingToStringIntern objectForKey:ratingNumber]; [stringToRatingMutable setObject:ratingNumber forKey:ratingName]; } ratingToString = ratingToStringIntern; stringToRating = [NSDictionary dictionaryWithDictionary:stringToRatingMutable]; } - (PEPRating)ratingFromString:(NSString * _Nonnull)string { NSNumber *num = [stringToRating objectForKey:string]; if (num != nil) { return (PEPRating) [num integerValue]; } else { return PEPRatingUndefined; } } - (NSString * _Nonnull)stringFromRating:(PEPRating)rating { NSString *stringRating = [ratingToString objectForKey:[NSNumber numberWithInteger:rating]]; if (stringRating) { return stringRating; } else { return kUndefined; } } - (NSNumber * _Nullable)isPEPUser:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; __block bool isPEP; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return is_pEp_user(session, ident, &isPEP); }]; free_identity(ident); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return nil; } else { return [NSNumber numberWithBool:isPEP]; } } - (BOOL)setOwnKey:(PEPIdentity * _Nonnull)identity fingerprint:(NSString * _Nonnull)fingerprint error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return set_own_key(session, ident, [[fingerprint precomposedStringWithCanonicalMapping] UTF8String]); }]; free_identity(ident); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return NO; } else { return YES; } } - (void)configurePassiveModeEnabled:(BOOL)enabled { config_passive_mode(_session, enabled); } - (BOOL)setFlags:(PEPIdentityFlags)flags forIdentity:(PEPIdentity *)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return set_identity_flags(session, ident, flags); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { free_identity(ident); return NO; } else { [identity reset]; [PEPObjCTypeConversionUtil overWritePEPIdentityObject:identity withValuesFromStruct:ident]; free_identity(ident); return YES; } } - (BOOL)deliverHandshakeResult:(PEPSyncHandshakeResult)result identitiesSharing:(NSArray * _Nullable)identitiesSharing error:(NSError * _Nullable * _Nullable)error; { identity_list *identitiesSharingData = NULL; if (identitiesSharing) { identitiesSharingData = [PEPObjCTypeConversionUtil arrayToIdentityList:identitiesSharing]; } PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return deliverHandshakeResult(session, (sync_handshake_result) result, identitiesSharingData); }]; free(identitiesSharingData); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return NO; } else { return YES; } } - (BOOL)trustOwnKeyIdentity:(PEPIdentity * _Nonnull)identity error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return trust_own_key(session, ident); }]; free_identity(ident); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return NO; } else { return YES; } } - (PEPColor)colorFromRating:(PEPRating)rating { return (PEPColor) color_from_rating((PEP_rating) rating); } - (BOOL)keyReset:(PEPIdentity * _Nonnull)identity fingerprint:(NSString * _Nullable)fingerprint error:(NSError * _Nullable * _Nullable)error { pEp_identity *ident = [PEPObjCTypeConversionUtil structFromPEPIdentity:identity]; const char *fpr = [[fingerprint precomposedStringWithCanonicalMapping] UTF8String]; PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return key_reset_user(session, ident->user_id, fpr); }]; free_identity(ident); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return NO; } else { return YES; } } - (BOOL)leaveDeviceGroup:(NSError * _Nullable * _Nullable)error { PEPStatus status = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return leave_device_group(session); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:status]) { return NO; } else { return YES; } } - (BOOL)keyResetAllOwnKeysError:(NSError * _Nullable * _Nullable)error { PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return key_reset_all_own_keys(self.session); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return NO; } else { return YES; } } - (BOOL)configurePassphrase:(NSString * _Nonnull)passphrase error:(NSError * _Nullable * _Nullable)error { if (error) { *error = nil; } NSString *normalizedPassphrase = [passphrase normalizedPassphraseWithError:error]; if (normalizedPassphrase == nil) { return NO; } [self.passphraseCache addPassphrase:normalizedPassphrase]; PEP_STATUS status = config_passphrase(_session, [normalizedPassphrase UTF8String]); if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:(PEPStatus) status]) { return NO; } [PEPSync.sharedInstance handleNewPassphraseConfigured]; return YES; } - (PEPPassphraseCache * _Nonnull)passphraseCache { return [PEPPassphraseCache sharedInstance]; } - (BOOL)disableAllSyncChannels:(NSError * _Nullable * _Nullable)error { PEPStatus theStatus = (PEPStatus) [self runWithPasswords:^PEP_STATUS(PEP_SESSION session) { return disable_all_sync_channels(self.session); }]; if ([PEPStatusNSErrorUtil setError:error fromPEPStatus:theStatus]) { return NO; } else { return YES; } } @end