darwinssl: fix SSL client certificate not found on MacOS Sierra
Reviewed-by: Nick Zitzmann Closes #1105
This commit is contained in:
Родитель
0744506cd2
Коммит
7c9b9add6f
|
@ -883,14 +883,18 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
|||
SecIdentityRef *out_cert_and_key)
|
||||
{
|
||||
OSStatus status = errSecItemNotFound;
|
||||
CFArrayRef keys_list;
|
||||
CFIndex keys_list_count;
|
||||
CFIndex i;
|
||||
CFStringRef common_name;
|
||||
|
||||
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
|
||||
/* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
|
||||
kSecClassIdentity was introduced in Lion. If both exist, let's use them
|
||||
to find the certificate. */
|
||||
if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
|
||||
CFTypeRef keys[4];
|
||||
CFTypeRef values[4];
|
||||
CFTypeRef keys[5];
|
||||
CFTypeRef values[5];
|
||||
CFDictionaryRef query_dict;
|
||||
CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
|
||||
kCFStringEncodingUTF8);
|
||||
|
@ -900,21 +904,53 @@ static OSStatus CopyIdentityWithLabel(char *label,
|
|||
keys[0] = kSecClass;
|
||||
values[1] = kCFBooleanTrue; /* we want a reference */
|
||||
keys[1] = kSecReturnRef;
|
||||
values[2] = kSecMatchLimitOne; /* one is enough, thanks */
|
||||
values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
|
||||
* label matching below worked correctly */
|
||||
keys[2] = kSecMatchLimit;
|
||||
/* identity searches need a SecPolicyRef in order to work */
|
||||
values[3] = SecPolicyCreateSSL(false, label_cf);
|
||||
values[3] = SecPolicyCreateSSL(false, NULL);
|
||||
keys[3] = kSecMatchPolicy;
|
||||
/* match the name of the certificate (doesn't work in macOS 10.12.1) */
|
||||
values[4] = label_cf;
|
||||
keys[4] = kSecAttrLabel;
|
||||
query_dict = CFDictionaryCreate(NULL, (const void **)keys,
|
||||
(const void **)values, 4L,
|
||||
&kCFCopyStringDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
(const void **)values, 5L,
|
||||
&kCFCopyStringDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
CFRelease(values[3]);
|
||||
CFRelease(label_cf);
|
||||
|
||||
/* Do we have a match? */
|
||||
status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key);
|
||||
status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
|
||||
|
||||
/* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
|
||||
* we need to find the correct identity ourselves */
|
||||
if(status == noErr) {
|
||||
keys_list_count = CFArrayGetCount(keys_list);
|
||||
*out_cert_and_key = NULL;
|
||||
for(i=0; i<keys_list_count; i++) {
|
||||
OSStatus err = noErr;
|
||||
SecCertificateRef cert = NULL;
|
||||
*out_cert_and_key =
|
||||
(SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
|
||||
err = SecIdentityCopyCertificate(*out_cert_and_key, &cert);
|
||||
if(err == noErr) {
|
||||
SecCertificateCopyCommonName(cert, &common_name);
|
||||
if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
|
||||
CFRelease(cert);
|
||||
CFRelease(common_name);
|
||||
status = noErr;
|
||||
break;
|
||||
}
|
||||
CFRelease(common_name);
|
||||
}
|
||||
*out_cert_and_key = NULL;
|
||||
status = 1;
|
||||
CFRelease(cert);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(query_dict);
|
||||
CFRelease(label_cf);
|
||||
}
|
||||
else {
|
||||
#if CURL_SUPPORT_MAC_10_6
|
||||
|
|
Загрузка…
Ссылка в новой задаче