From 93c571daec394d777bc0bcdf485b698f3b154660 Mon Sep 17 00:00:00 2001 From: Frederic Jacobs Date: Sat, 27 Dec 2014 01:08:05 +0100 Subject: [PATCH] Removing keying material and wiping messages. --- .../Attachements/TSAttachmentStream.h | 2 + .../Attachements/TSAttachmentStream.m | 27 +++++----- .../Messages/TSMessagesManager+sendMessages.m | 1 + .../TSStorageManager+IdentityKeyStore.h | 1 + .../TSStorageManager+IdentityKeyStore.m | 6 ++- .../src/textsecure/Storage/TSStorageManager.h | 1 + .../src/textsecure/Storage/TSStorageManager.m | 16 ++++++ .../FingerprintViewController.m | 53 ++++++++++++++----- .../SettingsTableViewController.m | 13 +++-- 9 files changed, 87 insertions(+), 33 deletions(-) diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h index d315669ca..2bb8f01d1 100644 --- a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.h @@ -20,4 +20,6 @@ - (BOOL)isImage; - (BOOL)isVideo; ++ (void)deleteAttachments; + @end diff --git a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m index 53916f867..dc14ff2c3 100644 --- a/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m +++ b/Signal/src/textsecure/Messages/Attachements/TSAttachmentStream.m @@ -11,21 +11,15 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge"; -@interface TSAttachmentStream () - -@property (nonatomic) NSString *attachmentPath; - -@end - @implementation TSAttachmentStream - (instancetype)initWithIdentifier:(NSString*)identifier data:(NSData*)data key:(NSData*)key - contentType:(NSString*)contentType{ + contentType:(NSString*)contentType { self = [super initWithIdentifier:identifier encryptionKey:key contentType:contentType]; - [[NSFileManager defaultManager] createFileAtPath:_attachmentPath contents:data attributes:nil]; + [[NSFileManager defaultManager] createFileAtPath:self.filePath contents:data attributes:nil]; return self; } @@ -64,7 +58,7 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge"; return [[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId]; } -- (BOOL)isImage{ +- (BOOL)isImage { if ([self.contentType containsString:@"image/"]) { return YES; } else{ @@ -72,7 +66,7 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge"; } } -- (BOOL)isVideo{ +- (BOOL)isVideo { if ([self.contentType containsString:@"video/"]) { return YES; } else{ @@ -80,12 +74,21 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge"; } } -- (UIImage*)image{ +- (UIImage*)image { if (![self isImage]) { return nil; } - + return [UIImage imageWithContentsOfFile:self.filePath]; } ++ (void)deleteAttachments { + NSFileManager *fm = [NSFileManager defaultManager]; + NSError *error; + [fm removeItemAtPath:[self attachmentsFolder] error:&error]; + if (error) { + DDLogError(@"Failed to delete attachment folder with error: %@", error.debugDescription); + } +} + @end diff --git a/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m b/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m index 89a5bc1ee..386377db6 100644 --- a/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m +++ b/Signal/src/textsecure/Messages/TSMessagesManager+sendMessages.m @@ -179,6 +179,7 @@ dispatch_queue_t sendingQueue() { bundle = [PreKeyBundle preKeyBundleFromDictionary:responseObject forDeviceNumber:deviceNumber]; dispatch_semaphore_signal(sema); } failure:^(NSURLSessionDataTask *task, NSError *error) { + DDLogError(@"Server replied on PreKeyBundle request with error: %@", error); dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); diff --git a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.h b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.h index 65080ed3f..12b67827a 100644 --- a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.h +++ b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.h @@ -13,5 +13,6 @@ - (void)generateNewIdentityKey; - (NSData*)identityKeyForRecipientId:(NSString*)recipientId; +- (void)removeIdentityKeyForRecipient:(NSString*)receipientId; @end diff --git a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.m b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.m index 17b852bbf..506c93bb3 100644 --- a/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.m +++ b/Signal/src/textsecure/Storage/AxolotlStore/TSStorageManager+IdentityKeyStore.m @@ -11,7 +11,7 @@ #import <25519/Curve25519.h> -#define TSStorageManagerIdentityKeyStoreIdentityKey @"TSStorageManagerIdentityKeyStoreIdentityKey" +#define TSStorageManagerIdentityKeyStoreIdentityKey @"TSStorageManagerIdentityKeyStoreIdentityKey" // Key for our identity key #define TSStorageManagerIdentityKeyStoreCollection @"TSStorageManagerIdentityKeyStoreCollection" #define TSStorageManagerTrustedKeysCollection @"TSStorageManagerTrustedKeysCollection" @@ -49,4 +49,8 @@ return (trusted == nil || [trusted isEqualToData:identityKey]); } +- (void)removeIdentityKeyForRecipient:(NSString*)receipientId{ + [self removeObjectForKey:receipientId inCollection:TSStorageManagerTrustedKeysCollection]; +} + @end diff --git a/Signal/src/textsecure/Storage/TSStorageManager.h b/Signal/src/textsecure/Storage/TSStorageManager.h index a71517e31..a5429b8c4 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager.h +++ b/Signal/src/textsecure/Storage/TSStorageManager.h @@ -21,6 +21,7 @@ extern NSString *const TSUIDatabaseConnectionDidUpdateNotification; + (instancetype)sharedManager; - (void)setupDatabase; +- (void)deleteThreadsAndMessages; - (YapDatabase*)database; - (YapDatabaseConnection*)newDatabaseConnection; diff --git a/Signal/src/textsecure/Storage/TSStorageManager.m b/Signal/src/textsecure/Storage/TSStorageManager.m index 955df1f2f..aac6b6fe2 100644 --- a/Signal/src/textsecure/Storage/TSStorageManager.m +++ b/Signal/src/textsecure/Storage/TSStorageManager.m @@ -13,6 +13,12 @@ #import "CryptoTools.h" #import "NSData+Base64.h" +#import "TSThread.h" +#import "TSInteraction.h" +#import "TSRecipient.h" +#import "TSAttachment.h" +#import "TSAttachmentStream.h" + #import #import "TSDatabaseView.h" @@ -235,6 +241,16 @@ static NSString * keychainDBPassAccount = @"TSDatabasePass"; [self setObject:[NSNumber numberWithInt:integer] forKey:key inCollection:collection]; } +- (void)deleteThreadsAndMessages { + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [transaction removeAllObjectsInCollection:[TSThread collection]]; + [transaction removeAllObjectsInCollection:[TSRecipient collection]]; + [transaction removeAllObjectsInCollection:[TSInteraction collection]]; + [transaction removeAllObjectsInCollection:[TSAttachment collection]]; + }]; + [TSAttachmentStream deleteAttachments]; +} + - (void)wipe{ self.database = nil; NSError *error; diff --git a/Signal/src/view controllers/FingerprintViewController.m b/Signal/src/view controllers/FingerprintViewController.m index e3201a571..3d7cf4343 100644 --- a/Signal/src/view controllers/FingerprintViewController.m +++ b/Signal/src/view controllers/FingerprintViewController.m @@ -15,8 +15,10 @@ #import "DJWActionSheet.h" #import "TSStorageManager.h" #import "TSStorageManager+IdentityKeyStore.h" +#import "TSStorageManager+SessionStore.h" #import "PresentIdentityQRCodeViewController.h" #import "ScanIdentityBarcodeViewController.h" +#import "SignalsNavigationController.h" #include "NSData+Base64.h" #import "TSFingerprintGenerator.h" @@ -44,9 +46,8 @@ - (void)viewWillAppear:(BOOL)animated { - self.contactFingerprintTitleLabel.text = self.thread.name; - NSData *identityKey = [[TSStorageManager sharedManager] identityKeyForRecipientId:self.thread.contactIdentifier]; - self.contactFingerprintLabel.text = [TSFingerprintGenerator getFingerprintForDisplay:identityKey]; + + [self setHisKeyInformation]; NSData *myPublicKey = [[TSStorageManager sharedManager] identityKeyPair].publicKey; self.userFingerprintLabel.text = [TSFingerprintGenerator getFingerprintForDisplay:myPublicKey]; @@ -60,6 +61,12 @@ [super didReceiveMemoryWarning]; } +- (void)setHisKeyInformation { + self.contactFingerprintTitleLabel.text = self.thread.name; + NSData *identityKey = [[TSStorageManager sharedManager] identityKeyForRecipientId:self.thread.contactIdentifier]; + self.contactFingerprintLabel.text = [TSFingerprintGenerator getFingerprintForDisplay:identityKey]; +} + -(NSData*) getMyPublicIdentityKey { return [[TSStorageManager sharedManager] identityKeyPair].publicKey; } @@ -87,7 +94,7 @@ } completion:nil]; _presentationLabel.hidden = YES; - + } -(void)hideInfo @@ -95,7 +102,7 @@ _didShowInfo = NO; _presentationLabel.hidden = NO; - + [UIView animateWithDuration:0.3f delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^(){ _infoArrowTop.alpha = 0; _infoArrowBottom.alpha = 0; @@ -110,10 +117,10 @@ _infoMyFingerprint.hidden = YES; _infoTheirFingerprint.hidden = YES; } - + }]; - + } #pragma mark - Action @@ -124,7 +131,7 @@ } completion:^(BOOL succeeded){ [self dismissViewControllerAnimated:YES completion:nil]; }]; - + } - (IBAction)showInfoAction:(id)sender @@ -138,15 +145,25 @@ - (IBAction)shredAndDelete:(id)sender { - [DJWActionSheet showInView:self.view withTitle:@"Are you sure wou want to shred all communications with this contact ? This action is irreversible." - cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@[@"Shred all communications & delete contact"] + [DJWActionSheet showInView:self.view withTitle:@"Are you sure wou want to shred the following? This action is irreversible." + cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@[@"Shred all keying material", @"Shred all keying material & communications history"] tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) { if (tappedButtonIndex == actionSheet.cancelButtonIndex) { NSLog(@"User Cancelled"); } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) { NSLog(@"Destructive button tapped"); }else { - [self shredAndDelete]; + switch (tappedButtonIndex) { + case 0: + [self shredKeyingMaterial]; + break; + case 1: + [self shredKeyingMaterial]; + [self shredDiscussionsWithContact]; + break; + default: + break; + } } }]; } @@ -174,8 +191,18 @@ #pragma mark - Shredding & Deleting -- (void)shredAndDelete { -#warning unimplemented: shredAndDelete +- (void)shredKeyingMaterial { + [[TSStorageManager sharedManager] removeIdentityKeyForRecipient:self.thread.contactIdentifier]; + [[TSStorageManager sharedManager] deleteAllSessionsForContact:self.thread.contactIdentifier]; + [self setHisKeyInformation]; +} + +- (void)shredDiscussionsWithContact { + [self.thread remove]; // this removes the thread and all it's discussion (YapDatabaseRelationships) + __block SignalsNavigationController *vc = (SignalsNavigationController*)[self presentingViewController]; + [vc dismissViewControllerAnimated:YES completion:^{ + [vc popToRootViewControllerAnimated:YES]; + }]; } @end diff --git a/Signal/src/view controllers/SettingsTableViewController.m b/Signal/src/view controllers/SettingsTableViewController.m index be8b6a1d4..48041fa64 100644 --- a/Signal/src/view controllers/SettingsTableViewController.m +++ b/Signal/src/view controllers/SettingsTableViewController.m @@ -14,7 +14,6 @@ #import "TSStorageManager.h" #import "Environment.h" #import "PreferencesUtil.h" - #import "RPServerRequestsManager.h" #import @@ -100,18 +99,18 @@ typedef enum { { //Present more info [DJWActionSheet showInView:self.tabBarController.view - withTitle:@"Are you sure you want to delete all your history ? This action cannot be reverted." + withTitle:@"Are you sure you want to delete all your history (messages, attachments, call history ...)? This action cannot be reverted." cancelButtonTitle:@"Cancel" - destructiveButtonTitle:nil - otherButtonTitles:@[@"I'm sure."] + destructiveButtonTitle:@"I'm sure." + otherButtonTitles:@[] tapBlock:^(DJWActionSheet *actionSheet, NSInteger tappedButtonIndex) { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; if (tappedButtonIndex == actionSheet.cancelButtonIndex) { NSLog(@"User Cancelled"); - } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex) { - NSLog(@"Destructive button tapped"); - }else { + } else if (tappedButtonIndex == actionSheet.destructiveButtonIndex){ + [[TSStorageManager sharedManager] deleteThreadsAndMessages]; + } else { NSLog(@"The user tapped button at index: %li", (long)tappedButtonIndex); } }];