summaryrefslogtreecommitdiff
path: root/libs/libcurl/src/vtls/sectransp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libcurl/src/vtls/sectransp.c')
-rw-r--r--libs/libcurl/src/vtls/sectransp.c199
1 files changed, 58 insertions, 141 deletions
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index 10dfe1e92e..9cb51f2c53 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -34,7 +34,7 @@
#include "urldata.h" /* for the Curl_easy definition */
#include "curl_base64.h"
-#include "strtok.h"
+#include "strparse.h"
#include "multiif.h"
#include "strcase.h"
#include "x509asn1.h"
@@ -211,9 +211,6 @@ static const uint16_t default_ciphers[] = {
#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
};
-#define DEFAULT_CIPHERS_LEN sizeof(default_ciphers)/sizeof(default_ciphers[0])
-
-
/* pinned public key support tests */
/* version 1 supports macOS 10.12+ and iOS 10+ */
@@ -266,7 +263,7 @@ static OSStatus sectransp_bio_cf_in_read(SSLConnectionRef connection,
void *buf,
size_t *dataLength) /* IN/OUT */
{
- struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
+ const struct Curl_cfilter *cf = (const struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
struct st_ssl_backend_data *backend =
(struct st_ssl_backend_data *)connssl->backend;
@@ -306,7 +303,7 @@ static OSStatus sectransp_bio_cf_out_write(SSLConnectionRef connection,
const void *buf,
size_t *dataLength) /* IN/OUT */
{
- struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
+ const struct Curl_cfilter *cf = (const struct Curl_cfilter *)connection;
struct ssl_connect_data *connssl = cf->ctx;
struct st_ssl_backend_data *backend =
(struct st_ssl_backend_data *)connssl->backend;
@@ -341,30 +338,28 @@ static OSStatus sectransp_bio_cf_out_write(SSLConnectionRef connection,
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;
- char *tok_buf;
+ char buf[256];
/* 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;
- os_version = malloc(os_version_len*sizeof(char));
- if(!os_version)
- return;
- if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
- free(os_version);
- return;
+ if(os_version_len < sizeof(buf)) {
+ if(sysctl(mib, 2, buf, &os_version_len, NULL, 0) != -1) {
+ const char *os = buf;
+ curl_off_t fnum;
+ curl_off_t snum;
+ /* Parse the version: */
+ if(!Curl_str_number(&os, &fnum, INT_MAX) &&
+ !Curl_str_single(&os, '.') &&
+ !Curl_str_number(&os, &snum, INT_MAX)) {
+ *major = (int)fnum;
+ *minor = (int)snum;
+ }
+ }
}
-
- /* Parse the version: */
- os_version_major = Curl_strtok_r(os_version, ".", &tok_buf);
- os_version_minor = Curl_strtok_r(NULL, ".", &tok_buf);
- *major = atoi(os_version_major);
- *minor = atoi(os_version_minor);
- free(os_version);
}
#endif /* CURL_BUILD_MAC */
@@ -541,8 +536,8 @@ static OSStatus CopyIdentityWithLabel(char *label,
for(i = 0; i < keys_list_count; i++) {
OSStatus err = noErr;
SecCertificateRef cert = NULL;
- SecIdentityRef identity =
- (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
+ const void *item = CFArrayGetValueAtIndex(keys_list, i);
+ SecIdentityRef identity = (SecIdentityRef)CURL_UNCONST(item);
err = SecIdentityCopyCertificate(identity, &cert);
if(err == noErr) {
CFStringRef common_name = NULL;
@@ -671,22 +666,22 @@ static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
count = CFArrayGetCount(items);
for(i = 0; i < count; i++) {
- CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
- CFTypeID itemID = CFGetTypeID(item);
+ const CFTypeRef item = CFArrayGetValueAtIndex(items, i);
+ CFTypeID itemID = CFGetTypeID(item);
if(itemID == CFDictionaryGetTypeID()) {
- CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
- (CFDictionaryRef) item,
- kSecImportItemIdentity);
+ const CFTypeRef identity = CFDictionaryGetValue(
+ (CFDictionaryRef)item,
+ kSecImportItemIdentity);
CFRetain(identity);
- *out_cert_and_key = (SecIdentityRef) identity;
+ *out_cert_and_key = (SecIdentityRef)CURL_UNCONST(identity);
break;
}
#if CURL_BUILD_MAC_10_7
else if(itemID == SecCertificateGetTypeID()) {
status = SecIdentityCreateWithCertificate(NULL,
- (SecCertificateRef) item,
- out_cert_and_key);
+ (SecCertificateRef)CURL_UNCONST(item),
+ out_cert_and_key);
break;
}
#endif
@@ -927,7 +922,7 @@ static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data,
/* Intersect the ciphers supported by Secure Transport with the default
* ciphers, using the order of the former. */
for(i = 0; i < supported_len; i++) {
- for(j = 0; j < DEFAULT_CIPHERS_LEN; j++) {
+ for(j = 0; j < CURL_ARRAYSIZE(default_ciphers); j++) {
if(default_ciphers[j] == ciphers[i]) {
ciphers[count++] = ciphers[i];
break;
@@ -1096,10 +1091,13 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
if(result != CURLE_OK)
return result;
+ if(connssl->alpn) {
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \
defined(HAVE_BUILTIN_AVAILABLE)
- if(connssl->alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
+#else
+ if(&SSLSetALPNProtocols && &SSLCopyALPNProtocols) {
+#endif
struct alpn_proto_buf proto;
size_t i;
CFStringRef cstr;
@@ -1122,7 +1120,6 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data);
}
}
-#endif
if(ssl_config->key) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
@@ -1338,8 +1335,9 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
size_t ssl_sessionid_len;
Curl_ssl_scache_lock(data);
- if(Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key,
- (void **)&ssl_sessionid)) {
+ ssl_sessionid = Curl_ssl_scache_get_obj(cf, data,
+ connssl->peer.scache_key);
+ if(ssl_sessionid) {
/* we got a session id, use it! */
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid,
strlen(ssl_sessionid));
@@ -1696,7 +1694,8 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
const char *pinnedpubkey)
{ /* Scratch */
size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
- unsigned char *pubkey = NULL, *realpubkey = NULL;
+ const unsigned char *pubkey = NULL;
+ unsigned char *realpubkey = NULL;
const unsigned char *spkiHeader = NULL;
CFDataRef publicKeyBits = NULL;
@@ -1746,7 +1745,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
pubkeylen = (size_t)CFDataGetLength(publicKeyBits);
- pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
+ pubkey = (const unsigned char *)CFDataGetBytePtr(publicKeyBits);
switch(pubkeylen) {
case 526:
@@ -2092,10 +2091,13 @@ check_handshake:
break;
}
+ if(connssl->alpn) {
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \
defined(HAVE_BUILTIN_AVAILABLE)
- if(connssl->alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
+#else
+ if(&SSLSetALPNProtocols && &SSLCopyALPNProtocols) {
+#endif
CFArrayRef alpnArr = NULL;
CFStringRef chosenProtocol = NULL;
err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
@@ -2123,7 +2125,6 @@ check_handshake:
CFRelease(alpnArr);
}
}
-#endif
return CURLE_OK;
}
@@ -2131,7 +2132,7 @@ check_handshake:
static CURLcode
add_cert_to_certinfo(struct Curl_easy *data,
- SecCertificateRef server_cert,
+ const SecCertificateRef server_cert,
int idx)
{
CURLcode result = CURLE_OK;
@@ -2151,7 +2152,7 @@ add_cert_to_certinfo(struct Curl_easy *data,
static CURLcode
collect_server_cert_single(struct Curl_cfilter *cf, struct Curl_easy *data,
- SecCertificateRef server_cert,
+ const SecCertificateRef server_cert,
CFIndex idx)
{
CURLcode result = CURLE_OK;
@@ -2248,8 +2249,8 @@ static CURLcode collect_server_cert(struct Curl_cfilter *cf,
if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
- server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
- i);
+ const void *item = CFArrayGetValueAtIndex(server_certs, i);
+ server_cert = (SecCertificateRef)CURL_UNCONST(item);
result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
@@ -2265,7 +2266,8 @@ static CURLcode collect_server_cert(struct Curl_cfilter *cf,
if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
- server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
+ const void *item = CFArrayGetValueAtIndex(server_certs, i);
+ server_cert = (SecCertificateRef)CURL_UNCONST(item);
result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
@@ -2292,15 +2294,12 @@ static CURLcode sectransp_connect_step3(struct Curl_cfilter *cf,
return CURLE_OK;
}
-static CURLcode
-sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
- bool nonblocking,
- bool *done)
+static CURLcode sectransp_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
CURLcode result;
struct ssl_connect_data *connssl = cf->ctx;
- curl_socket_t sockfd = Curl_conn_cf_get_socket(cf, data);
- int what;
/* check if the connection has already been established */
if(ssl_connection_complete == connssl->state) {
@@ -2308,73 +2307,20 @@ sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
return CURLE_OK;
}
- if(ssl_connect_1 == connssl->connecting_state) {
- /* Find out how much more time we are allowed */
- const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
- if(timeout_ms < 0) {
- /* no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
+ *done = FALSE;
+ connssl->io_need = CURL_SSL_IO_NEED_NONE;
+ if(ssl_connect_1 == connssl->connecting_state) {
result = sectransp_connect_step1(cf, data);
if(result)
return result;
}
- while(ssl_connect_2 == connssl->connecting_state) {
-
- /* check allowed time left */
- const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
-
- if(timeout_ms < 0) {
- /* no need to continue if time already is up */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
-
- /* if ssl is expecting something, check if it is available. */
- if(connssl->io_need) {
-
- curl_socket_t writefd = (connssl->io_need & CURL_SSL_IO_NEED_SEND) ?
- sockfd : CURL_SOCKET_BAD;
- curl_socket_t readfd = (connssl->io_need & CURL_SSL_IO_NEED_RECV) ?
- sockfd : CURL_SOCKET_BAD;
-
- what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking ? 0 : timeout_ms);
- if(what < 0) {
- /* fatal error */
- failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
- return CURLE_SSL_CONNECT_ERROR;
- }
- else if(0 == what) {
- if(nonblocking) {
- *done = FALSE;
- return CURLE_OK;
- }
- else {
- /* timeout */
- failf(data, "SSL connection timeout");
- return CURLE_OPERATION_TIMEDOUT;
- }
- }
- /* socket is readable or writable */
- }
-
- /* Run transaction, and return to the caller if it failed or if this
- * connection is done nonblocking and this loop would execute again. This
- * permits the owner of a multi handle to abort a connection attempt
- * before step2 has completed while ensuring that a client using select()
- * or epoll() will always have a valid fdset to wait on.
- */
+ if(ssl_connect_2 == connssl->connecting_state) {
result = sectransp_connect_step2(cf, data);
- if(result || (nonblocking && (ssl_connect_2 == connssl->connecting_state)))
+ if(result)
return result;
-
- } /* repeat step2 until all transactions are done. */
-
+ }
if(ssl_connect_3 == connssl->connecting_state) {
result = sectransp_connect_step3(cf, data);
@@ -2387,34 +2333,6 @@ sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
connssl->state = ssl_connection_complete;
*done = TRUE;
}
- else
- *done = FALSE;
-
- /* Reset our connect state machine */
- connssl->connecting_state = ssl_connect_1;
-
- return CURLE_OK;
-}
-
-static CURLcode sectransp_connect_nonblocking(struct Curl_cfilter *cf,
- struct Curl_easy *data,
- bool *done)
-{
- return sectransp_connect_common(cf, data, TRUE, done);
-}
-
-static CURLcode sectransp_connect(struct Curl_cfilter *cf,
- struct Curl_easy *data)
-{
- CURLcode result;
- bool done = FALSE;
-
- result = sectransp_connect_common(cf, data, FALSE, &done);
-
- if(result)
- return result;
-
- DEBUGASSERT(done);
return CURLE_OK;
}
@@ -2549,7 +2467,7 @@ static bool sectransp_data_pending(struct Curl_cfilter *cf,
DEBUGASSERT(backend);
if(backend->ssl_ctx) { /* SSL is in use */
- CURL_TRC_CF((struct Curl_easy *)data, cf, "data_pending");
+ CURL_TRC_CF((struct Curl_easy *)CURL_UNCONST(data), cf, "data_pending");
err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
if(err == noErr)
return buffer > 0UL;
@@ -2759,7 +2677,6 @@ const struct Curl_ssl Curl_ssl_sectransp = {
sectransp_random, /* random */
NULL, /* cert_status_request */
sectransp_connect, /* connect */
- sectransp_connect_nonblocking, /* connect_nonblocking */
Curl_ssl_adjust_pollset, /* adjust_pollset */
sectransp_get_internals, /* get_internals */
sectransp_close, /* close_one */