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.
diff --git a/lib/curl_darwinssl.c b/lib/curl_darwinssl.c
index d5685be..31531db 100644
--- a/lib/curl_darwinssl.c
+++ b/lib/curl_darwinssl.c
@@ -266,6 +266,44 @@
     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 @@
     }
   }
   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 @@
       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 @@
     }
   }
   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 @@
                                            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 @@
     }
   }
   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 @@
    * 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 @@
       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 @@
     }
   }
   else {
-#if TARGET_OS_EMBEDDED == 0
     err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
     if(err == noErr) {
       count = CFArrayGetCount(server_certs);
@@ -943,8 +1008,8 @@
       }
       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 @@
 #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 @@
         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;