c - SecKeychainItemCopyContents 在私钥上出现段错误

标签 c macos keychain

我正在使用此代码列出所有私钥并获取有关它们的一些信息,使用 Apple 的安全框架 API:

int main(int argc, const char * argv[]) {
    const void *keys[]   = { kSecClass,    kSecReturnRef,   kSecMatchLimit,    kSecAttrKeyClass};
    const void *values[] = { kSecClassKey, kCFBooleanTrue,  kSecMatchLimitAll, kSecAttrKeyClassPrivate};

    CFDictionaryRef searchDict = CFDictionaryCreate(
        NULL,
        keys, values, sizeof(keys) / sizeof(keys[0]),
        NULL, NULL
    );
    checkAlloc(searchDict);

    CFArrayRef items;
    check(SecItemCopyMatching(searchDict, (CFTypeRef *)&items));

    for(int i=0; i<CFArrayGetCount(items); i++) {
        SecKeychainItemRef item = (SecKeychainItemRef) CFArrayGetValueAtIndex(items, i);

        CFShow((CFTypeRef)item);

        SecItemClass cls;
        SecKeychainAttributeList attrs;
        UInt32 dataLen;
        void* data;

        check(SecKeychainItemCopyContent(item, &cls, &attrs, &dataLen, &data));

        printf("Key: %d\n", (int)dataLen);

        check(SecKeychainItemFreeContent(&attrs, data));
    }

    CFRelease(items);
    CFRelease(searchDict);

    return 0;
}

调用SecKeychainItemCopyContent段错误,即使我传递的所有指针都无效。

CFShow打印类似于 <SecKey 0x7fb4d9d01420 [0x7fff74790ed0]> 的行, 所以 item应该是 SecKeyRef ,但是 documentation for it说可以使用 SecKeyRef作为SecKeychainItemRef如果 key 在钥匙串(keychain)中。但是,我没有看到任何函数来查找 key 是否在钥匙串(keychain)中,因此我无法验证返回的 key 是否可以这样使用。

我在这里做错了什么?

最佳答案

要复制存储在给定钥匙串(keychain)项中的数据和/或属性, 函数 SecKeychainItemCopyContent() 的第三个参数是 SecKeychainAttributeList *attrList ,类型如下,

  struct SecKeychainAttributeList
  {
    UInt32 count;
    SecKeychainAttribute *attr;
  };

对于此 IN/OUT 参数 attrList:在输入时,它是您请求检索的属性列表。在输出时,属性被填充。如果不需要检索任何属性,则传递 NULL,或者传递您需要获取的属性列表。它应该是这两个提到的传递参数中的任何一个。让它未初始化可能会导致问题,例如段错误。

所以,请像这样尝试,它应该可以正常工作。

SecKeychainAttributeList attrs = {0, NULL};
//...  
check(SecKeychainItemCopyContent(item, &cls, &attrs, &dataLen, &data));

//SecKeychainAttributeList attrs ;
//... 
check(SecKeychainItemCopyContent(item, &cls, NULL, &dataLen, &data));
printf("Key: %d\n", (int)dataLen);
check(SecKeychainItemFreeContent(NULL, data));

如果需要获取属性列表,示例代码如下,

 SecKeychainAttributeList xlist;
 SecKeychainAttribute outList[] = 
 {
    {kSecAddressItemAttr,},
    {kSecAccountItemAttr,},
    {kSecVolumeItemAttr,},
    {kSecProtocolItemAttr}
 };

 xlist.count = sizeof(outList)/sizeof(outList[0]);
 xlist.attr = outList;

 //...
 err = SecKeychainItemCopyContent (itemRef, nil, &xlist, &len, &outData);
 //...

关于c - SecKeychainItemCopyContents 在私钥上出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31031476/

相关文章:

使用三重指针创建矩阵会导致段错误

c - 如何使 Tru64 Unix 中的 C 代码在 Linux 64 位中工作?

c - 在 C 代码中使用 libavformat,未定义的 x86_64 符号

python - 在 Snow Leopard 上查找 Python 附带的默认包时遇到问题

iphone - 清除 iPhone key 扣

C 程序使用函数查找两个数字之间的最大值和最小值

objective-c - 简单的检测算法

c++ - 退出 OpenGL 应用程序时清理

objective-c - 更新应用后,mac 会再次提示用户允许访问钥匙串(keychain)吗?

ios - 无法在 Xcode 中使用 iOS 发行版