mirror of
https://github.com/curl/curl.git
synced 2025-01-18 14:04:30 +08:00
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.
This commit is contained in:
parent
91ab2497c6
commit
6f1f7e5de8
@ -55,6 +55,7 @@ This release includes the following bugfixes:
|
||||
o curlbuild.h.dist: enhance non-configure GCC ABI detection logic
|
||||
o sasl: Fixed null pointer reference when decoding empty digest challenge [8]
|
||||
o easy: do not ignore poll() failures other than EINTR
|
||||
o darwinssl: disable ECC ciphers under Mountain Lion by default
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
|
||||
/* From MacTypes.h (which we can't include because it isn't present in iOS: */
|
||||
#define ioErr -36
|
||||
#define paramErr -50
|
||||
|
||||
/* In Mountain Lion and iOS 5, Apple made some changes to the API. They
|
||||
added TLS 1.1 and 1.2 support, and deprecated and replaced some
|
||||
@ -628,40 +629,36 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) {
|
||||
return "TLS_NULL_WITH_NULL_NULL";
|
||||
}
|
||||
|
||||
CF_INLINE bool IsRunningMountainLionOrLater(void)
|
||||
{
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
|
||||
{
|
||||
int mib[2];
|
||||
char *os_version;
|
||||
size_t os_version_len;
|
||||
char *os_version_major/*, *os_version_minor, *os_version_point*/;
|
||||
int os_version_major_int;
|
||||
char *os_version_major, *os_version_minor/*, *os_version_point*/;
|
||||
|
||||
/* Get the Darwin kernel version from the kernel using sysctl(): */
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_OSRELEASE;
|
||||
if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
|
||||
return false;
|
||||
return;
|
||||
os_version = malloc(os_version_len*sizeof(char));
|
||||
if(!os_version)
|
||||
return false;
|
||||
return;
|
||||
if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
|
||||
free(os_version);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse the version. If it's version 12.0.0 or later, then this user is
|
||||
using Mountain Lion. */
|
||||
/* Parse the version: */
|
||||
os_version_major = strtok(os_version, ".");
|
||||
/*os_version_minor = strtok(NULL, ".");
|
||||
os_version_point = strtok(NULL, ".");*/
|
||||
os_version_major_int = atoi(os_version_major);
|
||||
os_version_minor = strtok(NULL, ".");
|
||||
/*os_version_point = strtok(NULL, ".");*/
|
||||
*major = atoi(os_version_major);
|
||||
*minor = atoi(os_version_minor);
|
||||
free(os_version);
|
||||
return os_version_major_int >= 12;
|
||||
#else
|
||||
return true; /* iOS users: this doesn't concern you */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Apple provides a myriad of ways of getting information about a certificate
|
||||
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,
|
||||
#endif
|
||||
/*SSLConnectionRef ssl_connection;*/
|
||||
OSStatus err = noErr;
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
|
||||
SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
|
||||
int darwinver_maj = 0, darwinver_min = 0;
|
||||
|
||||
GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
|
||||
#endif
|
||||
|
||||
#if defined(__MAC_10_8) || defined(__IPHONE_5_0)
|
||||
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
|
||||
@ -851,7 +855,12 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
to disable certificate validation if the user turned that off.
|
||||
(SecureTransport will always validate the certificate chain by
|
||||
default.) */
|
||||
if(SSLSetSessionOption != NULL && IsRunningMountainLionOrLater()) {
|
||||
/* (Note: Darwin 12.x.x is Mountain Lion.) */
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
if(SSLSetSessionOption != NULL && darwinver_maj >= 12) {
|
||||
#else
|
||||
if(SSLSetSessionOption != NULL) {
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
err = SSLSetSessionOption(connssl->ssl_ctx,
|
||||
kSSLSessionOptionBreakOnServerAuth,
|
||||
data->set.ssl.verifypeer?false:true);
|
||||
@ -895,6 +904,31 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
/* There's a known bug in early versions of Mountain Lion where ST's ECC
|
||||
ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
|
||||
Work around the problem here by disabling those ciphers if we are running
|
||||
in an affected version of OS X. */
|
||||
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
|
||||
if(darwinver_maj == 12 && darwinver_min <= 3) {
|
||||
(void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
|
||||
all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
|
||||
allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
|
||||
if(all_ciphers && allowed_ciphers &&
|
||||
SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers,
|
||||
&all_ciphers_count) == noErr) {
|
||||
for(i = 0UL ; i < all_ciphers_count ; i++) {
|
||||
if(all_ciphers[i] < 0xC001 || all_ciphers[i] > 0xC032) {
|
||||
allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
|
||||
}
|
||||
}
|
||||
(void)SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
|
||||
allowed_ciphers_count);
|
||||
}
|
||||
Curl_safefree(all_ciphers);
|
||||
Curl_safefree(allowed_ciphers);
|
||||
}
|
||||
#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
|
||||
|
||||
err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
|
||||
if(err != noErr) {
|
||||
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
|
||||
@ -947,6 +981,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
/* the documentation says we need to call SSLHandshake() again */
|
||||
return darwinssl_connect_step2(conn, sockindex);
|
||||
|
||||
/* These are all certificate problems with the server: */
|
||||
case errSSLXCertChainInvalid:
|
||||
failf(data, "SSL certificate problem: Invalid certificate chain");
|
||||
return CURLE_SSL_CACERT;
|
||||
@ -961,14 +996,24 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|
||||
"expired certificate");
|
||||
return CURLE_SSL_CACERT;
|
||||
|
||||
/* This error is raised if the server's cert didn't match the server's
|
||||
host name: */
|
||||
case errSSLHostNameMismatch:
|
||||
failf(data, "SSL certificate peer verification failed, the "
|
||||
"certificate did not match \"%s\"\n", conn->host.dispname);
|
||||
return CURLE_PEER_FAILED_VERIFICATION;
|
||||
|
||||
/* Generic handshake errors: */
|
||||
case errSSLConnectionRefused:
|
||||
failf(data, "Server dropped the connection during the SSL handshake");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
case errSSLClosedAbort:
|
||||
failf(data, "Server aborted the SSL handshake");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
case paramErr: /* if you're getting this, it could be a cipher problem */
|
||||
failf(data, "Internal SSL engine error encountered during the "
|
||||
"SSL handshake");
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
default:
|
||||
failf(data, "Unknown SSL protocol error in connection to %s:%d",
|
||||
conn->host.name, err);
|
||||
|
Loading…
Reference in New Issue
Block a user