darwinssl: fix crash that started happening in Lion

Something (a recent security update maybe?) changed in Lion, and now it
has changed SSLCopyPeerTrust such that it may return noErr but also give
us a null trust, which caught us off guard and caused an eventual crash.
This commit is contained in:
Nick Zitzmann
2013-06-22 15:13:36 -06:00
parent 631e3e13a9
commit f3052c8a81

View File

@@ -1363,11 +1363,11 @@ darwinssl_connect_step3(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CFStringRef server_cert_summary; CFStringRef server_cert_summary;
char server_cert_summary_c[128]; char server_cert_summary_c[128];
CFArrayRef server_certs; CFArrayRef server_certs = NULL;
SecCertificateRef server_cert; SecCertificateRef server_cert;
OSStatus err; OSStatus err;
CFIndex i, count; CFIndex i, count;
SecTrustRef trust; SecTrustRef trust = NULL;
/* There is no step 3! /* There is no step 3!
* Well, okay, if verbose mode is on, let's print the details of the * Well, okay, if verbose mode is on, let's print the details of the
@@ -1376,7 +1376,9 @@ darwinssl_connect_step3(struct connectdata *conn,
#if CURL_BUILD_IOS #if CURL_BUILD_IOS
#pragma unused(server_certs) #pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) { /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust); count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) { for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i); server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1402,7 +1404,9 @@ darwinssl_connect_step3(struct connectdata *conn,
if(SecTrustEvaluateAsync != NULL) { if(SecTrustEvaluateAsync != NULL) {
#pragma unused(server_certs) #pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
if(err == noErr) { /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust); count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) { for(i = 0L ; i < count ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i); server_cert = SecTrustGetCertificateAtIndex(trust, i);
@@ -1422,7 +1426,8 @@ darwinssl_connect_step3(struct connectdata *conn,
else { else {
#if CURL_SUPPORT_MAC_10_8 #if CURL_SUPPORT_MAC_10_8
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
if(err == noErr) { /* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs); count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) { for(i = 0L ; i < count ; i++) {
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,