aboutsummaryrefslogtreecommitdiffstats
path: root/lib/vtls/darwinssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vtls/darwinssl.c')
-rw-r--r--lib/vtls/darwinssl.c542
1 files changed, 352 insertions, 190 deletions
diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c
index 6f9c6012..31690422 100644
--- a/lib/vtls/darwinssl.c
+++ b/lib/vtls/darwinssl.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
* Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
@@ -22,7 +22,7 @@
***************************************************************************/
/*
- * Source file for all iOS and Mac OS X SecureTransport-specific code for the
+ * Source file for all iOS and macOS SecureTransport-specific code for the
* TLS/SSL layer. No code but vtls.c should ever call or use these functions.
*/
@@ -44,16 +44,20 @@
#endif
#include <Security/Security.h>
+/* For some reason, when building for iOS, the omnibus header above does
+ * not include SecureTransport.h as of iOS SDK 5.1. */
#include <Security/SecureTransport.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CommonCrypto/CommonDigest.h>
-/* The Security framework has changed greatly between iOS and different OS X
+/* The Security framework has changed greatly between iOS and different macOS
versions, and we will try to support as many of them as we can (back to
Leopard and iOS 5) by using macros and weak-linking.
- IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
- you must build this project against the 10.8 SDK or later. */
+ In general, you want to build this using the most recent OS SDK, since some
+ features require curl to be built against the latest SDK. TLS 1.1 and 1.2
+ support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
+ requires the macOS 10.13 or iOS 11 SDK or later. */
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
@@ -62,6 +66,7 @@
#define CURL_BUILD_IOS 0
#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_IOS_11 0
#define CURL_BUILD_MAC 1
/* This is the maximum API level we are allowed to use when building: */
#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
@@ -69,10 +74,11 @@
#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
/* These macros mean "the following code is present to allow runtime backward
compatibility with at least this cat or earlier":
- (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
- environmental variable.) */
+ (You set this at build-time using the compiler command line option
+ "-mmacos-version-min.") */
#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
@@ -82,11 +88,14 @@
#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
#define CURL_BUILD_IOS 1
#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
#define CURL_BUILD_MAC 0
#define CURL_BUILD_MAC_10_5 0
#define CURL_BUILD_MAC_10_6 0
#define CURL_BUILD_MAC_10_7 0
#define CURL_BUILD_MAC_10_8 0
+#define CURL_BUILD_MAC_10_9 0
+#define CURL_BUILD_MAC_10_13 0
#define CURL_SUPPORT_MAC_10_5 0
#define CURL_SUPPORT_MAC_10_6 0
#define CURL_SUPPORT_MAC_10_7 0
@@ -118,6 +127,33 @@
#define ioErr -36
#define paramErr -50
+struct ssl_backend_data {
+ SSLContextRef ssl_ctx;
+ curl_socket_t ssl_sockfd;
+ bool ssl_direction; /* true if writing, false if reading */
+ size_t ssl_write_buffered_length;
+};
+
+#define BACKEND connssl->backend
+
+/* pinned public key support tests */
+
+/* version 1 supports macOS 10.12+ and iOS 10+ */
+#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
+ (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
+#define DARWIN_SSL_PINNEDPUBKEY_V1 1
+#endif
+
+/* version 2 supports MacOSX 10.7+ */
+#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+#define DARWIN_SSL_PINNEDPUBKEY_V2 1
+#endif
+
+#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
+/* this backend supports CURLOPT_PINNEDPUBLICKEY */
+#define DARWIN_SSL_PINNEDPUBKEY 1
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+
#ifdef DARWIN_SSL_PINNEDPUBKEY
/* both new and old APIs return rsa keys missing the spki header (not DER) */
static const unsigned char rsa4096SpkiHeader[] = {
@@ -161,7 +197,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,
UInt8 *currData = (UInt8 *)data;
/*int sock = *(int *)connection;*/
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
- int sock = connssl->ssl_sockfd;
+ int sock = BACKEND->ssl_sockfd;
OSStatus rtn = noErr;
size_t bytesRead;
ssize_t rrtn;
@@ -190,7 +226,7 @@ static OSStatus SocketRead(SSLConnectionRef connection,
break;
case EAGAIN:
rtn = errSSLWouldBlock;
- connssl->ssl_direction = false;
+ BACKEND->ssl_direction = false;
break;
default:
rtn = ioErr;
@@ -221,7 +257,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
size_t bytesSent = 0;
/*int sock = *(int *)connection;*/
struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
- int sock = connssl->ssl_sockfd;
+ int sock = BACKEND->ssl_sockfd;
ssize_t length;
size_t dataLen = *dataLength;
const UInt8 *dataPtr = (UInt8 *)data;
@@ -241,7 +277,7 @@ static OSStatus SocketWrite(SSLConnectionRef connection,
theErr = errno;
if(theErr == EAGAIN) {
ortn = errSSLWouldBlock;
- connssl->ssl_direction = true;
+ BACKEND->ssl_direction = true;
}
else {
ortn = ioErr;
@@ -809,6 +845,30 @@ CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
return "TLS_RSA_PSK_WITH_NULL_SHA384";
break;
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
+ case TLS_AES_128_GCM_SHA256:
+ return "TLS_AES_128_GCM_SHA256";
+ break;
+ case TLS_AES_256_GCM_SHA384:
+ return "TLS_AES_256_GCM_SHA384";
+ break;
+ case TLS_CHACHA20_POLY1305_SHA256:
+ return "TLS_CHACHA20_POLY1305_SHA256";
+ break;
+ case TLS_AES_128_CCM_SHA256:
+ return "TLS_AES_128_CCM_SHA256";
+ break;
+ case TLS_AES_128_CCM_8_SHA256:
+ return "TLS_AES_128_CCM_8_SHA256";
+ break;
+ case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+ return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
+ break;
+ case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+ return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
+ break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
}
return "TLS_NULL_WITH_NULL_NULL";
}
@@ -849,7 +909,7 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
into a string. Some aren't available under iOS or newer cats. So here's
a unified function for getting a string describing the certificate that
ought to work in all cats starting with Leopard. */
-CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
+CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
{
CFStringRef server_cert_summary = CFSTR("(null)");
@@ -876,6 +936,54 @@ CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert)
return server_cert_summary;
}
+static CURLcode CopyCertSubject(struct Curl_easy *data,
+ SecCertificateRef cert, char **certp)
+{
+ CFStringRef c = getsubject(cert);
+ CURLcode result = CURLE_OK;
+ const char *direct;
+ char *cbuf = NULL;
+ *certp = NULL;
+
+ if(!c) {
+ failf(data, "SSL: invalid CA certificate subject");
+ return CURLE_OUT_OF_MEMORY;
+ }
+
+ /* If the subject is already available as UTF-8 encoded (ie 'direct') then
+ use that, else convert it. */
+ direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
+ if(direct) {
+ *certp = strdup(direct);
+ if(!*certp) {
+ failf(data, "SSL: out of memory");
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+ else {
+ size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
+ cbuf = calloc(cbuf_size, 1);
+ if(cbuf) {
+ if(!CFStringGetCString(c, cbuf, cbuf_size,
+ kCFStringEncodingUTF8)) {
+ failf(data, "SSL: invalid CA certificate subject");
+ result = CURLE_SSL_CACERT;
+ }
+ else
+ /* pass back the buffer */
+ *certp = cbuf;
+ }
+ else {
+ failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ }
+ if(result)
+ free(cbuf);
+ CFRelease(c);
+ return result;
+}
+
#if CURL_SUPPORT_MAC_10_6
/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
deprecation warnings, so let's not compile this unless it's necessary: */
@@ -968,7 +1076,7 @@ static OSStatus CopyIdentityWithLabel(char *label,
keys_list_count = CFArrayGetCount(keys_list);
*out_cert_and_key = NULL;
status = 1;
- for(i=0; i<keys_list_count; i++) {
+ for(i = 0; i<keys_list_count; i++) {
OSStatus err = noErr;
SecCertificateRef cert = NULL;
SecIdentityRef identity =
@@ -1094,6 +1202,15 @@ static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
*darwinver = kTLSProtocol12;
return CURLE_OK;
case CURL_SSLVERSION_TLSv1_3:
+ /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ /* We can assume __builtin_available() will always work in the
+ 10.13/11.0 SDK: */
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ *darwinver = kTLSProtocol13;
+ return CURLE_OK;
+ }
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
break;
}
return CURLE_SSL_CONNECT_ERROR;
@@ -1107,12 +1224,27 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ long max_supported_version_by_os;
+
+ /* macOS 10.5-10.7 supported TLS 1.0 only.
+ macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
+ macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
+ }
+ else {
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+ }
+#else
+ max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
switch(ssl_version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
ssl_version = CURL_SSLVERSION_TLSv1_0;
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ ssl_version_max = max_supported_version_by_os;
break;
}
@@ -1121,7 +1253,7 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
ssl_version_max = ssl_version << 16;
break;
case CURL_SSLVERSION_MAX_DEFAULT:
- ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+ ssl_version_max = max_supported_version_by_os;
break;
}
@@ -1142,35 +1274,35 @@ set_ssl_version_min_max(struct connectdata *conn, int sockindex)
return result;
}
- (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, darwin_ver_min);
- (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, darwin_ver_max);
+ (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
return result;
}
else {
#if CURL_SUPPORT_MAC_10_8
long i = ssl_version;
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocolAll,
false);
for(; i <= (ssl_version_max >> 16); i++) {
switch(i) {
case CURL_SSLVERSION_TLSv1_0:
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol1,
true);
break;
case CURL_SSLVERSION_TLSv1_1:
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol11,
true);
break;
case CURL_SSLVERSION_TLSv1_2:
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol12,
true);
break;
case CURL_SSLVERSION_TLSv1_3:
- failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
+ failf(data, "Your version of the OS does not support TLSv1.3");
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -1211,10 +1343,10 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
- if(connssl->ssl_ctx)
- CFRelease(connssl->ssl_ctx);
- connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
- if(!connssl->ssl_ctx) {
+ if(BACKEND->ssl_ctx)
+ CFRelease(BACKEND->ssl_ctx);
+ BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+ if(!BACKEND->ssl_ctx) {
failf(data, "SSL: couldn't create a context!");
return CURLE_OUT_OF_MEMORY;
}
@@ -1222,9 +1354,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
else {
/* The old ST API does not exist under iOS, so don't compile it: */
#if CURL_SUPPORT_MAC_10_8
- if(connssl->ssl_ctx)
- (void)SSLDisposeContext(connssl->ssl_ctx);
- err = SSLNewContext(false, &(connssl->ssl_ctx));
+ if(BACKEND->ssl_ctx)
+ (void)SSLDisposeContext(BACKEND->ssl_ctx);
+ err = SSLNewContext(false, &(BACKEND->ssl_ctx));
if(err != noErr) {
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
@@ -1232,15 +1364,15 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
- if(connssl->ssl_ctx)
- (void)SSLDisposeContext(connssl->ssl_ctx);
- err = SSLNewContext(false, &(connssl->ssl_ctx));
+ if(BACKEND->ssl_ctx)
+ (void)SSLDisposeContext(BACKEND->ssl_ctx);
+ err = SSLNewContext(false, &(BACKEND->ssl_ctx));
if(err != noErr) {
failf(data, "SSL: couldn't create a context: OSStatus %d", err);
return CURLE_OUT_OF_MEMORY;
}
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
- connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+ BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
/* check to see if we've been told to use an explicit SSL/TLS version */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
@@ -1248,8 +1380,17 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
- (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1);
- (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12);
+ (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
+ }
+ else {
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+ }
+#else
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
break;
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
@@ -1262,20 +1403,20 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
break;
}
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3);
+ err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv3");
return CURLE_SSL_CONNECT_ERROR;
}
- (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3);
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
break;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2);
+ err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
if(err != noErr) {
failf(data, "Your version of the OS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
- (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2);
+ (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
break;
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
@@ -1284,19 +1425,19 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
#if CURL_SUPPORT_MAC_10_8
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocolAll,
false);
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol1,
true);
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol11,
true);
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol12,
true);
break;
@@ -1311,7 +1452,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
break;
}
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocol3,
true);
if(err != noErr) {
@@ -1320,7 +1461,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
break;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
@@ -1340,12 +1481,12 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
" SSL/TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false);
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
switch(conn->ssl_config.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
- (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kTLSProtocol1,
true);
break;
@@ -1359,7 +1500,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
failf(data, "Your version of the OS does not support TLSv1.3");
return CURLE_SSL_CONNECT_ERROR;
case CURL_SSLVERSION_SSLv2:
- err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocol2,
true);
if(err != noErr) {
@@ -1368,7 +1509,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
break;
case CURL_SSLVERSION_SSLv3:
- err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx,
+ err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
kSSLProtocol3,
true);
if(err != noErr) {
@@ -1418,25 +1559,21 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
/* If we found one, print it out: */
err = SecIdentityCopyCertificate(cert_and_key, &cert);
if(err == noErr) {
- CFStringRef cert_summary = CopyCertSubject(cert);
- char cert_summary_c[128];
-
- if(cert_summary) {
- memset(cert_summary_c, 0, 128);
- if(CFStringGetCString(cert_summary,
- cert_summary_c,
- 128,
- kCFStringEncodingUTF8)) {
- infof(data, "Client certificate: %s\n", cert_summary_c);
- }
- CFRelease(cert_summary);
- CFRelease(cert);
+ char *certp;
+ CURLcode result = CopyCertSubject(data, cert, &certp);
+ if(!result) {
+ infof(data, "Client certificate: %s\n", certp);
+ free(certp);
}
+
+ CFRelease(cert);
+ if(result)
+ return result;
}
certs_c[0] = cert_and_key;
certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
&kCFTypeArrayCallBacks);
- err = SSLSetCertificate(connssl->ssl_ctx, certs);
+ err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
if(certs)
CFRelease(certs);
if(err != noErr) {
@@ -1499,7 +1636,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
if(SSLSetSessionOption != NULL) {
#endif /* CURL_BUILD_MAC */
bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
- err = SSLSetSessionOption(connssl->ssl_ctx,
+ err = SSLSetSessionOption(BACKEND->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
break_on_auth);
if(err != noErr) {
@@ -1509,7 +1646,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
else {
#if CURL_SUPPORT_MAC_10_8
- err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+ err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
conn->ssl_config.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1518,7 +1655,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
- err = SSLSetEnableCertVerify(connssl->ssl_ctx,
+ err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
conn->ssl_config.verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
@@ -1539,7 +1676,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
* Both hostname check and SNI require SSLSetPeerDomainName().
* Also: the verifyhost setting influences SNI usage */
if(conn->ssl_config.verifyhost) {
- err = SSLSetPeerDomainName(connssl->ssl_ctx, hostname,
+ err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
strlen(hostname));
if(err != noErr) {
@@ -1565,11 +1702,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
higher priority, but it's probably better that we not connect at all than
to give the user a false sense of security if the server only supports
insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
- (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count);
+ (void)SSLGetNumberSupportedCiphers(BACKEND->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,
+ SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
&all_ciphers_count) == noErr) {
for(i = 0UL ; i < all_ciphers_count ; i++) {
#if CURL_BUILD_MAC
@@ -1651,7 +1788,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
break;
}
}
- err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers,
+ err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
allowed_ciphers_count);
if(err != noErr) {
failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
@@ -1672,9 +1809,9 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
specifically doesn't want us doing that: */
if(SSLSetSessionOption != NULL) {
/* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
- SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+ SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
!data->set.ssl.enable_beast);
- SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart,
+ SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
data->set.ssl.falsestart); /* false start support */
}
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
@@ -1688,7 +1825,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
&ssl_sessionid_len, sockindex)) {
/* we got a session id, use it! */
- err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+ err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
Curl_ssl_sessionid_unlock(conn);
if(err != noErr) {
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1706,7 +1843,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
ssl_sessionid_len = strlen(ssl_sessionid);
- err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+ err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
if(err != noErr) {
Curl_ssl_sessionid_unlock(conn);
failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
@@ -1723,7 +1860,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
}
}
- err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite);
+ err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
if(err != noErr) {
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -1733,8 +1870,8 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
/* We need to store the FD in a constant memory address, because
* SSLSetConnection() will not copy that address. I've found that
* conn->sock[sockindex] may change on its own. */
- connssl->ssl_sockfd = sockfd;
- err = SSLSetConnection(connssl->ssl_ctx, connssl);
+ BACKEND->ssl_sockfd = sockfd;
+ err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
if(err != noErr) {
failf(data, "SSL: SSLSetConnection() failed: %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -1797,7 +1934,7 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen)
{
int fd;
ssize_t n, len = 0, cap = 512;
- unsigned char buf[cap], *data;
+ unsigned char buf[512], *data;
fd = open(file, 0);
if(fd < 0)
@@ -1875,6 +2012,8 @@ static int append_cert_to_array(struct Curl_easy *data,
CFMutableArrayRef array)
{
CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
+ char *certp;
+ CURLcode result;
if(!certdata) {
failf(data, "SSL: failed to allocate array for CA certificate");
return CURLE_OUT_OF_MEMORY;
@@ -1889,25 +2028,10 @@ static int append_cert_to_array(struct Curl_easy *data,
}
/* Check if cacert is valid. */
- CFStringRef subject = CopyCertSubject(cacert);
- if(subject) {
- char subject_cbuf[128];
- memset(subject_cbuf, 0, 128);
- if(!CFStringGetCString(subject,
- subject_cbuf,
- 128,
- kCFStringEncodingUTF8)) {
- CFRelease(cacert);
- failf(data, "SSL: invalid CA certificate subject");
- return CURLE_SSL_CACERT;
- }
- CFRelease(subject);
- }
- else {
- CFRelease(cacert);
- failf(data, "SSL: invalid CA certificate");
- return CURLE_SSL_CACERT;
- }
+ result = CopyCertSubject(data, cacert, &certp);
+ if(result)
+ return result;
+ free(certp);
CFArrayAppendValue(array, cacert);
CFRelease(cacert);
@@ -2155,12 +2279,12 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
|| ssl_connect_2_writing == connssl->connecting_state);
/* Here goes nothing: */
- err = SSLHandshake(connssl->ssl_ctx);
+ err = SSLHandshake(BACKEND->ssl_ctx);
if(err != noErr) {
switch(err) {
case errSSLWouldBlock: /* they're not done with us yet */
- connssl->connecting_state = connssl->ssl_direction ?
+ connssl->connecting_state = BACKEND->ssl_direction ?
ssl_connect_2_writing : ssl_connect_2_reading;
return CURLE_OK;
@@ -2169,7 +2293,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
case -9841:
if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
- connssl->ssl_ctx);
+ BACKEND->ssl_ctx);
if(res != CURLE_OK)
return res;
}
@@ -2247,7 +2371,7 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
#ifdef DARWIN_SSL_PINNEDPUBKEY
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
- CURLcode result = pkp_pin_peer_pubkey(data, connssl->ssl_ctx,
+ CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
if(result) {
failf(data, "SSL: public key does not match pinned public key!");
@@ -2257,8 +2381,8 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
#endif /* DARWIN_SSL_PINNEDPUBKEY */
/* Informational message */
- (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher);
- (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol);
+ (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
+ (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
switch(protocol) {
case kSSLProtocol2:
infof(data, "SSL 2.0 connection using %s\n",
@@ -2281,7 +2405,13 @@ darwinssl_connect_step2(struct connectdata *conn, int sockindex)
infof(data, "TLS 1.2 connection using %s\n",
TLSCipherNameForNumber(cipher));
break;
-#endif
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+ case kTLSProtocol13:
+ infof(data, "TLS 1.3 connection using %s\n",
+ TLSCipherNameForNumber(cipher));
+ break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
default:
infof(data, "Unknown protocol connection\n");
break;
@@ -2299,36 +2429,32 @@ show_verbose_server_cert(struct connectdata *conn,
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- CFStringRef server_cert_summary;
- char server_cert_summary_c[128];
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
OSStatus err;
CFIndex i, count;
SecTrustRef trust = NULL;
- if(!connssl->ssl_ctx)
+ if(!BACKEND->ssl_ctx)
return;
#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
#if CURL_BUILD_IOS
#pragma unused(server_certs)
- err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+ err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
+ CURLcode result;
+ char *certp;
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- server_cert_summary = CopyCertSubject(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);
+ result = CopyCertSubject(data, server_cert, &certp);
+ if(!result) {
+ infof(data, "Server certificate: %s\n", certp);
+ free(certp);
}
- CFRelease(server_cert_summary);
}
CFRelease(trust);
}
@@ -2341,45 +2467,40 @@ show_verbose_server_cert(struct connectdata *conn,
Lion or later. */
if(SecTrustEvaluateAsync != NULL) {
#pragma unused(server_certs)
- err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust);
+ err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
/* For some reason, SSLCopyPeerTrust() can return noErr and yet return
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
for(i = 0L ; i < count ; i++) {
+ char *certp;
+ CURLcode result;
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- server_cert_summary = CopyCertSubject(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);
+ result = CopyCertSubject(data, server_cert, &certp);
+ if(!result) {
+ infof(data, "Server certificate: %s\n", certp);
+ free(certp);
}
- CFRelease(server_cert_summary);
}
CFRelease(trust);
}
}
else {
#if CURL_SUPPORT_MAC_10_8
- err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+ err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) {
+ char *certp;
+ CURLcode result;
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
i);
-
- server_cert_summary = CopyCertSubject(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);
+ result = CopyCertSubject(data, server_cert, &certp);
+ if(!result) {
+ infof(data, "Server certificate: %s\n", certp);
+ free(certp);
}
- CFRelease(server_cert_summary);
}
CFRelease(server_certs);
}
@@ -2388,20 +2509,18 @@ show_verbose_server_cert(struct connectdata *conn,
#endif /* CURL_BUILD_IOS */
#else
#pragma unused(trust)
- err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs);
+ err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
if(err == noErr) {
count = CFArrayGetCount(server_certs);
for(i = 0L ; i < count ; i++) {
+ CURLcode result;
+ char *certp;
server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
- server_cert_summary = CopyCertSubject(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);
+ result = CopyCertSubject(data, server_cert, &certp);
+ if(!result) {
+ infof(data, "Server certificate: %s\n", certp);
+ free(certp);
}
- CFRelease(server_cert_summary);
}
CFRelease(server_certs);
}
@@ -2450,7 +2569,7 @@ darwinssl_connect_common(struct connectdata *conn,
return CURLE_OK;
}
- if(ssl_connect_1==connssl->connecting_state) {
+ if(ssl_connect_1 == connssl->connecting_state) {
/* Find out how much more time we're allowed */
timeout_ms = Curl_timeleft(data, NULL, TRUE);
@@ -2545,17 +2664,13 @@ darwinssl_connect_common(struct connectdata *conn,
return CURLE_OK;
}
-CURLcode
-Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
- bool *done)
+static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+ int sockindex, bool *done)
{
return darwinssl_connect_common(conn, sockindex, TRUE, done);
}
-CURLcode
-Curl_darwinssl_connect(struct connectdata *conn,
- int sockindex)
+static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
{
CURLcode result;
bool done = FALSE;
@@ -2570,28 +2685,28 @@ Curl_darwinssl_connect(struct connectdata *conn,
return CURLE_OK;
}
-void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- if(connssl->ssl_ctx) {
- (void)SSLClose(connssl->ssl_ctx);
+ if(BACKEND->ssl_ctx) {
+ (void)SSLClose(BACKEND->ssl_ctx);
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLCreateContext != NULL)
- CFRelease(connssl->ssl_ctx);
+ CFRelease(BACKEND->ssl_ctx);
#if CURL_SUPPORT_MAC_10_8
else
- (void)SSLDisposeContext(connssl->ssl_ctx);
+ (void)SSLDisposeContext(BACKEND->ssl_ctx);
#endif /* CURL_SUPPORT_MAC_10_8 */
#else
- (void)SSLDisposeContext(connssl->ssl_ctx);
+ (void)SSLDisposeContext(BACKEND->ssl_ctx);
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
- connssl->ssl_ctx = NULL;
+ BACKEND->ssl_ctx = NULL;
}
- connssl->ssl_sockfd = 0;
+ BACKEND->ssl_sockfd = 0;
}
-int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct Curl_easy *data = conn->data;
@@ -2600,7 +2715,7 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
int rc;
char buf[120];
- if(!connssl->ssl_ctx)
+ if(!BACKEND->ssl_ctx)
return 0;
if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
@@ -2644,7 +2759,7 @@ int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
return rc;
}
-void Curl_darwinssl_session_free(void *ptr)
+static void Curl_darwinssl_session_free(void *ptr)
{
/* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
cached session ID inside the Security framework. There is a private
@@ -2655,7 +2770,7 @@ void Curl_darwinssl_session_free(void *ptr)
Curl_safefree(ptr);
}
-size_t Curl_darwinssl_version(char *buffer, size_t size)
+static size_t Curl_darwinssl_version(char *buffer, size_t size)
{
return snprintf(buffer, size, "SecureTransport");
}
@@ -2668,14 +2783,14 @@ size_t Curl_darwinssl_version(char *buffer, size_t size)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-int Curl_darwinssl_check_cxn(struct connectdata *conn)
+static int Curl_darwinssl_check_cxn(struct connectdata *conn)
{
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
OSStatus err;
SSLSessionState state;
- if(connssl->ssl_ctx) {
- err = SSLGetSessionState(connssl->ssl_ctx, &state);
+ if(BACKEND->ssl_ctx) {
+ err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
if(err == noErr)
return state == kSSLConnected || state == kSSLHandshake;
return -1;
@@ -2683,15 +2798,15 @@ int Curl_darwinssl_check_cxn(struct connectdata *conn)
return 0;
}
-bool Curl_darwinssl_data_pending(const struct connectdata *conn,
- int connindex)
+static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+ int connindex)
{
const struct ssl_connect_data *connssl = &conn->ssl[connindex];
OSStatus err;
size_t buffer;
- if(connssl->ssl_ctx) { /* SSL is in use */
- err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer);
+ if(BACKEND->ssl_ctx) { /* SSL is in use */
+ err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
if(err == noErr)
return buffer > 0UL;
return false;
@@ -2700,14 +2815,16 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn,
return false;
}
-CURLcode Curl_darwinssl_random(unsigned char *entropy,
- size_t length)
+static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
+ unsigned char *entropy, size_t length)
{
/* arc4random_buf() isn't available on cats older than Lion, so let's
do this manually for the benefit of the older cats. */
size_t i;
u_int32_t random_number = 0;
+ (void)data;
+
for(i = 0 ; i < length ; i++) {
if(i % sizeof(u_int32_t) == 0)
random_number = arc4random();
@@ -2718,25 +2835,26 @@ CURLcode Curl_darwinssl_random(unsigned char *entropy,
return CURLE_OK;
}
-void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
- size_t tmplen,
- unsigned char *md5sum, /* output */
- size_t md5len)
+static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *md5sum, /* output */
+ size_t md5len)
{
(void)md5len;
(void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
+ return CURLE_OK;
}
-void Curl_darwinssl_sha256sum(unsigned char *tmp, /* input */
- size_t tmplen,
- unsigned char *sha256sum, /* output */
- size_t sha256len)
+static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
+ size_t tmplen,
+ unsigned char *sha256sum, /* output */
+ size_t sha256len)
{
- assert(sha256len >= SHA256_DIGEST_LENGTH);
+ assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
(void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
}
-bool Curl_darwinssl_false_start(void)
+static bool Curl_darwinssl_false_start(void)
{
#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
if(SSLSetSessionOption != NULL)
@@ -2771,15 +2889,15 @@ static ssize_t darwinssl_send(struct connectdata *conn,
over again with no new data until it quits returning errSSLWouldBlock. */
/* Do we have buffered data to write from the last time we were called? */
- if(connssl->ssl_write_buffered_length) {
+ if(BACKEND->ssl_write_buffered_length) {
/* Write the buffered data: */
- err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed);
+ err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
switch(err) {
case noErr:
/* processed is always going to be 0 because we didn't write to
the buffer, so return how much was written to the socket */
- processed = connssl->ssl_write_buffered_length;
- connssl->ssl_write_buffered_length = 0UL;
+ processed = BACKEND->ssl_write_buffered_length;
+ BACKEND->ssl_write_buffered_length = 0UL;
break;
case errSSLWouldBlock: /* argh, try again */
*curlcode = CURLE_AGAIN;
@@ -2792,13 +2910,13 @@ static ssize_t darwinssl_send(struct connectdata *conn,
}
else {
/* We've got new data to write: */
- err = SSLWrite(connssl->ssl_ctx, mem, len, &processed);
+ err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
if(err != noErr) {
switch(err) {
case errSSLWouldBlock:
/* Data was buffered but not sent, we have to tell the caller
to try sending again, and remember how much was buffered */
- connssl->ssl_write_buffered_length = len;
+ BACKEND->ssl_write_buffered_length = len;
*curlcode = CURLE_AGAIN;
return -1L;
default:
@@ -2820,7 +2938,7 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
/*struct Curl_easy *data = conn->data;*/
struct ssl_connect_data *connssl = &conn->ssl[num];
size_t processed = 0UL;
- OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed);
+ OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
if(err != noErr) {
switch(err) {
@@ -2851,6 +2969,50 @@ static ssize_t darwinssl_recv(struct connectdata *conn,
return (ssize_t)processed;
}
+static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
+ CURLINFO info UNUSED_PARAM)
+{
+ (void)info;
+ return BACKEND->ssl_ctx;
+}
+
+const struct Curl_ssl Curl_ssl_darwinssl = {
+ { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
+
+ 0, /* have_ca_path */
+ 0, /* have_certinfo */
+#ifdef DARWIN_SSL_PINNEDPUBKEY
+ 1, /* have_pinnedpubkey */
+#else
+ 0, /* have_pinnedpubkey */
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+ 0, /* have_ssl_ctx */
+ 0, /* support_https_proxy */
+
+ sizeof(struct ssl_backend_data),
+
+ Curl_none_init, /* init */
+ Curl_none_cleanup, /* cleanup */
+ Curl_darwinssl_version, /* version */
+ Curl_darwinssl_check_cxn, /* check_cxn */
+ Curl_darwinssl_shutdown, /* shutdown */
+ Curl_darwinssl_data_pending, /* data_pending */
+ Curl_darwinssl_random, /* random */
+ Curl_none_cert_status_request, /* cert_status_request */
+ Curl_darwinssl_connect, /* connect */
+ Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
+ Curl_darwinssl_get_internals, /* get_internals */
+ Curl_darwinssl_close, /* close_one */
+ Curl_none_close_all, /* close_all */
+ Curl_darwinssl_session_free, /* session_free */
+ Curl_none_set_engine, /* set_engine */
+ Curl_none_set_engine_default, /* set_engine_default */
+ Curl_none_engines_list, /* engines_list */
+ Curl_darwinssl_false_start, /* false_start */
+ Curl_darwinssl_md5sum, /* md5sum */
+ Curl_darwinssl_sha256sum /* sha256sum */
+};
+
#ifdef __clang__
#pragma clang diagnostic pop
#endif