Skip to content
Browse files

Decorate the bare key that users will generally want to use with the …

…bundle

id, so a key like "MySecretKey" is actually stored as
"com.mycompany.myapp.MySecretKey". Otherwise, you can have apps sharing
secure keys in advertantly.
  • Loading branch information...
1 parent eabd2a7 commit 7f853062072a8b8499ca941b215404fb58f3cce0 @granoff committed Apr 24, 2012
Showing with 26 additions and 7 deletions.
  1. +26 −7 Lockbox.m
View
33 Lockbox.m
@@ -10,8 +10,15 @@
#define kDelimeter @"-|-"
+static NSString *_bundleId = nil;
+
@implementation Lockbox
++(void)initialize
+{
+ _bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey];
+}
+
+(NSMutableDictionary *)_service
{
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
@@ -31,45 +38,57 @@ +(NSMutableDictionary *)_query
return query;
}
+// Prefix a bare key like "MySecureKey" with the bundle id, so the actual key stored
+// is unique to this app, e.g. "com.mycompany.myapp.MySecretKey"
++(NSString *)_hierarchicalKey:(NSString *)key
+{
+ return [_bundleId stringByAppendingFormat:@".%@", key];
+}
+
+(BOOL)setObject:(NSString *)obj forKey:(NSString *)key
{
OSStatus status;
+
+ NSString *hierKey = [Lockbox _hierarchicalKey:key];
// If the object is nil, delete the item
if (!obj) {
NSMutableDictionary *query = [Lockbox _query];
- [query setObject:key forKey:(id)kSecAttrService];
+ [query setObject:hierKey forKey:(id)kSecAttrService];
status = SecItemDelete((CFDictionaryRef)query);
return (status == errSecSuccess);
}
NSMutableDictionary *dict = [Lockbox _service];
- [dict setObject: key forKey: (id) kSecAttrService];
+ [dict setObject: hierKey forKey: (id) kSecAttrService];
[dict setObject: [obj dataUsingEncoding:NSUTF8StringEncoding] forKey: (id) kSecValueData];
status = SecItemAdd ((CFDictionaryRef) dict, NULL);
if (status == errSecDuplicateItem) {
NSMutableDictionary *query = [Lockbox _query];
- [query setObject:key forKey:(id)kSecAttrService];
+ [query setObject:hierKey forKey:(id)kSecAttrService];
status = SecItemDelete((CFDictionaryRef)query);
if (status == errSecSuccess)
status = SecItemAdd((CFDictionaryRef) dict, NULL);
}
if (status != errSecSuccess)
- NSLog(@"SecItemAdd failed for key %@: %ld", key, status);
+ NSLog(@"SecItemAdd failed for key %@: %ld", hierKey, status);
return (status == errSecSuccess);
}
+(NSString *)objectForKey:(NSString *)key
{
+ NSString *hierKey = [Lockbox _hierarchicalKey:key];
+
NSMutableDictionary *query = [Lockbox _query];
- [query setObject:key forKey: (id)kSecAttrService];
+ [query setObject:hierKey forKey: (id)kSecAttrService];
NSData *data = nil;
- OSStatus status = SecItemCopyMatching ( (CFDictionaryRef) query, (CFTypeRef*) &data );
+ OSStatus status =
+ SecItemCopyMatching ( (CFDictionaryRef) query, (CFTypeRef*) &data );
if (status != errSecSuccess)
- NSLog(@"SecItemCopyMatching failed for key %@: %ld", key, status);
+ NSLog(@"SecItemCopyMatching failed for key %@: %ld", hierKey, status);
if (!data)
return nil;

0 comments on commit 7f85306

Please sign in to comment.
Something went wrong with that request. Please try again.