【发布时间】:2020-03-16 20:31:47
【问题描述】:
我编写了一个示例代码(之前收到了help)来从 OS X 钥匙串中添加和检索密码。我能够成功添加密码,但是当我尝试检索它时,我得到一个 EXC_BAD_ACCESS(代码=EXC_I386_GPFLT)。我尝试了两种方法:
- 使用 SecItemCopyMatching API,该 API 使用基于查询的方法来访问钥匙串。
- 使用 SecKeychainFindGenericPassword。
BAD ACCESS 错误只发生在第一种方法中,第二种方法成功。我正在尝试使用第一种方法,以便确保在完成后使用 SecKeychainItemFreeContent 进行清理。
注意 - 这是一个示例代码,因此我没有对返回值进行任何检查。虽然我一直在调试器中密切关注它们,但没有发现任何错误。
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
int main(int argc, const char * argv[])
{
char acc_name[20];
char password[20];
CFStringRef keys[3];
printf("Enter account name - ");
scanf("%s", acc_name);
printf("\nEnter password - ");
scanf("%s", password);
keys[0] = kSecClass;
keys[1] = kSecAttrAccount;
keys[2] = kSecValueData;
CFTypeRef values[3];
values[0] = kSecClassGenericPassword;
values[1] = CFStringCreateWithCString(kCFAllocatorDefault, acc_name, kCFStringEncodingUTF8);
values[2] = CFStringCreateWithCString(kCFAllocatorDefault, password, kCFStringEncodingUTF8);
CFDictionaryRef query;
query = CFDictionaryCreate(kCFAllocatorDefault, (const void**) keys, (const void**) values, 3, NULL, NULL);
OSStatus result = SecItemAdd(query, NULL);
printf("%d\n", result);
printf("Retrieve\n");
SecKeychainItemRef pitem = NULL;
SecKeychainItemRef kch_ref = NULL;
CFStringRef qkeys[6];
qkeys[0] = kSecClass;
qkeys[1] = kSecAttrAccount;
qkeys[2] = kSecMatchLimit;
qkeys[3] = kSecReturnAttributes;
qkeys[4] = kSecReturnData;
qkeys[5] = kSecReturnRef;
CFTypeRef qvalues[6];
qvalues[0] = kSecClassGenericPassword;
qvalues[1] = CFStringCreateWithCString(kCFAllocatorDefault, acc_name, kCFStringEncodingUTF8);
qvalues[2] = kSecMatchLimitOne;
qvalues[3] = kCFBooleanTrue;
qvalues[4] = kCFBooleanTrue;
qvalues[5] = kCFBooleanTrue;
unsigned int plength = 0;
char *pdata = NULL;
unsigned int plength2 = 0;
void *pdata2 = NULL;
CFDictionaryRef extract_query = CFDictionaryCreate(kCFAllocatorDefault, (const void **)qkeys, (const void **)qvalues, 6, NULL, NULL);
result = SecItemCopyMatching(extract_query, (CFTypeRef *)&kch_ref);
SecKeychainItemCopyAttributesAndData(kch_ref, NULL, NULL, NULL, &plength2, &pdata2); // <-- EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
//result = SecKeychainFindGenericPassword(NULL, 0, NULL, (uint32)strlen(acc_name), acc_name, &plength, (void **)&pdata, &pitem);
if (result)
{
//return error;
}
printf("password - %s\n", pdata);
return 0;
}
【问题讨论】:
标签: c xcode macos security keychain