I am working on an application for OSX Lion and beyond. The application has a root daemon process. I created a system keychain using "SecKeychainCreate" in / Library / Keychains, accessible only to daemons and wanting to keep the shared keys in this keychain. Can someone help me with software to get shared keys from this keychain? To add a key to the keychain, I used the "SecKeychainItemCreateFromContent" function because it takes a SecKeychainRef parameter and passed kSecPublicKeyItemClass as the first parameter. Here is my code:
char *itemLabel = "Generic public key"; //Setting up the attribute vector (each attribute consists of {tag, length, pointer}): SecKeychainAttribute attrs[] = {kSecLabelItemAttr, strlen(itemLabel), itemLabel}; SecKeychainAttributeList attributes = { sizeof(attrs)/sizeof(attrs[0]), attrs }; //pubKey is the key (NSData) that I want to store, while tempKeyChain is my keychain status = SecKeychainItemCreateFromContent(kSecPublicKeyItemClass, &attributes, [pubKey length],(__bridge const void *)pubKey, tempKeyChain, NULL, NULL); if (status != noErr) { NSString *error = (__bridge NSString *)SecCopyErrorMessageString(status, NULL); NSLog(@"Error in adding item to keychain : %@",error); return errSecUnimplemented; }
Now, to get the key, there are two options: "SecKeychainSearchCreateFromAttributes", which is deprecated in OS X 10.7 and therefore useless, or "SecItemCopyMatching". The first takes the SecKeychainRef parameter, and the second does not. So, I manually set my search list using "SecKeychainSetSearchList" to enable tempKeyChain, and then used "SecItemCopyMatching". Here is the code for this:
OSStatus status; SecKeychainRef defaultKeychain = nil; SecKeychainCopyDefault(&defaultKeychain); NSArray *searchList = [NSArray arrayWithObjects:(__bridge id)defaultKeychain,tempKeyChain, nil]; OSStatus result = SecKeychainSetSearchList((__bridge CFArrayRef)searchList); if (result != noErr) { NSString *error = (__bridge NSString *)SecCopyErrorMessageString(result, NULL); NSLog(@"Error : %@",error); return errSecUnimplemented; } NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; [query setObject:kSecClassKey forKey:(id)kSecClass]; [query setObject:@"Generic public key" forKey:kSecAttrLabel]; CFTypeRef items; status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &items); return status;
This code always gives the status "Item not found", although my keychain is added to the search list along with the default search list.
I would really appreciate any guidance on why this might happen, or any other ways to store and retrieve keys from a custom keychain.
PS - I do not want to store passwords, only keys (public and private). Can someone lead me to some code or provide a small piece of code explaining the same thing? Thanks.