Statistics
| Branch: | Tag: | Revision:

root / Classes / Keychain.m @ 9fee07a6

History | View | Annotate | Download (3.2 kB)

1
//
2
//  Keychain.m
3
//  OpenStack
4
//
5
//  Based on KeychainWrapper in BadassVNC by Dylan Barrie
6
//
7
//  Created by Mike Mayo on 10/1/10.
8
//  The OpenStack project is provided under the Apache 2.0 license.
9
//
10

    
11
#import "Keychain.h"
12
#import <Security/Security.h>
13

    
14
@implementation Keychain
15

    
16
+ (NSString *)appName {    
17
	NSBundle *bundle = [NSBundle bundleForClass:[self class]];
18
    
19
	// Attempt to find a name for this application
20
	NSString *appName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
21
	if (!appName) {
22
		appName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];	
23
	}
24
    return appName;
25
}
26

    
27
+ (BOOL)setString:(NSString *)string forKey:(NSString *)key {
28
	if (string == nil || key == nil) {
29
		return NO;
30
	}
31
    
32
    key = [NSString stringWithFormat:@"%@ - %@", [Keychain appName], key];
33
    
34
	// First check if it already exists, by creating a search dictionary and requesting that 
35
    // nothing be returned, and performing the search anyway.
36
	NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
37
	
38
	NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
39
	
40
	[existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
41
	
42
	// Add the keys to the search dict
43
	[existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
44
	[existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];
45
    
46
	OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, NULL);
47
	if (res == errSecItemNotFound) {
48
		if (string != nil) {
49
			NSMutableDictionary *addDict = existsQueryDictionary;
50
			[addDict setObject:data forKey:(id)kSecValueData];
51
            
52
			res = SecItemAdd((CFDictionaryRef)addDict, NULL);
53
			NSAssert1(res == errSecSuccess, @"Recieved %d from SecItemAdd!", res);
54
		}
55
	} else if (res == errSecSuccess) {
56
		// Modify an existing one
57
		// Actually pull it now of the keychain at this point.
58
		NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(id)kSecValueData];
59
        
60
		res = SecItemUpdate((CFDictionaryRef)existsQueryDictionary, (CFDictionaryRef)attributeDict);
61
		NSAssert1(res == errSecSuccess, @"SecItemUpdated returned %d!", res);
62
		
63
	} else {
64
		NSAssert1(NO, @"Received %d from SecItemCopyMatching!", res);
65
	}
66
	
67
	return YES;
68
}
69

    
70
+ (NSString *)getStringForKey:(NSString *)key {
71

    
72
    key = [NSString stringWithFormat:@"%@ - %@", [Keychain appName], key];
73
    
74
	NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
75
	
76
	[existsQueryDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
77
	
78
	// Add the keys to the search dict
79
	[existsQueryDictionary setObject:@"service" forKey:(id)kSecAttrService];
80
	[existsQueryDictionary setObject:key forKey:(id)kSecAttrAccount];
81
	
82
	// We want the data back!
83
	NSData *data = nil;
84
	
85
	[existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
86
	
87
	OSStatus res = SecItemCopyMatching((CFDictionaryRef)existsQueryDictionary, (CFTypeRef *)&data);
88
	[data autorelease];
89
	if (res == errSecSuccess) {
90
		NSString *string = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
91
		return string;
92
	} else {
93
		NSAssert1(res == errSecItemNotFound, @"SecItemCopyMatching returned %d!", res);
94
	}		
95
	
96
	return nil;
97
}
98

    
99
@end