I'm trying to add a simple string secret to they keychain in macOS, via the C++ APIs. Unfortunately, I can't get my call to SecItemAdd
to work. I know it is because my value for the kSecValueRef
key is the wrong type, but so far Google/Apple docs/existing StackOverflow questions have yet to reveal to me what type I should be using, and how to create it. Here's what I have so far:
CFStringRef keys[4];
keys[0] = kSecClass;
keys[1] = kSecValueRef;
keys[2] = kSecAttrAccount;
keys[3] = kSecAttrService;
CFTypeRef values[4];
values[0] = kSecClassGenericPassword;
values[1] = CFSTR("password");
values[2] = CFSTR( "account-1" );
values[3] = CFSTR( "service-1" );
CFDictionaryRef attributes = CFDictionaryCreate
(
( CFAllocatorRef )NULL,
( const void ** )keys,
( const void ** )values,
4,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks
);
CFShow(attributes);
OSStatus status = SecItemAdd(attributes, NULL);
So what should I be putting for my kSecValueRef
? I've tried making a reference to a CFStringRef, but that didn't work. I also see that in the Apple docs it says:
The corresponding value, depending on the item class requested, is of type SecKeychainItem, SecKey, SecCertificate, or SecIdentity.
But I don't have a SecKeychainItem
because I haven't made added the item yet, and the other types don't seem right for just a normal string.
Thoughts?
Figured it out! For simple data, such as a string, you should use the kSecValueData
key. That will let you just pass in a CFStringRef
.
Example:
CFStringRef keys[4];
keys[0] = kSecClass;
keys[1] = kSecAttrAccount;
keys[2] = kSecAttrService;
keys[3] = kSecValueData;
CFTypeRef values[4];
values[0] = kSecClassGenericPassword;
values[1] = CFSTR( "account-15" );
values[2] = CFSTR( "service-126" );
values[3] = CFSTR( "password" );