diff --git a/Podfile b/Podfile index 0fbe1c479..ba3526195 100644 --- a/Podfile +++ b/Podfile @@ -8,7 +8,7 @@ pod 'UICKeyChainStore', :podspec => 'Podspecs/UICKeyChainStore.podspec pod 'SocketRocket', :git => 'https://github.com/square/SocketRocket.git', :commit => 'd0585af165' pod 'OpenSSL', '~> 1.0.110' pod 'libPhoneNumber-iOS', '~> 0.7' -pod 'AxolotlKit', '~> 0.1' +pod 'AxolotlKit', '~> 0.3' pod 'PastelogKit', '~> 1.2' pod 'TwistedOakCollapsingFutures','~> 1.0' pod 'YapDatabase/SQLCipher' diff --git a/Podfile.lock b/Podfile.lock index a89667b3d..0bedffbb5 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -21,7 +21,7 @@ PODS: - AFNetworking/UIKit (2.5.0): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - AxolotlKit (0.1): + - AxolotlKit (0.3): - 25519 (~> 1.8) - HKDFKit (~> 0.0.3) - ProtocolBuffers (~> 1.9.2) @@ -32,7 +32,7 @@ PODS: - CocoaLumberjack/Core - DJWActionSheet (1.0.4) - HKDFKit (0.0.3) - - JSQMessagesViewController (6.0.0): + - JSQMessagesViewController (6.1.0): - JSQSystemSoundPlayer (~> 2.0.0) - JSQSystemSoundPlayer (2.0.0) - libPhoneNumber-iOS (0.7.3) @@ -51,15 +51,15 @@ PODS: - UnionFind (~> 1.0) - UICKeyChainStore (1.0.7) - UnionFind (1.0.1) - - YapDatabase/common (2.5.3): + - YapDatabase/common (2.5.4): - CocoaLumberjack (~> 1) - - YapDatabase/SQLCipher (2.5.3): + - YapDatabase/SQLCipher (2.5.4): - SQLCipher/fts - YapDatabase/common DEPENDENCIES: - AFNetworking (~> 2.5) - - AxolotlKit (~> 0.1) + - AxolotlKit (~> 0.3) - DJWActionSheet - JSQMessagesViewController (from `https://github.com/dtsbourg/JSQMessagesViewController`, branch `JSignalQ`) - libPhoneNumber-iOS (~> 0.7) @@ -83,7 +83,7 @@ EXTERNAL SOURCES: CHECKOUT OPTIONS: JSQMessagesViewController: - :commit: 597670e44663c9fa70b6a2deec2b19147c763048 + :commit: 5fc12f5cba461203046a6f0b2c62d1b1470197a4 :git: https://github.com/dtsbourg/JSQMessagesViewController SocketRocket: :commit: d0585af165 @@ -92,11 +92,11 @@ CHECKOUT OPTIONS: SPEC CHECKSUMS: 25519: 601ffb5d258aa33d642062d6fa4096db210e02e7 AFNetworking: 0f54cb5d16ce38c1b76948faffb8d5fb705021c7 - AxolotlKit: 395c3302e840a1b9f053e9733002d586d4b10ce0 + AxolotlKit: 19a7a6482e3deb6621e0f81a1733f60301802d40 CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817 DJWActionSheet: d88b302d7c29523e1e9fb9b62cfac46f59bb90d9 HKDFKit: 5998cf1bbb611e7ecc6bd3eaaef8c7a7da7be949 - JSQMessagesViewController: 49f449221a8f1da43403e6468ae2015fa0114a9e + JSQMessagesViewController: fb0f6e71c0a8009d210d6c7d73ba2b94bb77dc9b JSQSystemSoundPlayer: c98443b1cbb3b45db09d0d3d6c2355cf78294981 libPhoneNumber-iOS: 98fc07d70c8fdb5e6a8e3442c37e97353065c20e Mantle: d7c5ac734579ec751c58fecbf56189853056c58c @@ -108,6 +108,6 @@ SPEC CHECKSUMS: TwistedOakCollapsingFutures: 07aab84fd3958dc94d55ef705b12857d9fbe61d1 UICKeyChainStore: eef407137f0397e95a3df32cdf05f7e2ddd99647 UnionFind: 45777a8b6878d3a602af3654cc3a09b87389d356 - YapDatabase: 096e860167b04e629b88bea33dfb7a4153279bb0 + YapDatabase: c1d6912df1b4a160f7373ee7657d360e29bb00fd COCOAPODS: 0.35.0 diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 227bcc3dd..46ac4e6aa 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -327,6 +327,8 @@ B63761ED19E1FBE8005735D1 /* HttpRequestOrResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E719E1FBE8005735D1 /* HttpRequestOrResponse.m */; }; B63761EE19E1FBE8005735D1 /* HttpRequestUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761E919E1FBE8005735D1 /* HttpRequestUtil.m */; }; B63761EF19E1FBE8005735D1 /* HttpResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B63761EB19E1FBE8005735D1 /* HttpResponse.m */; }; + B63885CD1A26772D00A226A6 /* TSMessagesManager+callRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */; }; + B63885D01A2685D700A226A6 /* PreKeyBundle+jsonDict.m in Sources */ = {isa = PBXBuildFile; fileRef = B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */; }; B63AF5C71A1F757900D01AAD /* TSContactsIntersectionRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5AD1A1F757900D01AAD /* TSContactsIntersectionRequest.m */; }; B63AF5C81A1F757900D01AAD /* TSUnregisterAccountRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5AF1A1F757900D01AAD /* TSUnregisterAccountRequest.m */; }; B63AF5C91A1F757900D01AAD /* TSRecipientPrekeyRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B63AF5B11A1F757900D01AAD /* TSRecipientPrekeyRequest.m */; }; @@ -905,6 +907,10 @@ B63761E919E1FBE8005735D1 /* HttpRequestUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpRequestUtil.m; sourceTree = ""; }; B63761EA19E1FBE8005735D1 /* HttpResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpResponse.h; sourceTree = ""; }; B63761EB19E1FBE8005735D1 /* HttpResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpResponse.m; sourceTree = ""; }; + B63885CB1A26772D00A226A6 /* TSMessagesManager+callRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TSMessagesManager+callRecorder.h"; sourceTree = ""; }; + B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TSMessagesManager+callRecorder.m"; sourceTree = ""; }; + B63885CE1A2685D700A226A6 /* PreKeyBundle+jsonDict.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PreKeyBundle+jsonDict.h"; sourceTree = ""; }; + B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PreKeyBundle+jsonDict.m"; sourceTree = ""; }; B63AF5AC1A1F757900D01AAD /* TSContactsIntersectionRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSContactsIntersectionRequest.h; sourceTree = ""; }; B63AF5AD1A1F757900D01AAD /* TSContactsIntersectionRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSContactsIntersectionRequest.m; sourceTree = ""; }; B63AF5AE1A1F757900D01AAD /* TSUnregisterAccountRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSUnregisterAccountRequest.h; sourceTree = ""; }; @@ -1829,6 +1835,8 @@ 76EB04F018170B33006006FC /* protocols */ = { isa = PBXGroup; children = ( + B63885CE1A2685D700A226A6 /* PreKeyBundle+jsonDict.h */, + B63885CF1A2685D700A226A6 /* PreKeyBundle+jsonDict.m */, 76EB04F118170B33006006FC /* Terminable.h */, 76EB04F218170B33006006FC /* utilities */, ); @@ -2671,6 +2679,8 @@ B6B096101A1D25ED008BFAA6 /* TSInteraction.m */, B6B096111A1D25ED008BFAA6 /* TSMessage.h */, B6B096121A1D25ED008BFAA6 /* TSMessage.m */, + B63885CB1A26772D00A226A6 /* TSMessagesManager+callRecorder.h */, + B63885CC1A26772D00A226A6 /* TSMessagesManager+callRecorder.m */, B6B096131A1D25ED008BFAA6 /* TSMessagesManager+sendMessages.h */, B6B096141A1D25ED008BFAA6 /* TSMessagesManager+sendMessages.m */, B6B096151A1D25ED008BFAA6 /* TSMessagesManager.h */, @@ -3498,6 +3508,7 @@ FC31962D1A06A2190094C78E /* FingerprintViewController.m in Sources */, 76EB061418170B33006006FC /* AnonymousConditionLogger.m in Sources */, 76EB05C018170B33006006FC /* DhPacket.m in Sources */, + B63885D01A2685D700A226A6 /* PreKeyBundle+jsonDict.m in Sources */, 765052A1182945EF008313E1 /* LocalizableCustomFontLabel.m in Sources */, FC3196301A0814130094C78E /* SettingsTableViewController.m in Sources */, 7038632818F70C0700D4A43F /* EvpSymetricUtil.m in Sources */, @@ -3594,6 +3605,7 @@ B97CBFAE1886100E008E0DE9 /* CountryCodeTableViewCell.m in Sources */, B63761E319E1F487005735D1 /* AFHTTPSessionManager+SignalMethods.m in Sources */, 76EB05CC18170B33006006FC /* ShortAuthenticationStringGenerator.m in Sources */, + B63885CD1A26772D00A226A6 /* TSMessagesManager+callRecorder.m in Sources */, E16E5BEF18AAC40200B7C403 /* EC25KeyAgreementProtocol.m in Sources */, B6B096901A1D25ED008BFAA6 /* Cryptography.m in Sources */, 76EB064018170B33006006FC /* AnonymousTerminator.m in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 8c0a6d667..48288b41f 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -136,7 +136,7 @@ } }]; } - + [self.window.rootViewController dismissViewControllerAnimated:NO completion:nil]; [self.window.rootViewController presentViewController:callViewController animated:NO completion:nil]; } onThread:NSThread.mainThread untilCancelled:nil]; diff --git a/Signal/src/call/RecentCallManager.m b/Signal/src/call/RecentCallManager.m index 6efde4b24..f24cf8fc3 100644 --- a/Signal/src/call/RecentCallManager.m +++ b/Signal/src/call/RecentCallManager.m @@ -51,7 +51,7 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*); require(phoneManager != nil); [phoneManager.currentCallObservable watchLatestValue:^(CallState* latestCall) { - if (latestCall != nil && Environment.preferences.getHistoryLogEnabled) { + if (latestCall != nil) { [self addCall:latestCall]; } } onThread:NSThread.mainThread untilCancelled:untilCancelledToken]; @@ -101,7 +101,6 @@ typedef BOOL (^SearchTermConditionalBlock)(RecentCall*, NSUInteger, BOOL*); - (void)addRecentCall:(RecentCall *)recentCall { [_allRecents insertObject:recentCall atIndex:0]; - [Environment.preferences setFreshInstallTutorialsEnabled:NO]; [observableRecentsController updateValue:_allRecents.copy]; [self saveContactsToDefaults]; } diff --git a/Signal/src/contact/Contact.m b/Signal/src/contact/Contact.m index 3e0cd0380..409cff2ad 100644 --- a/Signal/src/contact/Contact.m +++ b/Signal/src/contact/Contact.m @@ -75,11 +75,7 @@ static NSString *const DEFAULTS_KEY_DATE = @"DefaultsKeyDate"; } - (UIImage *)image { - if (Environment.preferences.getContactImagesEnabled) { - return image; - } else { - return nil; - } + return image; } - (BOOL)isTextSecureContact{ diff --git a/Signal/src/environment/PreferencesUtil.h b/Signal/src/environment/PreferencesUtil.h index 88c4f6f02..76f550f26 100644 --- a/Signal/src/environment/PreferencesUtil.h +++ b/Signal/src/environment/PreferencesUtil.h @@ -12,18 +12,6 @@ -(NSTimeInterval) getCachedOrDefaultDesiredBufferDepth; -(void) setCachedDesiredBufferDepth:(double)value; --(BOOL) getFreshInstallTutorialsEnabled; --(BOOL) getContactImagesEnabled; --(BOOL) getAutocorrectEnabled; --(BOOL) getHistoryLogEnabled; - --(void) setFreshInstallTutorialsEnabled:(BOOL)enabled; --(void) setContactImagesEnabled:(BOOL)enabled; --(void) setAutocorrectEnabled:(BOOL)enabled; --(void) setHistoryLogEnabled:(BOOL)enabled; --(BOOL) encounteredRevokedPushPermission; --(void) setRevokedPushPermission:(BOOL)revoked; - -(BOOL)loggingIsEnabled; -(void)setLoggingEnabled:(BOOL)flag; diff --git a/Signal/src/environment/PreferencesUtil.m b/Signal/src/environment/PreferencesUtil.m index 385eabb76..842135137 100644 --- a/Signal/src/environment/PreferencesUtil.m +++ b/Signal/src/environment/PreferencesUtil.m @@ -156,6 +156,7 @@ [NSUserDefaults.standardUserDefaults setObject:[NSString stringWithFormat:@"%@", NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]] forKey:kSignalVersionKey]; [NSUserDefaults.standardUserDefaults synchronize]; + return lastVersion; } diff --git a/Signal/src/environment/PropertyListPreferences.h b/Signal/src/environment/PropertyListPreferences.h index 8bf828e79..c2c997b1b 100644 --- a/Signal/src/environment/PropertyListPreferences.h +++ b/Signal/src/environment/PropertyListPreferences.h @@ -7,7 +7,4 @@ -(id) adjustAndTryGetNewValueForKey:(NSString*)key afterAdjuster:(id (^)(id oldValue))adjuster; -(void) clear; --(NSData*) secureDataStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster; --(NSString*) secureStringStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster; - @end diff --git a/Signal/src/environment/PropertyListPreferences.m b/Signal/src/environment/PropertyListPreferences.m index d500a9448..2847d07de 100644 --- a/Signal/src/environment/PropertyListPreferences.m +++ b/Signal/src/environment/PropertyListPreferences.m @@ -34,61 +34,6 @@ } } -#pragma mark KeyChain store - --(void) secureTrySetValueForKey:(NSString *)key toValue:(id)value { - require(key != nil); - @synchronized(self) { - if (value == nil) { - [UICKeyChainStore removeItemForKey:key]; - DDLogWarn(@"Removing object for key: %@", key); - } else { - if ([value isKindOfClass:NSData.class]) { - [UICKeyChainStore setData:value forKey:key]; - } else if ([value isKindOfClass:NSString.class]){ - [UICKeyChainStore setString:value forKey:key]; - } else{ - DDLogError(@"Unexpected class stored in the Keychain."); - } - } - } -} - --(NSData*) secureTryGetDataForKey:(NSString *)key { - require(key != nil); - @synchronized(self) { - return [UICKeyChainStore dataForKey:key]; - } -} - --(NSString*) secureTryGetStringForKey:(NSString *)key { - require(key != nil); - @synchronized(self) { - return [UICKeyChainStore stringForKey:key]; - } -} - --(NSData*) secureDataStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster { - require(key != nil); - require(adjuster != nil); - @synchronized(self) { - NSData* oldValue = [self secureTryGetDataForKey:key]; - NSData* newValue = adjuster(oldValue); - [UICKeyChainStore setData:newValue forKey:key]; - return newValue; - } -} - --(NSString*) secureStringStoreAdjustAndTryGetNewValueForKey:(NSString *)key afterAdjuster:(id (^)(id))adjuster { - require(key != nil); - require(adjuster != nil); - @synchronized(self) { - NSString *oldValue = [self secureTryGetStringForKey:key]; - NSString *newValue = adjuster(oldValue); - [UICKeyChainStore setString:newValue forKey:key]; - return newValue; - } -} @end diff --git a/Signal/src/network/http/RPAPICall.m b/Signal/src/network/http/RPAPICall.m index e8bc9f39e..e44f5c588 100644 --- a/Signal/src/network/http/RPAPICall.m +++ b/Signal/src/network/http/RPAPICall.m @@ -82,7 +82,7 @@ RPAPICall *apiCall = [self defaultAPICall]; apiCall.method = HTTP_GET; apiCall.endPoint = @"/users/directory"; - apiCall.requestSerializer = [self otpAuthenticationSerializer]; + apiCall.requestSerializer = [self basicAuthenticationSerializer]; return apiCall; } @@ -90,7 +90,6 @@ RPAPICall *apiCall = [self defaultAPICall]; apiCall.method = HTTP_DELETE; apiCall.endPoint = @"/apn"; - apiCall.requestSerializer = [self otpAuthenticationSerializer]; return apiCall; } diff --git a/Signal/src/textsecure/Messages/TSCall.h b/Signal/src/textsecure/Messages/TSCall.h index 9cb3c219b..4140d9ea5 100644 --- a/Signal/src/textsecure/Messages/TSCall.h +++ b/Signal/src/textsecure/Messages/TSCall.h @@ -9,6 +9,7 @@ #import #import "TSInteraction.h" +#import "Contact.h" @interface TSCall : TSInteraction @@ -22,9 +23,11 @@ typedef NS_ENUM(NSInteger, TSCallType) { @property (nonatomic, readonly) NSNumber *duration; @property (nonatomic, readonly) BOOL wasCaller; @property (nonatomic, readonly) TSCallType callType; +@property (nonatomic) NSString *redPhoneNumber; -- (instancetype)initWithTimestamp:(uint64_t)timeStamp inThread:(TSThread*)thread - wasCaller:(BOOL)caller callType:(TSCallType)callType - duration:(NSNumber*)duration; +- (instancetype)initWithTimestamp:(uint64_t)timeStamp + withCallNumber:(NSString*)contactNumber + wasCaller:(BOOL)caller callType:(TSCallType)callType + duration:(NSNumber*)duration; @end diff --git a/Signal/src/textsecure/Messages/TSCall.m b/Signal/src/textsecure/Messages/TSCall.m index 400e979e0..e69722f44 100644 --- a/Signal/src/textsecure/Messages/TSCall.m +++ b/Signal/src/textsecure/Messages/TSCall.m @@ -10,15 +10,18 @@ @implementation TSCall -- (instancetype)initWithTimestamp:(uint64_t)timeStamp inThread:(TSThread*)thread +- (instancetype)initWithTimestamp:(uint64_t)timeStamp + withCallNumber:(NSString*)contactNumber wasCaller:(BOOL)caller callType:(TSCallType)callType - duration:(NSNumber*)duration{ - self = [super initWithTimestamp:timeStamp inThread:thread]; + duration:(NSNumber*)duration +{ + self = [super initWithTimestamp:timeStamp inThread:nil]; if (self) { - _wasCaller = caller; - _callType = callType; - _duration = duration; + _wasCaller = caller; + _callType = callType; + _duration = duration; + _redPhoneNumber = contactNumber; } return self; diff --git a/Signal/src/textsecure/Messages/TSErrorMessage.h b/Signal/src/textsecure/Messages/TSErrorMessage.h index aa1f1751a..74b97923c 100644 --- a/Signal/src/textsecure/Messages/TSErrorMessage.h +++ b/Signal/src/textsecure/Messages/TSErrorMessage.h @@ -22,13 +22,11 @@ typedef NS_ENUM(int32_t, TSErrorMessageType){ TSErrorMessageInvalidVersion }; -+ (instancetype)invalidProtocolBufferWithException:(NSException*)exception; -+ (instancetype)duplicateMessageWithSignal:(IncomingPushMessageSignal*)preKeyMessage; -+ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage; -+ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage; -+ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage; -+ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage; -+ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage; ++ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction; ++ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction; ++ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction; ++ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction; ++ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction; - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType; diff --git a/Signal/src/textsecure/Messages/TSErrorMessage.m b/Signal/src/textsecure/Messages/TSErrorMessage.m index 3d01b7b19..6a3049623 100644 --- a/Signal/src/textsecure/Messages/TSErrorMessage.m +++ b/Signal/src/textsecure/Messages/TSErrorMessage.m @@ -7,11 +7,12 @@ // #import "TSErrorMessage.h" +#import "NSDate+millisecondTimeStamp.h" @implementation TSErrorMessage - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread failedMessageType:(TSErrorMessageType)errorMessageType{ - self = [super initWithTimestamp:timestamp inThread:thread messageBody:@"Error Message" attachements:nil]; + self = [super initWithTimestamp:timestamp inThread:thread messageBody:@"" attachements:nil]; if (self) { _errorType = errorMessageType; @@ -20,4 +21,34 @@ return self; } ++ (instancetype)invalidVersionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{ + TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction]; + TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageInvalidVersion]; + return errorMessage; +} + ++ (instancetype)missingKeyIdWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{ + TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction]; + TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageMissingKeyId]; + return errorMessage; +} + ++ (instancetype)invalidKeyExceptionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{ + TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction]; + TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageInvalidKeyException]; + return errorMessage; +} + ++ (instancetype)untrustedKeyWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{ + TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction]; + TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageWrongTrustedIdentityKey]; + return errorMessage; +} + ++ (instancetype)missingSessionWithSignal:(IncomingPushMessageSignal*)preKeyMessage withTransaction:(YapDatabaseReadWriteTransaction*)transaction{ + TSContactThread *contactThread = [TSContactThread threadWithContactId:preKeyMessage.source transaction:transaction]; + TSErrorMessage *errorMessage = [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:contactThread failedMessageType:TSErrorMessageNoSession]; + return errorMessage; +} + @end diff --git a/Signal/src/textsecure/Messages/TSInfoMessage.h b/Signal/src/textsecure/Messages/TSInfoMessage.h index c2cb93f83..d5763c7a1 100644 --- a/Signal/src/textsecure/Messages/TSInfoMessage.h +++ b/Signal/src/textsecure/Messages/TSInfoMessage.h @@ -17,6 +17,5 @@ typedef NS_ENUM(NSInteger, TSInfoMessageType){ @property TSInfoMessageType messageType; - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSContactThread *)contact messageType:(TSInfoMessageType)infoMessage; -- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSGroupThread *)thread authorId:(NSString *)authorId messageType:(TSInfoMessageType)infoMessage; @end diff --git a/Signal/src/textsecure/Messages/TSInfoMessage.m b/Signal/src/textsecure/Messages/TSInfoMessage.m index b92a59f5f..b9c37a753 100644 --- a/Signal/src/textsecure/Messages/TSInfoMessage.m +++ b/Signal/src/textsecure/Messages/TSInfoMessage.m @@ -10,4 +10,14 @@ @implementation TSInfoMessage +- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSContactThread *)contact messageType:(TSInfoMessageType)infoMessage{ + self = [super initWithTimestamp:timestamp inThread:contact messageBody:nil attachements:nil]; + + if (self) { + _messageType = infoMessage; + } + + return self; +} + @end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.h b/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.h new file mode 100644 index 000000000..9e8712984 --- /dev/null +++ b/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.h @@ -0,0 +1,16 @@ +// +// TSMessagesManager+callRecorder.h +// Signal +// +// Created by Frederic Jacobs on 26/11/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSMessagesManager.h" +#import "TSCall.h" + +@interface TSMessagesManager (callRecorder) + +- (void)storePhoneCall:(TSCall*)call; + +@end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.m b/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.m new file mode 100644 index 000000000..7308b2df8 --- /dev/null +++ b/Signal/src/textsecure/Messages/TSMessagesManager+callRecorder.m @@ -0,0 +1,24 @@ +// +// TSMessagesManager+callRecorder.m +// Signal +// +// Created by Frederic Jacobs on 26/11/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "TSMessagesManager+callRecorder.h" +#import + +#import "Environment.h" +#import "ContactsManager.h" + +@implementation TSMessagesManager (callRecorder) + +- (void)storePhoneCall:(TSCall*)call{ + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [call saveWithTransaction:transaction]; + }]; +} + + +@end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m b/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m index c9b8ed889..b4ac68171 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m @@ -8,7 +8,9 @@ #import "TSMessagesManager+sendMessages.h" +#import #import +#import #import #import "IncomingPushMessageSignal.pb.h" @@ -18,33 +20,53 @@ #import "TSStorageManager+PreKeyStore.h" #import "TSStorageManager+SignedPreKeyStore.h" +#import "PreKeyBundle+jsonDict.h" +#import "TSErrorMessage.h" + #import "TSNetworkManager.h" #import "TSServerMessage.h" #import "TSSubmitMessageRequest.h" +#import "TSRecipientPrekeyRequest.h" #import "TSContactThread.h" #import "TSGroupThread.h" #import "TSRecipient.h" +@interface TSMessagesManager () +dispatch_queue_t sendingQueue(void); +@end + +typedef void (^messagesQueue)(NSArray *messages); + @implementation TSMessagesManager (sendMessages) -- (void)sendMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread{ - if ([thread isKindOfClass:[TSGroupThread class]]) { - NSLog(@"Currently unsupported"); - } else if([thread isKindOfClass:[TSContactThread class]]){ - TSContactThread *contactThread = (TSContactThread*)thread; - __block TSRecipient *recipient; - [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - recipient = [contactThread recipientWithTransaction:transaction]; - }]; - - [self sendMessage:message - toRecipient:recipient - inThread:thread - withAttemps:3]; - } +dispatch_queue_t sendingQueue() { + static dispatch_once_t queueCreationGuard; + static dispatch_queue_t queue; + dispatch_once(&queueCreationGuard, ^{ + queue = dispatch_queue_create("org.whispersystems.signal.sendQueue", NULL); + }); + return queue; } +- (void)sendMessage:(TSOutgoingMessage*)message inThread:(TSThread*)thread{ + dispatch_async(sendingQueue(), ^{ + if ([thread isKindOfClass:[TSGroupThread class]]) { + NSLog(@"Currently unsupported"); + } else if([thread isKindOfClass:[TSContactThread class]]){ + TSContactThread *contactThread = (TSContactThread*)thread; + __block TSRecipient *recipient; + [self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + recipient = [contactThread recipientWithTransaction:transaction]; + }]; + + [self sendMessage:message + toRecipient:recipient + inThread:thread + withAttemps:3]; + } + }); +} - (void)sendMessage:(TSOutgoingMessage*)message toRecipient:(TSRecipient*)recipient @@ -54,35 +76,32 @@ if (remainingAttempts > 0) { remainingAttempts -= 1; - NSArray *outgoingMessages = [self outgoingMessages:message toRecipient:recipient]; - - TSSubmitMessageRequest *request = [[TSSubmitMessageRequest alloc] initWithRecipient:recipient.uniqueId messages:outgoingMessages relay:recipient.relay timeStamp:message.timeStamp]; - - [[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) { - - [self handleMessageSent:message inThread:thread]; - } failure:^(NSURLSessionDataTask *task, NSError *error) { - NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; - long statuscode = response.statusCode; - - //TODO: Handle failures - - switch (statuscode) { - case 404: - // Recipient not found - break; - case 409: - // Mismatched devices - - break; - case 410: - // staledevices - break; - default: - break; - } - + [self outgoingMessages:message toRecipient:recipient completion:^(NSArray *messages) { + TSSubmitMessageRequest *request = [[TSSubmitMessageRequest alloc] initWithRecipient:recipient.uniqueId messages:messages relay:recipient.relay timeStamp:message.timeStamp]; + [[TSNetworkManager sharedManager] queueAuthenticatedRequest:request success:^(NSURLSessionDataTask *task, id responseObject) { + [self handleMessageSent:message inThread:thread]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; + long statuscode = response.statusCode; + + switch (statuscode) { + case 404: + // Recipient not found + DDLogError(@"Recipient not found"); + break; + case 409: + // Mismatched devices + DDLogError(@"Missing some devices"); + break; + case 410: + // staledevices + DDLogWarn(@"Stale devices"); + break; + default: + break; + } + }]; }]; } } @@ -97,44 +116,75 @@ }]; } -- (NSArray*)outgoingMessages:(TSOutgoingMessage*)message toRecipient:(TSRecipient*)recipient{ - +- (void)outgoingMessages:(TSOutgoingMessage*)message toRecipient:(TSRecipient*)recipient completion:(messagesQueue)sendMessages{ NSMutableArray *messagesArray = [NSMutableArray arrayWithCapacity:recipient.devices.count]; TSStorageManager *storage = [TSStorageManager sharedManager]; NSData *plainText = [self plainTextForMessage:message]; - - for (NSNumber *deviceNumber in recipient.devices) { - if (![storage containsSession:recipient.uniqueId deviceId:[deviceNumber intValue]]) { - // Needs to fetch prekey; - } - - @try{ - SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storage - preKeyStore:storage - signedPreKeyStore:storage - identityKeyStore:storage - recipientId:recipient.uniqueId - deviceId:[deviceNumber intValue]]; - - id encryptedMessage = [cipher encryptMessage:plainText]; - NSData *serializedMessage = encryptedMessage.serialized; - TSWhisperMessageType messageType = [self messageTypeForCipherMessage:encryptedMessage]; - - TSServerMessage *serverMessage = [[TSServerMessage alloc] initWithType:messageType - destination:recipient.uniqueId - device:[deviceNumber intValue] - body:serializedMessage]; - - - [messagesArray addObject:[MTLJSONAdapter JSONDictionaryFromModel:serverMessage]]; - - }@catch (NSException *exception) { + for (NSNumber *deviceNumber in recipient.devices) { + @try { + NSDictionary *messageDict = [self encryptedMessageWithPlaintext:plainText toRecipient:recipient.uniqueId deviceId:deviceNumber keyingStorage:storage]; + if (messageDict) { + [messagesArray addObject:messageDict]; + } else{ + @throw [NSException exceptionWithName:InvalidMessageException reason:@"Failed to encrypt message" userInfo:nil]; + } + } + @catch (NSException *exception) { [self processException:exception outgoingMessage:message]; + return; } } - return messagesArray; + sendMessages(messagesArray); +} + +- (NSDictionary*)encryptedMessageWithPlaintext:(NSData*)plainText toRecipient:(NSString*)identifier deviceId:(NSNumber*)deviceNumber keyingStorage:(TSStorageManager*)storage{ + + if (![storage containsSession:identifier deviceId:[deviceNumber intValue]]) { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + __block PreKeyBundle *bundle; + + [[TSNetworkManager sharedManager] queueAuthenticatedRequest:[[TSRecipientPrekeyRequest alloc] initWithRecipient:identifier deviceId:[deviceNumber stringValue]] success:^(NSURLSessionDataTask *task, id responseObject) { + bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject forDeviceNumber:deviceNumber]; + dispatch_semaphore_signal(sema); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + if (!bundle) { + @throw [NSException exceptionWithName:InvalidVersionException reason:@"Can't get a prekey bundle from the server with required information" userInfo:nil]; + } else{ + SessionBuilder *builder = [[SessionBuilder alloc] initWithSessionStore:storage + preKeyStore:storage + signedPreKeyStore:storage + identityKeyStore:storage + recipientId:identifier + deviceId:[deviceNumber intValue]]; + [builder processPrekeyBundle:bundle]; + } + } + + SessionCipher *cipher = [[SessionCipher alloc] initWithSessionStore:storage + preKeyStore:storage + signedPreKeyStore:storage + identityKeyStore:storage + recipientId:identifier + deviceId:[deviceNumber intValue]]; + + id encryptedMessage = [cipher encryptMessage:plainText]; + NSData *serializedMessage = encryptedMessage.serialized; + TSWhisperMessageType messageType = [self messageTypeForCipherMessage:encryptedMessage]; + + + TSServerMessage *serverMessage = [[TSServerMessage alloc] initWithType:messageType + destination:identifier + device:[deviceNumber intValue] + body:serializedMessage]; + + + return [MTLJSONAdapter JSONDictionaryFromModel:serverMessage]; } - (TSWhisperMessageType)messageTypeForCipherMessage:(id)cipherMessage{ @@ -151,7 +201,6 @@ PushMessageContentBuilder *builder = [PushMessageContentBuilder new]; [builder setBody:message.body]; - return [builder.build data]; //TO-DO: DEAL WITH ATTACHEMENTS AND GROUPS STUFF diff --git a/Signal/src/textsecure/Messages/TSMessagesManager.m b/Signal/src/textsecure/Messages/TSMessagesManager.m index 1b9d2d0ab..d324a0049 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager.m @@ -104,9 +104,10 @@ if (![storageManager containsSession:recipientId deviceId:deviceId]) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - TSErrorMessage *errorMessage = [TSErrorMessage missingSessionWithSignal:secureMessage]; + TSErrorMessage *errorMessage = [TSErrorMessage missingSessionWithSignal:secureMessage withTransaction:transaction]; [errorMessage saveWithTransaction:transaction]; }]; + return; } PushMessageContent *content; @@ -237,9 +238,12 @@ } - - (void)processException:(NSException*)exception outgoingMessage:(TSOutgoingMessage*)message{ - NSLog(@"Got exception: %@", exception.description); + DDLogWarn(@"Got exception: %@", exception.description); + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [message setMessageState:TSOutgoingMessageStateUnsent]; + [message saveWithTransaction:transaction]; + }]; } @end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.h b/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.h index 2a8e21d8a..08c49c87f 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.h +++ b/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.h @@ -9,5 +9,7 @@ #import "TSRequest.h" @class TSContact; @interface TSRecipientPrekeyRequest : TSRequest --(TSRequest*) initWithRecipient:(TSContact*) contact; + +-(TSRequest*) initWithRecipient:(NSString*)recipientNumber deviceId:(NSString*)deviceId; + @end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.m b/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.m index de7592f46..d34722e7f 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.m +++ b/Signal/src/textsecure/Network/API/Requests/TSRecipientPrekeyRequest.m @@ -11,14 +11,14 @@ @implementation TSRecipientPrekeyRequest --(TSRequest*) initWithRecipient:(NSString*)recipientNumber { - NSString* recipientInformation = recipientNumber; - - self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/*", textSecureKeysAPI, recipientInformation]]]; +-(TSRequest*) initWithRecipient:(NSString*)recipientNumber deviceId:(NSString*)deviceId{ + NSString* recipientInformation = recipientNumber; - [self setHTTPMethod:@"GET"]; - - return self; + self = [super initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@", textSecureKeysAPI, recipientInformation, deviceId]]]; + + [self setHTTPMethod:@"GET"]; + + return self; } @end diff --git a/Signal/src/textsecure/Network/API/Requests/TSRegisterPrekeysRequest.m b/Signal/src/textsecure/Network/API/Requests/TSRegisterPrekeysRequest.m index fe964eaaa..c537b3efa 100644 --- a/Signal/src/textsecure/Network/API/Requests/TSRegisterPrekeysRequest.m +++ b/Signal/src/textsecure/Network/API/Requests/TSRegisterPrekeysRequest.m @@ -20,8 +20,8 @@ self = [super initWithURL:[NSURL URLWithString:textSecureKeysAPI]]; self.HTTPMethod = @"PUT"; - NSString *publicIdentityKey = [[identityKeyPublic prependKeyType] base64EncodedStringWithOptions:0]; - NSMutableArray *serializedPrekeyList = [NSMutableArray array]; + NSString *publicIdentityKey = [[identityKeyPublic prependKeyType] base64EncodedStringWithOptions:0]; + NSMutableArray *serializedPrekeyList = [NSMutableArray array]; for (PreKeyRecord *preKey in prekeys) { [serializedPrekeyList addObject:[self dictionaryFromPreKey:preKey]]; diff --git a/Signal/src/textsecure/Storage/TSStorageManager.h b/Signal/src/textsecure/Storage/TSStorageManager.h index 5ff5678c6..a71517e31 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager.h +++ b/Signal/src/textsecure/Storage/TSStorageManager.h @@ -43,4 +43,5 @@ extern NSString *const TSUIDatabaseConnectionDidUpdateNotification; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection; +- (void)wipe; @end diff --git a/Signal/src/textsecure/Util/NSData+Base64.m b/Signal/src/textsecure/Util/NSData+Base64.m index e62d9eea3..76a2ab329 100644 --- a/Signal/src/textsecure/Util/NSData+Base64.m +++ b/Signal/src/textsecure/Util/NSData+Base64.m @@ -16,7 +16,17 @@ // returns the NSData representation of the base64 string // + (NSData *)dataFromBase64String:(NSString *)aString { - return [[NSData alloc] initWithBase64EncodedString:aString options:NSDataBase64DecodingIgnoreUnknownCharacters]; + int padding = aString.length%4; + + NSMutableString *strResult = [aString mutableCopy]; + if (padding != 0) { + int charsToAdd = 4 - padding; + for (int i = 0; i < charsToAdd; i++) { + [strResult appendString:@"="]; + } + } + + return [[NSData alloc] initWithBase64EncodedString:strResult options:NSDataBase64DecodingIgnoreUnknownCharacters]; } // diff --git a/Signal/src/util/protocols/PreKeyBundle+jsonDict.h b/Signal/src/util/protocols/PreKeyBundle+jsonDict.h new file mode 100644 index 000000000..70e2c2ce8 --- /dev/null +++ b/Signal/src/util/protocols/PreKeyBundle+jsonDict.h @@ -0,0 +1,15 @@ +// +// PreKeyBundle+jsonDict.h +// Signal +// +// Created by Frederic Jacobs on 26/11/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "PreKeyBundle.h" + +@interface PreKeyBundle (jsonDict) + ++ (PreKeyBundle*)preKeyBundleFromDictionary:(NSDictionary*)dictionary forDeviceNumber:(NSNumber*)number; + +@end diff --git a/Signal/src/util/protocols/PreKeyBundle+jsonDict.m b/Signal/src/util/protocols/PreKeyBundle+jsonDict.m new file mode 100644 index 000000000..653c73aa3 --- /dev/null +++ b/Signal/src/util/protocols/PreKeyBundle+jsonDict.m @@ -0,0 +1,99 @@ +// +// PreKeyBundle+jsonDict.m +// Signal +// +// Created by Frederic Jacobs on 26/11/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import "Constraints.h" +#import "PreKeyBundle+jsonDict.h" +#import "NSData+Base64.h" + +@implementation PreKeyBundle (jsonDict) + ++ (PreKeyBundle*)preKeyBundleFromDictionary:(NSDictionary*)dictionary forDeviceNumber:(NSNumber*)number{ + PreKeyBundle *bundle = nil; + NSString *identityKeyString = [dictionary objectForKey:@"identityKey"]; + NSArray *devicesArray = [dictionary objectForKey:@"devices"]; + + if (!(identityKeyString && [devicesArray isKindOfClass:[NSArray class]])) { + DDLogError(@"Failed to get identity key or messages array from server request"); + return nil; + } + + NSData *identityKey = [NSData dataFromBase64String:identityKeyString]; + NSLog(@"IDentityKey %@", identityKey); + + for (NSDictionary *deviceDict in devicesArray) { + NSNumber *registrationIdString = [deviceDict objectForKey:@"registrationId"]; + NSNumber *deviceIdString = [deviceDict objectForKey:@"deviceId"]; + + if (!(registrationIdString && deviceIdString)) { + DDLogError(@"Failed to get the registration id and device id"); + return nil; + } + + if (![deviceIdString isEqualToNumber:number]) { + DDLogWarn(@"Got a keyid for another device"); + return nil; + } + + int registrationId = [registrationIdString intValue]; + int deviceId = [deviceIdString intValue]; + + NSDictionary *preKey = [deviceDict objectForKey:@"preKey"]; + int prekeyId; + NSData *preKeyPublic = nil; + + if (!preKey) { + prekeyId = -1; + } else{ + prekeyId = [[preKey objectForKey:@"keyId"] intValue]; + NSString *preKeyPublicString = [preKey objectForKey:@"publicKey"]; + preKeyPublic = [NSData dataFromBase64String:preKeyPublicString]; + } + + NSDictionary *signedPrekey = [deviceDict objectForKey:@"signedPreKey"]; + + if (![signedPrekey isKindOfClass:[NSDictionary class]]) { + DDLogError(@"Device doesn't have signed prekeys registered"); + return nil; + } + + NSNumber *signedKeyIdNumber = [signedPrekey objectForKey:@"keyId"]; + NSString *signedSignatureString = [signedPrekey objectForKey:@"signature"]; + NSString *signedPublicKeyString = [signedPrekey objectForKey:@"publicKey"]; + + + + if (!(signedKeyIdNumber && signedPublicKeyString && signedSignatureString)) { + DDLogError(@"Missing signed key material"); + return nil; + } + + NSData *signedPrekeyPublic = [NSData dataFromBase64String:signedPublicKeyString]; + NSData *signedPreKeySignature = [NSData dataFromBase64String:signedSignatureString]; + + if (!(signedPrekeyPublic && signedPreKeySignature)) { + DDLogError(@"Failed to parse signed keying material"); + return nil; + } + + int signedPreKeyId = [signedKeyIdNumber intValue]; + + bundle = [[self alloc] initWithRegistrationId:registrationId + deviceId:deviceId + preKeyId:prekeyId + preKeyPublic:preKeyPublic + signedPreKeyPublic:signedPrekeyPublic + signedPreKeyId:signedPreKeyId + signedPreKeySignature:signedPreKeySignature + identityKey:identityKey]; + + } + + return bundle; +} + +@end diff --git a/Signal/src/view controllers/CodeVerificationViewController.m b/Signal/src/view controllers/CodeVerificationViewController.m index e618535a9..9f85b333e 100644 --- a/Signal/src/view controllers/CodeVerificationViewController.m +++ b/Signal/src/view controllers/CodeVerificationViewController.m @@ -8,6 +8,8 @@ #import "CodeVerificationViewController.h" +#import "Environment.h" +#import "PhoneNumberDirectoryFilterManager.h" #import "RPServerRequestsManager.h" #import "LocalizableText.h" #import "PushManager.h" @@ -39,11 +41,11 @@ //TODO: Lock UI interactions [self registerWithSuccess:^{ + [Environment.getCurrent.phoneDirectoryManager forceUpdate]; [self performSegueWithIdentifier:@"verifiedSegue" sender:self]; } failure:^(NSError *error) { // TODO: Unlock UI NSLog(@"Failed to register"); - [self showAlertForError:error]; }]; } diff --git a/Signal/src/view controllers/SettingsTableViewController.m b/Signal/src/view controllers/SettingsTableViewController.m index 1a504084a..b487b74d7 100644 --- a/Signal/src/view controllers/SettingsTableViewController.m +++ b/Signal/src/view controllers/SettingsTableViewController.m @@ -11,6 +11,7 @@ #import "SettingsTableViewCell.h" #import "TSAccountManager.h" +#import "TSStorageManager.h" #import "RPServerRequestsManager.h" @@ -119,11 +120,11 @@ typedef enum { break; case kUnregisterCell: - [[RPServerRequestsManager sharedInstance] performRequest:[RPAPICall unregister] success:^(NSURLSessionDataTask *task, id responseObject) { - NSLog(@"YEAH!"); - } failure:^(NSURLSessionDataTask *task, NSError *error) { - NSLog(@"Fail"); - NSLog(@"error: %@ ", error.debugDescription); + [TSAccountManager unregisterTextSecureWithSuccess:^{ + [[TSStorageManager sharedManager] wipe]; + exit(0); + } failure:^(NSError *error) { + SignalAlertView(@"Failed to unregister", @""); }]; break; @@ -133,6 +134,4 @@ typedef enum { } } - - @end diff --git a/Signal/src/view controllers/TSMessageAdapter.m b/Signal/src/view controllers/TSMessageAdapter.m index 63a91640e..8db726586 100644 --- a/Signal/src/view controllers/TSMessageAdapter.m +++ b/Signal/src/view controllers/TSMessageAdapter.m @@ -29,6 +29,8 @@ @property (nonatomic, copy) NSDate *messageDate; @property (nonatomic, retain) NSString *messageBody; +@property NSUInteger identifier; + @end @@ -38,7 +40,8 @@ TSMessageAdapter *adapter = [[TSMessageAdapter alloc] init]; adapter.messageDate = interaction.date; - + adapter.identifier = (NSUInteger)interaction.uniqueId; + if ([thread isKindOfClass:[TSContactThread class]]) { adapter.thread = (TSContactThread*)thread; if ([interaction isKindOfClass:[TSIncomingMessage class]]) { @@ -60,7 +63,7 @@ } } - if ([interaction isKindOfClass:[TSMessage class]]) { + if ([interaction isKindOfClass:[TSIncomingMessage class]] || [interaction isKindOfClass:[TSOutgoingMessage class]]) { TSMessage *message = (TSMessage*)interaction; adapter.messageBody = message.body; } else if ([interaction isKindOfClass:[TSCall class]]){ @@ -74,7 +77,6 @@ return adapter; } - - (NSString*)senderId{ if (_senderId) { return _senderId; @@ -103,4 +105,8 @@ return self.messageBody; } +- (NSUInteger)hash{ + return self.identifier; +} + @end