summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/vtls/sectransp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/sectransp.c')
-rw-r--r--Utilities/cmcurl/lib/vtls/sectransp.c414
1 files changed, 173 insertions, 241 deletions
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c
index c764e3631b..ab7965465f 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.c
+++ b/Utilities/cmcurl/lib/vtls/sectransp.c
@@ -122,12 +122,12 @@
#include <sys/sysctl.h>
#endif /* CURL_BUILD_MAC */
-#include "urldata.h"
#include "sendf.h"
#include "inet_pton.h"
#include "connect.h"
#include "select.h"
#include "vtls.h"
+#include "vtls_int.h"
#include "sectransp.h"
#include "curl_printf.h"
#include "strdup.h"
@@ -142,7 +142,6 @@
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;
};
@@ -825,115 +824,62 @@ static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
#endif /* SECTRANSP_PINNEDPUBKEY_V1 */
#endif /* SECTRANSP_PINNEDPUBKEY */
-/* The following two functions were ripped from Apple sample code,
- * with some modifications: */
-static OSStatus SocketRead(SSLConnectionRef connection,
- void *data, /* owned by
- * caller, data
- * RETURNED */
- size_t *dataLength) /* IN/OUT */
+static OSStatus bio_cf_in_read(SSLConnectionRef connection,
+ void *buf,
+ size_t *dataLength) /* IN/OUT */
{
- size_t bytesToGo = *dataLength;
- size_t initLen = bytesToGo;
- UInt8 *currData = (UInt8 *)data;
- /*int sock = *(int *)connection;*/
- struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+ struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- int sock;
+ struct Curl_easy *data = connssl->call_data;
+ ssize_t nread;
+ CURLcode result;
OSStatus rtn = noErr;
- size_t bytesRead;
- ssize_t rrtn;
- int theErr;
- DEBUGASSERT(backend);
- sock = backend->ssl_sockfd;
- *dataLength = 0;
-
- for(;;) {
- bytesRead = 0;
- rrtn = read(sock, currData, bytesToGo);
- if(rrtn <= 0) {
- /* this is guesswork... */
- theErr = errno;
- if(rrtn == 0) { /* EOF = server hung up */
- /* the framework will turn this into errSSLClosedNoNotify */
- rtn = errSSLClosedGraceful;
- }
- else /* do the switch */
- switch(theErr) {
- case ENOENT:
- /* connection closed */
- rtn = errSSLClosedGraceful;
- break;
- case ECONNRESET:
- rtn = errSSLClosedAbort;
- break;
- case EAGAIN:
- rtn = errSSLWouldBlock;
- backend->ssl_direction = false;
- break;
- default:
- rtn = ioErr;
- break;
- }
- break;
- }
- else {
- bytesRead = rrtn;
- }
- bytesToGo -= bytesRead;
- currData += bytesRead;
-
- if(bytesToGo == 0) {
- /* filled buffer with incoming data, done */
- break;
+ DEBUGASSERT(data);
+ nread = Curl_conn_cf_recv(cf->next, data, buf, *dataLength, &result);
+ if(nread < 0) {
+ switch(result) {
+ case CURLE_OK:
+ case CURLE_AGAIN:
+ rtn = errSSLWouldBlock;
+ backend->ssl_direction = false;
+ break;
+ default:
+ rtn = ioErr;
+ break;
}
+ nread = 0;
}
- *dataLength = initLen - bytesToGo;
-
+ *dataLength = nread;
return rtn;
}
-static OSStatus SocketWrite(SSLConnectionRef connection,
- const void *data,
- size_t *dataLength) /* IN/OUT */
+static OSStatus bio_cf_out_write(SSLConnectionRef connection,
+ const void *buf,
+ size_t *dataLength) /* IN/OUT */
{
- size_t bytesSent = 0;
- /*int sock = *(int *)connection;*/
- struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+ struct Curl_cfilter *cf = (struct Curl_cfilter *)connection;
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- int sock;
- ssize_t length;
- size_t dataLen = *dataLength;
- const UInt8 *dataPtr = (UInt8 *)data;
- OSStatus ortn;
- int theErr;
-
- DEBUGASSERT(backend);
- sock = backend->ssl_sockfd;
- *dataLength = 0;
+ struct Curl_easy *data = connssl->call_data;
+ ssize_t nwritten;
+ CURLcode result;
+ OSStatus ortn = noErr;
- do {
- length = write(sock,
- (char *)dataPtr + bytesSent,
- dataLen - bytesSent);
- } while((length > 0) &&
- ( (bytesSent += length) < dataLen) );
-
- if(length <= 0) {
- theErr = errno;
- if(theErr == EAGAIN) {
+ DEBUGASSERT(data);
+ nwritten = Curl_conn_cf_send(cf->next, data, buf, *dataLength, &result);
+ if(nwritten <= 0) {
+ if(result == CURLE_AGAIN) {
ortn = errSSLWouldBlock;
backend->ssl_direction = true;
}
else {
ortn = ioErr;
}
+ nwritten = 0;
}
- else {
- ortn = noErr;
- }
- *dataLength = bytesSent;
+ *dataLength = nwritten;
return ortn;
}
@@ -1372,14 +1318,14 @@ static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
}
#endif
-static CURLcode
-set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode set_ssl_version_min_max(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- long ssl_version = SSL_CONN_CONFIG(version);
- long ssl_version_max = SSL_CONN_CONFIG(version_max);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ long ssl_version = conn_config->version;
+ long ssl_version_max = conn_config->version_max;
long max_supported_version_by_os;
DEBUGASSERT(backend);
@@ -1665,23 +1611,21 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode sectransp_connect_step1(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- curl_socket_t sockfd = conn->sock[sockindex];
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
- const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob);
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ const struct curl_blob *ssl_cablob = conn_config->ca_info_blob;
const char * const ssl_cafile =
/* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
- (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile));
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
- const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
- bool isproxy = SSL_IS_PROXY();
- const char * const hostname = SSL_HOST_NAME();
- const long int port = SSL_HOST_PORT();
+ (ssl_cablob ? NULL : conn_config->CAfile);
+ const bool verifypeer = conn_config->verifypeer;
+ char * const ssl_cert = ssl_config->primary.clientcert;
+ const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob;
+ bool isproxy = Curl_ssl_cf_is_proxy(cf);
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
@@ -1733,7 +1677,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* check to see if we've been told to use an explicit SSL/TLS version */
#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
if(SSLSetProtocolVersionMax) {
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
@@ -1754,7 +1698,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
+ CURLcode result = set_ssl_version_min_max(cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1773,7 +1717,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
kSSLProtocolAll,
false);
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
@@ -1791,7 +1735,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
{
- CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
+ CURLcode result = set_ssl_version_min_max(cf, data);
if(result != CURLE_OK)
return result;
break;
@@ -1807,13 +1751,13 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_SUPPORT_MAC_10_8 */
}
#else
- if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
+ if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) {
failf(data, "Your version of the OS does not support to set maximum"
" SSL/TLS version");
return CURLE_SSL_CONNECT_ERROR;
}
(void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
- switch(conn->ssl_config.version) {
+ switch(conn_config->version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
case CURL_SSLVERSION_TLSv1_0:
@@ -1841,7 +1785,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
&kCFTypeArrayCallBacks);
@@ -1849,7 +1793,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#ifdef USE_HTTP2
if(data->state.httpwant >= CURL_HTTP_VERSION_2
#ifndef CURL_DISABLE_PROXY
- && (!isproxy || !conn->bits.tunnel_proxy)
+ && (!isproxy || !cf->conn->bits.tunnel_proxy)
#endif
) {
CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
@@ -1872,7 +1816,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
}
#endif
- if(SSL_SET_OPTION(key)) {
+ if(ssl_config->key) {
infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
"Transport. The private key must be in the Keychain.");
}
@@ -1891,17 +1835,17 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else
err = !noErr;
if((err != noErr) && (is_cert_file || is_cert_data)) {
- if(!SSL_SET_OPTION(cert_type))
+ if(!ssl_config->cert_type)
infof(data, "SSL: Certificate type not set, assuming "
"PKCS#12 format.");
- else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) {
+ else if(!strcasecompare(ssl_config->cert_type, "P12")) {
failf(data, "SSL: The Security framework only supports "
"loading identities that are in PKCS#12 format.");
return CURLE_SSL_CERTPROBLEM;
}
err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
- SSL_SET_OPTION(key_passwd),
+ ssl_config->key_passwd,
&cert_and_key);
}
@@ -1994,7 +1938,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
#else
if(SSLSetSessionOption) {
#endif /* CURL_BUILD_MAC */
- bool break_on_auth = !conn->ssl_config.verifypeer ||
+ bool break_on_auth = !conn_config->verifypeer ||
ssl_cafile || ssl_cablob;
err = SSLSetSessionOption(backend->ssl_ctx,
kSSLSessionOptionBreakOnServerAuth,
@@ -2007,7 +1951,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else {
#if CURL_SUPPORT_MAC_10_8
err = SSLSetEnableCertVerify(backend->ssl_ctx,
- conn->ssl_config.verifypeer?true:false);
+ conn_config->verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -2016,7 +1960,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
}
#else
err = SSLSetEnableCertVerify(backend->ssl_ctx,
- conn->ssl_config.verifypeer?true:false);
+ conn_config->verifypeer?true:false);
if(err != noErr) {
failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -2037,9 +1981,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
/* Configure hostname check. SNI is used if available.
* Both hostname check and SNI require SSLSetPeerDomainName().
* Also: the verifyhost setting influences SNI usage */
- if(conn->ssl_config.verifyhost) {
+ if(conn_config->verifyhost) {
size_t snilen;
- char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
+ char *snihost = Curl_ssl_snihost(data, connssl->hostname, &snilen);
if(!snihost) {
failf(data, "Failed to set SNI");
return CURLE_SSL_CONNECT_ERROR;
@@ -2052,9 +1996,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- if((Curl_inet_pton(AF_INET, hostname, &addr))
+ if((Curl_inet_pton(AF_INET, connssl->hostname, &addr))
#ifdef ENABLE_IPV6
- || (Curl_inet_pton(AF_INET6, hostname, &addr))
+ || (Curl_inet_pton(AF_INET6, connssl->hostname, &addr))
#endif
) {
infof(data, "WARNING: using IP address, SNI is being disabled by "
@@ -2065,7 +2009,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
infof(data, "WARNING: disabling hostname validation also disables SNI.");
}
- ciphers = SSL_CONN_CONFIG(cipher_list);
+ ciphers = conn_config->cipher_list;
if(ciphers) {
err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers);
}
@@ -2083,20 +2027,20 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
specifically doesn't want us doing that: */
if(SSLSetSessionOption) {
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
- !SSL_SET_OPTION(enable_beast));
+ !ssl_config->enable_beast);
SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
- data->set.ssl.falsestart); /* false start support */
+ ssl_config->falsestart); /* false start support */
}
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
/* Check if there's a cached ID we can/should use here! */
- if(SSL_SET_OPTION(primary.sessionid)) {
+ if(ssl_config->primary.sessionid) {
char *ssl_sessionid;
size_t ssl_sessionid_len;
Curl_ssl_sessionid_lock(data);
- if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid,
- &ssl_sessionid_len, sockindex)) {
+ if(!Curl_ssl_getsessionid(cf, data, (void **)&ssl_sessionid,
+ &ssl_sessionid_len)) {
/* we got a session id, use it! */
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
Curl_ssl_sessionid_unlock(data);
@@ -2112,9 +2056,10 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
else {
CURLcode result;
ssl_sessionid =
- aprintf("%s:%d:%d:%s:%ld",
+ aprintf("%s:%d:%d:%s:%d",
ssl_cafile ? ssl_cafile : "(blob memory)",
- verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
+ verifypeer, conn_config->verifyhost, connssl->hostname,
+ connssl->port);
ssl_sessionid_len = strlen(ssl_sessionid);
err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
@@ -2124,8 +2069,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
return CURLE_SSL_CONNECT_ERROR;
}
- result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
- ssl_sessionid_len, sockindex, NULL);
+ result = Curl_ssl_addsessionid(cf, data, ssl_sessionid,
+ ssl_sessionid_len, NULL);
Curl_ssl_sessionid_unlock(data);
if(result) {
failf(data, "failed to store ssl session");
@@ -2134,18 +2079,13 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
}
}
- err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
+ err = SSLSetIOFuncs(backend->ssl_ctx, bio_cf_in_read, bio_cf_out_write);
if(err != noErr) {
failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
return CURLE_SSL_CONNECT_ERROR;
}
- /* pass the raw socket into the SSL layers */
- /* 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. */
- backend->ssl_sockfd = sockfd;
- err = SSLSetConnection(backend->ssl_ctx, connssl);
+ err = SSLSetConnection(backend->ssl_ctx, cf);
if(err != noErr) {
failf(data, "SSL: SSLSetConnection() failed: %d", err);
return CURLE_SSL_CONNECT_ERROR;
@@ -2544,16 +2484,15 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
}
#endif /* SECTRANSP_PINNEDPUBKEY */
-static CURLcode
-sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step2(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
OSStatus err;
SSLCipherSuite cipher;
SSLProtocol protocol = 0;
- const char * const hostname = SSL_HOST_NAME();
DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
|| ssl_connect_2_reading == connssl->connecting_state
@@ -2573,16 +2512,16 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
/* The below is errSSLServerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
- SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(ca_info_blob),
+ if((conn_config->CAfile || conn_config->ca_info_blob) &&
+ conn_config->verifypeer) {
+ CURLcode result = verify_cert(data, conn_config->CAfile,
+ conn_config->ca_info_blob,
backend->ssl_ctx);
if(result)
return result;
}
/* the documentation says we need to call SSLHandshake() again */
- return sectransp_connect_step2(data, conn, sockindex);
+ return sectransp_connect_step2(cf, data);
/* Problem with encrypt / decrypt */
case errSSLPeerDecodeError:
@@ -2684,7 +2623,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
host name: */
case errSSLHostNameMismatch:
failf(data, "SSL certificate peer verification failed, the "
- "certificate did not match \"%s\"\n", conn->host.dispname);
+ "certificate did not match \"%s\"\n", connssl->dispname);
return CURLE_PEER_FAILED_VERIFICATION;
/* Problem with SSL / TLS negotiation */
@@ -2776,7 +2715,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
default:
/* May also return codes listed in Security Framework Result Codes */
failf(data, "Unknown SSL protocol error in connection to %s:%d",
- hostname, err);
+ connssl->hostname, err);
break;
}
return CURLE_SSL_CONNECT_ERROR;
@@ -2835,7 +2774,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
}
#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
- if(conn->bits.tls_enable_alpn) {
+ if(cf->conn->bits.tls_enable_alpn) {
if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
CFArrayRef alpnArr = NULL;
CFStringRef chosenProtocol = NULL;
@@ -2847,18 +2786,18 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
#ifdef USE_HTTP2
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
- conn->alpn = CURL_HTTP_VERSION_2;
+ cf->conn->alpn = CURL_HTTP_VERSION_2;
}
else
#endif
if(chosenProtocol &&
!CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
- conn->alpn = CURL_HTTP_VERSION_1_1;
+ cf->conn->alpn = CURL_HTTP_VERSION_1_1;
}
else
infof(data, VTLS_INFOF_NO_ALPN);
- Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ?
+ Curl_multiuse_state(data, cf->conn->alpn == CURL_HTTP_VERSION_2 ?
BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
/* chosenProtocol is a reference to the string within alpnArr
@@ -2894,11 +2833,12 @@ add_cert_to_certinfo(struct Curl_easy *data,
}
static CURLcode
-collect_server_cert_single(struct Curl_easy *data,
+collect_server_cert_single(struct Curl_cfilter *cf, struct Curl_easy *data,
SecCertificateRef server_cert,
CFIndex idx)
{
CURLcode result = CURLE_OK;
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
#ifndef CURL_DISABLE_VERBOSE_STRINGS
if(data->set.verbose) {
char *certp;
@@ -2909,25 +2849,24 @@ collect_server_cert_single(struct Curl_easy *data,
}
}
#endif
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = add_cert_to_certinfo(data, server_cert, (int)idx);
return result;
}
/* This should be called during step3 of the connection at the earliest */
-static CURLcode
-collect_server_cert(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex)
+static CURLcode collect_server_cert(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
#ifndef CURL_DISABLE_VERBOSE_STRINGS
const bool show_verbose_server_cert = data->set.verbose;
#else
const bool show_verbose_server_cert = false;
#endif
- CURLcode result = data->set.ssl.certinfo ?
+ struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+ CURLcode result = ssl_config->certinfo ?
CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
CFArrayRef server_certs = NULL;
SecCertificateRef server_cert;
@@ -2937,7 +2876,7 @@ collect_server_cert(struct Curl_easy *data,
DEBUGASSERT(backend);
- if(!show_verbose_server_cert && !data->set.ssl.certinfo)
+ if(!show_verbose_server_cert && !ssl_config->certinfo)
return CURLE_OK;
if(!backend->ssl_ctx)
@@ -2951,11 +2890,11 @@ collect_server_cert(struct Curl_easy *data,
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(trust);
}
@@ -2973,11 +2912,11 @@ collect_server_cert(struct Curl_easy *data,
a null trust, so be on guard for that: */
if(err == noErr && trust) {
count = SecTrustGetCertificateCount(trust);
- if(data->set.ssl.certinfo)
+ if(ssl_config->certinfo)
result = Curl_ssl_init_certinfo(data, (int)count);
for(i = 0L ; !result && (i < count) ; i++) {
server_cert = SecTrustGetCertificateAtIndex(trust, i);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(trust);
}
@@ -2988,12 +2927,12 @@ collect_server_cert(struct Curl_easy *data,
/* Just in case SSLCopyPeerCertificates() returns null too... */
if(err == noErr && server_certs) {
count = CFArrayGetCount(server_certs);
- if(data->set.ssl.certinfo)
+ 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);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
}
@@ -3005,11 +2944,11 @@ collect_server_cert(struct Curl_easy *data,
err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
if(err == noErr) {
count = CFArrayGetCount(server_certs);
- if(data->set.ssl.certinfo)
+ 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);
- result = collect_server_cert_single(data, server_cert, i);
+ result = collect_server_cert_single(cf, data, server_cert, i);
}
CFRelease(server_certs);
}
@@ -3017,16 +2956,15 @@ collect_server_cert(struct Curl_easy *data,
return result;
}
-static CURLcode
-sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static CURLcode sectransp_connect_step3(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
/* There is no step 3!
* Well, okay, let's collect server certificates, and if verbose mode is on,
* let's print the details of the server certificates. */
- const CURLcode result = collect_server_cert(data, conn, sockindex);
+ const CURLcode result = collect_server_cert(cf, data);
if(result)
return result;
@@ -3034,19 +2972,14 @@ sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
return CURLE_OK;
}
-static Curl_recv sectransp_recv;
-static Curl_send sectransp_send;
-
static CURLcode
-sectransp_connect_common(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex,
+sectransp_connect_common(struct Curl_cfilter *cf, struct Curl_easy *data,
bool nonblocking,
bool *done)
{
CURLcode result;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- curl_socket_t sockfd = conn->sock[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sockfd = cf->conn->sock[cf->sockindex];
int what;
/* check if the connection has already been established */
@@ -3065,7 +2998,7 @@ sectransp_connect_common(struct Curl_easy *data,
return CURLE_OPERATION_TIMEDOUT;
}
- result = sectransp_connect_step1(data, conn, sockindex);
+ result = sectransp_connect_step1(cf, data);
if(result)
return result;
}
@@ -3119,7 +3052,7 @@ sectransp_connect_common(struct Curl_easy *data,
* before step2 has completed while ensuring that a client using select()
* or epoll() will always have a valid fdset to wait on.
*/
- result = sectransp_connect_step2(data, conn, sockindex);
+ result = sectransp_connect_step2(cf, data);
if(result || (nonblocking &&
(ssl_connect_2 == connssl->connecting_state ||
ssl_connect_2_reading == connssl->connecting_state ||
@@ -3130,15 +3063,13 @@ sectransp_connect_common(struct Curl_easy *data,
if(ssl_connect_3 == connssl->connecting_state) {
- result = sectransp_connect_step3(data, conn, sockindex);
+ result = sectransp_connect_step3(cf, data);
if(result)
return result;
}
if(ssl_connect_done == connssl->connecting_state) {
connssl->state = ssl_connection_complete;
- conn->recv[sockindex] = sectransp_recv;
- conn->send[sockindex] = sectransp_send;
*done = TRUE;
}
else
@@ -3150,20 +3081,20 @@ sectransp_connect_common(struct Curl_easy *data,
return CURLE_OK;
}
-static CURLcode sectransp_connect_nonblocking(struct Curl_easy *data,
- struct connectdata *conn,
- int sockindex, bool *done)
+static CURLcode sectransp_connect_nonblocking(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ bool *done)
{
- return sectransp_connect_common(data, conn, sockindex, TRUE, done);
+ return sectransp_connect_common(cf, data, TRUE, done);
}
-static CURLcode sectransp_connect(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static CURLcode sectransp_connect(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
CURLcode result;
bool done = FALSE;
- result = sectransp_connect_common(data, conn, sockindex, FALSE, &done);
+ result = sectransp_connect_common(cf, data, FALSE, &done);
if(result)
return result;
@@ -3173,10 +3104,9 @@ static CURLcode sectransp_connect(struct Curl_easy *data,
return CURLE_OK;
}
-static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
- int sockindex)
+static void sectransp_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
(void) data;
@@ -3197,19 +3127,19 @@ static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
backend->ssl_ctx = NULL;
}
- backend->ssl_sockfd = 0;
}
-static int sectransp_shutdown(struct Curl_easy *data,
- struct connectdata *conn, int sockindex)
+static int sectransp_shutdown(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
ssize_t nread;
int what;
int rc;
char buf[120];
int loop = 10; /* avoid getting stuck */
+ CURLcode result;
DEBUGASSERT(backend);
@@ -3221,11 +3151,11 @@ static int sectransp_shutdown(struct Curl_easy *data,
return 0;
#endif
- sectransp_close(data, conn, sockindex);
+ sectransp_close(cf, data);
rc = 0;
- what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], SSL_SHUTDOWN_TIMEOUT);
while(loop--) {
if(what < 0) {
@@ -3243,19 +3173,17 @@ static int sectransp_shutdown(struct Curl_easy *data,
/* Something to read, let's do it and hope that it is the close
notify alert from the server. No way to SSL_Read now, so use read(). */
- nread = read(conn->sock[sockindex], buf, sizeof(buf));
+ nread = Curl_conn_cf_recv(cf->next, data, buf, sizeof(buf), &result);
if(nread < 0) {
- char buffer[STRERROR_LEN];
- failf(data, "read: %s",
- Curl_strerror(errno, buffer, sizeof(buffer)));
+ failf(data, "read: %s", curl_easy_strerror(result));
rc = -1;
}
if(nread <= 0)
break;
- what = SOCKET_READABLE(conn->sock[sockindex], 0);
+ what = SOCKET_READABLE(cf->conn->sock[cf->sockindex], 0);
}
return rc;
@@ -3285,13 +3213,15 @@ static size_t sectransp_version(char *buffer, size_t size)
* 0 means the connection has been closed
* -1 means the connection status is unknown
*/
-static int sectransp_check_cxn(struct connectdata *conn)
+static int sectransp_check_cxn(struct Curl_cfilter *cf,
+ struct Curl_easy *data)
{
- struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
OSStatus err;
SSLSessionState state;
+ (void)data;
DEBUGASSERT(backend);
if(backend->ssl_ctx) {
@@ -3303,14 +3233,15 @@ static int sectransp_check_cxn(struct connectdata *conn)
return 0;
}
-static bool sectransp_data_pending(const struct connectdata *conn,
- int connindex)
+static bool sectransp_data_pending(struct Curl_cfilter *cf,
+ const struct Curl_easy *data)
{
- const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+ const struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
OSStatus err;
size_t buffer;
+ (void)data;
DEBUGASSERT(backend);
if(backend->ssl_ctx) { /* SSL is in use */
@@ -3362,14 +3293,13 @@ static bool sectransp_false_start(void)
return FALSE;
}
-static ssize_t sectransp_send(struct Curl_easy *data,
- int sockindex,
+static ssize_t sectransp_send(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
const void *mem,
size_t len,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
size_t processed = 0UL;
OSStatus err;
@@ -3431,15 +3361,15 @@ static ssize_t sectransp_send(struct Curl_easy *data,
return (ssize_t)processed;
}
-static ssize_t sectransp_recv(struct Curl_easy *data,
- int num,
+static ssize_t sectransp_recv(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
char *buf,
size_t buffersize,
CURLcode *curlcode)
{
- struct connectdata *conn = data->conn;
- struct ssl_connect_data *connssl = &conn->ssl[num];
+ struct ssl_connect_data *connssl = cf->ctx;
struct ssl_backend_data *backend = connssl->backend;
+ struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
size_t processed = 0UL;
OSStatus err;
@@ -3470,10 +3400,10 @@ static ssize_t sectransp_recv(struct Curl_easy *data,
/* The below is errSSLPeerAuthCompleted; it's not defined in
Leopard's headers */
case -9841:
- if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
- SSL_CONN_CONFIG(verifypeer)) {
- CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
- SSL_CONN_CONFIG(ca_info_blob),
+ if((conn_config->CAfile || conn_config->ca_info_blob) &&
+ conn_config->verifypeer) {
+ CURLcode result = verify_cert(data, conn_config->CAfile,
+ conn_config->ca_info_blob,
backend->ssl_ctx);
if(result)
return result;
@@ -3504,10 +3434,9 @@ const struct Curl_ssl Curl_ssl_sectransp = {
SSLSUPP_CAINFO_BLOB |
SSLSUPP_CERTINFO |
#ifdef SECTRANSP_PINNEDPUBKEY
- SSLSUPP_PINNEDPUBKEY,
-#else
- 0,
+ SSLSUPP_PINNEDPUBKEY |
#endif /* SECTRANSP_PINNEDPUBKEY */
+ SSLSUPP_HTTPS_PROXY,
sizeof(struct ssl_backend_data),
@@ -3521,7 +3450,7 @@ const struct Curl_ssl Curl_ssl_sectransp = {
Curl_none_cert_status_request, /* cert_status_request */
sectransp_connect, /* connect */
sectransp_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_getsock, /* getsock */
+ Curl_ssl_get_select_socks, /* getsock */
sectransp_get_internals, /* get_internals */
sectransp_close, /* close_one */
Curl_none_close_all, /* close_all */
@@ -3532,7 +3461,10 @@ const struct Curl_ssl Curl_ssl_sectransp = {
sectransp_false_start, /* false_start */
sectransp_sha256sum, /* sha256sum */
NULL, /* associate_connection */
- NULL /* disassociate_connection */
+ NULL, /* disassociate_connection */
+ NULL, /* free_multi_ssl_backend_data */
+ sectransp_recv, /* recv decrypted data */
+ sectransp_send, /* send data to encrypt */
};
#ifdef __clang__