Fixup database conversion vis a vis SQLCipher4

This commit is contained in:
Michael Kirk 2019-01-11 15:20:32 -07:00 committed by Matthew Chen
parent 96fffb92cc
commit 119f309787
4 changed files with 36 additions and 19 deletions

View file

@ -452,8 +452,10 @@ static NSTimeInterval launchStartedAt;
return YES;
};
YapDatabaseOptions *dbOptions = [OWSStorage defaultDatabaseOptions];
error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:dbOptions
recordSaltBlock:recordSaltBlock];
if (!error) {
[OWSStorage removeLegacyPassphrase];

View file

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "SignalBaseTest.h"
@ -107,6 +107,7 @@ NS_ASSUME_NONNULL_BEGIN
};
options.cipherUnencryptedHeaderLength = kSqliteHeaderLength;
}
options.legacyCipherCompatibilityVersion = 3;
OWSAssertDebug(options.cipherDefaultkdfIterNumber == 0);
OWSAssertDebug(options.kdfIterNumber == 0);
@ -323,6 +324,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
if (error) {
OWSLogError(@"error: %@", error);
@ -364,6 +366,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
if (error) {
OWSLogError(@"error: %@", error);
@ -404,6 +407,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
XCTAssertNotNil(error);
@ -456,6 +460,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
if (error) {
OWSLogError(@"error: %@", error);
@ -499,6 +504,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
if (error) {
OWSLogError(@"error: %@", error);
@ -532,6 +538,7 @@ NS_ASSUME_NONNULL_BEGIN
NSError *_Nullable error = [YapDatabaseCryptoUtils convertDatabaseIfNecessary:databaseFilePath
databasePassword:databasePassword
options:OWSStorage.defaultDatabaseOptions
recordSaltBlock:recordSaltBlock];
if (error) {
OWSLogError(@"error: %@", error);

View file

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <YapDatabase/YapDatabase.h>
@ -69,6 +69,8 @@ typedef void (^OWSStorageMigrationBlock)(void);
- (YapDatabaseConnection *)newDatabaseConnection;
+ (YapDatabaseOptions *)defaultDatabaseOptions;
#pragma mark - Extension Registration
+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName;

View file

@ -410,27 +410,11 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return OWSPrimaryStorage.sharedManager.areAllRegistrationsComplete;
}
- (BOOL)tryToLoadDatabase
+ (YapDatabaseOptions *)defaultDatabaseOptions
{
__weak OWSStorage *weakSelf = self;
YapDatabaseOptions *options = [[YapDatabaseOptions alloc] init];
options.corruptAction = YapDatabaseCorruptAction_Fail;
options.enableMultiProcessSupport = YES;
options.cipherKeySpecBlock = ^{
// NOTE: It's critical that we don't capture a reference to self
// (e.g. by using OWSAssertDebug()) or this database will contain a
// circular reference and will leak.
OWSStorage *strongSelf = weakSelf;
OWSCAssertDebug(strongSelf);
// Rather than compute this once and capture the value of the key
// in the closure, we prefer to fetch the key from the keychain multiple times
// in order to keep the key out of application memory.
NSData *databaseKeySpec = [strongSelf databaseKeySpec];
OWSCAssertDebug(databaseKeySpec.length == kSQLCipherKeySpecLength);
return databaseKeySpec;
};
// We leave a portion of the header decrypted so that iOS will recognize the file
// as a SQLite database. Otherwise, because the database lives in a shared data container,
@ -452,6 +436,28 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
OWSAssertDebug(options.pragmaJournalSizeLimit == 0);
OWSAssertDebug(options.pragmaMMapSize == 0);
return options;
}
- (BOOL)tryToLoadDatabase
{
__weak OWSStorage *weakSelf = self;
YapDatabaseOptions *options = [self.class defaultDatabaseOptions];
options.cipherKeySpecBlock = ^{
// NOTE: It's critical that we don't capture a reference to self
// (e.g. by using OWSAssertDebug()) or this database will contain a
// circular reference and will leak.
OWSStorage *strongSelf = weakSelf;
OWSCAssertDebug(strongSelf);
// Rather than compute this once and capture the value of the key
// in the closure, we prefer to fetch the key from the keychain multiple times
// in order to keep the key out of application memory.
NSData *databaseKeySpec = [strongSelf databaseKeySpec];
OWSCAssertDebug(databaseKeySpec.length == kSQLCipherKeySpecLength);
return databaseKeySpec;
};
// Sanity checking elsewhere asserts we should only regenerate key specs when
// there is no existing database, so rather than lazily generate in the cipherKeySpecBlock
// we must ensure the keyspec exists before we create the database.