in macos/macos.c [278:334]
CFTypeRef HasSEKeyProtection(
const char* label,
const char* tag,
unsigned char* hash,
CFStringRef value,
CFStringRef* errorStr) {
CFDataRef cfTag = StringToDataRef(tag);
CFStringRef cfLabel = CFStringCreateWithCString(
kCFAllocatorDefault, label, kCFStringEncodingUTF8);
// Generate a query to return key attributes rather than key data.
CFMutableDictionaryRef query = CFDictionaryCreateMutable(
kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(query, kSecClass, kSecClassKey);
CFDictionaryAddValue(query, kSecAttrApplicationTag, cfTag);
CFDictionaryAddValue(query, kSecAttrLabel, cfLabel);
CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne);
if (hash) {
CFDataRef h = CFDataCreateWithBytesNoCopy(
kCFAllocatorDefault, (UInt8*)hash, 20, kCFAllocatorNull);
CFDictionaryAddValue(query, kSecAttrApplicationLabel, h);
}
CFTypeRef res = NULL;
OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, &res);
CFRelease((CFTypeRef)query);
CFRelease((CFTypeRef)cfTag);
CFRelease((CFTypeRef)cfLabel);
if (!res)
status = errSecBadReq;
if (status != errSecSuccess) {
*errorStr = SecCopyErrorMessageString(status, NULL);
return NULL;
}
SecAccessControlRef ac =
(SecAccessControlRef)CFDictionaryGetValue(res, kSecAttrAccessControl);
if (!ac) {
*errorStr = SecCopyErrorMessageString(errSecNoSuchAttr, NULL);
return NULL;
}
CFTypeRef protection = SecAccessControlGetProtection(ac);
if (!protection) {
*errorStr = SecCopyErrorMessageString(errSecDataNotAvailable, NULL);
return NULL;
}
CFRelease((CFTypeRef)ac);
return protection;
}