FreeRDP
EncryptionController.m
1 /*
2  Password Encryption Controller
3 
4  Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
5 
6  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7  If a copy of the MPL was not distributed with this file, You can obtain one at
8  http://mozilla.org/MPL/2.0/.
9  */
10 
11 #import "EncryptionController.h"
12 #import "SFHFKeychainUtils.h"
13 #import "TSXAdditions.h"
14 
15 @interface EncryptionController (Private)
16 
17 - (BOOL)verifyPassword:(Encryptor *)decryptor;
18 - (NSData *)encryptedVerificationData;
19 - (void)setEncryptedVerificationData:(Encryptor *)encryptor;
20 
21 - (NSString *)keychainServerName;
22 - (NSString *)keychainUsername;
23 - (void)setKeychainPassword:(NSString *)password;
24 - (NSString *)keychainPassword;
25 - (NSString *)keychainDefaultPassword;
26 
27 @end
28 
29 static EncryptionController *_shared_encryption_controller = nil;
30 
31 #pragma mark -
32 
33 @implementation EncryptionController
34 
35 + (EncryptionController *)sharedEncryptionController
36 {
37  @synchronized(self)
38  {
39  if (_shared_encryption_controller == nil)
40  _shared_encryption_controller = [[EncryptionController alloc] init];
41  }
42 
43  return _shared_encryption_controller;
44 }
45 
46 #pragma mark Getting an encryptor or decryptor
47 
48 - (Encryptor *)encryptor
49 {
50  if (_shared_encryptor)
51  return _shared_encryptor;
52 
53  NSString *saved_password = [self keychainPassword];
54  if (saved_password == nil)
55  {
56  saved_password = [self keychainDefaultPassword];
57  Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
58  [self setEncryptedVerificationData:encryptor];
59  _shared_encryptor = [encryptor retain];
60  }
61  else
62  {
63  Encryptor *encryptor = [[[Encryptor alloc] initWithPassword:saved_password] autorelease];
64  if ([self verifyPassword:encryptor])
65  _shared_encryptor = [encryptor retain];
66  }
67 
68  return _shared_encryptor;
69 }
70 
71 // For the current implementation, decryptors and encryptors are equivilant.
72 - (Encryptor *)decryptor
73 {
74  return [self encryptor];
75 }
76 
77 @end
78 
79 #pragma mark -
80 
81 @implementation EncryptionController (Private)
82 
83 #pragma mark -
84 #pragma mark Keychain password storage
85 
86 - (NSString *)keychainServerName
87 {
88  return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
89 }
90 
91 - (NSString *)keychainUsername
92 {
93  return @"master.password";
94 }
95 
96 - (void)setKeychainPassword:(NSString *)password
97 {
98  NSError *error;
99  if (password == nil)
100  {
101  [SFHFKeychainUtils deleteItemForUsername:[self keychainUsername]
102  andServerName:[self keychainServerName]
103  error:&error];
104  return;
105  }
106 
107  [SFHFKeychainUtils storeUsername:[self keychainUsername]
108  andPassword:password
109  forServerName:[self keychainServerName]
110  updateExisting:YES
111  error:&error];
112 }
113 
114 - (NSString *)keychainPassword
115 {
116  NSError *error;
117  return [SFHFKeychainUtils getPasswordForUsername:[self keychainUsername]
118  andServerName:[self keychainServerName]
119  error:&error];
120 }
121 
122 - (NSString *)keychainDefaultPassword
123 {
124  NSString *password = [[NSUserDefaults standardUserDefaults] stringForKey:@"UUID"];
125  if ([password length] == 0)
126  {
127  password = [NSString stringWithUUID];
128  [[NSUserDefaults standardUserDefaults] setObject:password forKey:@"UUID"];
129  [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"TSXMasterPasswordVerification"];
130  }
131  return password;
132 }
133 
134 #pragma mark -
135 #pragma mark Verification of encryption key against verification data
136 
137 - (BOOL)verifyPassword:(Encryptor *)decryptor
138 {
139  return [[decryptor plaintextPassword]
140  isEqualToString:[decryptor decryptString:[self encryptedVerificationData]]];
141 }
142 
143 - (NSData *)encryptedVerificationData
144 {
145  return [[NSUserDefaults standardUserDefaults] dataForKey:@"TSXMasterPasswordVerification"];
146 }
147 
148 - (void)setEncryptedVerificationData:(Encryptor *)encryptor
149 {
150  [[NSUserDefaults standardUserDefaults]
151  setObject:[encryptor encryptString:[encryptor plaintextPassword]]
152  forKey:@"TSXMasterPasswordVerification"];
153 }
154 
155 @end