Skip to content

Commit

Permalink
Merge pull request #270 from lolgear/change_passphrase_refactoring
Browse files Browse the repository at this point in the history
Change passphrase refactoring
  • Loading branch information
DanielBroad authored Mar 20, 2017
2 parents aecfad7 + a8375fb commit 4d24a78
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 14 deletions.
113 changes: 112 additions & 1 deletion Incremental Store/EncryptedStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,123 @@ typedef NS_ENUM(NSInteger, EncryptedStoreError)
passcode:(NSString *) passcode error:(NSError * __autoreleasing*)error;

#pragma mark - Passphrase manipulation
#pragma mark - Public

/**
@discussion Check old passphrase and if success change old passphrase to new passphrase.
@param oldPassphrase The old passhrase with which database was previously opened.
@param newPassphrase The new passhrase which is desired for database.
@param error Inout error.
@return The status of operation.
*/
- (BOOL)checkAndChangeDatabasePassphrase:(NSString *)oldPassphrase toNewPassphrase:(NSString *)newPassphrase error:(NSError *__autoreleasing*)error;


/**
@discussion Check database passphrase.
@param passphrase The desired passphrase to test for.
@param error Inout error.
@return The status of operation.
*/
- (BOOL)checkDatabasePassphrase:(NSString *)passphrase error:(NSError *__autoreleasing*)error;

#pragma mark - Internal

/**
@brief Configure database with passhrase.
@discussion Configure database with passphrase stored in options dictionary.
@attention Internal usage.
@pre (error != NULL)
@param error Inout error.
@return The status of operation.
*/
- (BOOL)configureDatabasePassphrase:(NSError *__autoreleasing*)error;

/**
@brief Test database connection against simple sql request.
@discussion Test database connection against simple sql request. Success means database open state and correctness of previous passphrase manipulation operation.
@attention Internal usage.
@pre (error != NULL)
@param error Inout error.
@return The status of operation.
*/
- (BOOL)checkDatabaseStatusWithError:(NSError *__autoreleasing*)error;


/**
@brief
Primitive change passphrase operation.
@discussion Ignores database state and tries to change database passphrase.
Behaviour is unknown if used before old passphrase validation.
@attention Internal usage.
@pre (error != NULL)
@param passphrase The new passphrase.
@param error Inout error.
@return The status of operation.
*/
- (BOOL)changeDatabasePassphrase:(NSString *)passphrase error:(NSError *__autoreleasing*)error;


/**
@brief Primitive set passphrase operation.
@discussion Ignores database state and tries to set database passphrase.
One of first-call functions in database setup.
@attention Internal usage.
@pre (error != NULL)
@param passphrase The desired first passphrase of database.
@param error Inout error.
@return The status of operation.
*/
- (BOOL)setDatabasePassphrase:(NSString *)passphrase error:(NSError *__autoreleasing*)error;
// Warning! // This method could close database connection ( look at implementation for details )


/**
@brief Validates database passphrase for correctness.
@discussion Tries to reopen database on provided passphrase.
Closes database and try to open in on provided passphrase.
@warning Could close database connection ( look at an implementation for details ).
@pre (error != NULL)
@param passphrase The desired passphrase to validate.
@param error Inout error.
@return The status of operation.
*/
- (BOOL)validateDatabasePassphrase:(NSString *)passphrase error:(NSError *__autoreleasing*)error;

/**
@brief Primitive database change passphrase operation.
@discussion Tries to open database on provided oldPassphrase and in success it tries to change passphrase to new passphrase.
@attention Internal usage.
@pre (error != NULL)
@param oldPassphrase: The old passphrase.
@param newPassphrase: The new passphrase.
@param error: Inout error.
@return The status of operation.
*/
- (BOOL)changeDatabasePassphrase:(NSString *)oldPassphrase toNewPassphrase:(NSString *)newPassphrase error:(NSError *__autoreleasing*)error;


Expand Down
67 changes: 54 additions & 13 deletions Incremental Store/EncryptedStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ - (NSURL *)applicationSupportURL {
}

- (void)setAttributes:(NSDictionary *)attributes ofItemAtURL:(NSURL *)url error:(NSError *__autoreleasing *)error {
[self.configuration.fileManager setAttributes:attributes ofItemAtPath:[url copy] error:error];
[self.configuration.fileManager setAttributes:attributes ofItemAtPath:[[url absoluteString] copy] error:error];
}
@end

Expand Down Expand Up @@ -1081,8 +1081,49 @@ - (BOOL)saveMetadata {
return YES;
}

#pragma mark - passphrase
#pragma mark - Passphrase manipulation

#pragma mark - Public
- (BOOL)checkAndChangeDatabasePassphrase:(NSString *)oldPassphrase toNewPassphrase:(NSString *)newPassphrase error:(NSError *__autoreleasing *)error {

NSError *validateError = nil;
BOOL validateResult = [self validateDatabasePassphrase:oldPassphrase error:&validateError];

if (error) {
*error = validateError;
}

BOOL checked = validateResult && validateError == nil;

if (!checked) {
return checked;
}

NSError *changeError = nil;
BOOL changeResult = [self changeDatabasePassphrase:oldPassphrase toNewPassphrase:newPassphrase error:&changeError];

BOOL changed = changeResult && changeError == nil;

if (error) {
*error = changeError;
}

return changed;
}

- (BOOL)checkDatabasePassphrase:(NSString *)passphrase error:(NSError *__autoreleasing *)error {
NSError *theError = nil;
BOOL operationResult = [self validateDatabasePassphrase:passphrase error:&theError];
BOOL checked = operationResult && theError == nil;

if (error) {
*error = theError;
}

return checked;
}

#pragma mark - Internal
- (BOOL)configureDatabasePassphrase:(NSError *__autoreleasing*)error {
NSString *passphrase = [[self options] objectForKey:EncryptedStorePassphraseKey];
return [self setDatabasePassphrase:passphrase error:error];
Expand Down Expand Up @@ -1161,7 +1202,7 @@ - (BOOL)validateDatabasePassphrase:(NSString *)passphrase error:(NSError *__auto
int status;
status = sqlite3_close(database);
BOOL result = status == SQLITE_OK;

if (result) {
// try to open
status = sqlite3_open([[[self URL] path] UTF8String], &database);
Expand All @@ -1185,22 +1226,22 @@ - (BOOL)validateDatabasePassphrase:(NSString *)passphrase error:(NSError *__auto
database = NULL;
}
}

else {
// could not close databse? hm
if (error) {
if (error) {
NSMutableDictionary *userInfo = [@{NSLocalizedDescriptionKey : @"Could not close database :("} mutableCopy];
// If we have a DB error keep it for extra info
NSError *underlyingError = [self databaseError];
if (underlyingError) {
userInfo[NSUnderlyingErrorKey] = underlyingError;
}
*error = [NSError errorWithDomain:EncryptedStoreErrorDomain code:EncryptedStoreErrorIncorrectPasscode userInfo:userInfo];
}
// If we have a DB error keep it for extra info
NSError *underlyingError = [self databaseError];
if (underlyingError) {
userInfo[NSUnderlyingErrorKey] = underlyingError;
}
*error = [NSError errorWithDomain:EncryptedStoreErrorDomain code:EncryptedStoreErrorIncorrectPasscode userInfo:userInfo];
}
}

return result && (*error == nil);
}
}

- (BOOL)changeDatabasePassphrase:(NSString *)oldPassphrase toNewPassphrase:(NSString *)newPassphrase error:(NSError *__autoreleasing*)error {
BOOL result;
Expand Down

0 comments on commit 4d24a78

Please sign in to comment.