From 2cdb05754cefce4905fc956b8de6a6dbe81d6437 Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Fri, 11 Jul 2014 00:33:51 +0200 Subject: [PATCH] Bug fixes + Keychain store --- Signal.xcodeproj/project.pbxproj | 6 + Signal/src/AppDelegate.m | 5 +- Signal/src/environment/Environment.h | 4 + Signal/src/environment/Environment.m | 27 ++++ Signal/src/environment/PreferencesUtil.h | 11 -- Signal/src/environment/PreferencesUtil.m | 99 +----------- Signal/src/environment/SGNKeychainUtil.h | 41 +++++ Signal/src/environment/SGNKeychainUtil.m | 141 ++++++++++++++++++ Signal/src/network/http/HttpRequestUtil.m | 11 +- Signal/src/network/rtp/zrtp/ZrtpInitiator.m | 3 +- Signal/src/network/rtp/zrtp/ZrtpResponder.m | 3 +- .../signaling/ResponderSessionDescriptor.m | 5 +- Signal/src/phone/signaling/SignalUtil.m | 9 +- .../InboxFeedViewController.m | 2 +- .../view controllers/RegisterViewController.m | 8 +- .../view controllers/SettingsViewController.m | 3 +- 16 files changed, 250 insertions(+), 128 deletions(-) create mode 100644 Signal/src/environment/SGNKeychainUtil.h create mode 100644 Signal/src/environment/SGNKeychainUtil.m diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index fc197b747..1aad5ba4b 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -382,6 +382,7 @@ AA0C8E498E2046B0B81EEE6E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313AE91B4954215858A5662 /* libPods.a */; }; B62686301964AE3D00D2D697 /* LogSubmit.m in Sources */ = {isa = PBXBuildFile; fileRef = B626862F1964AE3D00D2D697 /* LogSubmit.m */; }; B67EBF5D19194AC60084CCFD /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = B67EBF5C19194AC60084CCFD /* Settings.bundle */; }; + B6B1013C196D213F007E3930 /* SGNKeychainUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B1013B196D213F007E3930 /* SGNKeychainUtil.m */; }; B6B6C3C71919440C00C0B76B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6B6C3C51919440C00C0B76B /* Localizable.strings */; }; B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; B90418E7183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; }; @@ -1092,6 +1093,8 @@ B626862F1964AE3D00D2D697 /* LogSubmit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogSubmit.m; sourceTree = ""; }; B657DDC91911A40500F45B0C /* Signal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Signal.entitlements; sourceTree = ""; }; B67EBF5C19194AC60084CCFD /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Settings.bundle; path = SettingsBundle/Settings.bundle; sourceTree = SOURCE_ROOT; }; + B6B1013A196D213F007E3930 /* SGNKeychainUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGNKeychainUtil.h; sourceTree = ""; }; + B6B1013B196D213F007E3930 /* SGNKeychainUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGNKeychainUtil.m; sourceTree = ""; }; B6B6C3C61919440C00C0B76B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; B6B6C3C81919441D00C0B76B /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; B6B6C3C91919448900C0B76B /* ca-ES */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ca-ES"; path = "ca-ES.lproj/Localizable.strings"; sourceTree = ""; }; @@ -1670,6 +1673,8 @@ 76EB041918170B33006006FC /* PropertyListPreferences.m */, 76EB041A18170B33006006FC /* Release.h */, 76EB041B18170B33006006FC /* Release.m */, + B6B1013A196D213F007E3930 /* SGNKeychainUtil.h */, + B6B1013B196D213F007E3930 /* SGNKeychainUtil.m */, ); path = environment; sourceTree = ""; @@ -3172,6 +3177,7 @@ 76EB054418170B33006006FC /* AsyncUtilHelperRacingOperation.m in Sources */, 76EB060418170B33006006FC /* PhoneNumberDirectoryFilter.m in Sources */, B97CBFA818860EA3008E0DE9 /* CountryCodeViewController.m in Sources */, + B6B1013C196D213F007E3930 /* SGNKeychainUtil.m in Sources */, 76EB059218170B33006006FC /* UnrecognizedRequestFailure.m in Sources */, 76EB05F818170B33006006FC /* CallConnectUtil_Initiator.m in Sources */, B97CBFAE1886100E008E0DE9 /* CountryCodeTableViewCell.m in Sources */, diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 6603ca29b..1b18f0cd5 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -15,6 +15,7 @@ #import "TabBarParentViewController.h" #import "Util.h" #import +#import "Environment.h" #define kSignalVersionKey @"SignalUpdateVersionKey" @@ -42,9 +43,11 @@ NSString *currentVersion = [NSString stringWithFormat:@"%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]; if (!previousVersion) { - [UICKeyChainStore removeAllItems]; + DDLogError(@"No previous version found. Possibly first launch since install."); + [Environment resetAppData]; // We clean previous keychain entries in case their are some entries remaining. } else if ([currentVersion compare:previousVersion options:NSNumericSearch] == NSOrderedDescending) { // The application was updated + DDLogWarn(@"Application was updated from %@ to %@", previousVersion, currentVersion); } [[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:kSignalVersionKey]; diff --git a/Signal/src/environment/Environment.h b/Signal/src/environment/Environment.h index b3aea8164..28629639e 100644 --- a/Signal/src/environment/Environment.h +++ b/Signal/src/environment/Environment.h @@ -74,4 +74,8 @@ +(bool) hasEnabledTestingOrLegacyOption:(NSString*)flag; +(PhoneManager*) phoneManager; ++(BOOL)isRegistered; +-(void)setRegistered; ++(void)resetAppData; + @end diff --git a/Signal/src/environment/Environment.m b/Signal/src/environment/Environment.m index 1a766d0a5..c6caa926d 100644 --- a/Signal/src/environment/Environment.m +++ b/Signal/src/environment/Environment.m @@ -7,6 +7,9 @@ #import "RecentCallManager.h" #import "ContactsManager.h" #import "PhoneNumberDirectoryFilterManager.h" +#import "SGNKeychainUtil.h" + +#define isRegisteredUserDefaultString @"isRegistered" static Environment* environment = nil; @@ -143,4 +146,28 @@ static Environment* environment = nil; return [[Environment getCurrent] logging]; } ++(BOOL)isRegistered{ + // Attributes that need to be set + NSData *signalingKey = [SGNKeychainUtil signalingCipherKey]; + NSData *macKey = [SGNKeychainUtil signalingMacKey]; + NSData *extra = [SGNKeychainUtil signalingExtraKey]; + NSString *serverAuth = [SGNKeychainUtil serverAuthPassword]; + BOOL registered = [[NSUserDefaults standardUserDefaults] objectForKey:isRegisteredUserDefaultString]; + + if (signalingKey && macKey && extra && serverAuth && registered) { + return YES; + } else{ + return NO; + } +} + +-(void)setRegistered:(BOOL)status{ + [[NSUserDefaults standardUserDefaults] setObject:status?@YES:@NO forKey:isRegisteredUserDefaultString]; +} + ++(void)resetAppData{ + [SGNKeychainUtil wipeKeychain]; + [NSUserDefaults resetStandardUserDefaults]; +} + @end diff --git a/Signal/src/environment/PreferencesUtil.h b/Signal/src/environment/PreferencesUtil.h index b1d0cbe33..cf2d48f10 100644 --- a/Signal/src/environment/PreferencesUtil.h +++ b/Signal/src/environment/PreferencesUtil.h @@ -12,15 +12,6 @@ -(void) setSavedPhoneNumberDirectory:(PhoneNumberDirectoryFilter*)phoneNumberDirectoryFilter; -(NSTimeInterval) getCachedOrDefaultDesiredBufferDepth; -(void) setCachedDesiredBufferDepth:(double)value; --(int64_t) getAndIncrementOneTimeCounter; --(PhoneNumber*) forceGetLocalNumber; --(PhoneNumber*)tryGetLocalNumber; --(void) setLocalNumberTo:(PhoneNumber*)localNumber; --(Zid*) getOrGenerateZid; --(NSString*) getOrGenerateSavedPassword; --(NSData*) getOrGenerateSignalingMacKey; --(NSData*) getOrGenerateSignalingCipherKey; --(NSData*) getOrGenerateSignalingExtraKey; -(void) setSettingsRowExpandedPrefs:(NSArray *)prefs; -(NSArray *) getOrGenerateSettingsRowExpandedPrefs; -(NSArray *) getAvailableDateFormats; @@ -30,7 +21,6 @@ -(BOOL) getAutocorrectEnabled; -(BOOL) getHistoryLogEnabled; -(BOOL) getAnonymousFeedbackEnabled; --(BOOL) getIsRegistered; -(NSString *) getDateFormat; -(void) setDateFormat:(NSString *)format; @@ -39,7 +29,6 @@ -(void) setAutocorrectEnabled:(BOOL)enabled; -(void) setHistoryLogEnabled:(BOOL)enabled; -(void) setAnonymousFeedbackEnabled:(BOOL)enabled; --(void) setIsRegistered:(BOOL)registered; -(NSString *)getDateFormatKey; diff --git a/Signal/src/environment/PreferencesUtil.m b/Signal/src/environment/PreferencesUtil.m index 1a0ed13fd..7a965c86e 100644 --- a/Signal/src/environment/PreferencesUtil.m +++ b/Signal/src/environment/PreferencesUtil.m @@ -7,22 +7,12 @@ #import "NotificationManifest.h" #define CALL_STREAM_DES_BUFFER_LEVEL_KEY @"CallStreamDesiredBufferLevel" -#define LOCAL_NUMBER_KEY @"Number" -#define PASSWORD_COUNTER_KEY @"PasswordCounter" -#define SAVED_PASSWORD_KEY @"Password" -#define SIGNALING_MAC_KEY @"Signaling Mac Key" -#define SIGNALING_CIPHER_KEY @"Signaling Cipher Key" -#define ZID_KEY @"ZID" -#define SIGNALING_EXTRA_KEY @"Signaling Extra Key" + #define PHONE_DIRECTORY_BLOOM_FILTER_HASH_COUNT_KEY @"Directory Bloom Hash Count" #define PHONE_DIRECTORY_BLOOM_FILTER_DATA_KEY @"Directory Bloom Data" #define PHONE_DIRECTORY_EXPIRATION @"Directory Expiration" #define DEFAULT_CALL_STREAM_DES_BUFFER_LEVEL 0.5 -#define SIGNALING_MAC_KEY_LENGTH 20 -#define SIGNALING_CIPHER_KEY_LENGTH 16 -#define SAVED_PASSWORD_LENGTH 18 -#define SIGNALING_EXTRA_KEY_LENGTH 4 #define SETTINGS_EXPANDED_ROW_PREF_DICT_KEY @"Settings Expanded Row Pref Dict Key" @@ -40,8 +30,6 @@ #define DATE_FORMAT_5 @"yyyy/MM/dd" #define DATE_FORMAT_6 @"MM/dd/yyyy" -#define IS_REGISTERED_KEY @"Is Registered" - @implementation PropertyListPreferences (PropertyUtil) -(PhoneNumberDirectoryFilter*) tryGetSavedPhoneNumberDirectory { @@ -73,22 +61,6 @@ [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_DIRECTORY_UPDATE object:nil]; } --(NSData*) getOrGenerateRandomDataWithKey:(NSString*)key andLength:(NSUInteger)length { - require(key != nil); - - return [self secureDataStoreAdjustAndTryGetNewValueForKey:key afterAdjuster:^NSData*(NSData* oldValue) { - if (oldValue != nil) { - requireState([oldValue isKindOfClass:[NSData class]]); - requireState([oldValue length] == length); - return oldValue; - } - - DDLogInfo(@"A new %@ key of sie %lu has been generated.", key, (unsigned long)length); - - return [CryptoTools generateSecureRandomData:length]; - }]; -} - -(NSTimeInterval) getCachedOrDefaultDesiredBufferDepth { id v = [self tryGetValueForKey:CALL_STREAM_DES_BUFFER_LEVEL_KEY]; if (v == nil) return DEFAULT_CALL_STREAM_DES_BUFFER_LEVEL; @@ -99,62 +71,6 @@ [self setValueForKey:CALL_STREAM_DES_BUFFER_LEVEL_KEY toValue:[NSNumber numberWithDouble:value]]; } --(int64_t) getAndIncrementOneTimeCounter { - __block int64_t oldCounter; - [self adjustAndTryGetNewValueForKey:PASSWORD_COUNTER_KEY afterAdjuster:^(id oldValue) { - oldCounter = [oldValue longLongValue]; - int64_t newCounter = (oldCounter == INT64_MAX) - ? INT64_MIN - : (oldCounter + 1); - return [NSNumber numberWithLongLong:newCounter]; - }]; - return oldCounter; -} - --(PhoneNumber*) forceGetLocalNumber { - NSString* localNumber = [self tryGetValueForKey:LOCAL_NUMBER_KEY]; - checkOperation(localNumber != nil); - return [PhoneNumber tryParsePhoneNumberFromE164:localNumber]; -} --(void) setLocalNumberTo:(PhoneNumber*)localNumber { - require(localNumber != nil); - require([localNumber toE164]!= nil); - [self setValueForKey:LOCAL_NUMBER_KEY toValue:[localNumber toE164]]; -} - --(PhoneNumber*)tryGetLocalNumber { - NSString* localNumber = [self tryGetValueForKey:LOCAL_NUMBER_KEY]; - return (localNumber != nil ? [PhoneNumber tryParsePhoneNumberFromE164:localNumber] : nil); -} - --(Zid*) getOrGenerateZid { - return [Zid zidWithData:[self getOrGenerateRandomDataWithKey:ZID_KEY andLength:12]]; -} - --(NSString*) getOrGenerateSavedPassword { - return [self secureStringStoreAdjustAndTryGetNewValueForKey:SAVED_PASSWORD_KEY afterAdjuster:^NSString*(id oldValue) { - if (oldValue != nil) { - requireState([oldValue isKindOfClass:[NSString class]]); - return oldValue; - } - - NSString *string = [[CryptoTools generateSecureRandomData:SAVED_PASSWORD_LENGTH] encodedAsBase64]; - return string; - }]; -} - --(NSData*) getOrGenerateSignalingMacKey { - return [self getOrGenerateRandomDataWithKey:SIGNALING_MAC_KEY andLength:SIGNALING_MAC_KEY_LENGTH]; -} - --(NSData*) getOrGenerateSignalingCipherKey { - return [self getOrGenerateRandomDataWithKey:SIGNALING_CIPHER_KEY andLength:SIGNALING_CIPHER_KEY_LENGTH]; -} - --(NSData*) getOrGenerateSignalingExtraKey { - return [self getOrGenerateRandomDataWithKey:SIGNALING_EXTRA_KEY andLength:SIGNALING_EXTRA_KEY_LENGTH]; -} - -(void) setSettingsRowExpandedPrefs:(NSArray *)prefs { [self setValueForKey:SETTINGS_EXPANDED_ROW_PREF_DICT_KEY toValue:prefs]; } @@ -224,15 +140,6 @@ } } --(BOOL) getIsRegistered { - NSNumber *preference = [self tryGetValueForKey:IS_REGISTERED_KEY]; - if (preference) { - return [preference boolValue]; - } else { - return NO; - } -} - -(void) setDateFormat:(NSString *)format { [self setValueForKey:DATE_FORMAT_KEY toValue:format]; } @@ -252,8 +159,4 @@ -(void) setAnonymousFeedbackEnabled:(BOOL)enabled { [self setValueForKey:ANONYMOUS_FEEDBACK_ENABLED_KEY toValue:[NSNumber numberWithBool:enabled]]; } --(void) setIsRegistered:(BOOL)registered { - [self setValueForKey:IS_REGISTERED_KEY toValue:[NSNumber numberWithBool:registered]]; -} - @end diff --git a/Signal/src/environment/SGNKeychainUtil.h b/Signal/src/environment/SGNKeychainUtil.h new file mode 100644 index 000000000..e7b63e468 --- /dev/null +++ b/Signal/src/environment/SGNKeychainUtil.h @@ -0,0 +1,41 @@ +// +// SGNKeychainUtil.h +// Signal +// +// Created by Frederic Jacobs on 09/07/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// + +#import +#import "PhoneNumber.h" +#import "Zid.h" + +@interface SGNKeychainUtil : NSObject + ++(void)generateKeyingMaterial; ++(void)wipeKeychain; + +#pragma mark Registered Phone Number + ++(PhoneNumber*)localNumber; ++(void)setLocalNumberTo:(PhoneNumber*)localNumber; + +#pragma mark Signaling Key + ++(int64_t)getAndIncrementOneTimeCounter; + +#pragma mark Zid + ++(Zid*)zid; + +#pragma mark Server Auth + ++(NSString*)serverAuthPassword; + +#pragma mark Signaling + ++(NSData*)signalingMacKey; ++(NSData*)signalingCipherKey; ++(NSData*)signalingExtraKey; + +@end diff --git a/Signal/src/environment/SGNKeychainUtil.m b/Signal/src/environment/SGNKeychainUtil.m new file mode 100644 index 000000000..ecfe0fa91 --- /dev/null +++ b/Signal/src/environment/SGNKeychainUtil.m @@ -0,0 +1,141 @@ +// +// SGNKeychainUtil.m +// Signal +// +// Created by Frederic Jacobs on 09/07/14. +// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// +#import "CryptoTools.h" +#import "SGNKeychainUtil.h" +#import +#import "Constraints.h" +#import "Util.h" + +#define LOCAL_NUMBER_KEY @"Number" +#define PASSWORD_COUNTER_KEY @"PasswordCounter" +#define SAVED_PASSWORD_KEY @"Password" +#define SIGNALING_MAC_KEY @"Signaling Mac Key" +#define SIGNALING_CIPHER_KEY @"Signaling Cipher Key" +#define ZID_KEY @"ZID" +#define ZID_LENGTH 12 +#define SIGNALING_EXTRA_KEY @"Signaling Extra Key" + +#define SIGNALING_MAC_KEY_LENGTH 20 +#define SIGNALING_CIPHER_KEY_LENGTH 16 +#define SAVED_PASSWORD_LENGTH 18 +#define SIGNALING_EXTRA_KEY_LENGTH 4 + +@implementation SGNKeychainUtil + ++ (void)generateKeyingMaterial{ + [self storeData:[CryptoTools generateSecureRandomData:SIGNALING_MAC_KEY_LENGTH] forKey:SIGNALING_MAC_KEY]; + [self storeData:[CryptoTools generateSecureRandomData:SIGNALING_CIPHER_KEY_LENGTH] forKey:SIGNALING_CIPHER_KEY]; + [self storeData:[CryptoTools generateSecureRandomData:SIGNALING_EXTRA_KEY_LENGTH] forKey:SIGNALING_EXTRA_KEY]; + + [self storeData:[CryptoTools generateSecureRandomData:ZID_LENGTH] forKey:ZID_KEY]; + [self storeString:[[CryptoTools generateSecureRandomData:SAVED_PASSWORD_LENGTH] encodedAsBase64] forKey:SAVED_PASSWORD_KEY]; +} + ++(void)wipeKeychain{ + [UICKeyChainStore removeAllItems]; +} + ++(int64_t) getAndIncrementOneTimeCounter { + __block int64_t oldCounter; + oldCounter = [[UICKeyChainStore stringForKey:PASSWORD_COUNTER_KEY] longLongValue]; + int64_t newCounter = (oldCounter == INT64_MAX)?INT64_MIN:(oldCounter + 1); + [self storeString:[[NSNumber numberWithLongLong:newCounter] stringValue] forKey:PASSWORD_COUNTER_KEY]; + return newCounter; +} + ++ (void)setLocalNumberTo:(PhoneNumber *)localNumber{ + require(localNumber != nil); + require([localNumber toE164]!= nil); + + NSString *e164 = [localNumber toE164]; + [self storeString:e164 forKey:LOCAL_NUMBER_KEY]; +} + ++ (PhoneNumber *)localNumber{ + NSString *lnString = [self stringForKey:LOCAL_NUMBER_KEY]; + checkOperation(lnString != nil ); + PhoneNumber *num = [PhoneNumber tryParsePhoneNumberFromE164:lnString]; + return num; +} + ++(Zid *)zid{ + NSData *data = [self dataForKey:ZID_KEY]; + if ([data length] != ZID_LENGTH) { + DDLogError(@"ZID length is incorrect. Is %lu, should be %d", (unsigned long)[data length], ZID_LENGTH); + } + Zid *zid = [Zid zidWithData:data]; + return zid; +} + + ++(NSData *)signalingCipherKey{ + return [self dataForKey:SIGNALING_CIPHER_KEY andVerifyLength:SIGNALING_CIPHER_KEY_LENGTH]; +} + ++(NSData *)signalingMacKey{ + return [self dataForKey:SIGNALING_MAC_KEY andVerifyLength:SIGNALING_MAC_KEY_LENGTH]; +} + ++ (NSData *)signalingExtraKey{ + return [self dataForKey:SIGNALING_EXTRA_KEY andVerifyLength:SIGNALING_EXTRA_KEY_LENGTH]; +} + ++(NSString *)serverAuthPassword{ + NSString *password = [self stringForKey:SAVED_PASSWORD_KEY]; + NSData *data = [password decodedAsBase64Data]; + if ([data length] != SAVED_PASSWORD_LENGTH) { + DDLogError(@"The server password has incorrect length. Is %lu but should be %d", (unsigned long)[data length], SAVED_PASSWORD_LENGTH); + } + return password; +} + +#pragma mark Keychain wrapper methods + ++(BOOL)storeData:(NSData*)data forKey:(NSString*)key{ + BOOL success = [UICKeyChainStore setData:data forKey:key]; + if (!success) { + DDLogError(@"Failed to set value for key: %@", key); + } + return success; +} + ++(NSData*)dataForKey:(NSString*)key andVerifyLength:(uint)length{ + NSData *data = [self dataForKey:key]; + + if ([data length] != length) { + DDLogError(@"Length of data not matching. Got %lu, expected %u", [data length], length); + } + + return data; +} + ++(NSData*)dataForKey:(NSString*)key{ + NSData *data = [UICKeyChainStore dataForKey:key]; + if (!data) { + DDLogError(@"Failed to get value for key: %@", key); + } + return data; +} + ++(NSString*)stringForKey:(NSString*)key{ + NSString *string = [UICKeyChainStore stringForKey:key]; + if (!string) { + DDLogError(@"Failed to get value for key: %@", key); + } + return string; +} + ++(BOOL)storeString:(NSString*)string forKey:(NSString*)key{ + BOOL success = [UICKeyChainStore setString:string forKey:key]; + if (!success) { + DDLogError(@"Failed to set value for key: %@", key); + } + return success; +} + +@end diff --git a/Signal/src/network/http/HttpRequestUtil.m b/Signal/src/network/http/HttpRequestUtil.m index f7ab3523b..cc9d489fc 100644 --- a/Signal/src/network/http/HttpRequestUtil.m +++ b/Signal/src/network/http/HttpRequestUtil.m @@ -2,6 +2,7 @@ #import "Constraints.h" #import "PreferencesUtil.h" #import "Util.h" +#import "SGNKeychainUtil.h" @implementation HttpRequest (HttpRequestUtil) @@ -17,8 +18,8 @@ return [HttpRequest httpRequestWithBasicAuthenticationAndMethod:method andLocation:location andOptionalBody:optionalBody - andLocalNumber:[[[Environment getCurrent] preferences] forceGetLocalNumber] - andPassword:[[[Environment getCurrent] preferences] getOrGenerateSavedPassword]]; + andLocalNumber:[SGNKeychainUtil localNumber] + andPassword:[SGNKeychainUtil serverAuthPassword]]; } +(HttpRequest*)httpRequestWithOtpAuthenticationAndMethod:(NSString*)method andLocation:(NSString*)location { @@ -32,9 +33,9 @@ return [HttpRequest httpRequestWithOtpAuthenticationAndMethod:method andLocation:location andOptionalBody:optionalBody - andLocalNumber:[[[Environment getCurrent] preferences] forceGetLocalNumber] - andPassword:[[[Environment getCurrent] preferences] getOrGenerateSavedPassword] - andCounter:[[[Environment getCurrent] preferences] getAndIncrementOneTimeCounter]]; + andLocalNumber:[SGNKeychainUtil localNumber] + andPassword:[SGNKeychainUtil serverAuthPassword] + andCounter:[SGNKeychainUtil getAndIncrementOneTimeCounter]]; } +(HttpRequest*)httpRequestUnauthenticatedWithMethod:(NSString*)method andLocation:(NSString*)location { diff --git a/Signal/src/network/rtp/zrtp/ZrtpInitiator.m b/Signal/src/network/rtp/zrtp/ZrtpInitiator.m index ae1d69855..0c7c6381f 100644 --- a/Signal/src/network/rtp/zrtp/ZrtpInitiator.m +++ b/Signal/src/network/rtp/zrtp/ZrtpInitiator.m @@ -7,6 +7,7 @@ #import "Util.h" #import "ZrtpInitiator.h" #import "PreferencesUtil.h" +#import "SGNKeychainUtil.h" #define DHRS1_LENGTH 8 #define DHRS2_LENGTH 8 @@ -23,7 +24,7 @@ s->allowedKeyAgreementProtocols = [[Environment getCurrent] keyAgreementProtocolsInDescendingPriority]; s->dhSharedSecretHashes = [DhPacketSharedSecretHashes dhPacketSharedSecretHashesRandomized]; - s->zid = [[Environment preferences] getOrGenerateZid]; + s->zid = [SGNKeychainUtil zid]; s->confirmIv = [CryptoTools generateSecureRandomData:IV_LENGTH]; s->hashChain = [HashChain hashChainWithSecureGeneratedData]; s->badPacketLogger = [[Environment logging] getOccurrenceLoggerForSender:self withKey:@"Bad Packet"]; diff --git a/Signal/src/network/rtp/zrtp/ZrtpResponder.m b/Signal/src/network/rtp/zrtp/ZrtpResponder.m index ed5ede5bf..6afb2359d 100644 --- a/Signal/src/network/rtp/zrtp/ZrtpResponder.m +++ b/Signal/src/network/rtp/zrtp/ZrtpResponder.m @@ -8,6 +8,7 @@ #import "ZrtpResponder.h" #import "HelloAckPacket.h" #import "ConfirmAckPacket.h" +#import "SGNKeychainUtil.h" #define DHRS1_LENGTH 8 #define DHRS2_LENGTH 8 @@ -29,7 +30,7 @@ s->badPacketLogger = [[Environment logging] getOccurrenceLoggerForSender:self withKey:@"Bad Packet"]; s->localHello = [HelloPacket helloPacketWithDefaultsAndHashChain:s->hashChain - andZid:[[Environment preferences] getOrGenerateZid] + andZid:[SGNKeychainUtil zid] andKeyAgreementProtocols:s->allowedKeyAgreementProtocols]; s->packetExpectation = EXPECTING_HELLO; s->callController = callController; diff --git a/Signal/src/phone/signaling/ResponderSessionDescriptor.m b/Signal/src/phone/signaling/ResponderSessionDescriptor.m index 047c9e7b1..e96b20799 100644 --- a/Signal/src/phone/signaling/ResponderSessionDescriptor.m +++ b/Signal/src/phone/signaling/ResponderSessionDescriptor.m @@ -5,6 +5,7 @@ #import "PreferencesUtil.h" #import "Util.h" #import "InitiateSignal.pb.h" +#import "SGNKeychainUtil.h" #define MessagePropertyKey @"m" #define RelayPortKey @"p" @@ -90,7 +91,7 @@ checkOperation([data length] >= HMAC_TRUNCATED_SIZE); NSData* includedMac = [data takeLast:HMAC_TRUNCATED_SIZE]; NSData* payload = [data skipLast:HMAC_TRUNCATED_SIZE]; - NSData* signalingMacKey = [[Environment preferences] getOrGenerateSignalingMacKey]; + NSData* signalingMacKey = [SGNKeychainUtil signalingMacKey]; require(signalingMacKey != nil); NSData* computedMac = [[payload hmacWithSha1WithKey:signalingMacKey] takeLast:HMAC_TRUNCATED_SIZE]; checkOperation([includedMac isEqualToData_TimingSafe:computedMac]); @@ -99,7 +100,7 @@ +(NSData*) decryptRemoteNotificationData:(NSData*)data { require(data != nil); checkOperation([data length] >= VERSION_SIZE + IV_SIZE); - NSData* cipherKey = [[Environment preferences] getOrGenerateSignalingCipherKey]; + NSData* cipherKey = [SGNKeychainUtil signalingCipherKey]; NSData* iv = [data subdataWithRange:NSMakeRange(VERSION_SIZE, IV_SIZE)]; NSData* cipherText = [data skip:VERSION_SIZE+IV_SIZE]; return [cipherText decryptWithAesInCipherBlockChainingModeWithPkcs7PaddingWithKey:cipherKey andIv:iv]; diff --git a/Signal/src/phone/signaling/SignalUtil.m b/Signal/src/phone/signaling/SignalUtil.m index b9b3d0425..2f671d69b 100644 --- a/Signal/src/phone/signaling/SignalUtil.m +++ b/Signal/src/phone/signaling/SignalUtil.m @@ -4,6 +4,7 @@ #import "Environment.h" #import "PreferencesUtil.h" #import "Util.h" +#import "SGNKeychainUtil.h" #define CLAIMED_INTEROP_VERSION_IN_INITIATE_SIGNAL 1 @@ -79,12 +80,12 @@ +(HttpRequest*) httpRequestToVerifyAccessToPhoneNumberWithChallenge:(NSString*)challenge { require(challenge != nil); - PhoneNumber* localPhoneNumber = [[Environment preferences] forceGetLocalNumber]; + PhoneNumber* localPhoneNumber = [SGNKeychainUtil localNumber]; NSString* query = [NSString stringWithFormat:@"/users/verification/%@", [localPhoneNumber toE164]]; - NSData* signalingCipherKey = [[Environment preferences] getOrGenerateSignalingCipherKey]; - NSData* signalingMacKey = [[Environment preferences] getOrGenerateSignalingMacKey]; - NSData* signalingExtraKeyData = [[Environment preferences] getOrGenerateSignalingExtraKey]; + NSData* signalingCipherKey = [SGNKeychainUtil signalingCipherKey]; + NSData* signalingMacKey = [SGNKeychainUtil signalingMacKey]; + NSData* signalingExtraKeyData = [SGNKeychainUtil signalingCipherKey]; NSString* encodedSignalingKey = [[@[signalingCipherKey, signalingMacKey, signalingExtraKeyData] concatDatas] encodedAsBase64]; NSString* body = [@{@"key" : encodedSignalingKey, @"challenge" : challenge} encodedAsJson]; diff --git a/Signal/src/view controllers/InboxFeedViewController.m b/Signal/src/view controllers/InboxFeedViewController.m index 97e8152cb..2102b11f2 100644 --- a/Signal/src/view controllers/InboxFeedViewController.m +++ b/Signal/src/view controllers/InboxFeedViewController.m @@ -48,7 +48,7 @@ static NSString *const FOOTER_TABLE_CELL_IDENTIFIER = @"InboxFeedFooterCell"; [self observeKeyboardNotifications]; [self setupLabelLocalizationAndStyles]; - if (![[Environment preferences] getIsRegistered]) { + if (![Environment isRegistered]) { RegisterViewController *registerViewController = [RegisterViewController registerViewControllerForApn:_apnId]; [self presentViewController:registerViewController animated:NO completion:nil]; } diff --git a/Signal/src/view controllers/RegisterViewController.m b/Signal/src/view controllers/RegisterViewController.m index cf6d07b1e..a2b01e03d 100644 --- a/Signal/src/view controllers/RegisterViewController.m +++ b/Signal/src/view controllers/RegisterViewController.m @@ -8,6 +8,7 @@ #import "PreferencesUtil.h" #import "RegisterViewController.h" #import "SignalUtil.h" +#import "SGNKeychainUtil.h" #import "ThreadManager.h" #import "Util.h" @@ -41,7 +42,7 @@ _scrollView.contentSize = _containerView.bounds.size; - BOOL isRegisteredAlready = [[Environment preferences] getIsRegistered]; + BOOL isRegisteredAlready = [Environment isRegistered]; _registerCancelButton.hidden = !isRegisteredAlready; [self initializeKeyboardHandlers]; @@ -116,10 +117,11 @@ } -(Future*) asyncRegister:(PhoneNumber*)phoneNumber untilCancelled:(id)cancelToken { - // @todo: should we force regenerating of all keys? // @todo: clear current registered status before making a new one, to avoid splinching issues? - [[Environment preferences] setLocalNumberTo:phoneNumber]; + [SGNKeychainUtil setLocalNumberTo:phoneNumber]; + [SGNKeychainUtil generateKeyingMaterial]; + CancellableOperationStarter regStarter = ^Future *(id internalUntilCancelledToken) { HttpRequest *registerRequest = [HttpRequest httpRequestToStartRegistrationOfPhoneNumber]; diff --git a/Signal/src/view controllers/SettingsViewController.m b/Signal/src/view controllers/SettingsViewController.m index ccdc0b0e0..3f2c3566b 100644 --- a/Signal/src/view controllers/SettingsViewController.m +++ b/Signal/src/view controllers/SettingsViewController.m @@ -9,6 +9,7 @@ #import "RegisterViewController.h" #import "SettingsViewController.h" #import "LogSubmit.h" +#import "SGNKeychainUtil.h" #import "UIViewController+MMDrawerController.h" @@ -67,7 +68,7 @@ static NSString *const CHECKBOX_EMPTY_IMAGE_NAME = @"checkbox_empty"; #pragma mark - Local number - (void)configureLocalNumber { - PhoneNumber *localNumber = [[[Environment getCurrent] preferences] tryGetLocalNumber]; + PhoneNumber *localNumber = [SGNKeychainUtil localNumber]; if (localNumber) { _phoneNumberLabel.attributedText = [self localNumberAttributedStringForNumber:localNumber]; } else {