Privacy preferences for blocking identity change

// FREEBIE
pull/1/head
Michael Kirk 9 years ago
parent 725153307e
commit 70e536ca8f

@ -35,7 +35,7 @@ PODS:
- ProtocolBuffers (1.9.10) - ProtocolBuffers (1.9.10)
- Reachability (3.2) - Reachability (3.2)
- SAMKeychain (1.5.0) - SAMKeychain (1.5.0)
- SignalServiceKit (0.4.0): - SignalServiceKit (0.6.0):
- '25519' - '25519'
- AFNetworking - AFNetworking
- AxolotlKit - AxolotlKit
@ -130,7 +130,7 @@ SPEC CHECKSUMS:
ProtocolBuffers: d088180c10072b3d24a9939a6314b7b9bcc2340b ProtocolBuffers: d088180c10072b3d24a9939a6314b7b9bcc2340b
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SAMKeychain: 1fc9ae02f576365395758b12888c84704eebc423 SAMKeychain: 1fc9ae02f576365395758b12888c84704eebc423
SignalServiceKit: 5c3877241082a778c8c130e1fed17d0904085205 SignalServiceKit: c580eb2197f87212fcba9f7faf56163f410225e9
SocketRocket: 3f77ec2104cc113add553f817ad90a77114f5d43 SocketRocket: 3f77ec2104cc113add553f817ad90a77114f5d43
SQLCipher: 4c768761421736a247ed6cf412d9045615d53dff SQLCipher: 4c768761421736a247ed6cf412d9045615d53dff
TwistedOakCollapsingFutures: f359b90f203e9ab13dfb92c9ff41842a7fe1cd0c TwistedOakCollapsingFutures: f359b90f203e9ab13dfb92c9ff41842a7fe1cd0c

@ -8,7 +8,7 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "SignalServiceKit" s.name = "SignalServiceKit"
s.version = "0.5.3" s.version = "0.6.0"
s.summary = "An Objective-C library for communicating with the Signal messaging service." s.summary = "An Objective-C library for communicating with the Signal messaging service."
s.description = <<-DESC s.description = <<-DESC

@ -0,0 +1,16 @@
// Created by Michael Kirk on 11/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "TSYapDatabaseObject.h"
NS_ASSUME_NONNULL_BEGIN
@interface TSPrivacyPreferences : TSYapDatabaseObject
+ (instancetype)sharedInstance;
@property BOOL shouldBlockOnIdentityChange;
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,45 @@
// Created by Michael Kirk on 11/7/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "TSPrivacyPreferences.h"
NS_ASSUME_NONNULL_BEGIN
NSString *const TSPrivacyPreferencesSingletonKey = @"TSPrivacyPreferences";
@implementation TSPrivacyPreferences
+ (instancetype)sharedInstance
{
static TSPrivacyPreferences *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [self fetchObjectWithUniqueID:TSPrivacyPreferencesSingletonKey];
if (!sharedInstance) {
sharedInstance = [[self alloc] initDefault];
}
});
return sharedInstance;
}
- (instancetype)initDefault
{
return [self initWithShouldBlockOnIdentityChange:NO];
}
- (instancetype)initWithShouldBlockOnIdentityChange:(BOOL)shouldBlockOnIdentityChange
{
self = [super initWithUniqueId:TSPrivacyPreferencesSingletonKey];
if (!self) {
return self;
}
_shouldBlockOnIdentityChange = shouldBlockOnIdentityChange;
return self;
}
@end
NS_ASSUME_NONNULL_END

