From 6cea2779d20e6871a3af91e3bef7258745f43f6b Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 8 Mar 2018 10:49:44 -0300 Subject: [PATCH] Stub out backup private key. --- Signal/src/util/OWSBackup.m | 43 +++++++++++++++--- Signal/src/util/OWSBackupExport.m | 75 +++++++++++++++---------------- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/Signal/src/util/OWSBackup.m b/Signal/src/util/OWSBackup.m index e50a66d50..ff457138c 100644 --- a/Signal/src/util/OWSBackup.m +++ b/Signal/src/util/OWSBackup.m @@ -5,6 +5,7 @@ #import "OWSBackup.h" #import "NSNotificationCenter+OWS.h" #import "OWSBackupExport.h" +#import #import #import #import @@ -16,6 +17,7 @@ NSString *const NSNotificationNameBackupStateDidChange = @"NSNotificationNameBac NSString *const OWSPrimaryStorage_OWSBackupCollection = @"OWSPrimaryStorage_OWSBackupCollection"; NSString *const OWSBackup_IsBackupEnabledKey = @"OWSBackup_IsBackupEnabledKey"; +NSString *const OWSBackup_BackupKeyKey = @"OWSBackup_BackupKeyKey"; NSString *const OWSBackup_LastExportSuccessDateKey = @"OWSBackup_LastExportSuccessDateKey"; NSString *const OWSBackup_LastExportFailureDateKey = @"OWSBackup_LastExportFailureDateKey"; @@ -99,14 +101,43 @@ NS_ASSUME_NONNULL_BEGIN }); } +- (void)setBackupPrivateKey:(NSData *)value +{ + OWSAssert(value); + + // TODO: This should eventually be the backup key stored in the Signal Service + // and retrieved with the backup PIN. It will eventually be stored in + // the keychain. + [self.dbConnection setObject:value + forKey:OWSBackup_BackupKeyKey + inCollection:OWSPrimaryStorage_OWSBackupCollection]; +} + +- (nullable NSData *)backupPrivateKey +{ + NSData *_Nullable result = + [self.dbConnection objectForKey:OWSBackup_BackupKeyKey inCollection:OWSPrimaryStorage_OWSBackupCollection]; + if (!result) { + // TODO: This is temporary measure until we have proper private key + // storage in the service. + const NSUInteger kBackupPrivateKeyLength = 32; + result = [Randomness generateRandomBytes:kBackupPrivateKeyLength]; + [self setBackupPrivateKey:result]; + } + OWSAssert(result); + OWSAssert([result isKindOfClass:[NSData class]]); + return result; +} + - (void)setLastExportSuccessDate:(NSDate *)value { + OWSAssert(value); + [self.dbConnection setDate:value forKey:OWSBackup_LastExportSuccessDateKey inCollection:OWSPrimaryStorage_OWSBackupCollection]; } - - (nullable NSDate *)lastExportSuccessDate { return [self.dbConnection dateForKey:OWSBackup_LastExportSuccessDateKey @@ -115,6 +146,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)setLastExportFailureDate:(NSDate *)value { + OWSAssert(value); + [self.dbConnection setDate:value forKey:OWSBackup_LastExportFailureDateKey inCollection:OWSPrimaryStorage_OWSBackupCollection]; @@ -139,7 +172,6 @@ NS_ASSUME_NONNULL_BEGIN [self.dbConnection setBool:value forKey:OWSBackup_IsBackupEnabledKey inCollection:OWSPrimaryStorage_OWSBackupCollection]; - OWSAssert(self.isBackupEnabled); if (!value) { [self.dbConnection removeObjectForKey:OWSBackup_LastExportSuccessDateKey @@ -253,13 +285,10 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - OWSBackupExportDelegate -// TODO: This should eventually be the backup key stored in the Signal Service -// and retrieved with the backup PIN. +// We use a delegate method to avoid storing this key in memory. - (nullable NSData *)backupKey { - // We use a delegate method to avoid storing this key in memory. - // It will eventually be stored in the keychain. - return [@"test backup key" dataUsingEncoding:NSUTF8StringEncoding]; + return self.backupPrivateKey; } - (void)backupExportDidSucceed:(OWSBackupExport *)backupExport diff --git a/Signal/src/util/OWSBackupExport.m b/Signal/src/util/OWSBackupExport.m index 8178e3711..d5d5f4131 100644 --- a/Signal/src/util/OWSBackupExport.m +++ b/Signal/src/util/OWSBackupExport.m @@ -26,10 +26,19 @@ NS_ASSUME_NONNULL_BEGIN typedef void (^OWSBackupExportBoolCompletion)(BOOL success); typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); +@interface OWSBackupExport (Private) + ++ (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath + exportDirPath:(NSString *)exportDirPath + delegate:(id)delegate; + +@end + #pragma mark - @interface OWSAttachmentExport : NSObject +@property (nonatomic, weak) id delegate; @property (nonatomic) NSString *exportDirPath; @property (nonatomic) NSString *attachmentId; @property (nonatomic) NSString *attachmentFilePath; @@ -73,7 +82,9 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); } self.relativeFilePath = relativeFilePath; - NSString *_Nullable tempFilePath = [self encryptAsTempFile:self.attachmentFilePath]; + NSString *_Nullable tempFilePath = [OWSBackupExport encryptAsTempFile:self.attachmentFilePath + exportDirPath:self.exportDirPath + delegate:self.delegate]; if (!tempFilePath) { DDLogError(@"%@ attachment could not be encrypted.", self.logTag); OWSFail(@"%@ attachment could not be encrypted: %@", self.logTag, self.attachmentFilePath); @@ -82,23 +93,6 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); self.tempFilePath = tempFilePath; } -- (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath -{ - OWSAssert(self.exportDirPath.length > 0); - - // TODO: Encrypt the file using self.delegate.backupKey; - - NSString *dstFilePath = [self.exportDirPath stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error; - BOOL success = [fileManager copyItemAtPath:srcFilePath toPath:dstFilePath error:&error]; - if (!success || error) { - OWSProdLogAndFail(@"%@ error writing encrypted file: %@", self.logTag, error); - return nil; - } - return dstFilePath; -} - @end #pragma mark - @@ -252,10 +246,6 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); } __weak OWSBackupExport *weakSelf = self; BackupStorageKeySpecBlock keySpecBlock = ^{ - NSData *_Nullable backupKey = [weakSelf.delegate backupKey]; - if (!backupKey) { - return (NSData *)nil; - } return weakSelf.databaseKeySpec; }; self.backupStorage = @@ -449,6 +439,7 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); // OWSAttachmentExport is used to lazily write an encrypted copy of the // attachment to disk. OWSAttachmentExport *attachmentExport = [OWSAttachmentExport new]; + attachmentExport.delegate = self.delegate; attachmentExport.exportDirPath = self.exportDirPath; attachmentExport.attachmentId = attachmentId; attachmentExport.attachmentFilePath = attachmentFilePath; @@ -519,23 +510,6 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); completion(nil); } -- (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath -{ - OWSAssert(self.exportDirPath.length > 0); - - // TODO: Encrypt the file using self.delegate.backupKey; - - NSString *dstFilePath = [self.exportDirPath stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; - NSFileManager *fileManager = [NSFileManager defaultManager]; - NSError *error; - BOOL success = [fileManager copyItemAtPath:srcFilePath toPath:dstFilePath error:&error]; - if (!success || error) { - OWSProdLogAndFail(@"%@ error writing encrypted file: %@", self.logTag, error); - return nil; - } - return dstFilePath; -} - - (BOOL)writeManifestFile { OWSAssert(self.databaseRecordMap.count > 0); @@ -688,6 +662,29 @@ typedef void (^OWSBackupExportCompletion)(NSError *_Nullable error); }); } ++ (nullable NSString *)encryptAsTempFile:(NSString *)srcFilePath + exportDirPath:(NSString *)exportDirPath + delegate:(id)delegate +{ + OWSAssert(srcFilePath.length > 0); + OWSAssert(exportDirPath.length > 0); + OWSAssert(delegate); + + // TODO: Encrypt the file using self.delegate.backupKey; + NSData *_Nullable backupKey = [delegate backupKey]; + OWSAssert(backupKey); + + NSString *dstFilePath = [exportDirPath stringByAppendingPathComponent:[NSUUID UUID].UUIDString]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error; + BOOL success = [fileManager copyItemAtPath:srcFilePath toPath:dstFilePath error:&error]; + if (!success || error) { + OWSProdLogAndFail(@"%@ error writing encrypted file: %@", self.logTag, error); + return nil; + } + return dstFilePath; +} + @end NS_ASSUME_NONNULL_END