2014-07-11 00:33:51 +02:00
|
|
|
//
|
2014-11-21 00:51:23 +01:00
|
|
|
// SignalKeyingStorage.m
|
2014-07-11 00:33:51 +02:00
|
|
|
// Signal
|
|
|
|
//
|
|
|
|
// Created by Frederic Jacobs on 09/07/14.
|
|
|
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
|
|
|
//
|
|
|
|
#import "CryptoTools.h"
|
2014-11-21 00:51:23 +01:00
|
|
|
#import "SignalKeyingStorage.h"
|
2014-07-11 00:33:51 +02:00
|
|
|
#import "Constraints.h"
|
2014-11-21 00:51:23 +01:00
|
|
|
#import "TSStorageManager.h"
|
2015-01-11 17:48:18 +01:00
|
|
|
#import "Util.h"
|
2014-07-11 00:33:51 +02:00
|
|
|
|
2014-11-21 00:51:23 +01:00
|
|
|
#define SignalKeyingCollection @"SignalKeyingCollection"
|
|
|
|
|
2014-07-11 00:33:51 +02:00
|
|
|
#define SIGNALING_MAC_KEY_LENGTH 20
|
|
|
|
#define SIGNALING_CIPHER_KEY_LENGTH 16
|
|
|
|
#define SAVED_PASSWORD_LENGTH 18
|
|
|
|
#define SIGNALING_EXTRA_KEY_LENGTH 4
|
|
|
|
|
2014-11-21 00:51:23 +01:00
|
|
|
@implementation SignalKeyingStorage
|
2014-07-11 00:33:51 +02:00
|
|
|
|
2014-07-11 19:41:16 +02:00
|
|
|
+ (void)generateServerAuthPassword{
|
|
|
|
[self storeString:[[CryptoTools generateSecureRandomData:SAVED_PASSWORD_LENGTH] encodedAsBase64] forKey:SAVED_PASSWORD_KEY];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (void)generateSignaling{
|
2014-07-11 00:33:51 +02:00
|
|
|
[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];
|
|
|
|
}
|
|
|
|
|
|
|
|
+(int64_t) getAndIncrementOneTimeCounter {
|
|
|
|
__block int64_t oldCounter;
|
2014-11-21 00:51:23 +01:00
|
|
|
oldCounter = [[self stringForKey:PASSWORD_COUNTER_KEY] longLongValue];
|
2014-07-11 00:33:51 +02:00
|
|
|
int64_t newCounter = (oldCounter == INT64_MAX)?INT64_MIN:(oldCounter + 1);
|
2014-08-13 02:02:29 +02:00
|
|
|
[self storeString:[@(newCounter) stringValue] forKey:PASSWORD_COUNTER_KEY];
|
2014-07-11 00:33:51 +02:00
|
|
|
return newCounter;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (void)setLocalNumberTo:(PhoneNumber *)localNumber{
|
|
|
|
require(localNumber != nil);
|
2014-09-07 20:43:53 +02:00
|
|
|
require(localNumber.toE164!= nil);
|
2014-07-11 00:33:51 +02:00
|
|
|
|
2014-09-07 20:43:53 +02:00
|
|
|
NSString *e164 = localNumber.toE164;
|
2014-07-11 00:33:51 +02:00
|
|
|
[self storeString:e164 forKey:LOCAL_NUMBER_KEY];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (PhoneNumber *)localNumber{
|
|
|
|
NSString *lnString = [self stringForKey:LOCAL_NUMBER_KEY];
|
|
|
|
checkOperation(lnString != nil );
|
|
|
|
PhoneNumber *num = [PhoneNumber tryParsePhoneNumberFromE164:lnString];
|
2014-07-11 23:40:12 +02:00
|
|
|
return lnString?num:nil;
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
+(Zid *)zid{
|
|
|
|
NSData *data = [self dataForKey:ZID_KEY];
|
2014-08-14 03:13:24 +02:00
|
|
|
if (data.length != ZID_LENGTH) {
|
|
|
|
DDLogError(@"ZID length is incorrect. Is %lu, should be %d", (unsigned long)data.length, ZID_LENGTH);
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
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];
|
2014-08-14 03:13:24 +02:00
|
|
|
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);
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
return password;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark Keychain wrapper methods
|
|
|
|
|
2014-11-21 00:51:23 +01:00
|
|
|
+(void)storeData:(NSData*)data forKey:(NSString*)key{
|
|
|
|
[TSStorageManager.sharedManager setObject:data forKey:key inCollection:SignalKeyingCollection];
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
+(NSData*)dataForKey:(NSString*)key andVerifyLength:(uint)length{
|
|
|
|
NSData *data = [self dataForKey:key];
|
|
|
|
|
2014-08-14 03:13:24 +02:00
|
|
|
if (data.length != length) {
|
|
|
|
DDLogError(@"Length of data not matching. Got %lu, expected %u", (unsigned long)data.length, length);
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
+(NSData*)dataForKey:(NSString*)key{
|
2014-11-21 00:51:23 +01:00
|
|
|
return [TSStorageManager.sharedManager dataForKey:key inCollection:SignalKeyingCollection];
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
+(NSString*)stringForKey:(NSString*)key{
|
2014-11-21 00:51:23 +01:00
|
|
|
return [TSStorageManager.sharedManager stringForKey:key inCollection:SignalKeyingCollection];
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
2014-11-21 00:51:23 +01:00
|
|
|
+(void)storeString:(NSString*)string forKey:(NSString*)key{
|
|
|
|
[TSStorageManager.sharedManager setObject:string forKey:key inCollection:SignalKeyingCollection];
|
2014-07-11 00:33:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|