mirror of
https://github.com/moparisthebest/curl
synced 2024-11-16 06:25:03 -05:00
darwinssl: un-broke iOS build, fix error on server disconnect
The iOS build was broken by a reference to a function that only existed under OS X; fixed. Also fixed a hard-to-reproduce problem where, if the server disconnected before libcurl got the chance to hang up first and SecureTransport was in use, then we'd raise an error instead of failing gracefully.
This commit is contained in:
parent
1a02e84589
commit
f1d2e18508
@ -266,6 +266,44 @@ CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
|
|||||||
case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
|
case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
|
||||||
return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
|
return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
|
||||||
break;
|
break;
|
||||||
|
/* TLS 1.0 with AES (RFC 3268)
|
||||||
|
(Apparently these are used in SSLv3 implementations as well.) */
|
||||||
|
case TLS_RSA_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_RSA_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_anon_WITH_AES_128_CBC_SHA:
|
||||||
|
return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_RSA_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_RSA_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
|
case TLS_DH_anon_WITH_AES_256_CBC_SHA:
|
||||||
|
return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
|
||||||
|
break;
|
||||||
/* SSL version 2.0 */
|
/* SSL version 2.0 */
|
||||||
case SSL_RSA_WITH_RC2_CBC_MD5:
|
case SSL_RSA_WITH_RC2_CBC_MD5:
|
||||||
return "SSL_RSA_WITH_RC2_CBC_MD5";
|
return "SSL_RSA_WITH_RC2_CBC_MD5";
|
||||||
@ -614,7 +652,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if TARGET_OS_EMBEDDED == 0 /* the older API does not exist on iOS */
|
/* The old ST API does not exist under iOS, so don't compile it: */
|
||||||
|
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||||
if(connssl->ssl_ctx)
|
if(connssl->ssl_ctx)
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||||
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
err = SSLNewContext(false, &(connssl->ssl_ctx));
|
||||||
@ -622,7 +661,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
#endif /* TARGET_OS_EMBEDDED == 0 */
|
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if(connssl->ssl_ctx)
|
if(connssl->ssl_ctx)
|
||||||
@ -656,7 +695,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if TARGET_OS_EMBEDDED == 0
|
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
|
||||||
kSSLProtocolAll,
|
kSSLProtocolAll,
|
||||||
false);
|
false);
|
||||||
@ -697,7 +736,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
true);
|
true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* TARGET_OS_EMBEDDED == 0 */
|
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
|
||||||
@ -747,14 +786,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if TARGET_OS_EMBEDDED == 0
|
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||||
data->set.ssl.verifypeer?true:false);
|
data->set.ssl.verifypeer?true:false);
|
||||||
if(err != noErr) {
|
if(err != noErr) {
|
||||||
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
|
||||||
return CURLE_SSL_CONNECT_ERROR;
|
return CURLE_SSL_CONNECT_ERROR;
|
||||||
}
|
}
|
||||||
#endif /* TARGET_OS_EMBEDDED == 0 */
|
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
|
||||||
@ -902,6 +941,32 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
* 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
|
||||||
* server certificates. */
|
* server certificates. */
|
||||||
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
|
#if defined(__MAC_10_7) || defined(__IPHONE_5_0)
|
||||||
|
#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
|
||||||
|
#pragma unused(server_certs)
|
||||||
|
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
|
||||||
|
if(err == noErr) {
|
||||||
|
count = SecTrustGetCertificateCount(trust);
|
||||||
|
for(i = 0L ; i < count ; i++) {
|
||||||
|
server_cert = SecTrustGetCertificateAtIndex(trust, i);
|
||||||
|
server_cert_summary = SecCertificateCopySubjectSummary(server_cert);
|
||||||
|
memset(server_cert_summary_c, 0, 128);
|
||||||
|
if(CFStringGetCString(server_cert_summary,
|
||||||
|
server_cert_summary_c,
|
||||||
|
128,
|
||||||
|
kCFStringEncodingUTF8)) {
|
||||||
|
infof(data, "Server certificate: %s\n", server_cert_summary_c);
|
||||||
|
}
|
||||||
|
CFRelease(server_cert_summary);
|
||||||
|
}
|
||||||
|
CFRelease(trust);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
|
||||||
|
The function SecTrustGetCertificateAtIndex() is officially present
|
||||||
|
in Lion, but it is unfortunately also present in Snow Leopard as
|
||||||
|
private API and doesn't work as expected. So we have to look for
|
||||||
|
a different symbol to make sure this code is only executed under
|
||||||
|
Lion or later. */
|
||||||
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);
|
||||||
@ -909,7 +974,8 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
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);
|
||||||
server_cert_summary = SecCertificateCopySubjectSummary(server_cert);
|
server_cert_summary =
|
||||||
|
SecCertificateCopyLongDescription(NULL, server_cert, NULL);
|
||||||
memset(server_cert_summary_c, 0, 128);
|
memset(server_cert_summary_c, 0, 128);
|
||||||
if(CFStringGetCString(server_cert_summary,
|
if(CFStringGetCString(server_cert_summary,
|
||||||
server_cert_summary_c,
|
server_cert_summary_c,
|
||||||
@ -923,7 +989,6 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if TARGET_OS_EMBEDDED == 0
|
|
||||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||||
if(err == noErr) {
|
if(err == noErr) {
|
||||||
count = CFArrayGetCount(server_certs);
|
count = CFArrayGetCount(server_certs);
|
||||||
@ -943,8 +1008,8 @@ darwinssl_connect_step3(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
CFRelease(server_certs);
|
CFRelease(server_certs);
|
||||||
}
|
}
|
||||||
#endif /* TARGET_OS_EMBEDDED == 0 */
|
|
||||||
}
|
}
|
||||||
|
#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
|
||||||
#else
|
#else
|
||||||
#pragma unused(trust)
|
#pragma unused(trust)
|
||||||
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
|
||||||
@ -1120,10 +1185,10 @@ void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
|
|||||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||||
if(SSLCreateContext != NULL)
|
if(SSLCreateContext != NULL)
|
||||||
CFRelease(connssl->ssl_ctx);
|
CFRelease(connssl->ssl_ctx);
|
||||||
#if TARGET_OS_EMBEDDED == 0
|
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||||
else
|
else
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||||
#endif /* TARGET_OS_EMBEDDED == 0 */
|
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||||
#else
|
#else
|
||||||
(void)SSLDisposeContext(connssl->ssl_ctx);
|
(void)SSLDisposeContext(connssl->ssl_ctx);
|
||||||
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
|
||||||
@ -1311,6 +1376,11 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case errSSLClosedGraceful: /* they're done; fail gracefully */
|
||||||
|
*curlcode = CURLE_OK;
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
failf(conn->data, "SSLRead() return error %d", err);
|
failf(conn->data, "SSLRead() return error %d", err);
|
||||||
*curlcode = CURLE_RECV_ERROR;
|
*curlcode = CURLE_RECV_ERROR;
|
||||||
|
Loading…
Reference in New Issue
Block a user