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