Loading lib/vtls/darwinssl.c +45 −9 Original line number Original line Diff line number Diff line Loading @@ -883,14 +883,18 @@ static OSStatus CopyIdentityWithLabel(char *label, SecIdentityRef *out_cert_and_key) SecIdentityRef *out_cert_and_key) { { OSStatus status = errSecItemNotFound; OSStatus status = errSecItemNotFound; CFArrayRef keys_list; CFIndex keys_list_count; CFIndex i; CFStringRef common_name; #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. kSecClassIdentity was introduced in Lion. If both exist, let's use them kSecClassIdentity was introduced in Lion. If both exist, let's use them to find the certificate. */ to find the certificate. */ if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { CFTypeRef keys[4]; CFTypeRef keys[5]; CFTypeRef values[4]; CFTypeRef values[5]; CFDictionaryRef query_dict; CFDictionaryRef query_dict; CFStringRef label_cf = CFStringCreateWithCString(NULL, label, CFStringRef label_cf = CFStringCreateWithCString(NULL, label, kCFStringEncodingUTF8); kCFStringEncodingUTF8); Loading @@ -900,21 +904,53 @@ static OSStatus CopyIdentityWithLabel(char *label, keys[0] = kSecClass; keys[0] = kSecClass; values[1] = kCFBooleanTrue; /* we want a reference */ values[1] = kCFBooleanTrue; /* we want a reference */ keys[1] = kSecReturnRef; 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; keys[2] = kSecMatchLimit; /* identity searches need a SecPolicyRef in order to work */ /* identity searches need a SecPolicyRef in order to work */ values[3] = SecPolicyCreateSSL(false, label_cf); values[3] = SecPolicyCreateSSL(false, NULL); keys[3] = kSecMatchPolicy; 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, query_dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 4L, (const void **)values, 5L, &kCFCopyStringDictionaryKeyCallBacks, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); &kCFTypeDictionaryValueCallBacks); CFRelease(values[3]); CFRelease(values[3]); CFRelease(label_cf); /* Do we have a match? */ /* 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(query_dict); CFRelease(label_cf); } } else { else { #if CURL_SUPPORT_MAC_10_6 #if CURL_SUPPORT_MAC_10_6 Loading Loading
lib/vtls/darwinssl.c +45 −9 Original line number Original line Diff line number Diff line Loading @@ -883,14 +883,18 @@ static OSStatus CopyIdentityWithLabel(char *label, SecIdentityRef *out_cert_and_key) SecIdentityRef *out_cert_and_key) { { OSStatus status = errSecItemNotFound; OSStatus status = errSecItemNotFound; CFArrayRef keys_list; CFIndex keys_list_count; CFIndex i; CFStringRef common_name; #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. kSecClassIdentity was introduced in Lion. If both exist, let's use them kSecClassIdentity was introduced in Lion. If both exist, let's use them to find the certificate. */ to find the certificate. */ if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { CFTypeRef keys[4]; CFTypeRef keys[5]; CFTypeRef values[4]; CFTypeRef values[5]; CFDictionaryRef query_dict; CFDictionaryRef query_dict; CFStringRef label_cf = CFStringCreateWithCString(NULL, label, CFStringRef label_cf = CFStringCreateWithCString(NULL, label, kCFStringEncodingUTF8); kCFStringEncodingUTF8); Loading @@ -900,21 +904,53 @@ static OSStatus CopyIdentityWithLabel(char *label, keys[0] = kSecClass; keys[0] = kSecClass; values[1] = kCFBooleanTrue; /* we want a reference */ values[1] = kCFBooleanTrue; /* we want a reference */ keys[1] = kSecReturnRef; 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; keys[2] = kSecMatchLimit; /* identity searches need a SecPolicyRef in order to work */ /* identity searches need a SecPolicyRef in order to work */ values[3] = SecPolicyCreateSSL(false, label_cf); values[3] = SecPolicyCreateSSL(false, NULL); keys[3] = kSecMatchPolicy; 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, query_dict = CFDictionaryCreate(NULL, (const void **)keys, (const void **)values, 4L, (const void **)values, 5L, &kCFCopyStringDictionaryKeyCallBacks, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); &kCFTypeDictionaryValueCallBacks); CFRelease(values[3]); CFRelease(values[3]); CFRelease(label_cf); /* Do we have a match? */ /* 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(query_dict); CFRelease(label_cf); } } else { else { #if CURL_SUPPORT_MAC_10_6 #if CURL_SUPPORT_MAC_10_6 Loading