Blame client/iOS/Controllers/EncryptionController.m

Packit Service fa4841
/*
Packit Service fa4841
 Password Encryption Controller
Packit Service fa4841
Packit Service fa4841
 Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
Packit Service fa4841
Packit Service fa4841
 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
Packit Service fa4841
 If a copy of the MPL was not distributed with this file, You can obtain one at
Packit Service fa4841
 http://mozilla.org/MPL/2.0/.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#import "EncryptionController.h"
Packit Service fa4841
#import "SFHFKeychainUtils.h"
Packit Service fa4841
#import "TSXAdditions.h"
Packit Service fa4841
Packit Service fa4841
@interface EncryptionController (Private)
Packit Service fa4841
Packit Service fa4841
- (BOOL)verifyPassword:(Encryptor *)decryptor;
Packit Service fa4841
- (NSData *)encryptedVerificationData;
Packit Service fa4841
- (void)setEncryptedVerificationData:(Encryptor *)encryptor;
Packit Service fa4841
Packit Service fa4841
- (NSString *)keychainServerName;
Packit Service fa4841
- (NSString *)keychainUsername;
Packit Service fa4841
- (void)setKeychainPassword:(NSString *)password;
Packit Service fa4841
- (NSString *)keychainPassword;
Packit Service fa4841
- (NSString *)keychainDefaultPassword;
Packit Service fa4841
Packit Service fa4841
@end
Packit Service fa4841
Packit Service fa4841
static EncryptionController *_shared_encryption_controller = nil;
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
Packit Service fa4841
@implementation EncryptionController
Packit Service fa4841
Packit Service fa4841
+ (EncryptionController *)sharedEncryptionController
Packit Service fa4841
{
Packit Service fa4841
	@synchronized(self)
Packit Service fa4841
	{
Packit Service fa4841
		if (_shared_encryption_controller == nil)
Packit Service fa4841
			_shared_encryption_controller = [[EncryptionController alloc] init];
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return _shared_encryption_controller;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#pragma mark Getting an encryptor or decryptor
Packit Service fa4841
Packit Service fa4841
- (Encryptor *)encryptor
Packit Service fa4841
{
Packit Service fa4841
	if (_shared_encryptor)
Packit Service fa4841
		return _shared_encryptor;
Packit Service fa4841
Packit Service fa4841
	NSString *saved_password = [self keychainPassword];
Packit Service fa4841
	if (saved_password == nil)
Packit Service fa4841
	{
Packit Service fa4841
		saved_password = [self keychainDefaultPassword];
Packit Service fa4841
		Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
Packit Service fa4841
		[self setEncryptedVerificationData:encryptor];
Packit Service fa4841
		_shared_encryptor = [encryptor retain];
Packit Service fa4841
	}
Packit Service fa4841
	else
Packit Service fa4841
	{
Packit Service fa4841
		Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
Packit Service fa4841
		if ([self verifyPassword:encryptor])
Packit Service fa4841
			_shared_encryptor = [encryptor retain];
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return _shared_encryptor;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
// For the current implementation, decryptors and encryptors are equivilant.
Packit Service fa4841
- (Encryptor *)decryptor
Packit Service fa4841
{
Packit Service fa4841
	return [self encryptor];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
@end
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
Packit Service fa4841
@implementation EncryptionController (Private)
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
#pragma mark Keychain password storage
Packit Service fa4841
Packit Service fa4841
- (NSString *)keychainServerName
Packit Service fa4841
{
Packit Service fa4841
	return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (NSString *)keychainUsername
Packit Service fa4841
{
Packit Service fa4841
	return @"master.password";
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (void)setKeychainPassword:(NSString *)password
Packit Service fa4841
{
Packit Service fa4841
	NSError *error;
Packit Service fa4841
	if (password == nil)
Packit Service fa4841
	{
Packit Service fa4841
		[SFHFKeychainUtils deleteItemForUsername:[self keychainUsername]
Packit Service fa4841
		                           andServerName:[self keychainServerName]
Packit Service fa4841
		                                   error:&error];
Packit Service fa4841
		return;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	[SFHFKeychainUtils storeUsername:[self keychainUsername]
Packit Service fa4841
	                     andPassword:password
Packit Service fa4841
	                   forServerName:[self keychainServerName]
Packit Service fa4841
	                  updateExisting:YES
Packit Service fa4841
	                           error:&error];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (NSString *)keychainPassword
Packit Service fa4841
{
Packit Service fa4841
	NSError *error;
Packit Service fa4841
	return [SFHFKeychainUtils getPasswordForUsername:[self keychainUsername]
Packit Service fa4841
	                                   andServerName:[self keychainServerName]
Packit Service fa4841
	                                           error:&error];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (NSString *)keychainDefaultPassword
Packit Service fa4841
{
Packit Service fa4841
	NSString *password = [[NSUserDefaults standardUserDefaults] stringForKey:@"UUID"];
Packit Service fa4841
	if ([password length] == 0)
Packit Service fa4841
	{
Packit Service fa4841
		password = [NSString stringWithUUID];
Packit Service fa4841
		[[NSUserDefaults standardUserDefaults] setObject:password forKey:@"UUID"];
Packit Service fa4841
		[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"TSXMasterPasswordVerification"];
Packit Service fa4841
	}
Packit Service fa4841
	return password;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#pragma mark -
Packit Service fa4841
#pragma mark Verification of encryption key against verification data
Packit Service fa4841
Packit Service fa4841
- (BOOL)verifyPassword:(Encryptor *)decryptor
Packit Service fa4841
{
Packit Service fa4841
	return [[decryptor plaintextPassword]
Packit Service fa4841
	    isEqualToString:[decryptor decryptString:[self encryptedVerificationData]]];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (NSData *)encryptedVerificationData
Packit Service fa4841
{
Packit Service fa4841
	return [[NSUserDefaults standardUserDefaults] dataForKey:@"TSXMasterPasswordVerification"];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
- (void)setEncryptedVerificationData:(Encryptor *)encryptor
Packit Service fa4841
{
Packit Service fa4841
	[[NSUserDefaults standardUserDefaults]
Packit Service fa4841
	    setObject:[encryptor encryptString:[encryptor plaintextPassword]]
Packit Service fa4841
	       forKey:@"TSXMasterPasswordVerification"];
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
@end