From 0706edf42a2c400a22fd55c6a7689246d90fac06 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 10 Oct 2017 15:06:45 -0400 Subject: [PATCH] Generate new registrationId on re-register In order for others to know they should start a new session with us, we need to change our registration id. To achieve this, I consolidated all the Account related attributes on TSAccountManager - luckily they were already in the proper collection, I just moved the API to hang on the AccountManager instead of a TSStorage category extension. Also: @synchronize access to `registrationId` // FREEBIE --- .../src/Account/TSAccountManager.h | 16 ++++ .../src/Account/TSAccountManager.m | 83 +++++++++++++------ SignalServiceKit/src/Account/TSAttributes.m | 1 - .../src/Network/API/Requests/TSRequest.m | 6 +- .../src/Network/API/TSNetworkManager.m | 3 +- .../src/Network/WebSockets/TSSocketManager.m | 7 +- SignalServiceKit/src/Storage/TSStorageKeys.h | 7 -- .../Storage/TSStorageManager+keyingMaterial.h | 29 ------- .../Storage/TSStorageManager+keyingMaterial.m | 41 --------- 9 files changed, 81 insertions(+), 112 deletions(-) delete mode 100644 SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.h delete mode 100644 SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.m diff --git a/SignalServiceKit/src/Account/TSAccountManager.h b/SignalServiceKit/src/Account/TSAccountManager.h index ae7e7ed92d..a80e5c12a8 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.h +++ b/SignalServiceKit/src/Account/TSAccountManager.h @@ -42,6 +42,22 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange; + (nullable NSString *)localNumber; - (nullable NSString *)localNumber; +/** + * Symmetric key that's used to encrypt message payloads from the server, + * + * @return signaling key + */ ++ (nullable NSString *)signalingKey; +- (nullable NSString *)signalingKey; + +/** + * The server auth token allows the Signal client to connect to the Signal server + * + * @return server authentication token + */ ++ (nullable NSString *)serverAuthToken; +- (nullable NSString *)serverAuthToken; + /** * The registration ID is unique to an installation of TextSecure, it allows to know if the app was reinstalled * diff --git a/SignalServiceKit/src/Account/TSAccountManager.m b/SignalServiceKit/src/Account/TSAccountManager.m index 2d03aebcc0..6af08e06bd 100644 --- a/SignalServiceKit/src/Account/TSAccountManager.m +++ b/SignalServiceKit/src/Account/TSAccountManager.m @@ -13,7 +13,7 @@ #import "TSPreKeyManager.h" #import "TSSocketManager.h" #import "TSStorageManager+SessionStore.h" -#import "TSStorageManager+keyingMaterial.h" +#import "YapDatabaseConnection+OWS.h" NS_ASSUME_NONNULL_BEGIN @@ -25,6 +25,10 @@ NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName NSString *const TSAccountManager_RegisteredNumberKey = @"TSStorageRegisteredNumberKey"; NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegistrationId"; +NSString *const TSAccountManager_UserAccountCollection = @"TSStorageUserAccountCollection"; +NSString *const TSAccountManager_ServerAuthToken = @"TSStorageServerAuthToken"; +NSString *const TSAccountManager_ServerSignalingKey = @"TSStorageServerSignalingKey"; + @interface TSAccountManager () @property (nonatomic, readonly) BOOL isRegistered; @@ -84,7 +88,9 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist _isRegistered = NO; _cachedLocalNumber = nil; _phoneNumberAwaitingVerification = nil; - [self removeStoredLocalNumber]; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + [transaction removeAllObjectsInCollection:TSAccountManager_UserAccountCollection]; + }]; } [[TSStorageManager sharedManager] resetSessionStore]; } @@ -150,20 +156,11 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist return self.cachedLocalNumber; } -- (void)removeStoredLocalNumber -{ - @synchronized(self) - { - [self.dbConnection removeObjectForKey:TSAccountManager_RegisteredNumberKey - inCollection:TSStorageUserAccountCollection]; - } -} - - (nullable NSString *)storedLocalNumber { @synchronized (self) { return [self.dbConnection stringForKey:TSAccountManager_RegisteredNumberKey - inCollection:TSStorageUserAccountCollection]; + inCollection:TSAccountManager_UserAccountCollection]; } } @@ -172,7 +169,7 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist @synchronized (self) { [self.dbConnection setObject:localNumber forKey:TSAccountManager_RegisteredNumberKey - inCollection:TSStorageUserAccountCollection]; + inCollection:TSAccountManager_UserAccountCollection]; } } @@ -183,19 +180,22 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist - (uint32_t)getOrGenerateRegistrationId { - uint32_t registrationID = [[self.dbConnection objectForKey:TSAccountManager_LocalRegistrationIdKey - inCollection:TSStorageUserAccountCollection] unsignedIntValue]; + @synchronized(self) + { + uint32_t registrationID = + [[self.dbConnection objectForKey:TSAccountManager_LocalRegistrationIdKey + inCollection:TSAccountManager_UserAccountCollection] unsignedIntValue]; - if (registrationID == 0) { - registrationID = (uint32_t)arc4random_uniform(16380) + 1; - DDLogWarn(@"%@ Generated a new registrationID: %u", self.tag, registrationID); + if (registrationID == 0) { + registrationID = (uint32_t)arc4random_uniform(16380) + 1; + DDLogWarn(@"%@ Generated a new registrationID: %u", self.tag, registrationID); - [self.dbConnection setObject:[NSNumber numberWithUnsignedInteger:registrationID] - forKey:TSAccountManager_LocalRegistrationIdKey - inCollection:TSStorageUserAccountCollection]; + [self.dbConnection setObject:[NSNumber numberWithUnsignedInteger:registrationID] + forKey:TSAccountManager_LocalRegistrationIdKey + inCollection:TSAccountManager_UserAccountCollection]; + } + return registrationID; } - - return registrationID; } - (void)registerForPushNotificationsWithPushToken:(NSString *)pushToken @@ -336,7 +336,7 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist case 200: case 204: { DDLogInfo(@"%@ Verification code accepted.", self.tag); - [TSStorageManager storeServerToken:authToken signalingKey:signalingKey]; + [self storeServerToken:authToken signalingKey:signalingKey]; [TSPreKeyManager registerPreKeysWithMode:RefreshPreKeysMode_SignedAndOneTime success:successBlock failure:failureBlock]; @@ -389,6 +389,41 @@ NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegist return signalingKeyTokenPrint; } ++ (nullable NSString *)signalingKey +{ + return [[self sharedInstance] signalingKey]; +} + +- (nullable NSString *)signalingKey +{ + return [self.dbConnection stringForKey:TSAccountManager_ServerSignalingKey + inCollection:TSAccountManager_UserAccountCollection]; +} + ++ (nullable NSString *)serverAuthToken +{ + return [[self sharedInstance] serverAuthToken]; +} + +- (nullable NSString *)serverAuthToken +{ + return [self.dbConnection stringForKey:TSAccountManager_ServerAuthToken + inCollection:TSAccountManager_UserAccountCollection]; +} + +- (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey +{ + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [transaction setObject:authToken + forKey:TSAccountManager_ServerAuthToken + inCollection:TSAccountManager_UserAccountCollection]; + [transaction setObject:signalingKey + forKey:TSAccountManager_ServerSignalingKey + inCollection:TSAccountManager_UserAccountCollection]; + + }]; +} + + (void)unregisterTextSecureWithSuccess:(void (^)())success failure:(void (^)(NSError *error))failureBlock { [[TSNetworkManager sharedManager] makeRequest:[[TSUnregisterAccountRequest alloc] init] diff --git a/SignalServiceKit/src/Account/TSAttributes.m b/SignalServiceKit/src/Account/TSAttributes.m index ad1053d4a1..8ac6cc7def 100644 --- a/SignalServiceKit/src/Account/TSAttributes.m +++ b/SignalServiceKit/src/Account/TSAttributes.m @@ -4,7 +4,6 @@ #import "TSAttributes.h" #import "TSAccountManager.h" -#import "TSStorageManager+keyingMaterial.h" NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Network/API/Requests/TSRequest.m b/SignalServiceKit/src/Network/API/Requests/TSRequest.m index 8922ad353f..06b0f7fa73 100644 --- a/SignalServiceKit/src/Network/API/Requests/TSRequest.m +++ b/SignalServiceKit/src/Network/API/Requests/TSRequest.m @@ -3,9 +3,8 @@ // #import "TSRequest.h" - +#import "TSAccountManager.h" #import "TSConstants.h" -#import "TSStorageManager+keyingMaterial.h" @implementation TSRequest @@ -37,7 +36,8 @@ #pragma clang diagnostic pop - (void)makeAuthenticatedRequest { - [self.parameters addEntriesFromDictionary:@{ @"Authorization" : [TSStorageManager serverAuthToken] }]; + OWSAssert([TSAccountManager serverAuthToken]); + [self.parameters addEntriesFromDictionary:@{ @"Authorization" : [TSAccountManager serverAuthToken] }]; } @end diff --git a/SignalServiceKit/src/Network/API/TSNetworkManager.m b/SignalServiceKit/src/Network/API/TSNetworkManager.m index d8853ca6e1..9979758d37 100644 --- a/SignalServiceKit/src/Network/API/TSNetworkManager.m +++ b/SignalServiceKit/src/Network/API/TSNetworkManager.m @@ -6,7 +6,6 @@ #import "NSURLSessionDataTask+StatusCode.h" #import "OWSSignalService.h" #import "TSAccountManager.h" -#import "TSStorageManager+keyingMaterial.h" #import "TSVerifyCodeRequest.h" #import @@ -74,7 +73,7 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); if (![request isKindOfClass:[TSRequestVerificationCodeRequest class]]) { [sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:[TSAccountManager localNumber] - password:[TSStorageManager serverAuthToken]]; + password:[TSAccountManager serverAuthToken]]; } if ([request.HTTPMethod isEqualToString:@"GET"]) { diff --git a/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m b/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m index 648741169f..8edbac46fc 100644 --- a/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m +++ b/SignalServiceKit/src/Network/WebSockets/TSSocketManager.m @@ -14,7 +14,6 @@ #import "SubProtocol.pb.h" #import "TSAccountManager.h" #import "TSConstants.h" -#import "TSStorageManager+keyingMaterial.h" #import "Threading.h" static const CGFloat kSocketHeartbeatPeriodSeconds = 30.f; @@ -380,11 +379,9 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_ [self requestSocketAliveForAtLeastSeconds:kBackgroundKeepSocketAliveDurationSeconds]; if ([message.path isEqualToString:@"/api/v1/message"] && [message.verb isEqualToString:@"PUT"]) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSData *decryptedPayload = - [Cryptography decryptAppleMessagePayload:message.body withSignalingKey:TSStorageManager.signalingKey]; + [Cryptography decryptAppleMessagePayload:message.body withSignalingKey:TSAccountManager.signalingKey]; if (!decryptedPayload) { DDLogWarn(@"%@ Failed to decrypt incoming payload or bad HMAC", self.tag); @@ -485,7 +482,7 @@ NSString *const kNSNotification_SocketManagerStateDidChange = @"kNSNotification_ - (NSString *)webSocketAuthenticationString { return [NSString stringWithFormat:@"?login=%@&password=%@", [[TSAccountManager localNumber] stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"], - [TSStorageManager serverAuthToken]]; + [TSAccountManager serverAuthToken]]; } #pragma mark - Socket LifeCycle diff --git a/SignalServiceKit/src/Storage/TSStorageKeys.h b/SignalServiceKit/src/Storage/TSStorageKeys.h index f969915e69..b18a8205f9 100644 --- a/SignalServiceKit/src/Storage/TSStorageKeys.h +++ b/SignalServiceKit/src/Storage/TSStorageKeys.h @@ -5,13 +5,6 @@ #ifndef TextSecureKit_TSStorageKeys_h #define TextSecureKit_TSStorageKeys_h -#pragma mark User Account Keys - -#define TSStorageUserAccountCollection @"TSStorageUserAccountCollection" - -#define TSStorageServerAuthToken @"TSStorageServerAuthToken" -#define TSStorageServerSignalingKey @"TSStorageServerSignalingKey" - /** * Preferences exposed to the user */ diff --git a/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.h b/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.h deleted file mode 100644 index 390f85cb02..0000000000 --- a/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -#import "TSStorageManager.h" - -@interface TSStorageManager (keyingMaterial) - -#pragma mark Server Credentials - -/** - * The server signaling key that's used to encrypt push payloads - * - * @return signaling key - */ - -+ (NSString *)signalingKey; - -/** - * The server auth token allows the TextSecure client to connect to the server - * - * @return server authentication token - */ - -+ (NSString *)serverAuthToken; - -+ (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey; - -@end diff --git a/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.m b/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.m deleted file mode 100644 index bc0703c2cd..0000000000 --- a/SignalServiceKit/src/Storage/TSStorageManager+keyingMaterial.m +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -#import "TSStorageManager+keyingMaterial.h" - -// TODO merge this category extension's functionality into TSAccountManager -@implementation TSStorageManager (keyingMaterial) - -+ (NSString *)signalingKey { - return [[self sharedManager] stringForKey:TSStorageServerSignalingKey inCollection:TSStorageUserAccountCollection]; -} - -+ (NSString *)serverAuthToken { - return [[self sharedManager] stringForKey:TSStorageServerAuthToken inCollection:TSStorageUserAccountCollection]; -} - -+ (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey { - TSStorageManager *sharedManager = self.sharedManager; - [sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction setObject:authToken forKey:TSStorageServerAuthToken inCollection:TSStorageUserAccountCollection]; - [transaction setObject:signalingKey - forKey:TSStorageServerSignalingKey - inCollection:TSStorageUserAccountCollection]; - - }]; -} - -#pragma mark - Logging - -+ (NSString *)logTag -{ - return [NSString stringWithFormat:@"[%@]", self.class]; -} - -- (NSString *)logTag -{ - return self.class.logTag; -} - -@end