Какао: добавление элемента в настраиваемую цепочку ключей OS X, чтобы к нему можно было получить доступ из любого другого приложения без запроса

Я создаю специальную цепочку для ключей, а затем сохраняю в ней пароль следующим образом:

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

Сейчас я хотел бы сделать добавленный someItem доступным для любого приложения, которое знает keychainPass, не предлагая пользователю разрешить. Я попробовал вот так:

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

Но:

  1. Я не знаю, подходит ли функция SecACLCreateWithSimpleContents для достижения этой цели
  2. Если это так, я не знаю, как записать созданный с его помощью список ACL обратно в someItem
  3. Я не знаю, как работать с этими CFArrays, которые он возвращает (я новичок в objective-c)

Я знаю, что это должно быть возможно, потому что, когда я импортирую только что созданную связку ключей в приложение Keychain Access OS X и отмечаю свойства someItem как доступные для любого приложения, подсказка исчезает, и все работает. Я не знаю, как этого добиться программно. Я понимаю, что это может быть глупый вопрос, но не знаю, что делать.


person Michał Siwek    schedule 29.05.2014    source источник
comment
Удалось ли вам решить эту проблему?   -  person solgar    schedule 24.01.2017


Ответы (3)


Я исхожу из iOS, но, согласно справочной документации, он должен быть примерно таким же.

Вам необходимо использовать SecItemAdd с опцией [kSecAttrAccessGroup) ( https://developer.apple.com/library/mac/documentation/security/Reference/keychainservices/Reference/reference.html#//apple_ref/c/data/kSecAttrAccessGroup < / а>). Взгляните на справочную документацию для SecItemAdd

Вот сообщение, в котором В walks есть пример кода о том, как использовать SecItemAdd.

person Todd Anderson    schedule 07.06.2014
comment
Это не совсем то, что мне нужно - я хотел бы просто снять ограничения доступа, как приложение Keychain Access с графическим интерфейсом, не разрешая групповой доступ. - person Michał Siwek; 10.06.2014
comment
Почему? Если два приложения могут иметь один и тот же пароль для доступа к зашифрованным данным, они должны иметь доступ к одной и той же kSecAttrAccessGroup. Если вы не хотите хранить зашифрованные данные и хотите, чтобы любое приложение имело доступ к ним без защиты, вам следует использовать [NSUserDefaults addSuiteNamed:]. Единственное ограничение заключается в том, что приложения нельзя изолировать. - person Todd Anderson; 10.06.2014
comment
Есть одна вещь, о которой я пока не совсем понимаю SecItemAdd - где мне предоставить ссылку на цепочку для ключей, которую я создаю? Я искал ответ, но боюсь, он работает только для системной связки ключей по умолчанию. - person Michał Siwek; 11.06.2014
comment
SecItemAdd - это удобная функция для использования связки ключей по умолчанию. Если вы используете другой, вы должны использовать SecKeychainItemCreateFromContent или SecKeychainItemCreatePersistentReference в зависимости от ваших потребностей. - person Todd Anderson; 11.06.2014
comment
Группа доступа @ToddAnderson в macOS работает только тогда, когда вы устанавливаете kSecAttrSynchronizable на kCFBooleanTrue, и это автоматически отправляет эту запись в iCloud, что может быть нежелательным для некоторых. - person solgar; 25.01.2017

Что вам нужно сделать, так это настроить список управления доступом для элемента и связки ключей.

Вот код для создания ссылки доступа

#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;
}

Вы не указали, создает ли ваше приложение связку ключей, но если это так, вы можете разрешить свое приложение при его создании с помощью этого кода.

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

Это даст вашему приложению доступ к любым элементам в этой связке ключей. Вы также можете передать ссылку на управление доступом при создании отдельных элементов.

person Douglas Cobb    schedule 06.07.2015

Вы можете получить доступ «Разрешить всем приложениям доступ к этому элементу» для ваших новых элементов связки ключей (в macOS) с помощью старых методов API безопасности, которые принимают параметр SecAccessRef:

  • SecKeychainItemCreateFromContent()
  • SecKeyCreatePair() (устарело в OS X 10.7, но все еще работает)

А именно:

  • Создайте SecAccessRef с помощью SecAccessCreate() или SecAccessCreateWithOwnerAndACL()
  • Добавьте одну запись ACL в SecAccessRef с Any авторизацией, без подсказок (SecKeychainPromptSelector = 0) и NULL список доверенных приложений с помощью SecACLCreateWithSimpleContents()
  • Передайте SecAccessRef при создании элемента (ов) связки ключей с помощью вышеуказанных API

Я добавил более длинный ответ на этот (обманутый?) Вопрос: Как разрешить всем приложениям доступ к элементу связки ключей без запроса

person Mike C.    schedule 02.02.2018