diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-04-09 00:41:32 +0300 |
---|---|---|
committer | shadchin <shadchin@yandex-team.ru> | 2022-04-09 00:41:32 +0300 |
commit | 3bbb3d7e7e261716b0a83c1a35022e5d36f7875f (patch) | |
tree | 96955fafe753aad4486b22280aafe9050c508954 /contrib/libs/curl/lib/vtls | |
parent | beae089571d44f32f0edd323496377d3abe1bce6 (diff) | |
download | ydb-3bbb3d7e7e261716b0a83c1a35022e5d36f7875f.tar.gz |
CONTRIB-2513 Update contrib/libs/curl to 7.77.0
ref:88dc545867909534adecc7502c44301cabf1a899
Diffstat (limited to 'contrib/libs/curl/lib/vtls')
-rw-r--r-- | contrib/libs/curl/lib/vtls/bearssl.c | 17 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/gskit.c | 37 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/gtls.c | 85 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/mbedtls.c | 38 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/mesalink.c | 7 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/nss.c | 53 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/openssl.c | 361 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/rustls.c | 271 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/schannel.c | 122 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/schannel.h | 3 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/schannel_verify.c | 283 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/sectransp.c | 1741 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/vtls.c | 32 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/vtls.h | 20 | ||||
-rw-r--r-- | contrib/libs/curl/lib/vtls/wolfssl.c | 65 |
15 files changed, 1749 insertions, 1386 deletions
diff --git a/contrib/libs/curl/lib/vtls/bearssl.c b/contrib/libs/curl/lib/vtls/bearssl.c index a63056d4ef..7f729713d8 100644 --- a/contrib/libs/curl/lib/vtls/bearssl.c +++ b/contrib/libs/curl/lib/vtls/bearssl.c @@ -300,12 +300,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); -#ifndef CURL_DISABLE_PROXY - const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char *hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const bool verifyhost = SSL_CONN_CONFIG(verifyhost); CURLcode ret; @@ -390,14 +385,14 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, * protocols array in `struct ssl_backend_data`. */ -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + backend->protocols[cur++] = ALPN_H2; + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -545,8 +540,8 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, if(protocol) { infof(data, "ALPN, server accepted to use %s\n", protocol); -#ifdef USE_NGHTTP2 - if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) +#ifdef USE_HTTP2 + if(!strcmp(protocol, ALPN_H2)) conn->negnpn = CURL_HTTP_VERSION_2; else #endif diff --git a/contrib/libs/curl/lib/vtls/gskit.c b/contrib/libs/curl/lib/vtls/gskit.c index 4b69dc7e70..ffe944fb8e 100644 --- a/contrib/libs/curl/lib/vtls/gskit.c +++ b/contrib/libs/curl/lib/vtls/gskit.c @@ -101,8 +101,10 @@ struct ssl_backend_data { gsk_handle handle; int iocport; +#ifndef CURL_DISABLE_PROXY int localfd; int remotefd; +#endif }; #define BACKEND connssl->backend @@ -302,8 +304,9 @@ static CURLcode set_callback(struct Curl_easy *data, static CURLcode set_ciphers(struct Curl_easy *data, - gsk_handle h, unsigned int *protoflags) + gsk_handle h, unsigned int *protoflags) { + struct connectdata *conn = data->conn; const char *cipherlist = SSL_CONN_CONFIG(cipher_list); const char *clp; const struct gskit_cipher *ctp; @@ -515,6 +518,7 @@ static void close_async_handshake(struct ssl_connect_data *connssl) static int pipe_ssloverssl(struct connectdata *conn, int sockindex, int directions) { +#ifndef CURL_DISABLE_PROXY struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex]; fd_set fds_read; @@ -583,6 +587,9 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex, } return ret; /* OK */ +#else + return 0; +#endif } @@ -596,6 +603,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data, while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0) ; BACKEND->handle = (gsk_handle) NULL; +#ifndef CURL_DISABLE_PROXY if(BACKEND->localfd >= 0) { close(BACKEND->localfd); BACKEND->localfd = -1; @@ -604,6 +612,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data, close(BACKEND->remotefd); BACKEND->remotefd = -1; } +#endif } if(BACKEND->iocport >= 0) close_async_handshake(connssl); @@ -665,6 +674,7 @@ static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf, static CURLcode set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data) { + struct connectdata *conn = data->conn; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); long i = ssl_version; @@ -705,20 +715,23 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); const long int ssl_version = SSL_CONN_CONFIG(version); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: - conn->host.name; + const char * const hostname = SSL_HOST_NAME(); const char *sni; unsigned int protoflags = 0; Qso_OverlappedIO_t commarea; +#ifndef CURL_DISABLE_PROXY int sockpair[2]; static const int sobufsize = CURL_MAX_WRITE_SIZE; +#endif /* Create SSL environment, start (preferably asynchronous) handshake. */ BACKEND->handle = (gsk_handle) NULL; BACKEND->iocport = -1; +#ifndef CURL_DISABLE_PROXY BACKEND->localfd = -1; BACKEND->remotefd = -1; +#endif /* GSKit supports two ways of specifying an SSL context: either by * application identifier (that should have been defined at the system @@ -757,6 +770,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, if(result) return result; +#ifndef CURL_DISABLE_PROXY /* Establish a pipelining socket pair for SSL over SSL. */ if(conn->proxy_ssl[sockindex].use) { if(Curl_socketpair(0, 0, 0, sockpair)) @@ -774,6 +788,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, curlx_nonblock(BACKEND->localfd, TRUE); curlx_nonblock(BACKEND->remotefd, TRUE); } +#endif /* Determine which SSL/TLS version should be enabled. */ sni = hostname; @@ -826,8 +841,13 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, if(!result) result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1); if(!result) +#ifndef CURL_DISABLE_PROXY result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0? BACKEND->localfd: conn->sock[sockindex]); +#else + result = set_numeric(data, BACKEND->handle, GSK_FD, + conn->sock[sockindex]); +#endif if(!result) result = set_ciphers(data, BACKEND->handle, &protoflags); if(!protoflags) { @@ -896,10 +916,12 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, else if(errno != ENOBUFS) result = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0); +#ifndef CURL_DISABLE_PROXY else if(conn->proxy_ssl[sockindex].use) { /* Cannot pipeline while handshaking synchronously. */ result = CURLE_SSL_CONNECT_ERROR; } +#endif else { /* No more completion port available. Use synchronous IO. */ result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle), @@ -1035,8 +1057,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data, } /* Check pinned public key. */ - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(!result && ptr) { curl_X509certificate x509; curl_asn1Element *p; @@ -1158,7 +1179,9 @@ static void gskit_close(struct Curl_easy *data, struct connectdata *conn, int sockindex) { close_one(&conn->ssl[sockindex], data, conn, sockindex); +#ifndef CURL_DISABLE_PROXY close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex); +#endif } @@ -1281,7 +1304,9 @@ const struct Curl_ssl Curl_ssl_gskit = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_GSKIT */ diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c index 94c3f17c63..fb2d522c5f 100644 --- a/contrib/libs/curl/lib/vtls/gtls.c +++ b/contrib/libs/curl/lib/vtls/gtls.c @@ -263,7 +263,7 @@ static CURLcode handshake(struct Curl_easy *data, strerr = gnutls_alert_get_name(alert); } - if(strerr == NULL) + if(!strerr) strerr = gnutls_strerror(rc); infof(data, "gnutls_handshake() warning: %s\n", strerr); @@ -277,7 +277,7 @@ static CURLcode handshake(struct Curl_easy *data, strerr = gnutls_alert_get_name(alert); } - if(strerr == NULL) + if(!strerr) strerr = gnutls_strerror(rc); failf(data, "gnutls_handshake() failed: %s", strerr); @@ -308,15 +308,29 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type) #define GNUTLS_SRP "+SRP" static CURLcode -set_ssl_version_min_max(const char **prioritylist, struct Curl_easy *data) +set_ssl_version_min_max(struct Curl_easy *data, + const char **prioritylist, + const char *tls13support) { struct connectdata *conn = data->conn; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); - if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) { + if((ssl_version == CURL_SSLVERSION_DEFAULT) || + (ssl_version == CURL_SSLVERSION_TLSv1)) + ssl_version = CURL_SSLVERSION_TLSv1_0; + if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; + if(!tls13support) { + /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a + prioritylist involving that since it will make GnuTLS return an en + error back at us */ + if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) || + (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + } } + switch(ssl_version | ssl_version_max) { case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" @@ -395,6 +409,7 @@ gtls_connect_step1(struct Curl_easy *data, const char *err = NULL; const char * const hostname = SSL_HOST_NAME(); long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); + const char *tls13support; if(connssl->state == ssl_connection_complete) /* to make us tolerant against being called more than once for the @@ -542,36 +557,34 @@ gtls_connect_step1(struct Curl_easy *data, if(rc != GNUTLS_E_SUCCESS) return CURLE_SSL_CONNECT_ERROR; + /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ + tls13support = gnutls_check_version("3.6.5"); + /* Ensure +SRP comes at the *end* of all relevant strings so that it can be * removed if a run-time error indicates that SRP is not supported by this * GnuTLS version */ switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_SSLv3: - prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0"; - break; + case CURL_SSLVERSION_TLSv1_3: + if(!tls13support) { + failf(data, "This GnuTLS installation does not support TLS 1.3"); + return CURLE_SSL_CONNECT_ERROR; + } + /* FALLTHROUGH */ case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0" -#ifdef HAS_TLS13 - ":+VERS-TLS1.3" -#endif - ; - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(&prioritylist, data); - if(result != CURLE_OK) - return result; - break; - } + case CURL_SSLVERSION_TLSv1_2: { + CURLcode result = set_ssl_version_min_max(data, &prioritylist, + tls13support); + if(result) + return result; + break; + } case CURL_SSLVERSION_SSLv2: - failf(data, "GnuTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + failf(data, "GnuTLS does not support SSLv2 or SSLv3"); return CURLE_SSL_CONNECT_ERROR; } @@ -586,7 +599,6 @@ gtls_connect_step1(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; strcpy(prioritysrp, prioritylist); strcpy(prioritysrp + len, ":" GNUTLS_SRP); - rc = gnutls_priority_set_direct(session, prioritysrp, &err); free(prioritysrp); @@ -611,16 +623,16 @@ gtls_connect_step1(struct Curl_easy *data, int cur = 0; gnutls_datum_t protocols[2]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; - protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur].data = (unsigned char *)ALPN_H2; + protocols[cur].size = ALPN_H2_LENGTH; cur++; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + infof(data, "ALPN, offering %.*s\n", ALPN_H2_LENGTH, ALPN_H2); } #endif @@ -1178,8 +1190,7 @@ gtls_connect_step3(struct Curl_easy *data, infof(data, "\t server certificate activation date OK\n"); } - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(ptr) { result = pkp_pin_peer_pubkey(data, x509_cert, ptr); if(result != CURLE_OK) { @@ -1243,10 +1254,10 @@ gtls_connect_step3(struct Curl_easy *data, infof(data, "ALPN, server accepted to use %.*s\n", proto.size, proto.data); -#ifdef USE_NGHTTP2 - if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, - NGHTTP2_PROTO_VERSION_ID_LEN)) { +#ifdef USE_HTTP2 + if(proto.size == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, proto.data, + ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1645,7 +1656,9 @@ const struct Curl_ssl Curl_ssl_gnutls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - gtls_sha256sum /* sha256sum */ + gtls_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_GNUTLS */ diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c index b7df301ef0..4f9a6d2683 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls.c +++ b/contrib/libs/curl/lib/vtls/mbedtls.c @@ -251,22 +251,16 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, const char * const ssl_capath = SSL_CONN_CONFIG(CApath); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); int ret = -1; char errorbuf[128]; errorbuf[0] = 0; - /* mbedTLS only supports SSLv3 and TLSv1 */ - if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { - failf(data, "mbedTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; + if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) || + (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) { + failf(data, "Not supported SSL version"); + return CURLE_NOT_BUILT_IN; } #ifdef THREADING_SUPPORT @@ -414,13 +408,6 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, MBEDTLS_SSL_MINOR_VERSION_1); infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); break; - case CURL_SSLVERSION_SSLv3: - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - infof(data, "mbedTLS: Set SSL version to SSLv3\n"); - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: @@ -549,14 +536,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; const mbedtls_x509_crt *peercert; -#ifndef CURL_DISABLE_PROXY - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif + const char * const pinnedpubkey = SSL_PINNED_PUB_KEY(); conn->recv[sockindex] = mbed_recv; conn->send[sockindex] = mbed_send; @@ -1113,7 +1093,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - mbedtls_sha256sum /* sha256sum */ + mbedtls_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_MBEDTLS */ diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c index 5df5253b1e..80d3d01724 100644 --- a/contrib/libs/curl/lib/vtls/mesalink.c +++ b/contrib/libs/curl/lib/vtls/mesalink.c @@ -98,8 +98,7 @@ mesalink_connect_step1(struct Curl_easy *data, #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif - const char *const hostname = - SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + const char * const hostname = SSL_HOST_NAME(); size_t hostname_len = strlen(hostname); SSL_METHOD *req_method = NULL; @@ -667,7 +666,9 @@ const struct Curl_ssl Curl_ssl_mesalink = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c index dc252e8c93..b5d23bffe0 100644 --- a/contrib/libs/curl/lib/vtls/nss.c +++ b/contrib/libs/curl/lib/vtls/nss.c @@ -139,9 +139,15 @@ static const struct cipher_s cipherlist[] = { {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, + {"dhe_rsa_3des_sha", SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA}, + {"dhe_dss_3des_sha", SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA}, + {"dhe_rsa_des_sha", SSL_DHE_RSA_WITH_DES_CBC_SHA}, + {"dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA}, /* TLS 1.0: Exportable 56-bit Cipher Suites. */ {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, + /* Ephemeral DH with RC4 bulk encryption */ + {"dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA}, /* AES ciphers. */ {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, @@ -219,6 +225,25 @@ static const struct cipher_s cipherlist[] = { {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, #endif +#ifdef TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 + /* AES CBC cipher suites in RFC 5246. Introduced in NSS release 3.20 */ + {"dhe_dss_aes_128_sha_256", TLS_DHE_DSS_WITH_AES_128_CBC_SHA256}, + {"dhe_dss_aes_256_sha_256", TLS_DHE_DSS_WITH_AES_256_CBC_SHA256}, +#endif +#ifdef TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + /* Camellia cipher suites in RFC 4132/5932. + Introduced in NSS release 3.12 */ + {"dhe_rsa_camellia_128_sha", TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA}, + {"dhe_dss_camellia_128_sha", TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA}, + {"dhe_rsa_camellia_256_sha", TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA}, + {"dhe_dss_camellia_256_sha", TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA}, + {"rsa_camellia_128_sha", TLS_RSA_WITH_CAMELLIA_128_CBC_SHA}, + {"rsa_camellia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA}, +#endif +#ifdef TLS_RSA_WITH_SEED_CBC_SHA + /* SEED cipher suite in RFC 4162. Introduced in NSS release 3.12.3 */ + {"rsa_seed_sha", TLS_RSA_WITH_SEED_CBC_SHA}, +#endif }; #if defined(WIN32) @@ -312,7 +337,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model, while((*cipher) && (ISSPACE(*cipher))) ++cipher; - cipher_list = strchr(cipher, ','); + cipher_list = strpbrk(cipher, ":, "); if(cipher_list) { *cipher_list++ = '\0'; } @@ -380,7 +405,7 @@ static int is_file(const char *filename) { struct_stat st; - if(filename == NULL) + if(!filename) return 0; if(stat(filename, &st) == 0) @@ -845,8 +870,8 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) } #ifdef USE_NGHTTP2 - if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) { + if(buflen == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1423,7 +1448,7 @@ static CURLcode nss_setup(struct Curl_easy *data) static int nss_init(void) { /* curl_global_init() is not thread-safe so this test is ok */ - if(nss_initlock == NULL) { + if(!nss_initlock) { PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); nss_initlock = PR_NewLock(); nss_crllock = PR_NewLock(); @@ -1699,8 +1724,7 @@ static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version) return CURLE_OK; case CURL_SSLVERSION_SSLv3: - *nssver = SSL_LIBRARY_VERSION_3_0; - return CURLE_OK; + return CURLE_NOT_BUILT_IN; case CURL_SSLVERSION_TLSv1_0: *nssver = SSL_LIBRARY_VERSION_TLS_1_0; @@ -1806,7 +1830,7 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl, struct Curl_easy *data, bool blocking) { - static PRSocketOptionData sock_opt; + PRSocketOptionData sock_opt; struct ssl_backend_data *backend = connssl->backend; sock_opt.option = PR_SockOpt_Nonblocking; sock_opt.value.non_blocking = !blocking; @@ -2079,16 +2103,15 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, int cur = 0; unsigned char protocols[128]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur++] = ALPN_H2_LENGTH; + memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; } #endif protocols[cur++] = ALPN_HTTP_1_1_LENGTH; @@ -2442,7 +2465,9 @@ const struct Curl_ssl Curl_ssl_nss = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ nss_false_start, /* false_start */ - nss_sha256sum /* sha256sum */ + nss_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_NSS */ diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c index 6583300b3c..ebd7abc3b4 100644 --- a/contrib/libs/curl/lib/vtls/openssl.c +++ b/contrib/libs/curl/lib/vtls/openssl.c @@ -122,12 +122,6 @@ #define HAVE_ERR_REMOVE_THREAD_STATE 1 #endif -#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */ -#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */ -#define OPENSSL_NO_SSL2 -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ !(defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -246,6 +240,10 @@ struct ssl_backend_data { #endif }; +static void ossl_associate_connection(struct Curl_easy *data, + struct connectdata *conn, + int sockindex); + /* * Number of bytes to read from the random number seed file. This must be * a finite value (because some entropy "files" like /dev/urandom have @@ -625,7 +623,7 @@ SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob, goto end; } - if(x == NULL) { + if(!x) { ret = 0; goto end; } @@ -656,7 +654,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob, ret = 0; goto end; } - if(pkey == NULL) { + if(!pkey) { ret = 0; goto end; } @@ -669,7 +667,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob, static int SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, - const char *key_passwd) + const char *key_passwd) { /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \ @@ -687,7 +685,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, (void *)key_passwd); - if(x == NULL) { + if(!x) { ret = 0; goto end; } @@ -731,7 +729,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, return ret; #else (void)ctx; /* unused */ - (void)in; /* unused */ + (void)blob; /* unused */ (void)key_passwd; /* unused */ return 0; #endif @@ -875,7 +873,7 @@ int cert_stuff(struct Curl_easy *data, STACK_OF(X509) *ca = NULL; if(cert_blob) { cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); - if(cert_bio == NULL) { + if(!cert_bio) { failf(data, "BIO_new_mem_buf NULL, " OSSL_PACKAGE " error %s", @@ -886,7 +884,7 @@ int cert_stuff(struct Curl_easy *data, } else { cert_bio = BIO_new(BIO_s_file()); - if(cert_bio == NULL) { + if(!cert_bio) { failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", @@ -2262,12 +2260,10 @@ select_next_proto_cb(SSL *ssl, struct connectdata *conn = data->conn; (void)ssl; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 && - !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - infof(data, "NPN, negotiated HTTP2 (%s)\n", - NGHTTP2_PROTO_VERSION_ID); + !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) { + infof(data, "NPN, negotiated HTTP2 (%s)\n", ALPN_H2); conn->negnpn = CURL_HTTP_VERSION_2; return SSL_TLSEXT_ERR_OK; } @@ -2518,6 +2514,67 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) return res; } +static CURLcode load_cacert_from_memory(SSL_CTX *ctx, + const struct curl_blob *ca_info_blob) +{ + /* these need freed at the end */ + BIO *cbio = NULL; + STACK_OF(X509_INFO) *inf = NULL; + + /* everything else is just a reference */ + int i, count = 0; + X509_STORE *cts = NULL; + X509_INFO *itmp = NULL; + + if(ca_info_blob->len > (size_t)INT_MAX) + return CURLE_SSL_CACERT_BADFILE; + + cts = SSL_CTX_get_cert_store(ctx); + if(!cts) + return CURLE_OUT_OF_MEMORY; + + cbio = BIO_new_mem_buf(ca_info_blob->data, (int)ca_info_blob->len); + if(!cbio) + return CURLE_OUT_OF_MEMORY; + + inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL); + if(!inf) { + BIO_free(cbio); + return CURLE_SSL_CACERT_BADFILE; + } + + /* add each entry from PEM file to x509_store */ + for(i = 0; i < (int)sk_X509_INFO_num(inf); ++i) { + itmp = sk_X509_INFO_value(inf, i); + if(itmp->x509) { + if(X509_STORE_add_cert(cts, itmp->x509)) { + ++count; + } + else { + /* set count to 0 to return an error */ + count = 0; + break; + } + } + if(itmp->crl) { + if(X509_STORE_add_crl(cts, itmp->crl)) { + ++count; + } + else { + /* set count to 0 to return an error */ + count = 0; + break; + } + } + } + + sk_X509_INFO_pop_free(inf, X509_INFO_free); + BIO_free(cbio); + + /* if we didn't end up importing anything, treat that as an error */ + return (count > 0 ? CURLE_OK : CURLE_SSL_CACERT_BADFILE); +} + static CURLcode ossl_connect_step1(struct Curl_easy *data, struct connectdata *conn, int sockindex) { @@ -2528,6 +2585,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ctx_option_t ctx_options = 0; + void *ssl_sessionid = NULL; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME bool sni; @@ -2545,8 +2603,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); + const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob); const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char * const ssl_cafile = + /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ + (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile)); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); @@ -2581,31 +2642,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, use_sni(TRUE); break; case CURL_SSLVERSION_SSLv2: -#ifdef OPENSSL_NO_SSL2 - failf(data, OSSL_PACKAGE " was built without SSLv2 support"); + failf(data, "No SSLv2 support"); return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_OPENSSL_SRP - if(ssl_authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv2_client_method(); - use_sni(FALSE); - break; -#endif case CURL_SSLVERSION_SSLv3: -#ifdef OPENSSL_NO_SSL3_METHOD - failf(data, OSSL_PACKAGE " was built without SSLv3 support"); + failf(data, "No SSLv3 support"); return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_OPENSSL_SRP - if(ssl_authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv3_client_method(); - use_sni(FALSE); - break; -#endif default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -2693,41 +2734,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif switch(ssl_version) { - /* "--sslv2" option means SSLv2 only, disable all others */ case CURL_SSLVERSION_SSLv2: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; - - /* "--sslv3" option means SSLv3 only, disable all others */ case CURL_SSLVERSION_SSLv3: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; + return CURLE_NOT_BUILT_IN; /* "--tlsv<x.y>" options mean TLS >= version <x.y> */ case CURL_SSLVERSION_DEFAULT: @@ -2768,18 +2777,17 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, int cur = 0; unsigned char protocols[128]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur++] = ALPN_H2_LENGTH; - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -2885,8 +2893,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) && (SSL_SET_OPTION(native_ca_store))) { X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx); - HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, - TEXT("ROOT")); + HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT")); if(hStore) { PCCERT_CONTEXT pContext = NULL; @@ -3023,6 +3030,19 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, } #endif + if(ca_info_blob) { + result = load_cacert_from_memory(backend->ctx, ca_info_blob); + if(result) { + if(result == CURLE_OUT_OF_MEMORY || + (verifypeer && !imported_native_ca)) { + failf(data, "error importing CA certificate blob"); + return result; + } + /* Only warning if no certificate verification is required. */ + infof(data, "error importing CA certificate blob, continuing anyway\n"); + } + } + #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ { @@ -3079,7 +3099,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif #ifdef CURL_CA_FALLBACK - if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) { + if(verifypeer && + !ca_info_blob && !ssl_cafile && !ssl_capath && !imported_native_ca) { /* verifying the peer without any CA certificates won't work so use openssl's built in default as fallback */ SSL_CTX_set_default_verify_paths(backend->ctx); @@ -3209,46 +3230,23 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, } #endif - /* Check if there's a cached ID we can/should use here! */ - if(SSL_SET_OPTION(primary.sessionid)) { - void *ssl_sessionid = NULL; - int data_idx = ossl_get_ssl_data_index(); - int connectdata_idx = ossl_get_ssl_conn_index(); - int sockindex_idx = ossl_get_ssl_sockindex_index(); - int proxy_idx = ossl_get_proxy_index(); + ossl_associate_connection(data, conn, sockindex); - if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && - proxy_idx >= 0) { - /* Store the data needed for the "new session" callback. - * The sockindex is stored as a pointer to an array element. */ - SSL_set_ex_data(backend->handle, data_idx, data); - SSL_set_ex_data(backend->handle, connectdata_idx, conn); - SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); -#ifndef CURL_DISABLE_PROXY - SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: - NULL); -#else - SSL_set_ex_data(backend->handle, proxy_idx, NULL); -#endif - - } - - Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, - &ssl_sessionid, NULL, sockindex)) { - /* we got a session id, use it! */ - if(!SSL_set_session(backend->handle, ssl_sessionid)) { - Curl_ssl_sessionid_unlock(data); - failf(data, "SSL: SSL_set_session failed: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); + Curl_ssl_sessionid_lock(data); + if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, + &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(backend->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(data); + failf(data, "SSL: SSL_set_session failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; } - Curl_ssl_sessionid_unlock(data); + /* Informational message */ + infof(data, "SSL re-using session ID\n"); } + Curl_ssl_sessionid_unlock(data); #ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { @@ -3353,6 +3351,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, error_buffer */ strcpy(error_buffer, "SSL certificate verification failed"); } +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) + /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on + OpenSSL version above v1.1.1, not Libre SSL nor BoringSSL */ + else if((lib == ERR_LIB_SSL) && + (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) { + /* If client certificate is required, communicate the + error to client */ + result = CURLE_SSL_CLIENTCERT; + ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); + } +#endif else { result = CURLE_SSL_CONNECT_ERROR; ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); @@ -3366,11 +3377,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, */ if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { const char * const hostname = SSL_HOST_NAME(); -#ifndef CURL_DISABLE_PROXY - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const long int port = conn->remote_port; -#endif + const long int port = SSL_HOST_PORT(); char extramsg[80]=""; int sockerr = SOCKERRNO; if(sockerr && detail == SSL_ERROR_SYSCALL) @@ -3404,12 +3411,12 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, const unsigned char *neg_protocol; unsigned int len; SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); - if(len != 0) { + if(len) { infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); -#ifdef USE_NGHTTP2 - if(len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) { +#ifdef USE_HTTP2 + if(len == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, neg_protocol, len)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -3896,7 +3903,7 @@ static CURLcode servercert(struct Curl_easy *data, (int)SSL_SET_OPTION(issuercert_blob)->len); else { fp = BIO_new(BIO_s_file()); - if(fp == NULL) { + if(!fp) { failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", @@ -3983,8 +3990,7 @@ static CURLcode servercert(struct Curl_easy *data, /* when not strict, we don't bother about the verify cert problems */ result = CURLE_OK; - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(!result && ptr) { result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); if(result) @@ -4474,10 +4480,95 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl, (void *)backend->ctx : (void *)backend->handle; } +static void ossl_associate_connection(struct Curl_easy *data, + struct connectdata *conn, + int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + + /* If we don't have SSL context, do nothing. */ + if(!backend->handle) + return; + + if(SSL_SET_OPTION(primary.sessionid)) { + int data_idx = ossl_get_ssl_data_index(); + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + int proxy_idx = ossl_get_proxy_index(); + + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && + proxy_idx >= 0) { + /* Store the data needed for the "new session" callback. + * The sockindex is stored as a pointer to an array element. */ + SSL_set_ex_data(backend->handle, data_idx, data); + SSL_set_ex_data(backend->handle, connectdata_idx, conn); + SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); +#ifndef CURL_DISABLE_PROXY + SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: + NULL); +#else + SSL_set_ex_data(backend->handle, proxy_idx, NULL); +#endif + } + } +} + +/* + * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after + * the handshake. If the transfer that sets up the callback gets killed before + * this callback arrives, we must make sure to properly clear the data to + * avoid UAF problems. A future optimization could be to instead store another + * transfer that might still be using the same connection. + */ + +static void ossl_disassociate_connection(struct Curl_easy *data, + int sockindex) +{ + struct connectdata *conn = data->conn; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + + /* If we don't have SSL context, do nothing. */ + if(!backend->handle) + return; + + if(SSL_SET_OPTION(primary.sessionid)) { + bool isproxy = FALSE; + bool incache; + void *old_ssl_sessionid = NULL; + int data_idx = ossl_get_ssl_data_index(); + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + int proxy_idx = ossl_get_proxy_index(); + + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && + proxy_idx >= 0) { + /* Invalidate the session cache entry, if any */ + isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE; + + /* Disable references to data in "new session" callback to avoid + * accessing a stale pointer. */ + SSL_set_ex_data(backend->handle, data_idx, NULL); + SSL_set_ex_data(backend->handle, connectdata_idx, NULL); + SSL_set_ex_data(backend->handle, sockindex_idx, NULL); + SSL_set_ex_data(backend->handle, proxy_idx, NULL); + } + + Curl_ssl_sessionid_lock(data); + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, + &old_ssl_sessionid, NULL, sockindex)); + if(incache) + Curl_ssl_delsessionid(data, old_ssl_sessionid); + Curl_ssl_sessionid_unlock(data); + } +} + const struct Curl_ssl Curl_ssl_openssl = { { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ SSLSUPP_CA_PATH | + SSLSUPP_CAINFO_BLOB | SSLSUPP_CERTINFO | SSLSUPP_PINNEDPUBKEY | SSLSUPP_SSL_CTX | @@ -4508,10 +4599,12 @@ const struct Curl_ssl Curl_ssl_openssl = { ossl_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) - ossl_sha256sum /* sha256sum */ + ossl_sha256sum, /* sha256sum */ #else - NULL /* sha256sum */ + NULL, /* sha256sum */ #endif + ossl_associate_connection, /* associate_connection */ + ossl_disassociate_connection /* disassociate_connection */ }; #endif /* USE_OPENSSL */ diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c index 944a80e706..e9b75a5dc5 100644 --- a/contrib/libs/curl/lib/vtls/rustls.c +++ b/contrib/libs/curl/lib/vtls/rustls.c @@ -37,16 +37,11 @@ #include "multiif.h" -/* Per https://www.bearssl.org/api1.html, max TLS record size plus max - per-record overhead. */ -#define TLSBUF_SIZE (16384 + 325) - struct ssl_backend_data { const struct rustls_client_config *config; - struct rustls_client_session *session; + struct rustls_connection *conn; bool data_pending; - uint8_t *tlsbuf; }; /* For a given rustls_result error code, return the best-matching CURLcode. */ @@ -82,6 +77,28 @@ cr_connect(struct Curl_easy *data UNUSED_PARAM, return CURLE_SSL_CONNECT_ERROR; } +static int +read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) +{ + ssize_t n = sread(*(int *)userdata, buf, len); + if(n < 0) { + return SOCKERRNO; + } + *out_n = n; + return 0; +} + +static int +write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) +{ + ssize_t n = swrite(*(int *)userdata, buf, len); + if(n < 0) { + return SOCKERRNO; + } + *out_n = n; + return 0; +} + /* * On each run: * - Read a chunk of bytes from the socket into rustls' TLS input buffer. @@ -101,65 +118,44 @@ cr_recv(struct Curl_easy *data, int sockindex, struct connectdata *conn = data->conn; struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *const session = backend->session; - curl_socket_t sockfd = conn->sock[sockindex]; + struct rustls_connection *const rconn = backend->conn; size_t n = 0; - ssize_t tls_bytes_read = 0; - size_t tls_bytes_processed = 0; + size_t tls_bytes_read = 0; size_t plain_bytes_copied = 0; rustls_result rresult = 0; char errorbuf[255]; + rustls_io_result io_error; - tls_bytes_read = sread(sockfd, backend->tlsbuf, TLSBUF_SIZE); - if(tls_bytes_read == 0) { - failf(data, "connection closed without TLS close_notify alert"); + io_error = rustls_connection_read_tls(rconn, read_cb, + &conn->sock[sockindex], &tls_bytes_read); + if(io_error == EAGAIN || io_error == EWOULDBLOCK) { + infof(data, "sread: EAGAIN or EWOULDBLOCK\n"); + } + else if(io_error) { + failf(data, "reading from socket: %s", strerror(io_error)); *err = CURLE_READ_ERROR; return -1; } - else if(tls_bytes_read < 0) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - infof(data, "sread: EAGAIN or EWOULDBLOCK\n"); - *err = CURLE_AGAIN; - return -1; - } - failf(data, "reading from socket: %s", strerror(SOCKERRNO)); + else if(tls_bytes_read == 0) { + failf(data, "connection closed without TLS close_notify alert"); *err = CURLE_READ_ERROR; return -1; } - /* - * Now pull those bytes from the buffer into ClientSession. - */ - DEBUGASSERT(tls_bytes_read > 0); - while(tls_bytes_processed < (size_t)tls_bytes_read) { - rresult = rustls_client_session_read_tls(session, - backend->tlsbuf + tls_bytes_processed, - tls_bytes_read - tls_bytes_processed, - &n); - if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_read_tls"); - *err = CURLE_READ_ERROR; - return -1; - } - else if(n == 0) { - infof(data, "EOF from rustls_client_session_read_tls\n"); - break; - } + infof(data, "cr_recv read %ld bytes from the network\n", tls_bytes_read); - rresult = rustls_client_session_process_new_packets(session); - if(rresult != RUSTLS_RESULT_OK) { - rustls_error(rresult, errorbuf, sizeof(errorbuf), &n); - failf(data, "%.*s", n, errorbuf); - *err = map_error(rresult); - return -1; - } - - tls_bytes_processed += n; - backend->data_pending = TRUE; + rresult = rustls_connection_process_new_packets(rconn); + if(rresult != RUSTLS_RESULT_OK) { + rustls_error(rresult, errorbuf, sizeof(errorbuf), &n); + failf(data, "%.*s", n, errorbuf); + *err = map_error(rresult); + return -1; } + backend->data_pending = TRUE; + while(plain_bytes_copied < plainlen) { - rresult = rustls_client_session_read(session, + rresult = rustls_connection_read(rconn, (uint8_t *)plainbuf + plain_bytes_copied, plainlen - plain_bytes_copied, &n); @@ -168,20 +164,21 @@ cr_recv(struct Curl_easy *data, int sockindex, return 0; } else if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_read"); + failf(data, "error in rustls_connection_read"); *err = CURLE_READ_ERROR; return -1; } else if(n == 0) { - /* rustls returns 0 from client_session_read to mean "all currently + /* rustls returns 0 from connection_read to mean "all currently available data has been read." If we bring in more ciphertext with read_tls, more plaintext will become available. So don't tell curl this is an EOF. Instead, say "come back later." */ - infof(data, "EOF from rustls_client_session_read\n"); + infof(data, "cr_recv got 0 bytes of plaintext\n"); backend->data_pending = FALSE; break; } else { + infof(data, "cr_recv copied out %ld bytes of plaintext\n", n); plain_bytes_copied += n; } } @@ -214,68 +211,50 @@ cr_send(struct Curl_easy *data, int sockindex, struct connectdata *conn = data->conn; struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *const session = backend->session; - curl_socket_t sockfd = conn->sock[sockindex]; - ssize_t n = 0; + struct rustls_connection *const rconn = backend->conn; size_t plainwritten = 0; - size_t tlslen = 0; size_t tlswritten = 0; + size_t tlswritten_total = 0; rustls_result rresult; + rustls_io_result io_error; + + infof(data, "cr_send %ld bytes of plaintext\n", plainlen); if(plainlen > 0) { - rresult = rustls_client_session_write(session, - plainbuf, plainlen, &plainwritten); + rresult = rustls_connection_write(rconn, plainbuf, plainlen, + &plainwritten); if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_write"); + failf(data, "error in rustls_connection_write"); *err = CURLE_WRITE_ERROR; return -1; } else if(plainwritten == 0) { - failf(data, "EOF in rustls_client_session_write"); + failf(data, "EOF in rustls_connection_write"); *err = CURLE_WRITE_ERROR; return -1; } } - while(rustls_client_session_wants_write(session)) { - rresult = rustls_client_session_write_tls( - session, backend->tlsbuf, TLSBUF_SIZE, &tlslen); - if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_write_tls"); - *err = CURLE_WRITE_ERROR; + while(rustls_connection_wants_write(rconn)) { + io_error = rustls_connection_write_tls(rconn, write_cb, + &conn->sock[sockindex], &tlswritten); + if(io_error == EAGAIN || io_error == EWOULDBLOCK) { + infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten_total); + *err = CURLE_AGAIN; return -1; } - else if(tlslen == 0) { - failf(data, "EOF in rustls_client_session_write_tls"); + else if(io_error) { + failf(data, "writing to socket: %s", strerror(io_error)); *err = CURLE_WRITE_ERROR; return -1; } - - tlswritten = 0; - - while(tlswritten < tlslen) { - n = swrite(sockfd, backend->tlsbuf + tlswritten, tlslen - tlswritten); - if(n < 0) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - /* Since recv is called from poll, there should be room to - write at least some bytes before hitting EAGAIN. */ - infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten); - DEBUGASSERT(tlswritten > 0); - break; - } - failf(data, "error in swrite"); - *err = CURLE_WRITE_ERROR; - return -1; - } - if(n == 0) { - failf(data, "EOF in swrite"); - *err = CURLE_WRITE_ERROR; - return -1; - } - tlswritten += n; + if(tlswritten == 0) { + failf(data, "EOF in swrite"); + *err = CURLE_WRITE_ERROR; + return -1; } - - DEBUGASSERT(tlswritten <= tlslen); + infof(data, "cr_send wrote %ld bytes to network\n", tlswritten); + tlswritten_total += tlswritten; } return plainwritten; @@ -310,7 +289,7 @@ static CURLcode cr_init_backend(struct Curl_easy *data, struct connectdata *conn, struct ssl_backend_data *const backend) { - struct rustls_client_session *session = backend->session; + struct rustls_connection *rconn = backend->conn; struct rustls_client_config_builder *config_builder = NULL; const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); @@ -318,19 +297,26 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, char errorbuf[256]; size_t errorlen; int result; - - backend->tlsbuf = calloc(TLSBUF_SIZE, 1); - if(backend->tlsbuf == NULL) { - return CURLE_OUT_OF_MEMORY; - } + rustls_slice_bytes alpn[2] = { + { (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH }, + { (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH }, + }; config_builder = rustls_client_config_builder_new(); +#ifdef USE_HTTP2 + infof(data, "offering ALPN for HTTP/1.1 and HTTP/2\n"); + rustls_client_config_builder_set_protocols(config_builder, alpn, 2); +#else + infof(data, "offering ALPN for HTTP/1.1 only\n"); + rustls_client_config_builder_set_protocols(config_builder, alpn, 1); +#endif if(!verifypeer) { rustls_client_config_builder_dangerous_set_certificate_verifier( - config_builder, cr_verify_none, NULL); + config_builder, cr_verify_none); /* rustls doesn't support IP addresses (as of 0.19.0), and will reject - * sessions created with an IP address, even when certificate verification - * is turned off. Set a placeholder hostname and disable SNI. */ + * connections created with an IP address, even when certificate + * verification is turned off. Set a placeholder hostname and disable + * SNI. */ if(cr_hostname_is_ip(hostname)) { rustls_client_config_builder_set_enable_sni(config_builder, false); hostname = "example.invalid"; @@ -357,18 +343,51 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, } backend->config = rustls_client_config_builder_build(config_builder); - DEBUGASSERT(session == NULL); - result = rustls_client_session_new( - backend->config, hostname, &session); + DEBUGASSERT(rconn == NULL); + result = rustls_client_connection_new(backend->config, hostname, &rconn); if(result != RUSTLS_RESULT_OK) { rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen); - failf(data, "failed to create client session: %.*s", errorlen, errorbuf); + failf(data, "rustls_client_connection_new: %.*s", errorlen, errorbuf); return CURLE_COULDNT_CONNECT; } - backend->session = session; + rustls_connection_set_userdata(rconn, backend); + backend->conn = rconn; return CURLE_OK; } +static void +cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn, + const struct rustls_connection *rconn) +{ + const uint8_t *protocol = NULL; + size_t len = 0; + + rustls_connection_get_alpn_protocol(rconn, &protocol, &len); + if(NULL == protocol) { + infof(data, "ALPN, server did not agree to a protocol\n"); + return; + } + +#ifdef USE_HTTP2 + if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) { + infof(data, "ALPN, negotiated h2\n"); + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(len == ALPN_HTTP_1_1_LENGTH && + 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) { + infof(data, "ALPN, negotiated http/1.1\n"); + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + else { + infof(data, "ALPN, negotiated an unrecognized protocol\n"); + } + + Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); +} + static CURLcode cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, int sockindex, bool *done) @@ -376,7 +395,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *session = NULL; + struct rustls_connection *rconn = NULL; CURLcode tmperr = CURLE_OK; int result; int what; @@ -393,7 +412,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, connssl->state = ssl_connection_negotiating; } - session = backend->session; + rconn = backend->conn; /* Read/write data until the handshake is done or the socket would block. */ for(;;) { @@ -404,18 +423,21 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, * then becomes true when we first write data, then becomes false again * once the handshake is done. */ - if(!rustls_client_session_is_handshaking(session)) { + if(!rustls_connection_is_handshaking(rconn)) { infof(data, "Done handshaking\n"); /* Done with the handshake. Set up callbacks to send/receive data. */ connssl->state = ssl_connection_complete; + + cr_set_negotiated_alpn(data, conn, rconn); + conn->recv[sockindex] = cr_recv; conn->send[sockindex] = cr_send; *done = TRUE; return CURLE_OK; } - wants_read = rustls_client_session_wants_read(session); - wants_write = rustls_client_session_wants_write(session); + wants_read = rustls_connection_wants_read(rconn); + wants_write = rustls_connection_wants_write(rconn); DEBUGASSERT(wants_read || wants_write); writefd = wants_write?sockfd:CURL_SOCKET_BAD; readfd = wants_read?sockfd:CURL_SOCKET_BAD; @@ -439,7 +461,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* socket is readable or writable */ if(wants_write) { - infof(data, "ClientSession wants us to write_tls.\n"); + infof(data, "rustls_connection wants us to write_tls.\n"); cr_send(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { infof(data, "writing would block\n"); @@ -451,7 +473,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, } if(wants_read) { - infof(data, "ClientSession wants us to read_tls.\n"); + infof(data, "rustls_connection wants us to read_tls.\n"); cr_recv(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { @@ -482,13 +504,13 @@ cr_getsock(struct connectdata *conn, curl_socket_t *socks) struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET]; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *session = backend->session; + struct rustls_connection *rconn = backend->conn; - if(rustls_client_session_wants_write(session)) { + if(rustls_connection_wants_write(rconn)) { socks[0] = sockfd; return GETSOCK_WRITESOCK(0); } - if(rustls_client_session_wants_read(session)) { + if(rustls_connection_wants_read(rconn)) { socks[0] = sockfd; return GETSOCK_READSOCK(0); } @@ -501,7 +523,7 @@ cr_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { struct ssl_backend_data *backend = connssl->backend; - return &backend->session; + return &backend->conn; } static void @@ -513,21 +535,20 @@ cr_close(struct Curl_easy *data, struct connectdata *conn, CURLcode tmperr = CURLE_OK; ssize_t n = 0; - if(backend->session) { - rustls_client_session_send_close_notify(backend->session); + if(backend->conn) { + rustls_connection_send_close_notify(backend->conn); n = cr_send(data, sockindex, NULL, 0, &tmperr); if(n < 0) { failf(data, "error sending close notify: %d", tmperr); } - rustls_client_session_free(backend->session); - backend->session = NULL; + rustls_connection_free(backend->conn); + backend->conn = NULL; } if(backend->config) { rustls_client_config_free(backend->config); backend->config = NULL; } - free(backend->tlsbuf); } const struct Curl_ssl Curl_ssl_rustls = { @@ -554,7 +575,9 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_RUSTLS */ diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c index 51cf940b4d..574af6a005 100644 --- a/contrib/libs/curl/lib/vtls/schannel.c +++ b/contrib/libs/curl/lib/vtls/schannel.c @@ -117,6 +117,10 @@ #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif +#ifndef SCH_USE_STRONG_CRYPTO +#define SCH_USE_STRONG_CRYPTO 0x00400000 +#endif + #ifndef SECBUFFER_ALERT #define SECBUFFER_ALERT 17 #endif @@ -324,17 +328,22 @@ get_alg_id_by_name(char *name) } static CURLcode -set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers) +set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, + ALG_ID *algIds) { char *startCur = ciphers; int algCount = 0; - static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/ - while(startCur && (0 != *startCur) && (algCount < 45)) { + while(startCur && (0 != *startCur) && (algCount < NUMOF_CIPHERS)) { long alg = strtol(startCur, 0, 0); if(!alg) alg = get_alg_id_by_name(startCur); if(alg) algIds[algCount++] = alg; + else if(!strncmp(startCur, "USE_STRONG_CRYPTO", + sizeof("USE_STRONG_CRYPTO") - 1) || + !strncmp(startCur, "SCH_USE_STRONG_CRYPTO", + sizeof("SCH_USE_STRONG_CRYPTO") - 1)) + schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO; else return CURLE_SSL_CIPHER; startCur = strchr(startCur, ':'); @@ -358,7 +367,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, size_t store_name_len; sep = _tcschr(path, TEXT('\\')); - if(sep == NULL) + if(!sep) return CURLE_SSL_CERTPROBLEM; store_name_len = sep - path; @@ -388,7 +397,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, store_path_start = sep + 1; sep = _tcschr(store_path_start, TEXT('\\')); - if(sep == NULL) + if(!sep) return CURLE_SSL_CERTPROBLEM; *thumbprint = sep + 1; @@ -398,7 +407,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, *sep = TEXT('\0'); *store_path = _tcsdup(store_path_start); *sep = TEXT('\\'); - if(*store_path == NULL) + if(!*store_path) return CURLE_OUT_OF_MEMORY; return CURLE_OK; @@ -428,12 +437,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #endif TCHAR *host_name; CURLcode result; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", @@ -469,7 +473,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #endif #else #ifdef HAS_MANUAL_VERIFY_API - if(SSL_CONN_CONFIG(CAfile)) { + if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) { if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { BACKEND->use_manual_cred_validation = true; @@ -483,7 +487,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, else BACKEND->use_manual_cred_validation = false; #else - if(SSL_CONN_CONFIG(CAfile)) { + if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) { failf(data, "schannel: CA cert support not built in"); return CURLE_NOT_BUILT_IN; } @@ -558,6 +562,14 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, "names in server certificates.\n")); } + if(!SSL_SET_OPTION(auto_client_cert)) { + schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS; + schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; + infof(data, "schannel: disabled automatic use of client certificate\n"); + } + else + infof(data, "schannel: enabled automatic use of client certificate\n"); + switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: @@ -572,18 +584,17 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, break; } case CURL_SSLVERSION_SSLv3: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; - break; case CURL_SSLVERSION_SSLv2: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT; - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; } if(SSL_CONN_CONFIG(cipher_list)) { - result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list)); + result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list), + BACKEND->algIds); if(CURLE_OK != result) { failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG"); return result; @@ -700,7 +711,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, } if(!blob) free(certdata); - if(cert_store == NULL) { + if(!cert_store) { DWORD errorcode = GetLastError(); if(errorcode == ERROR_INVALID_PASSWORD) failf(data, "schannel: Failed to import cert file %s, " @@ -717,7 +728,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL); - if(client_certs[0] == NULL) { + if(!client_certs[0]) { failf(data, "schannel: Failed to get certificate from file %s" ", last error is 0x%x", cert_showfilename_error, GetLastError()); @@ -861,11 +872,11 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, list_start_index = cur; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { - memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN); - cur += NGHTTP2_PROTO_ALPN_LEN; - infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; + infof(data, "schannel: ALPN, offering %s\n", ALPN_H2); } #endif @@ -893,11 +904,15 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - /* setup request flags */ + /* security request flags */ BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM; + if(!SSL_SET_OPTION(auto_client_cert)) { + BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; + } + /* allocate memory for the security context handle */ BACKEND->ctxt = (struct Curl_schannel_ctxt *) calloc(1, sizeof(struct Curl_schannel_ctxt)); @@ -997,12 +1012,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, SECURITY_STATUS sspi_status = SEC_E_OK; CURLcode result; bool doread; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); const char *pubkey_ptr; doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; @@ -1015,23 +1025,23 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; /* buffer to store previously received and decrypted data */ - if(BACKEND->decdata_buffer == NULL) { + if(!BACKEND->decdata_buffer) { BACKEND->decdata_offset = 0; BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; BACKEND->decdata_buffer = malloc(BACKEND->decdata_length); - if(BACKEND->decdata_buffer == NULL) { + if(!BACKEND->decdata_buffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } } /* buffer to store previously received and encrypted data */ - if(BACKEND->encdata_buffer == NULL) { + if(!BACKEND->encdata_buffer) { BACKEND->encdata_is_incomplete = false; BACKEND->encdata_offset = 0; BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; BACKEND->encdata_buffer = malloc(BACKEND->encdata_length); - if(BACKEND->encdata_buffer == NULL) { + if(!BACKEND->encdata_buffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1046,7 +1056,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, reallocated_buffer = realloc(BACKEND->encdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { failf(data, "schannel: unable to re-allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1101,7 +1111,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&outbuf_desc, outbuf, 3); - if(inbuf[0].pvBuffer == NULL) { + if(!inbuf[0].pvBuffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1251,9 +1261,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); } - pubkey_ptr = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + pubkey_ptr = SSL_PINNED_PUB_KEY(); if(pubkey_ptr) { result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr); if(result) { @@ -1340,8 +1348,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, CERT_CONTEXT *ccert_context = NULL; bool isproxy = SSL_IS_PROXY(); #ifdef DEBUGBUILD - const char * const hostname = isproxy ? conn->http_proxy.host.name : - conn->host.name; + const char * const hostname = SSL_HOST_NAME(); #endif #ifdef HAS_ALPN SecPkgContext_ApplicationProtocol alpn_result; @@ -1389,10 +1396,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, infof(data, "schannel: ALPN, server accepted to use %.*s\n", alpn_result.ProtocolIdSize, alpn_result.ProtocolId); -#ifdef USE_NGHTTP2 - if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId, - NGHTTP2_PROTO_VERSION_ID_LEN)) { +#ifdef USE_HTTP2 + if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1453,7 +1459,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); - if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { + if((sspi_status != SEC_E_OK) || !ccert_context) { failf(data, "schannel: failed to retrieve remote cert context"); return CURLE_PEER_FAILED_VERIFICATION; } @@ -1805,7 +1811,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, } reallocated_buffer = realloc(BACKEND->encdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { *err = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; @@ -1894,7 +1900,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, } reallocated_buffer = realloc(BACKEND->decdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { *err = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; @@ -2128,12 +2134,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, * Shutting Down an Schannel Connection */ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); DEBUGASSERT(data); @@ -2296,7 +2297,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || !pCertContextServer) { char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); @@ -2406,6 +2407,9 @@ const struct Curl_ssl Curl_ssl_schannel = { { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ SSLSUPP_CERTINFO | +#ifdef HAS_MANUAL_VERIFY_API + SSLSUPP_CAINFO_BLOB | +#endif SSLSUPP_PINNEDPUBKEY, sizeof(struct ssl_backend_data), @@ -2429,7 +2433,9 @@ const struct Curl_ssl Curl_ssl_schannel = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - schannel_sha256sum /* sha256sum */ + schannel_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_SCHANNEL */ diff --git a/contrib/libs/curl/lib/vtls/schannel.h b/contrib/libs/curl/lib/vtls/schannel.h index 2952caa1a5..77853aa30f 100644 --- a/contrib/libs/curl/lib/vtls/schannel.h +++ b/contrib/libs/curl/lib/vtls/schannel.h @@ -71,6 +71,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, #endif #endif +#define NUMOF_CIPHERS 45 /* There are 45 listed in the MS headers */ + struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; @@ -102,6 +104,7 @@ struct ssl_backend_data { #ifdef HAS_MANUAL_VERIFY_API bool use_manual_cred_validation; /* true if manual cred validation is used */ #endif + ALG_ID algIds[NUMOF_CIPHERS]; }; #endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */ diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c index e0fdbd5b63..25d47b8087 100644 --- a/contrib/libs/curl/lib/vtls/schannel_verify.c +++ b/contrib/libs/curl/lib/vtls/schannel_verify.c @@ -77,21 +77,156 @@ static int is_cr_or_lf(char c) return c == '\r' || c == '\n'; } -static CURLcode add_certs_to_store(HCERTSTORE trust_store, - const char *ca_file, - struct Curl_easy *data) +/* Search the substring needle,needlelen into string haystack,haystacklen + * Strings don't need to be terminated by a '\0'. + * Similar of OSX/Linux memmem (not available on Visual Studio). + * Return position of beginning of first occurence or NULL if not found + */ +static const char *c_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + const char *p; + char first; + const char *str_limit = (const char *)haystack + haystacklen; + if(!needlelen || needlelen > haystacklen) + return NULL; + first = *(const char *)needle; + for(p = (const char *)haystack; p <= (str_limit - needlelen); p++) + if(((*p) == first) && (memcmp(p, needle, needlelen) == 0)) + return p; + + return NULL; +} + +static CURLcode add_certs_data_to_store(HCERTSTORE trust_store, + const char *ca_buffer, + size_t ca_buffer_size, + const char *ca_file_text, + struct Curl_easy *data) +{ + const size_t begin_cert_len = strlen(BEGIN_CERT); + const size_t end_cert_len = strlen(END_CERT); + CURLcode result = CURLE_OK; + int num_certs = 0; + bool more_certs = 1; + const char *current_ca_file_ptr = ca_buffer; + const char *ca_buffer_limit = ca_buffer + ca_buffer_size; + + while(more_certs && (current_ca_file_ptr<ca_buffer_limit)) { + const char *begin_cert_ptr = c_memmem(current_ca_file_ptr, + ca_buffer_limit-current_ca_file_ptr, + BEGIN_CERT, + begin_cert_len); + if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[begin_cert_len])) { + more_certs = 0; + } + else { + const char *end_cert_ptr = c_memmem(begin_cert_ptr, + ca_buffer_limit-begin_cert_ptr, + END_CERT, + end_cert_len); + if(!end_cert_ptr) { + failf(data, + "schannel: CA file '%s' is not correctly formatted", + ca_file_text); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + CERT_BLOB cert_blob; + CERT_CONTEXT *cert_context = NULL; + BOOL add_cert_result = FALSE; + DWORD actual_content_type = 0; + DWORD cert_size = (DWORD) + ((end_cert_ptr + end_cert_len) - begin_cert_ptr); + + cert_blob.pbData = (BYTE *)begin_cert_ptr; + cert_blob.cbData = cert_size; + if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, + &cert_blob, + CERT_QUERY_CONTENT_FLAG_CERT, + CERT_QUERY_FORMAT_FLAG_ALL, + 0, + NULL, + &actual_content_type, + NULL, + NULL, + NULL, + (const void **)&cert_context)) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to extract certificate from CA file " + "'%s': %s", + ca_file_text, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + current_ca_file_ptr = begin_cert_ptr + cert_size; + + /* Sanity check that the cert_context object is the right type */ + if(CERT_QUERY_CONTENT_CERT != actual_content_type) { + failf(data, + "schannel: unexpected content type '%d' when extracting " + "certificate from CA file '%s'", + actual_content_type, ca_file_text); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + add_cert_result = + CertAddCertificateContextToStore(trust_store, + cert_context, + CERT_STORE_ADD_ALWAYS, + NULL); + CertFreeCertificateContext(cert_context); + if(!add_cert_result) { + char buffer[STRERROR_LEN]; + failf(data, + "schannel: failed to add certificate from CA file '%s' " + "to certificate store: %s", + ca_file_text, + Curl_winapi_strerror(GetLastError(), buffer, + sizeof(buffer))); + result = CURLE_SSL_CACERT_BADFILE; + more_certs = 0; + } + else { + num_certs++; + } + } + } + } + } + } + + if(result == CURLE_OK) { + if(!num_certs) { + infof(data, + "schannel: did not add any certificates from CA file '%s'\n", + ca_file_text); + } + else { + infof(data, + "schannel: added %d certificate(s) from CA file '%s'\n", + num_certs, ca_file_text); + } + } + return result; +} + +static CURLcode add_certs_file_to_store(HCERTSTORE trust_store, + const char *ca_file, + struct Curl_easy *data) { CURLcode result; HANDLE ca_file_handle = INVALID_HANDLE_VALUE; LARGE_INTEGER file_size; char *ca_file_buffer = NULL; - char *current_ca_file_ptr = NULL; TCHAR *ca_file_tstr = NULL; size_t ca_file_bufsize = 0; DWORD total_bytes_read = 0; - bool more_certs = 0; - int num_certs = 0; - size_t END_CERT_LEN; ca_file_tstr = curlx_convert_UTF8_to_tchar((char *)ca_file); if(!ca_file_tstr) { @@ -181,106 +316,10 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, if(result != CURLE_OK) { goto cleanup; } - - END_CERT_LEN = strlen(END_CERT); - - more_certs = 1; - current_ca_file_ptr = ca_file_buffer; - while(more_certs && *current_ca_file_ptr != '\0') { - char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT); - if(!begin_cert_ptr || !is_cr_or_lf(begin_cert_ptr[strlen(BEGIN_CERT)])) { - more_certs = 0; - } - else { - char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT); - if(!end_cert_ptr) { - failf(data, - "schannel: CA file '%s' is not correctly formatted", - ca_file); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - CERT_BLOB cert_blob; - CERT_CONTEXT *cert_context = NULL; - BOOL add_cert_result = FALSE; - DWORD actual_content_type = 0; - DWORD cert_size = (DWORD) - ((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr); - - cert_blob.pbData = (BYTE *)begin_cert_ptr; - cert_blob.cbData = cert_size; - if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, - &cert_blob, - CERT_QUERY_CONTENT_FLAG_CERT, - CERT_QUERY_FORMAT_FLAG_ALL, - 0, - NULL, - &actual_content_type, - NULL, - NULL, - NULL, - (const void **)&cert_context)) { - char buffer[STRERROR_LEN]; - failf(data, - "schannel: failed to extract certificate from CA file " - "'%s': %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - current_ca_file_ptr = begin_cert_ptr + cert_size; - - /* Sanity check that the cert_context object is the right type */ - if(CERT_QUERY_CONTENT_CERT != actual_content_type) { - failf(data, - "schannel: unexpected content type '%d' when extracting " - "certificate from CA file '%s'", - actual_content_type, ca_file); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - add_cert_result = - CertAddCertificateContextToStore(trust_store, - cert_context, - CERT_STORE_ADD_ALWAYS, - NULL); - CertFreeCertificateContext(cert_context); - if(!add_cert_result) { - char buffer[STRERROR_LEN]; - failf(data, - "schannel: failed to add certificate from CA file '%s' " - "to certificate store: %s", - ca_file, - Curl_winapi_strerror(GetLastError(), buffer, - sizeof(buffer))); - result = CURLE_SSL_CACERT_BADFILE; - more_certs = 0; - } - else { - num_certs++; - } - } - } - } - } - } - - if(result == CURLE_OK) { - if(!num_certs) { - infof(data, - "schannel: did not add any certificates from CA file '%s'\n", - ca_file); - } - else { - infof(data, - "schannel: added %d certificate(s) from CA file '%s'\n", - num_certs, ca_file); - } - } + result = add_certs_data_to_store(trust_store, + ca_file_buffer, ca_file_bufsize, + ca_file, + data); cleanup: if(ca_file_handle != INVALID_HANDLE_VALUE) { @@ -389,7 +428,7 @@ static DWORD cert_get_name_string(struct Curl_easy *data, if(entry->dwAltNameChoice != CERT_ALT_NAME_DNS_NAME) { continue; } - if(entry->pwszDNSName == NULL) { + if(!entry->pwszDNSName) { infof(data, "schannel: Empty DNS name."); continue; } @@ -536,27 +575,22 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, const CERT_CHAIN_CONTEXT *pChainContext = NULL; HCERTCHAINENGINE cert_chain_engine = NULL; HCERTSTORE trust_store = NULL; -#ifndef CURL_DISABLE_PROXY - const char * const conn_hostname = SSL_IS_PROXY() ? - conn->http_proxy.host.name : - conn->host.name; -#else - const char * const conn_hostname = conn->host.name; -#endif + const char * const conn_hostname = SSL_HOST_NAME(); sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || !pCertContextServer) { char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); result = CURLE_PEER_FAILED_VERIFICATION; } - if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) && + if(result == CURLE_OK && + (SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) && BACKEND->use_manual_cred_validation) { /* * Create a chain engine that uses the certificates in the CA file as @@ -582,8 +616,19 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, result = CURLE_SSL_CACERT_BADFILE; } else { - result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile), - data); + const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob); + if(ca_info_blob) { + result = add_certs_data_to_store(trust_store, + (const char *)ca_info_blob->data, + ca_info_blob->len, + "(memory blob)", + data); + } + else { + result = add_certs_file_to_store(trust_store, + SSL_CONN_CONFIG(CAfile), + data); + } } } diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c index 9d637da2ec..edd375ea7d 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.c +++ b/contrib/libs/curl/lib/vtls/sectransp.c @@ -67,6 +67,7 @@ #define CURL_BUILD_IOS_7 0 #define CURL_BUILD_IOS_9 0 #define CURL_BUILD_IOS_11 0 +#define CURL_BUILD_IOS_13 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 @@ -76,6 +77,7 @@ #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 #define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 #define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +#define CURL_BUILD_MAC_10_15 MAC_OS_X_VERSION_MAX_ALLOWED >= 101500 /* 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 using the compiler command line option @@ -91,6 +93,7 @@ #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 #define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 #define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 +#define CURL_BUILD_IOS_13 __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 #define CURL_BUILD_MAC 0 #define CURL_BUILD_MAC_10_5 0 #define CURL_BUILD_MAC_10_6 0 @@ -99,6 +102,7 @@ #define CURL_BUILD_MAC_10_9 0 #define CURL_BUILD_MAC_10_11 0 #define CURL_BUILD_MAC_10_13 0 +#define CURL_BUILD_MAC_10_15 0 #define CURL_SUPPORT_MAC_10_5 0 #define CURL_SUPPORT_MAC_10_6 0 #define CURL_SUPPORT_MAC_10_7 0 @@ -138,6 +142,636 @@ struct ssl_backend_data { size_t ssl_write_buffered_length; }; +struct st_cipher { + const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */ + const char *alias_name; /* Alias name is the same as OpenSSL cipher name */ + SSLCipherSuite num; /* Cipher suite code/number defined in IANA registry */ + bool weak; /* Flag to mark cipher as weak based on previous implementation + of Secure Transport back-end by CURL */ +}; + +/* Macro to initialize st_cipher data structure: stringify id to name, cipher + number/id, 'weak' suite flag + */ +#define CIPHER_DEF(num, alias, weak) \ + { #num, alias, num, weak } + +/* + Macro to initialize st_cipher data structure with name, code (IANA cipher + number/id value), and 'weak' suite flag. The first 28 cipher suite numbers + have the same IANA code for both SSL and TLS standards: numbers 0x0000 to + 0x001B. They have different names though. The first 4 letters of the cipher + suite name are the protocol name: "SSL_" or "TLS_", rest of the IANA name is + the same for both SSL and TLS cipher suite name. + The second part of the problem is that macOS/iOS SDKs don't define all TLS + codes but only 12 of them. The SDK defines all SSL codes though, i.e. SSL_NUM + constant is always defined for those 28 ciphers while TLS_NUM is defined only + for 12 of the first 28 ciphers. Those 12 TLS cipher codes match to + corresponding SSL enum value and represent the same cipher suite. Therefore + we'll use the SSL enum value for those cipher suites because it is defined + for all 28 of them. + We make internal data consistent and based on TLS names, i.e. all st_cipher + item names start with the "TLS_" prefix. + Summarizing all the above, those 28 first ciphers are presented in our table + with both TLS and SSL names. Their cipher numbers are assigned based on the + SDK enum value for the SSL cipher, which matches to IANA TLS number. + */ +#define CIPHER_DEF_SSLTLS(num_wo_prefix, alias, weak) \ + { "TLS_" #num_wo_prefix, alias, SSL_##num_wo_prefix, weak } + +/* + Cipher suites were marked as weak based on the following: + RC4 encryption - rfc7465, the document contains a list of deprecated ciphers. + Marked in the code below as weak. + RC2 encryption - many mentions, was found vulnerable to a relatively easy + attack https://link.springer.com/chapter/10.1007%2F3-540-69710-1_14 + Marked in the code below as weak. + DES and IDEA encryption - rfc5469, has a list of deprecated ciphers. + Marked in the code below as weak. + Anonymous Diffie-Hellman authentication and anonymous elliptic curve + Diffie-Hellman - vulnerable to a man-in-the-middle attack. Deprecated by + RFC 4346 aka TLS 1.1 (section A.5, page 60) + Null bulk encryption suites - not encrypted communication + Export ciphers, i.e. ciphers with restrictions to be used outside the US for + software exported to some countries, they were excluded from TLS 1.1 + version. More precisely, they were noted as ciphers which MUST NOT be + negotiated in RFC 4346 aka TLS 1.1 (section A.5, pages 60 and 61). + All of those filters were considered weak because they contain a weak + algorithm like DES, RC2 or RC4, and already considered weak by other + criteria. + 3DES - NIST deprecated it and is going to retire it by 2023 + https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA + OpenSSL https://www.openssl.org/blog/blog/2016/08/24/sweet32/ also + deprecated those ciphers. Some other libraries also consider it + vulnerable or at least not strong enough. + + CBC ciphers are vulnerable with SSL3.0 and TLS1.0: + https://www.cisco.com/c/en/us/support/docs/security/email-security-appliance + /118518-technote-esa-00.html + We don't take care of this issue because it is resolved by later TLS + versions and for us, it requires more complicated checks, we need to + check a protocol version also. Vulnerability doesn't look very critical + and we do not filter out those cipher suites. + */ + +#define CIPHER_WEAK_NOT_ENCRYPTED TRUE +#define CIPHER_WEAK_RC_ENCRYPTION TRUE +#define CIPHER_WEAK_DES_ENCRYPTION TRUE +#define CIPHER_WEAK_IDEA_ENCRYPTION TRUE +#define CIPHER_WEAK_ANON_AUTH TRUE +#define CIPHER_WEAK_3DES_ENCRYPTION TRUE +#define CIPHER_STRONG_ENOUGH FALSE + +/* Please do not change the order of the first ciphers available for SSL. + Do not insert and do not delete any of them. Code below + depends on their order and continuity. + If you add a new cipher, please maintain order by number, i.e. + insert in between existing items to appropriate place based on + cipher suite IANA number +*/ +const static struct st_cipher ciphertable[] = { + /* SSL version 3.0 and initial TLS 1.0 cipher suites. + Defined since SDK 10.2.8 */ + CIPHER_DEF_SSLTLS(NULL_WITH_NULL_NULL, /* 0x0000 */ + NULL, + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_WITH_NULL_MD5, /* 0x0001 */ + "NULL-MD5", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_WITH_NULL_SHA, /* 0x0002 */ + "NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC4_40_MD5, /* 0x0003 */ + "EXP-RC4-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_MD5, /* 0x0004 */ + "RC4-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_SHA, /* 0x0005 */ + "RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* 0x0006 */ + "EXP-RC2-CBC-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_IDEA_CBC_SHA, /* 0x0007 */ + "IDEA-CBC-SHA", + CIPHER_WEAK_IDEA_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0008 */ + "EXP-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_DES_CBC_SHA, /* 0x0009 */ + "DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */ + "DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x000B */ + "EXP-DH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_WITH_DES_CBC_SHA, /* 0x000C */ + "DH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x000D */ + "DH-DSS-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x000E */ + "EXP-DH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_WITH_DES_CBC_SHA, /* 0x000F */ + "DH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0010 */ + "DH-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x0011 */ + "EXP-EDH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_WITH_DES_CBC_SHA, /* 0x0012 */ + "EDH-DSS-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x0013 */ + "DHE-DSS-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0014 */ + "EXP-EDH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_WITH_DES_CBC_SHA, /* 0x0015 */ + "EDH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0016 */ + "DHE-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_RC4_40_MD5, /* 0x0017 */ + "EXP-ADH-RC4-MD5", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_RC4_128_MD5, /* 0x0018 */ + "ADH-RC4-MD5", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_DES40_CBC_SHA, /* 0x0019 */ + "EXP-ADH-DES-CBC-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_DES_CBC_SHA, /* 0x001A */ + "ADH-DES-CBC-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_3DES_EDE_CBC_SHA, /* 0x001B */ + "ADH-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* 0x001C */ + NULL, + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* 0x001D */ + NULL, + CIPHER_STRONG_ENOUGH), + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption */ + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA, /* 0x002C */ + "PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA, /* 0x002D */ + "DHE-PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA, /* 0x002E */ + "RSA-PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* TLS addenda using AES, per RFC 3268. Defined since SDK 10.4u */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */ + "AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA, /* 0x0030 */ + "DH-DSS-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA, /* 0x0031 */ + "DH-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* 0x0032 */ + "DHE-DSS-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* 0x0033 */ + "DHE-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA, /* 0x0034 */ + "ADH-AES128-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */ + "AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA, /* 0x0036 */ + "DH-DSS-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA, /* 0x0037 */ + "DH-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* 0x0038 */ + "DHE-DSS-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* 0x0039 */ + "DHE-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA, /* 0x003A */ + "ADH-AES256-SHA", + CIPHER_WEAK_ANON_AUTH), + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* TLS 1.2 addenda, RFC 5246 */ + /* Server provided RSA certificate for key exchange. */ + CIPHER_DEF(TLS_RSA_WITH_NULL_SHA256, /* 0x003B */ + "NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */ + "AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */ + "AES256-SHA256", + CIPHER_STRONG_ENOUGH), + /* Server-authenticated (and optionally client-authenticated) + Diffie-Hellman. */ + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, /* 0x003E */ + "DH-DSS-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, /* 0x003F */ + "DH-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, /* 0x0040 */ + "DHE-DSS-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + + /* TLS 1.2 addenda, RFC 5246 */ + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, /* 0x0067 */ + "DHE-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, /* 0x0068 */ + "DH-DSS-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, /* 0x0069 */ + "DH-RSA-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, /* 0x006A */ + "DHE-DSS-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, /* 0x006B */ + "DHE-RSA-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA256, /* 0x006C */ + "ADH-AES128-SHA256", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA256, /* 0x006D */ + "ADH-AES256-SHA256", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* Addendum from RFC 4279, TLS PSK */ + CIPHER_DEF(TLS_PSK_WITH_RC4_128_SHA, /* 0x008A */ + "PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008B */ + "PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA, /* 0x008C */ + "PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA, /* 0x008D */ + "PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_RC4_128_SHA, /* 0x008E */ + "DHE-PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008F */ + "DHE-PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, /* 0x0090 */ + "DHE-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, /* 0x0091 */ + "DHE-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_RC4_128_SHA, /* 0x0092 */ + "RSA-PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x0093 */ + "RSA-PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, /* 0x0094 */ + "RSA-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, /* 0x0095 */ + "RSA-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites + for TLS. */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */ + "AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */ + "AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, /* 0x009E */ + "DHE-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, /* 0x009F */ + "DHE-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, /* 0x00A0 */ + "DH-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, /* 0x00A1 */ + "DH-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A2 */ + "DHE-DSS-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A3 */ + "DHE-DSS-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A4 */ + "DH-DSS-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A5 */ + "DH-DSS-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_GCM_SHA256, /* 0x00A6 */ + "ADH-AES128-GCM-SHA256", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_GCM_SHA384, /* 0x00A7 */ + "ADH-AES256-GCM-SHA384", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* RFC 5487 - PSK with SHA-256/384 and AES GCM */ + CIPHER_DEF(TLS_PSK_WITH_AES_128_GCM_SHA256, /* 0x00A8 */ + "PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_GCM_SHA384, /* 0x00A9 */ + "PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AA */ + "DHE-PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AB */ + "DHE-PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AC */ + "RSA-PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AD */ + "RSA-PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA256, /* 0x00AE */ + "PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA384, /* 0x00AF */ + "PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA256, /* 0x00B0 */ + "PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA384, /* 0x00B1 */ + "PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B2 */ + "DHE-PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B3 */ + "DHE-PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA256, /* 0x00B4 */ + "DHE-PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA384, /* 0x00B5 */ + "DHE-PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B6 */ + "RSA-PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B7 */ + "RSA-PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA256, /* 0x00B8 */ + "RSA-PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA384, /* 0x00B9 */ + "RSA-PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* RFC 5746 - Secure Renegotiation. This is not a real suite, + it is a response to initiate negotiation again */ + CIPHER_DEF(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, /* 0x00FF */ + NULL, + CIPHER_STRONG_ENOUGH), + +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* TLS 1.3 standard cipher suites for ChaCha20+Poly1305. + Note: TLS 1.3 ciphersuites do not specify the key exchange + algorithm -- they only specify the symmetric ciphers. + Cipher alias name matches to OpenSSL cipher name, and for + TLS 1.3 ciphers */ + CIPHER_DEF(TLS_AES_128_GCM_SHA256, /* 0x1301 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_256_GCM_SHA384, /* 0x1302 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_CHACHA20_POLY1305_SHA256, /* 0x1303 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_128_CCM_SHA256, /* 0x1304 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_128_CCM_8_SHA256, /* 0x1305 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* ECDSA addenda, RFC 4492 */ + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_NULL_SHA, /* 0xC001 */ + "ECDH-ECDSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* 0xC002 */ + "ECDH-ECDSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */ + "ECDH-ECDSA-DES-CBC3-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */ + "ECDH-ECDSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */ + "ECDH-ECDSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_NULL_SHA, /* 0xC006 */ + "ECDHE-ECDSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, /* 0xC007 */ + "ECDHE-ECDSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */ + "ECDHE-ECDSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */ + "ECDHE-ECDSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */ + "ECDHE-ECDSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_NULL_SHA, /* 0xC00B */ + "ECDH-RSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDH_RSA_WITH_RC4_128_SHA, /* 0xC00C */ + "ECDH-RSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */ + "ECDH-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */ + "ECDH-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */ + "ECDH-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_NULL_SHA, /* 0xC010 */ + "ECDHE-RSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* 0xC011 */ + "ECDHE-RSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */ + "ECDHE-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */ + "ECDHE-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */ + "ECDHE-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_anon_WITH_NULL_SHA, /* 0xC015 */ + "AECDH-NULL-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_RC4_128_SHA, /* 0xC016 */ + "AECDH-RC4-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, /* 0xC017 */ + "AECDH-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, /* 0xC018 */ + "AECDH-AES128-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, /* 0xC019 */ + "AECDH-AES256-SHA", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with + HMAC SHA-256/384. */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */ + "ECDHE-ECDSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */ + "ECDHE-ECDSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */ + "ECDH-ECDSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */ + "ECDH-ECDSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */ + "ECDHE-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */ + "ECDHE-RSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */ + "ECDH-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */ + "ECDH-RSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with + SHA-256/384 and AES Galois Counter Mode (GCM) */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */ + "ECDHE-ECDSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */ + "ECDHE-ECDSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */ + "ECDH-ECDSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */ + "ECDH-ECDSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */ + "ECDHE-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */ + "ECDHE-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */ + "ECDH-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */ + "ECDH-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 + /* ECDHE_PSK Cipher Suites for Transport Layer Security (TLS), RFC 5489 */ + CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, /* 0xC035 */ + "ECDHE-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, /* 0xC036 */ + "ECDHE-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */ + +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* Addenda from rfc 7905 ChaCha20-Poly1305 Cipher Suites for + Transport Layer Security (TLS). */ + CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */ + "ECDHE-RSA-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */ + "ECDHE-ECDSA-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + +#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 + /* ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS), + RFC 7905 */ + CIPHER_DEF(TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCAB */ + "PSK-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */ + + /* Tags for SSL 2 cipher kinds which are not specified for SSL 3. + Defined since SDK 10.2.8 */ + CIPHER_DEF(SSL_RSA_WITH_RC2_CBC_MD5, /* 0xFF80 */ + NULL, + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_IDEA_CBC_MD5, /* 0xFF81 */ + NULL, + CIPHER_WEAK_IDEA_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_DES_CBC_MD5, /* 0xFF82 */ + NULL, + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_3DES_EDE_CBC_MD5, /* 0xFF83 */ + NULL, + CIPHER_WEAK_3DES_ENCRYPTION), +}; + +#define NUM_OF_CIPHERS sizeof(ciphertable)/sizeof(ciphertable[0]) + + /* pinned public key support tests */ /* version 1 supports macOS 10.12+ and iOS 10+ */ @@ -295,586 +929,23 @@ static OSStatus SocketWrite(SSLConnectionRef connection, } #ifndef CURL_DISABLE_VERBOSE_STRINGS -CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) -{ - switch(cipher) { - /* SSL version 3.0 */ - case SSL_RSA_WITH_NULL_MD5: - return "SSL_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "SSL_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "SSL_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "SSL_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_SHA: - return "SSL_RSA_WITH_IDEA_CBC_SHA"; - break; - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_RSA_WITH_DES_CBC_SHA: - return "SSL_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_DES_CBC_SHA: - return "SSL_DH_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_DES_CBC_SHA: - return "SSL_DH_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "SSL_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_anon_WITH_DES_CBC_SHA: - return "SSL_DH_anon_WITH_DES_CBC_SHA"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: - return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; - break; - /* TLS 1.0 with AES (RFC 3268) - (Apparently these are used in SSLv3 implementations as well.) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; - /* SSL version 2.0 */ - case SSL_RSA_WITH_RC2_CBC_MD5: - return "SSL_RSA_WITH_RC2_CBC_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_MD5: - return "SSL_RSA_WITH_IDEA_CBC_MD5"; - break; - case SSL_RSA_WITH_DES_CBC_MD5: - return "SSL_RSA_WITH_DES_CBC_MD5"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: - return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; - break; - } - return "SSL_NULL_WITH_NULL_NULL"; -} - CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) { - switch(cipher) { - /* TLS 1.0 with AES (RFC 3268) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* TLS 1.0 with ECDSA (RFC 4492) */ - case TLS_ECDH_ECDSA_WITH_NULL_SHA: - return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_NULL_SHA: - return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_NULL_SHA: - return "TLS_ECDH_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_RSA_WITH_RC4_128_SHA: - return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_NULL_SHA: - return "TLS_ECDHE_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_RSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_NULL_SHA: - return "TLS_ECDH_anon_WITH_NULL_SHA"; - break; - case TLS_ECDH_anon_WITH_RC4_128_SHA: - return "TLS_ECDH_anon_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - /* TLS 1.2 (RFC 5246) */ - case TLS_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case TLS_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case TLS_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case TLS_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_WITH_NULL_SHA256: - return "TLS_RSA_WITH_NULL_SHA256"; - break; - case TLS_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; - break; - /* TLS 1.2 with AES GCM (RFC 5288) */ - case TLS_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_anon_WITH_AES_128_GCM_SHA256: - return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: - return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; - break; - /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: - return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - break; -#else - case SSL_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* TLS PSK (RFC 4279): */ - case TLS_PSK_WITH_RC4_128_SHA: - return "TLS_PSK_WITH_RC4_128_SHA"; - break; - case TLS_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA: - return "TLS_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA: - return "TLS_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_RC4_128_SHA: - return "TLS_DHE_PSK_WITH_RC4_128_SHA"; - break; - case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_RC4_128_SHA: - return "TLS_RSA_PSK_WITH_RC4_128_SHA"; - break; - case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; - break; - /* More TLS PSK (RFC 4785): */ - case TLS_PSK_WITH_NULL_SHA: - return "TLS_PSK_WITH_NULL_SHA"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA: - return "TLS_DHE_PSK_WITH_NULL_SHA"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA: - return "TLS_RSA_PSK_WITH_NULL_SHA"; - break; - /* Even more TLS PSK (RFC 5487): */ - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_PSK_WITH_NULL_SHA256: - return "TLS_PSK_WITH_NULL_SHA256"; - break; - case TLS_PSK_WITH_NULL_SHA384: - return "TLS_PSK_WITH_NULL_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA256: - return "TLS_DHE_PSK_WITH_NULL_SHA256"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA256: - return "TLS_RSA_PSK_WITH_NULL_SHA256"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA384: - 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 */ + /* The first ciphers in the ciphertable are continuos. Here we do small + optimization and instead of loop directly get SSL name by cipher number. + */ + if(cipher <= SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA) { + return ciphertable[cipher].name; + } + /* Iterate through the rest of the ciphers */ + for(size_t i = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA + 1; + i < NUM_OF_CIPHERS; + ++i) { + if(ciphertable[i].num == cipher) { + return ciphertable[i].name; + } } - return "TLS_NULL_WITH_NULL_NULL"; + return ciphertable[SSL_NULL_WITH_NULL_NULL].name; } #endif /* !CURL_DISABLE_VERBOSE_STRINGS */ @@ -1087,12 +1158,14 @@ static OSStatus CopyIdentityWithLabel(char *label, (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i); err = SecIdentityCopyCertificate(identity, &cert); if(err == noErr) { + OSStatus copy_status = noErr; #if CURL_BUILD_IOS common_name = SecCertificateCopySubjectSummary(cert); #elif CURL_BUILD_MAC_10_7 - SecCertificateCopyCommonName(cert, &common_name); + copy_status = SecCertificateCopyCommonName(cert, &common_name); #endif - if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { + if(copy_status == noErr && + CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { CFRelease(cert); CFRelease(common_name); CFRetain(identity); @@ -1253,7 +1326,7 @@ CF_INLINE bool is_file(const char *filename) { struct_stat st; - if(filename == NULL) + if(!filename) return false; if(stat(filename, &st) == 0) @@ -1386,6 +1459,200 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } +static bool is_cipher_suite_strong(SSLCipherSuite suite_num) +{ + for(size_t i = 0; i < NUM_OF_CIPHERS; ++i) { + if(ciphertable[i].num == suite_num) { + return !ciphertable[i].weak; + } + } + /* If the cipher is not in our list, assume it is a new one + and therefore strong. Previous implementation was the same, + if cipher suite is not in the list, it was considered strong enough */ + return true; +} + +static bool is_separator(char c) +{ + /* Return whether character is a cipher list separator. */ + switch(c) { + case ' ': + case '\t': + case ':': + case ',': + case ';': + return true; + } + return false; +} + +static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data, + SSLContextRef ssl_ctx) +{ + size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; + SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + OSStatus err = noErr; + +#if CURL_BUILD_MAC + int darwinver_maj = 0, darwinver_min = 0; + + GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); +#endif /* CURL_BUILD_MAC */ + + /* Disable cipher suites that ST supports but are not safe. These ciphers + are unlikely to be used in any case since ST gives other ciphers a much + 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.) */ + err = SSLGetNumberSupportedCiphers(ssl_ctx, &all_ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", + err); + return CURLE_SSL_CIPHER; + } + all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!all_ciphers) { + failf(data, "SSL: Failed to allocate memory for all ciphers"); + return CURLE_OUT_OF_MEMORY; + } + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!allowed_ciphers) { + Curl_safefree(all_ciphers); + failf(data, "SSL: Failed to allocate memory for allowed ciphers"); + return CURLE_OUT_OF_MEMORY; + } + err = SSLGetSupportedCiphers(ssl_ctx, all_ciphers, + &all_ciphers_count); + if(err != noErr) { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + return CURLE_SSL_CIPHER; + } + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* 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(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + if(is_cipher_suite_strong(all_ciphers[i])) { + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + } + } + err = SSLSetEnabledCiphers(ssl_ctx, allowed_ciphers, + allowed_ciphers_count); + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + return CURLE_OK; +} + +static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data, + SSLContextRef ssl_ctx, + const char *ciphers) +{ + size_t ciphers_count = 0; + const char *cipher_start = ciphers; + OSStatus err = noErr; + SSLCipherSuite selected_ciphers[NUM_OF_CIPHERS]; + + if(!ciphers) + return CURLE_OK; + + while(is_separator(*ciphers)) /* Skip initial separators. */ + ciphers++; + if(!*ciphers) + return CURLE_OK; + + cipher_start = ciphers; + while(*cipher_start && ciphers_count < NUM_OF_CIPHERS) { + bool cipher_found = FALSE; + size_t cipher_len = 0; + const char *cipher_end = NULL; + bool tls_name = FALSE; + + /* Skip separators */ + while(is_separator(*cipher_start)) + cipher_start++; + if(*cipher_start == '\0') { + break; + } + /* Find last position of a cipher in the ciphers string */ + cipher_end = cipher_start; + while (*cipher_end != '\0' && !is_separator(*cipher_end)) { + ++cipher_end; + } + + /* IANA cipher names start with the TLS_ or SSL_ prefix. + If the 4th symbol of the cipher is '_' we look for a cipher in the + table by its (TLS) name. + Otherwise, we try to match cipher by an alias. */ + if(cipher_start[3] == '_') { + tls_name = TRUE; + } + /* Iterate through the cipher table and look for the cipher, starting + the cipher number 0x01 because the 0x00 is not the real cipher */ + cipher_len = cipher_end - cipher_start; + for(size_t i = 1; i < NUM_OF_CIPHERS; ++i) { + const char *table_cipher_name = NULL; + if(tls_name) { + table_cipher_name = ciphertable[i].name; + } + else if(ciphertable[i].alias_name != NULL) { + table_cipher_name = ciphertable[i].alias_name; + } + else { + continue; + } + /* Compare a part of the string between separators with a cipher name + in the table and make sure we matched the whole cipher name */ + if(strncmp(cipher_start, table_cipher_name, cipher_len) == 0 + && table_cipher_name[cipher_len] == '\0') { + selected_ciphers[ciphers_count] = ciphertable[i].num; + ++ciphers_count; + cipher_found = TRUE; + break; + } + } + if(!cipher_found) { + /* It would be more human-readable if we print the wrong cipher name + but we don't want to allocate any additional memory and copy the name + into it, then add it into logs. + Also, we do not modify an original cipher list string. We just point + to positions where cipher starts and ends in the cipher list string. + The message is a bit cryptic and longer than necessary but can be + understood by humans. */ + failf(data, "SSL: cipher string \"%s\" contains unsupported cipher name" + " starting position %d and ending position %d", + ciphers, + cipher_start - ciphers, + cipher_end - ciphers); + return CURLE_SSL_CIPHER; + } + if(*cipher_end) { + cipher_start = cipher_end + 1; + } + else { + break; + } + } + /* All cipher suites in the list are found. Report to logs as-is */ + infof(data, "SSL: Setting cipher suites list \"%s\"\n", ciphers); + + err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + return CURLE_OK; +} static CURLcode sectransp_connect_step1(struct Curl_easy *data, struct connectdata *conn, @@ -1394,28 +1661,22 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); - const struct curl_blob *ssl_cablob = NULL; + const struct curl_blob *ssl_cablob = SSL_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); -#ifndef CURL_DISABLE_PROXY bool isproxy = SSL_IS_PROXY(); - const char * const hostname = isproxy ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const isproxy = FALSE; - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); #ifdef ENABLE_IPV6 struct in6_addr addr; #else struct in_addr addr; #endif /* ENABLE_IPV6 */ - size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; - SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + char *ciphers; OSStatus err = noErr; #if CURL_BUILD_MAC int darwinver_maj = 0, darwinver_min = 0; @@ -1486,21 +1747,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, break; } case CURL_SSLVERSION_SSLv3: - 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(backend->ssl_ctx, kSSLProtocol3); - break; case CURL_SSLVERSION_SSLv2: - 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(backend->ssl_ctx, kSSLProtocol2); - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1535,23 +1784,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, break; } case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1583,23 +1818,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, failf(data, "Your version of the OS does not support TLSv1.3"); return CURLE_SSL_CONNECT_ERROR; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1612,14 +1833,14 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!isproxy || !conn->bits.tunnel_proxy) #endif ) { - CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2)); + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -1790,7 +2011,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile); if(!(is_cert_file || is_cert_data)) { - failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); + failf(data, "SSL: can't load CA certificate file %s", + ssl_cafile ? ssl_cafile : "(blob memory)"); return CURLE_SSL_CACERT_BADFILE; } } @@ -1820,121 +2042,16 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); } - /* Disable cipher suites that ST supports but are not safe. These ciphers - are unlikely to be used in any case since ST gives other ciphers a much - 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.) */ - err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count); - if(err != noErr) { - failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", - err); - return CURLE_SSL_CIPHER; - } - all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!all_ciphers) { - failf(data, "SSL: Failed to allocate memory for all ciphers"); - return CURLE_OUT_OF_MEMORY; - } - allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!allowed_ciphers) { - Curl_safefree(all_ciphers); - failf(data, "SSL: Failed to allocate memory for allowed ciphers"); - return CURLE_OUT_OF_MEMORY; - } - err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers, - &all_ciphers_count); - if(err != noErr) { - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - return CURLE_SSL_CIPHER; + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { + err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers); } - for(i = 0UL ; i < all_ciphers_count ; i++) { -#if CURL_BUILD_MAC - /* 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(darwinver_maj == 12 && darwinver_min <= 3 && - all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { - continue; - } -#endif /* CURL_BUILD_MAC */ - switch(all_ciphers[i]) { - /* Disable NULL ciphersuites: */ - case SSL_NULL_WITH_NULL_NULL: - case SSL_RSA_WITH_NULL_MD5: - case SSL_RSA_WITH_NULL_SHA: - case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ - case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ - case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ - case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ - case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ - case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ - case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ - case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ - case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ - case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ - case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ - case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ - case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ - /* Disable anonymous ciphersuites: */ - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - case SSL_DH_anon_WITH_RC4_128_MD5: - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_anon_WITH_DES_CBC_SHA: - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ - case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ - case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ - case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ - case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ - case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ - case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ - case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ - case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ - /* Disable weak key ciphersuites: */ - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_RSA_WITH_DES_CBC_SHA: - case SSL_DH_DSS_WITH_DES_CBC_SHA: - case SSL_DH_RSA_WITH_DES_CBC_SHA: - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - /* Disable IDEA: */ - case SSL_RSA_WITH_IDEA_CBC_SHA: - case SSL_RSA_WITH_IDEA_CBC_MD5: - /* Disable RC4: */ - case SSL_RSA_WITH_RC4_128_MD5: - case SSL_RSA_WITH_RC4_128_SHA: - case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ - case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ - case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ - case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ - case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ - case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ - case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ - break; - default: /* enable everything else */ - allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; - break; - } + else { + err = sectransp_set_default_ciphers(data, backend->ssl_ctx); } - err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers, - allowed_ciphers_count); - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); if(err != noErr) { - failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + failf(data, "SSL: Unable to set ciphers for SSL/TLS handshake. " + "Error code: %d", err); return CURLE_SSL_CIPHER; } @@ -1972,7 +2089,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, else { CURLcode result; ssl_sessionid = - aprintf("%s:%d:%d:%s:%ld", ssl_cafile, + aprintf("%s:%d:%d:%s:%ld", + ssl_cafile ? ssl_cafile : "(blob memory)", verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); ssl_sessionid_len = strlen(ssl_sessionid); @@ -2023,21 +2141,21 @@ static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) /* Jump through the separators at the beginning of the certificate. */ sep_start = strstr(in, "-----"); - if(sep_start == NULL) + if(!sep_start) return 0; cert_start = strstr(sep_start + 1, "-----"); - if(cert_start == NULL) + if(!cert_start) return -1; cert_start += 5; /* Find separator after the end of the certificate. */ cert_end = strstr(cert_start, "-----"); - if(cert_end == NULL) + if(!cert_end) return -1; sep_end = strstr(cert_end + 1, "-----"); - if(sep_end == NULL) + if(!sep_end) return -1; sep_end += 5; @@ -2112,7 +2230,7 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen) } static int append_cert_to_array(struct Curl_easy *data, - unsigned char *buf, size_t buflen, + const unsigned char *buf, size_t buflen, CFMutableArrayRef array) { CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); @@ -2150,18 +2268,14 @@ static int append_cert_to_array(struct Curl_easy *data, return CURLE_OK; } -static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, - SSLContextRef ctx) +static CURLcode verify_cert_buf(struct Curl_easy *data, + const unsigned char *certbuf, size_t buflen, + SSLContextRef ctx) { int n = 0, rc; long res; - unsigned char *certbuf, *der; - size_t buflen, derlen, offset = 0; - - if(read_cert(cafile, &certbuf, &buflen) < 0) { - failf(data, "SSL: failed to read or invalid CA certificate"); - return CURLE_SSL_CACERT_BADFILE; - } + unsigned char *der; + size_t derlen, offset = 0; /* * Certbuf now contains the contents of the certificate file, which can be @@ -2174,8 +2288,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, */ CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if(array == NULL) { - free(certbuf); + if(!array) { failf(data, "SSL: out of memory creating CA certificate array"); return CURLE_OUT_OF_MEMORY; } @@ -2189,7 +2302,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, */ res = pem_to_der((const char *)certbuf + offset, &der, &derlen); if(res < 0) { - free(certbuf); CFRelease(array); failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle", n, offset); @@ -2200,7 +2312,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, if(res == 0 && offset == 0) { /* This is not a PEM file, probably a certificate in DER format. */ rc = append_cert_to_array(data, certbuf, buflen, array); - free(certbuf); if(rc != CURLE_OK) { CFRelease(array); return rc; @@ -2209,14 +2320,12 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, } else if(res == 0) { /* No more certificates in the bundle. */ - free(certbuf); break; } rc = append_cert_to_array(data, der, derlen, array); free(der); if(rc != CURLE_OK) { - free(certbuf); CFRelease(array); return rc; } @@ -2224,7 +2333,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, SecTrustRef trust; OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(trust == NULL) { + if(!trust) { failf(data, "SSL: error getting certificate chain"); CFRelease(array); return CURLE_PEER_FAILED_VERIFICATION; @@ -2273,6 +2382,38 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, } } +static CURLcode verify_cert(struct Curl_easy *data, const char *cafile, + const struct curl_blob *ca_info_blob, + SSLContextRef ctx) +{ + int result; + unsigned char *certbuf; + size_t buflen; + + if(ca_info_blob) { + certbuf = (unsigned char *)malloc(ca_info_blob->len + 1); + if(!certbuf) { + return CURLE_OUT_OF_MEMORY; + } + buflen = ca_info_blob->len; + memcpy(certbuf, ca_info_blob->data, ca_info_blob->len); + certbuf[ca_info_blob->len]='\0'; + } + else if(cafile) { + if(read_cert(cafile, &certbuf, &buflen) < 0) { + failf(data, "SSL: failed to read or invalid CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + } + else + return CURLE_SSL_CACERT_BADFILE; + + result = verify_cert_buf(data, certbuf, buflen, ctx); + free(certbuf); + return result; +} + + #ifdef SECTRANSP_PINNEDPUBKEY static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, SSLContextRef ctx, @@ -2297,19 +2438,19 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, do { SecTrustRef trust; OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(ret != noErr || trust == NULL) + if(ret != noErr || !trust) break; SecKeyRef keyRef = SecTrustCopyPublicKey(trust); CFRelease(trust); - if(keyRef == NULL) + if(!keyRef) break; #ifdef SECTRANSP_PINNEDPUBKEY_V1 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); CFRelease(keyRef); - if(publicKeyBits == NULL) + if(!publicKeyBits) break; #elif SECTRANSP_PINNEDPUBKEY_V2 @@ -2317,7 +2458,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, &publicKeyBits); CFRelease(keyRef); - if(success != errSecSuccess || publicKeyBits == NULL) + if(success != errSecSuccess || !publicKeyBits) break; #endif /* SECTRANSP_PINNEDPUBKEY_V2 */ @@ -2389,12 +2530,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, OSStatus err; SSLCipherSuite cipher; SSLProtocol protocol = 0; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state @@ -2413,8 +2549,10 @@ 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(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + 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), backend->ssl_ctx); if(result) return result; @@ -2601,8 +2739,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, #if CURL_BUILD_MAC_10_6 /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ case errSSLClientCertRequested: - failf(data, "The server has requested a client certificate"); - break; + failf(data, "Server requested a client certificate during the " + "handshake"); + return CURLE_SSL_CLIENTCERT; #endif #if CURL_BUILD_MAC_10_9 /* Alias for errSSLLast, end of error range */ @@ -2640,11 +2779,11 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, switch(protocol) { case kSSLProtocol2: infof(data, "SSL 2.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); + TLSCipherNameForNumber(cipher)); break; case kSSLProtocol3: infof(data, "SSL 3.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); + TLSCipherNameForNumber(cipher)); break; case kTLSProtocol1: infof(data, "TLS 1.0 connection using %s\n", @@ -2681,10 +2820,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(chosenProtocol && - !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), - 0)) { + !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -3258,8 +3396,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(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + 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), backend->ssl_ctx); if(result) return result; @@ -3286,6 +3426,7 @@ static void *sectransp_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_sectransp = { { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ + SSLSUPP_CAINFO_BLOB | #ifdef SECTRANSP_PINNEDPUBKEY SSLSUPP_PINNEDPUBKEY, #else @@ -3313,7 +3454,9 @@ const struct Curl_ssl Curl_ssl_sectransp = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ sectransp_false_start, /* false_start */ - sectransp_sha256sum /* sha256sum */ + sectransp_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #ifdef __clang__ diff --git a/contrib/libs/curl/lib/vtls/vtls.c b/contrib/libs/curl/lib/vtls/vtls.c index 2e07df0a04..65f4f773dd 100644 --- a/contrib/libs/curl/lib/vtls/vtls.c +++ b/contrib/libs/curl/lib/vtls/vtls.c @@ -135,6 +135,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, (data->verifyhost == needle->verifyhost) && (data->verifystatus == needle->verifystatus) && blobcmp(data->cert_blob, needle->cert_blob) && + blobcmp(data->ca_info_blob, needle->ca_info_blob) && Curl_safe_strcasecompare(data->CApath, needle->CApath) && Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && @@ -161,6 +162,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, dest->sessionid = source->sessionid; CLONE_BLOB(cert_blob); + CLONE_BLOB(ca_info_blob); CLONE_STRING(CApath); CLONE_STRING(CAfile); CLONE_STRING(clientcert); @@ -185,6 +187,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) Curl_safefree(sslc->cipher_list13); Curl_safefree(sslc->pinned_key); Curl_safefree(sslc->cert_blob); + Curl_safefree(sslc->ca_info_blob); Curl_safefree(sslc->curves); } @@ -315,6 +318,8 @@ Curl_ssl_connect(struct Curl_easy *data, struct connectdata *conn, if(!result) Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ + else + conn->ssl[sockindex].use = FALSE; return result; } @@ -338,7 +343,9 @@ Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* mark this is being ssl requested from here on. */ conn->ssl[sockindex].use = TRUE; result = Curl_ssl->connect_nonblocking(data, conn, sockindex, done); - if(!result && *done) + if(result) + conn->ssl[sockindex].use = FALSE; + else if(*done) Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ return result; } @@ -579,6 +586,25 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, return CURLE_OK; } +void Curl_ssl_associate_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + if(Curl_ssl->associate_connection) { + Curl_ssl->associate_connection(data, conn, FIRSTSOCKET); + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) + Curl_ssl->associate_connection(data, conn, SECONDARYSOCKET); + } +} + +void Curl_ssl_detach_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + if(Curl_ssl->disassociate_connection) { + Curl_ssl->disassociate_connection(data, FIRSTSOCKET); + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) + Curl_ssl->disassociate_connection(data, SECONDARYSOCKET); + } +} void Curl_ssl_close_all(struct Curl_easy *data) { @@ -1207,7 +1233,9 @@ static const struct Curl_ssl Curl_ssl_multi = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; const struct Curl_ssl *Curl_ssl = diff --git a/contrib/libs/curl/lib/vtls/vtls.h b/contrib/libs/curl/lib/vtls/vtls.h index 2b43e7744b..7f93e7aedb 100644 --- a/contrib/libs/curl/lib/vtls/vtls.h +++ b/contrib/libs/curl/lib/vtls/vtls.h @@ -32,6 +32,7 @@ struct ssl_connect_data; #define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */ #define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */ #define SSLSUPP_TLS13_CIPHERSUITES (1<<5) /* supports TLS 1.3 ciphersuites */ +#define SSLSUPP_CAINFO_BLOB (1<<6) struct Curl_ssl { /* @@ -83,6 +84,11 @@ struct Curl_ssl { bool (*false_start)(void); CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen); + + void (*associate_connection)(struct Curl_easy *data, + struct connectdata *conn, + int sockindex); + void (*disassociate_connection)(struct Curl_easy *data, int sockindex); }; #ifdef USE_SSL @@ -126,9 +132,11 @@ bool Curl_ssl_tls13_ciphersuites(void); #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ #endif -/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */ +/* see https://www.iana.org/assignments/tls-extensiontype-values/ */ #define ALPN_HTTP_1_1_LENGTH 8 #define ALPN_HTTP_1_1 "http/1.1" +#define ALPN_H2_LENGTH 2 +#define ALPN_H2 "h2" /* set of helper macros for the backends to access the correct fields. For the proxy or for the remote host - to properly support HTTPS proxy */ @@ -148,6 +156,8 @@ bool Curl_ssl_tls13_ciphersuites(void); (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name) #define SSL_HOST_DISPNAME() \ (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) +#define SSL_HOST_PORT() \ + (SSL_IS_PROXY() ? conn->port : conn->remote_port) #define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ : data->set.str[STRING_SSL_PINNEDPUBLICKEY]) @@ -158,6 +168,7 @@ bool Curl_ssl_tls13_ciphersuites(void); #define SSL_CONN_CONFIG(var) conn->ssl_config.var #define SSL_HOST_NAME() conn->host.name #define SSL_HOST_DISPNAME() conn->host.dispname +#define SSL_HOST_PORT() conn->remote_port #define SSL_PINNED_PUB_KEY() \ data->set.str[STRING_SSL_PINNEDPUBLICKEY] #endif @@ -277,6 +288,11 @@ bool Curl_ssl_cert_status_request(void); bool Curl_ssl_false_start(void); +void Curl_ssl_associate_conn(struct Curl_easy *data, + struct connectdata *conn); +void Curl_ssl_detach_conn(struct Curl_easy *data, + struct connectdata *conn); + #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ #else /* if not USE_SSL */ @@ -303,6 +319,8 @@ bool Curl_ssl_false_start(void); #define Curl_ssl_cert_status_request() FALSE #define Curl_ssl_false_start() FALSE #define Curl_ssl_tls13_ciphersuites() FALSE +#define Curl_ssl_associate_conn(a,b) Curl_nop_stmt +#define Curl_ssl_detach_conn(a,b) Curl_nop_stmt #endif #endif /* HEADER_CURL_VTLS_H */ diff --git a/contrib/libs/curl/lib/vtls/wolfssl.c b/contrib/libs/curl/lib/vtls/wolfssl.c index f7534ef918..4fa8cb8a27 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.c +++ b/contrib/libs/curl/lib/vtls/wolfssl.c @@ -47,16 +47,6 @@ #endif #endif -/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in - options.h, but is only seen in >= 3.6.6 since that's when they started - disabling SSLv3 by default. */ -#ifndef WOLFSSL_ALLOW_SSLV3 -#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \ - defined(HAVE_WOLFSSLV3_CLIENT_METHOD) -#define WOLFSSL_ALLOW_SSLV3 -#endif -#endif - #include <limits.h> #include "urldata.h" @@ -285,18 +275,6 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, failf(data, "wolfSSL: TLS 1.3 is not yet supported"); return CURLE_SSL_CONNECT_ERROR; #endif - case CURL_SSLVERSION_SSLv3: -#ifdef WOLFSSL_ALLOW_SSLV3 - req_method = SSLv3_client_method(); - use_sni(FALSE); -#else - failf(data, "wolfSSL does not support SSLv3"); - return CURLE_NOT_BUILT_IN; -#endif - break; - case CURL_SSLVERSION_SSLv2: - failf(data, "wolfSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -418,12 +396,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); size_t hostname_len = strlen(hostname); if((hostname_len < USHRT_MAX) && (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && @@ -474,10 +447,10 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, /* wolfSSL's ALPN protocol name list format is a comma separated string of protocols in descending order of preference, eg: "h2,http/1.1" */ -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { - strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + strcpy(protocols + strlen(protocols), ALPN_H2 ","); + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -552,20 +525,9 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, int ret = -1; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const char * const dispname = SSL_IS_PROXY() ? - conn->http_proxy.host.dispname : conn->host.dispname; - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const hostname = conn->host.name; - const char * const dispname = conn->host.dispname; - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif + const char * const hostname = SSL_HOST_NAME(); + const char * const dispname = SSL_HOST_DISPNAME(); + const char * const pinnedpubkey = SSL_PINNED_PUB_KEY(); conn->recv[sockindex] = wolfssl_recv; conn->send[sockindex] = wolfssl_send; @@ -725,11 +687,10 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(protocol_len == ALPN_HTTP_1_1_LENGTH && !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) conn->negnpn = CURL_HTTP_VERSION_1_1; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 else if(data->state.httpwant >= CURL_HTTP_VERSION_2 && - protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) + protocol_len == ALPN_H2_LENGTH && + !memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH)) conn->negnpn = CURL_HTTP_VERSION_2; #endif else @@ -820,7 +781,7 @@ static ssize_t wolfssl_send(struct Curl_easy *data, int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; int rc = SSL_write(backend->handle, mem, memlen); - if(rc < 0) { + if(rc <= 0) { int err = SSL_get_error(backend->handle, rc); switch(err) { @@ -1164,7 +1125,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - wolfssl_sha256sum /* sha256sum */ + wolfssl_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif |