Cocoa: adding an item to a custom OS X keychain so it could be accessed by any other application without prompt

I create a custom keychain and then I save a password inside it this way:

SecKeychainRef someKeychain; //keychain reference
SecKeychainItemRef someItem; //keychain key item reference

SecKeychainCreate([keychainPath UTF8String], (UInt32)strlen(keychainPass), keychainPass, FALSE, NULL, &someKeychain);
SecKeychainAddGenericPassword(someKeychain, (UInt32)strlen(someServiceName), someServiceName, (UInt32)strlen(someAccountName), someAccountName, (UInt32)strlen(encryptedPass), encryptedPass, &someItem);

What I would like to do now is to make the added someItem accessible by any application that knows the keychainPass without prompting the user to allow. So I tried it this way:

SecACLRef aclList;
SecAccessRef itemAccessRef;
uid_t userid = 0;
gid_t groupid;
CFArrayRef aclListArr;
SecACLRef newAcl;

SecKeychainItemCopyAccess(someItem, &itemAccessRef);
SecAccessCopyOwnerAndACL(itemAccessRef, &userid, &groupid, (UInt32*)kSecUseOnlyUID, &aclListArr);

SecACLCreateWithSimpleContents(itemAccessRef, NULL, (__bridge CFStringRef)@"someTagName", kSecKeychainPromptInvalid, &newAcl);

But:

  1. I don't know if the function SecACLCreateWithSimpleContents is the right way to achieve this at all
  2. If it is, I don't know how to write the ACLlist created with it back to someItem
  3. I don't know how to work with these CFArrays it returns (I'm an objective-c beginner)

I know that this has to be possible, because when I import the newly created keychain into the Keychain Access OS X app and I mark the properties of someItem to be accessible by any application, the prompt is gone and everything works. What I don't know is how to achieve this programatically. I realize this might be a silly question, but I don't know what to do.

Answers


I'm coming from iOS but according to the reference docs it should be roughly the same.

You need to use SecItemAdd with the option [kSecAttrAccessGroup)(https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/c/data/kSecAttrAccessGroup). Take a look at the reference docs for SecItemAdd

Here's a post that walks has some example code on how to use SecItemAdd.


What you need to do is setup an access control list for the item and the keychain

Here is the code to create the access reference

#pragma mark - Keychain Access Methods

+ (SecAccessRef)createAccess:(NSString *)accessLabel
{
    OSStatus err;
    SecAccessRef access = nil;
    NSArray *trustedApplications = nil;

    SecTrustedApplicationRef myself;
    err = SecTrustedApplicationCreateFromPath(NULL, &myself);

    if (err)
        return nil;

    trustedApplications = [NSArray arrayWithObjects:(__bridge id)myself, nil];
    err = SecAccessCreate((__bridge CFStringRef)accessLabel,(__bridge CFArrayRef)trustedApplications, &access);

    if (err)
        return nil;

    return access;
}

You Didn't specify if your application creates the keychain but if it does you can allow your application when you create it using this code.

// Create Keychain
SecKeychainCreate(name, (UInt32)[password length], [password cStringUsingEncoding:NSUTF8StringEncoding], false, [self createAccess:keychainKey], NULL);

This would give your application access to any items in that keychain. You can also pass in the access control ref when you create the individual items.


You can achieve "Allow all applications to access this item" access for your new keychain items (Under macOS) by using the older Security API methods that accept a SecAccessRef parameter:

  • SecKeychainItemCreateFromContent()
  • SecKeyCreatePair() (deprecated in OS X 10.7 but still works)

Namely:

  • Create an SecAccessRef using SecAccessCreate() or SecAccessCreateWithOwnerAndACL()
  • Add a single ACL entry to the SecAccessRef with Any authorization, no prompt behavior (SecKeychainPromptSelector = 0) and a NULL trusted application list using SecACLCreateWithSimpleContents()
  • Pass the SecAccessRef when creating the keychain item(s) with the above APIs

I added a longer winded answer to this (dupe?) question: How to allow all applications to access keychain item without prompt


Need Your Help

select count doesn't count

php mysql variables select count

I try to build a variable that integrates some other variable.

Scala method won't compile

list scala methods

I am trying to create a recursive method that will remove 0's from a list and return that list.