Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

darwinssl: disable ECC ciphers under Mountain Lion by default

I found out that ECC doesn't work as of OS X 10.8.3, so those ciphers are
turned off until the next point release of OS X.
  • Loading branch information...
commit 6f1f7e5de8c774e51957afd988d8d316b5a6d92f 1 parent 91ab249
nickzman authored March 19, 2013
1  RELEASE-NOTES
@@ -55,6 +55,7 @@ This release includes the following bugfixes:
55 55
  o curlbuild.h.dist: enhance non-configure GCC ABI detection logic
56 56
  o sasl: Fixed null pointer reference when decoding empty digest challenge [8]
57 57
  o easy: do not ignore poll() failures other than EINTR
  58
+ o darwinssl: disable ECC ciphers under Mountain Lion by default
58 59
 
59 60
 This release includes the following known bugs:
60 61
 
79  lib/curl_darwinssl.c
@@ -59,6 +59,7 @@
59 59
 
60 60
 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
61 61
 #define ioErr -36
  62
+#define paramErr -50
62 63
 
63 64
 /* In Mountain Lion and iOS 5, Apple made some changes to the API. They
64 65
    added TLS 1.1 and 1.2 support, and deprecated and replaced some
@@ -628,40 +629,36 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
628 629
   return "TLS_NULL_WITH_NULL_NULL";
629 630
 }
630 631
 
631  
-CF_INLINE bool IsRunningMountainLionOrLater(void)
632  
-{
633 632
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
  633
+CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
  634
+{
634 635
   int mib[2];
635 636
   char *os_version;
636 637
   size_t os_version_len;
637  
-  char *os_version_major/*, *os_version_minor, *os_version_point*/;
638  
-  int os_version_major_int;
  638
+  char *os_version_major, *os_version_minor/*, *os_version_point*/;
639 639
 
640 640
   /* Get the Darwin kernel version from the kernel using sysctl(): */
641 641
   mib[0] = CTL_KERN;
642 642
   mib[1] = KERN_OSRELEASE;
643 643
   if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
644  
-    return false;
  644
+    return;
645 645
   os_version = malloc(os_version_len*sizeof(char));
646 646
   if(!os_version)
647  
-    return false;
  647
+    return;
648 648
   if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
649 649
     free(os_version);
650  
-    return false;
  650
+    return;
651 651
   }
652 652
 
653  
-  /* Parse the version. If it's version 12.0.0 or later, then this user is
654  
-     using Mountain Lion. */
  653
+  /* Parse the version: */
655 654
   os_version_major = strtok(os_version, ".");
656  
-  /*os_version_minor = strtok(NULL, ".");
657  
-  os_version_point = strtok(NULL, ".");*/
658  
-  os_version_major_int = atoi(os_version_major);
  655
+  os_version_minor = strtok(NULL, ".");
  656
+  /*os_version_point = strtok(NULL, ".");*/
  657
+  *major = atoi(os_version_major);
  658
+  *minor = atoi(os_version_minor);
659 659
   free(os_version);
660  
-  return os_version_major_int >= 12;
661  
-#else
662  
-  return true;  /* iOS users: this doesn't concern you */
663  
-#endif
664 660
 }
  661
+#endif
665 662
 
666 663
 /* Apple provides a myriad of ways of getting information about a certificate
667 664
    into a string. Some aren't available under iOS or newer cats. So here's
@@ -707,6 +704,13 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
707 704
 #endif
708 705
   /*SSLConnectionRef ssl_connection;*/
709 706
   OSStatus err = noErr;
  707
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
  708
+  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
  709
+  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
  710
+  int darwinver_maj = 0, darwinver_min = 0;
  711
+
  712
+  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
  713
+#endif
710 714
 
711 715
 #if defined(__MAC_10_8) || defined(__IPHONE_5_0)
712 716
   if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
@@ -851,7 +855,12 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
851 855
      to disable certificate validation if the user turned that off.
852 856
      (SecureTransport will always validate the certificate chain by
853 857
      default.) */
854  
-  if(SSLSetSessionOption != NULL && IsRunningMountainLionOrLater()) {
  858
+  /* (Note: Darwin 12.x.x is Mountain Lion.) */
  859
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
  860
+  if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
  861
+#else
  862
+  if(SSLSetSessionOption != NULL) {
  863
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
855 864
     err = SSLSetSessionOption(connssl->ssl_ctx,
856 865
                               kSSLSessionOptionBreakOnServerAuth,
857 866
                               data->set.ssl.verifypeer?false:true);
@@ -895,6 +904,31 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
895 904
     }
896 905
   }
897 906
 
  907
+  /* There's a known bug in early versions of Mountain Lion where ST's ECC
  908
+     ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
  909
+     Work around the problem here by disabling those ciphers if we are running
  910
+     in an affected version of OS X. */
  911
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
  912
+  if(darwinver_maj == 12 && darwinver_min <= 3) {
  913
+    (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
  914
+    all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
  915
+    allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
  916
+    if(all_ciphers && allowed_ciphers &&
  917
+       SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
  918
+         &all_ciphers_count) == noErr) {
  919
+      for(i = 0UL ; i < all_ciphers_count ; i++) {
  920
+        if(all_ciphers[i] < 0xC001 || all_ciphers[i] > 0xC032) {
  921
+          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
  922
+        }
  923
+      }
  924
+      (void)SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
  925
+                                 allowed_ciphers_count);
  926
+    }
  927
+    Curl_safefree(all_ciphers);
  928
+    Curl_safefree(allowed_ciphers);
  929
+  }
  930
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
  931
+
898 932
   err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
899 933
   if(err != noErr) {
900 934
     failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
@@ -947,6 +981,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
947 981
         /* the documentation says we need to call SSLHandshake() again */
948 982
         return darwinssl_connect_step2(conn, sockindex);
949 983
 
  984
+      /* These are all certificate problems with the server: */
950 985
       case errSSLXCertChainInvalid:
951 986
         failf(data, "SSL certificate problem: Invalid certificate chain");
952 987
         return CURLE_SSL_CACERT;
@@ -961,14 +996,24 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
961 996
               "expired certificate");
962 997
         return CURLE_SSL_CACERT;
963 998
 
  999
+      /* This error is raised if the server's cert didn't match the server's
  1000
+         host name: */
964 1001
       case errSSLHostNameMismatch:
965 1002
         failf(data, "SSL certificate peer verification failed, the "
966 1003
               "certificate did not match \"%s\"\n", conn->host.dispname);
967 1004
         return CURLE_PEER_FAILED_VERIFICATION;
968 1005
 
  1006
+      /* Generic handshake errors: */
969 1007
       case errSSLConnectionRefused:
970 1008
         failf(data, "Server dropped the connection during the SSL handshake");
971 1009
         return CURLE_SSL_CONNECT_ERROR;
  1010
+      case errSSLClosedAbort:
  1011
+        failf(data, "Server aborted the SSL handshake");
  1012
+        return CURLE_SSL_CONNECT_ERROR;
  1013
+      case paramErr: /* if you're getting this, it could be a cipher problem */
  1014
+        failf(data, "Internal SSL engine error encountered during the "
  1015
+              "SSL handshake");
  1016
+        return CURLE_SSL_CONNECT_ERROR;
972 1017
       default:
973 1018
         failf(data, "Unknown SSL protocol error in connection to %s:%d",
974 1019
               conn->host.name, err);

0 notes on commit 6f1f7e5

Please sign in to comment.
Something went wrong with that request. Please try again.