aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNick Zitzmann <nick@chronosnet.com>2012-10-16 10:33:13 -0600
committerDaniel Stenberg <daniel@haxx.se>2012-10-16 19:55:03 +0200
commitf1d2e1850819f54d1c950989614da7445bdd457f (patch)
tree8aa35b5ce6b43e2b5d15e93d2316227e3e94fbe0 /lib
parent1a02e84589efb3f8717d50bdc78d3f369b799198 (diff)
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/curl_darwinssl.c92
1 files changed, 81 insertions, 11 deletions
diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c
index d5685bede..31531dbcc 100644
--- a/lib/curl_darwinssl.c
+++ b/lib/curl_darwinssl.c
@@ -266,6 +266,44 @@ CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) {
case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
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 */
case 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 {
-#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)
(void)SSLDisposeContext(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);
return CURLE_OUT_OF_MEMORY;
}
-#endif /* TARGET_OS_EMBEDDED == 0 */
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
}
#else
if(connssl->ssl_ctx)
@@ -656,7 +695,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
else {
-#if TARGET_OS_EMBEDDED == 0
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
kSSLProtocolAll,
false);
@@ -697,7 +736,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
true);
break;
}
-#endif /* TARGET_OS_EMBEDDED == 0 */
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
}
#else
(void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
@@ -747,14 +786,14 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
else {
-#if TARGET_OS_EMBEDDED == 0
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
err = SSLSetEnableCertVerify(connssl->ssl_ctx,
data->set.ssl.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
-#endif /* TARGET_OS_EMBEDDED == 0 */
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
}
#else
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
* server certificates. */
#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) {
#pragma unused(server_certs)
err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
@@ -909,7 +974,8 @@ darwinssl_connect_step3(struct connectdata *conn,
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; 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);
if(CFStringGetCString(server_cert_summary,
server_cert_summary_c,
@@ -923,7 +989,6 @@ darwinssl_connect_step3(struct connectdata *conn,
}
}
else {
-#if TARGET_OS_EMBEDDED == 0
err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
if(err == noErr) {
count = CFArrayGetCount(server_certs);
@@ -943,8 +1008,8 @@ darwinssl_connect_step3(struct connectdata *conn,
}
CFRelease(server_certs);
}
-#endif /* TARGET_OS_EMBEDDED == 0 */
}
+#endif /* (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) */
#else
#pragma unused(trust)
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(SSLCreateContext != NULL)
CFRelease(connssl->ssl_ctx);
-#if TARGET_OS_EMBEDDED == 0
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
else
(void)SSLDisposeContext(connssl->ssl_ctx);
-#endif /* TARGET_OS_EMBEDDED == 0 */
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
#else
(void)SSLDisposeContext(connssl->ssl_ctx);
#endif /* defined(__MAC_10_8) || defined(__IPHONE_5_0) */
@@ -1311,6 +1376,11 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
return -1;
break;
+ case errSSLClosedGraceful: /* they're done; fail gracefully */
+ *curlcode = CURLE_OK;
+ return -1;
+ break;
+
default:
failf(conn->data, "SSLRead() return error %d", err);
*curlcode = CURLE_RECV_ERROR;