@ -14,6 +14,7 @@ typedef NS_ENUM(int32_t, TSErrorMessageType) {
TSErrorMessageInvalidMessage, TSErrorMessageInvalidMessage,
TSErrorMessageDuplicateMessage, TSErrorMessageDuplicateMessage,
TSErrorMessageInvalidVersion, TSErrorMessageInvalidVersion,
TSErrorMessageNonBlockingIdentityChange,
}; };
-(instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; -(instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

@ -65,6 +65,8 @@
return NSLocalizedString(@"ERROR_MESSAGE_INVALID_KEY_EXCEPTION", @""); return NSLocalizedString(@"ERROR_MESSAGE_INVALID_KEY_EXCEPTION", @"");
case TSErrorMessageWrongTrustedIdentityKey: case TSErrorMessageWrongTrustedIdentityKey:
return NSLocalizedString(@"ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY", @""); return NSLocalizedString(@"ERROR_MESSAGE_WRONG_TRUSTED_IDENTITY_KEY", @"");
case TSErrorMessageNonBlockingIdentityChange:
return NSLocalizedString(@"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE", @"");
default: default:
return NSLocalizedString(@"ERROR_MESSAGE_UNKNOWN_ERROR", @""); return NSLocalizedString(@"ERROR_MESSAGE_UNKNOWN_ERROR", @"");
break; break;

@ -1,13 +0,0 @@
//
// UserPreferences.h
// Pods
//
// Created by Frederic Jacobs on 05/12/15.
//
//
#import <Foundation/Foundation.h>
@protocol UserPreferencesProtocol <NSObject>
@end

@ -1,9 +1,12 @@
// Created by Frederic Jacobs on 06/11/14. // Created by Frederic Jacobs on 06/11/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved. // Copyright (c) 2014 Open Whisper Systems. All rights reserved.
#import "NSDate+millisecondTimeStamp.h"
#import "TSAccountManager.h" #import "TSAccountManager.h"
#import "TSContactThread.h"
#import "TSErrorMessage.h"
#import "TSPrivacyPreferences.h"
#import "TSStorageManager+IdentityKeyStore.h" #import "TSStorageManager+IdentityKeyStore.h"
#import <25519/Curve25519.h> #import <25519/Curve25519.h>
#define TSStorageManagerIdentityKeyStoreIdentityKey \ #define TSStorageManagerIdentityKeyStoreIdentityKey \
@ -40,13 +43,36 @@
} }
- (BOOL)isTrustedIdentityKey:(NSData *)identityKey recipientId:(NSString *)recipientId { - (BOOL)isTrustedIdentityKey:(NSData *)identityKey recipientId:(NSString *)recipientId {
NSData *trusted = [self dataForKey:recipientId inCollection:TSStorageManagerTrustedKeysCollection]; NSData *existingKey = [self dataForKey:recipientId inCollection:TSStorageManagerTrustedKeysCollection];
if (!existingKey) {
return YES;
}
if ([existingKey isEqualToData:identityKey]) {
return YES;
}
return (trusted == nil || [trusted isEqualToData:identityKey]); if (self.privacyPreferences.shouldBlockOnIdentityChange) {
return NO;
}
DDLogInfo(@"Updating identity key for recipient:%@", recipientId);
[self createIdentityChangeInfoMessageForRecipientId:recipientId];
[self saveRemoteIdentity:identityKey recipientId:recipientId];
return YES;
} }
- (void)removeIdentityKeyForRecipient:(NSString *)receipientId { - (void)removeIdentityKeyForRecipient:(NSString *)receipientId {
[self removeObjectForKey:receipientId inCollection:TSStorageManagerTrustedKeysCollection]; [self removeObjectForKey:receipientId inCollection:TSStorageManagerTrustedKeysCollection];
} }
- (void)createIdentityChangeInfoMessageForRecipientId:(NSString *)recipientId
{
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
[[[TSErrorMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:contactThread
failedMessageType:TSErrorMessageNonBlockingIdentityChange] save];
}
@end @end

@ -14,6 +14,7 @@
@class ECKeyPair; @class ECKeyPair;
@class PreKeyRecord; @class PreKeyRecord;
@class SignedPreKeyRecord; @class SignedPreKeyRecord;
@class TSPrivacyPreferences;
extern NSString *const TSUIDatabaseConnectionDidUpdateNotification; extern NSString *const TSUIDatabaseConnectionDidUpdateNotification;
@ -46,5 +47,6 @@ extern NSString *const TSUIDatabaseConnectionDidUpdateNotification;
- (void)purgeCollection:(NSString *)collection; - (void)purgeCollection:(NSString *)collection;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@property (nonatomic, readonly) TSPrivacyPreferences *privacyPreferences;
@end @end

@ -10,6 +10,7 @@
#import "TSDatabaseSecondaryIndexes.h" #import "TSDatabaseSecondaryIndexes.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
#import "TSInteraction.h" #import "TSInteraction.h"
#import "TSPrivacyPreferences.h"
#import "TSThread.h" #import "TSThread.h"
#import <25519/Randomness.h> #import <25519/Randomness.h>
#import <SAMKeychain/SAMKeychain.h> #import <SAMKeychain/SAMKeychain.h>
@ -73,18 +74,19 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
@implementation TSStorageManager @implementation TSStorageManager
+ (instancetype)sharedManager { + (instancetype)sharedManager {
static TSStorageManager *sharedMyManager = nil; static TSStorageManager *sharedManager = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init]; sharedManager = [[self alloc] initDefault];
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
[sharedMyManager protectSignalFiles]; [sharedManager protectSignalFiles];
#endif #endif
}); });
return sharedMyManager; return sharedManager;
} }
- (instancetype)init { - (instancetype)initDefault
{
self = [super init]; self = [super init];
YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init]; YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init];
@ -178,6 +180,11 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
return self.database.newConnection; return self.database.newConnection;
} }
- (TSPrivacyPreferences *)privacyPreferences
{
return [TSPrivacyPreferences sharedInstance];
}
- (BOOL)userSetPassword { - (BOOL)userSetPassword {
return FALSE; return FALSE;
} }

