Search code examples
c++macoskeychaincore-foundationseckeyref

Unable to call SecItemAdd Successfully


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?


Solution

  • 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" );