@ -9,9 +9,10 @@
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#import <25519/Curve25519.h> #import <25519/Curve25519.h>
#import "TSStorageManager.h"
#import "TSStorageManager+IdentityKeyStore.h"
#import "SecurityUtils.h" #import "SecurityUtils.h"
#import "TSPrivacyPreferences.h"
#import "TSStorageManager+IdentityKeyStore.h"
#import "TSStorageManager.h"
@interface TSStorageIdentityKeyStoreTests : XCTestCase @interface TSStorageIdentityKeyStoreTests : XCTestCase
@ -47,7 +48,12 @@
} }
- (void)testChangedKey { - (void)testChangedKeyWithBlockingIdentityChanges
{
TSPrivacyPreferences *preferences = [TSPrivacyPreferences sharedInstance];
preferences.shouldBlockOnIdentityChange = YES;
[preferences save];
NSData *newKey = [SecurityUtils generateRandomBytes:32]; NSData *newKey = [SecurityUtils generateRandomBytes:32];
NSString *recipientId = @"test@gmail.com"; NSString *recipientId = @"test@gmail.com";
@ -60,6 +66,25 @@
XCTAssertFalse([[TSStorageManager sharedManager] isTrustedIdentityKey:otherKey recipientId:recipientId]); XCTAssertFalse([[TSStorageManager sharedManager] isTrustedIdentityKey:otherKey recipientId:recipientId]);
} }
- (void)testChangedKeyWIthNonBlockingIdentityChanges
{
TSPrivacyPreferences *preferences = [TSPrivacyPreferences sharedInstance];
preferences.shouldBlockOnIdentityChange = NO;
[preferences save];
NSData *newKey = [SecurityUtils generateRandomBytes:32];
NSString *recipientId = @"test@gmail.com";
[[TSStorageManager sharedManager] saveRemoteIdentity:newKey recipientId:recipientId];
XCTAssert([[TSStorageManager sharedManager] isTrustedIdentityKey:newKey recipientId:recipientId]);
NSData *otherKey = [SecurityUtils generateRandomBytes:32];
XCTAssertTrue([[TSStorageManager sharedManager] isTrustedIdentityKey:otherKey recipientId:recipientId]);
}
- (void)testIdentityKey { - (void)testIdentityKey {
[[TSStorageManager sharedManager] generateNewIdentityKey]; [[TSStorageManager sharedManager] generateNewIdentityKey];

Loading…
Cancel
Save