vtls: cleanup SSL config management

- remove `Curl_ssl_get_config()`, no longer needed

Closes #12204
This commit is contained in:
Stefan Eissing 2023-10-26 11:27:42 +02:00 committed by Daniel Stenberg
parent faa45a637f
commit bf0e278a3c
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
9 changed files with 316 additions and 278 deletions

View File

@ -1921,10 +1921,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
TRUE : FALSE; TRUE : FALSE;
/* Update the current connection ssl_config. */ /* Update the current connection ssl_config. */
if(data->conn) { Curl_ssl_conn_config_update(data, FALSE);
data->conn->ssl_config.verifypeer =
data->set.ssl.primary.verifypeer;
}
break; break;
#ifndef CURL_DISABLE_DOH #ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYPEER: case CURLOPT_DOH_SSL_VERIFYPEER:
@ -1944,10 +1941,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
(0 != va_arg(param, long))?TRUE:FALSE; (0 != va_arg(param, long))?TRUE:FALSE;
/* Update the current connection proxy_ssl_config. */ /* Update the current connection proxy_ssl_config. */
if(data->conn) { Curl_ssl_conn_config_update(data, TRUE);
data->conn->proxy_ssl_config.verifypeer =
data->set.proxy_ssl.primary.verifypeer;
}
break; break;
#endif #endif
case CURLOPT_SSL_VERIFYHOST: case CURLOPT_SSL_VERIFYHOST:
@ -1962,10 +1956,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE); data->set.ssl.primary.verifyhost = (bool)((arg & 3) ? TRUE : FALSE);
/* Update the current connection ssl_config. */ /* Update the current connection ssl_config. */
if(data->conn) { Curl_ssl_conn_config_update(data, FALSE);
data->conn->ssl_config.verifyhost =
data->set.ssl.primary.verifyhost;
}
break; break;
#ifndef CURL_DISABLE_DOH #ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYHOST: case CURLOPT_DOH_SSL_VERIFYHOST:
@ -1987,12 +1978,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
/* Treat both 1 and 2 as TRUE */ /* Treat both 1 and 2 as TRUE */
data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE); data->set.proxy_ssl.primary.verifyhost = (bool)((arg & 3)?TRUE:FALSE);
/* Update the current connection proxy_ssl_config. */ /* Update the current connection proxy_ssl_config. */
if(data->conn) { Curl_ssl_conn_config_update(data, TRUE);
data->conn->proxy_ssl_config.verifyhost =
data->set.proxy_ssl.primary.verifyhost;
}
break; break;
#endif #endif
case CURLOPT_SSL_VERIFYSTATUS: case CURLOPT_SSL_VERIFYSTATUS:
@ -2008,10 +1995,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
TRUE : FALSE; TRUE : FALSE;
/* Update the current connection ssl_config. */ /* Update the current connection ssl_config. */
if(data->conn) { Curl_ssl_conn_config_update(data, FALSE);
data->conn->ssl_config.verifystatus =
data->set.ssl.primary.verifystatus;
}
break; break;
#ifndef CURL_DISABLE_DOH #ifndef CURL_DISABLE_DOH
case CURLOPT_DOH_SSL_VERIFYSTATUS: case CURLOPT_DOH_SSL_VERIFYSTATUS:

116
lib/url.c
View File

@ -526,26 +526,16 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
Curl_mime_initpart(&set->mimepost); Curl_mime_initpart(&set->mimepost);
/* Curl_ssl_easy_config_init(data);
* libcurl 7.10 introduced SSL verification *by default*! This needs to be
* switched off unless wanted.
*/
#ifndef CURL_DISABLE_DOH #ifndef CURL_DISABLE_DOH
set->doh_verifyhost = TRUE; set->doh_verifyhost = TRUE;
set->doh_verifypeer = TRUE; set->doh_verifypeer = TRUE;
#endif #endif
set->ssl.primary.verifypeer = TRUE;
set->ssl.primary.verifyhost = TRUE;
#ifdef USE_SSH #ifdef USE_SSH
/* defaults to any auth type */ /* defaults to any auth type */
set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; set->ssh_auth_types = CURLSSH_AUTH_DEFAULT;
set->new_directory_perms = 0755; /* Default permissions */ set->new_directory_perms = 0755; /* Default permissions */
#endif #endif
set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
default */
#ifndef CURL_DISABLE_PROXY
set->proxy_ssl = set->ssl;
#endif
set->new_file_perms = 0644; /* Default permissions */ set->new_file_perms = 0644; /* Default permissions */
set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL; set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL;
@ -707,7 +697,6 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn)
Curl_safefree(conn->socks_proxy.passwd); Curl_safefree(conn->socks_proxy.passwd);
Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
#endif #endif
Curl_safefree(conn->user); Curl_safefree(conn->user);
Curl_safefree(conn->passwd); Curl_safefree(conn->passwd);
@ -722,7 +711,7 @@ static void conn_free(struct Curl_easy *data, struct connectdata *conn)
Curl_safefree(conn->hostname_resolve); Curl_safefree(conn->hostname_resolve);
Curl_safefree(conn->secondaryhostname); Curl_safefree(conn->secondaryhostname);
Curl_safefree(conn->localdev); Curl_safefree(conn->localdev);
Curl_free_primary_ssl_config(&conn->ssl_config); Curl_ssl_conn_config_cleanup(conn);
#ifdef USE_UNIX_SOCKETS #ifdef USE_UNIX_SOCKETS
Curl_safefree(conn->unix_domain_socket); Curl_safefree(conn->unix_domain_socket);
@ -1220,12 +1209,10 @@ ConnectionExists(struct Curl_easy *data,
continue; continue;
else if(needle->handler->flags&PROTOPT_SSL) { else if(needle->handler->flags&PROTOPT_SSL) {
/* use double layer ssl */ /* use double layer ssl */
if(!Curl_ssl_config_matches(&needle->proxy_ssl_config, if(!Curl_ssl_conn_config_match(data, needle, check, TRUE))
&check->proxy_ssl_config))
continue; continue;
} }
else if(!Curl_ssl_config_matches(&needle->ssl_config, else if(!Curl_ssl_conn_config_match(data, needle, check, FALSE))
&check->ssl_config))
continue; continue;
} }
} }
@ -1343,8 +1330,7 @@ ConnectionExists(struct Curl_easy *data,
if(needle->handler->flags & PROTOPT_SSL) { if(needle->handler->flags & PROTOPT_SSL) {
/* This is a SSL connection so verify that we're using the same /* This is a SSL connection so verify that we're using the same
SSL options as well */ SSL options as well */
if(!Curl_ssl_config_matches(&needle->ssl_config, if(!Curl_ssl_conn_config_match(data, needle, check, FALSE)) {
&check->ssl_config)) {
DEBUGF(infof(data, DEBUGF(infof(data,
"Connection #%" CURL_FORMAT_CURL_OFF_T "Connection #%" CURL_FORMAT_CURL_OFF_T
" has different SSL parameters, can't reuse", " has different SSL parameters, can't reuse",
@ -1550,17 +1536,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
#endif
conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
#ifndef CURL_DISABLE_PROXY
conn->proxy_ssl_config.verifystatus =
data->set.proxy_ssl.primary.verifystatus;
conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
#endif #endif
conn->ip_version = data->set.ipver; conn->ip_version = data->set.ipver;
conn->connect_only = data->set.connect_only; conn->connect_only = data->set.connect_only;
@ -3587,85 +3562,10 @@ static CURLcode create_conn(struct Curl_easy *data,
conn->send[SECONDARYSOCKET] = Curl_conn_send; conn->send[SECONDARYSOCKET] = Curl_conn_send;
conn->bits.tcp_fastopen = data->set.tcp_fastopen; conn->bits.tcp_fastopen = data->set.tcp_fastopen;
/* Get a cloned copy of the SSL config situation stored in the /* Init the SSL configuration for the connection from settings in data */
connection struct. But to get this going nicely, we must first make result = Curl_ssl_conn_config_init(data, conn);
sure that the strings in the master copy are pointing to the correct if(result)
strings in the session handle strings array!
Keep in mind that the pointers in the master copy are pointing to strings
that will be freed as part of the Curl_easy struct, but all cloned
copies will be separately allocated.
*/
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
data->set.ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST];
data->set.ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST];
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT];
data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO];
data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.primary.ca_info_blob =
data->set.blobs[BLOB_CAINFO_PROXY];
data->set.proxy_ssl.primary.issuercert =
data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.primary.issuercert_blob =
data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.primary.CRLfile =
data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
#endif
data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
data->set.ssl.key = data->set.str[STRING_KEY];
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
#ifdef USE_TLS_SRP
data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
#ifndef CURL_DISABLE_PROXY
data->set.proxy_ssl.primary.username =
data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.proxy_ssl.primary.password =
data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
#endif
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY];
if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
&conn->ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out; goto out;
}
#ifndef CURL_DISABLE_PROXY
if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
&conn->proxy_ssl_config)) {
result = CURLE_OUT_OF_MEMORY;
goto out;
}
#endif
prune_dead_connections(data); prune_dead_connections(data);

View File

@ -38,6 +38,7 @@
#include "http1.h" #include "http1.h"
#include "curl_msh3.h" #include "curl_msh3.h"
#include "socketpair.h" #include "socketpair.h"
#include "vtls/vtls.h"
#include "vquic/vquic.h" #include "vquic/vquic.h"
/* The last 3 #include files should be in this order */ /* The last 3 #include files should be in this order */
@ -796,14 +797,20 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
{ {
struct cf_msh3_ctx *ctx = cf->ctx; struct cf_msh3_ctx *ctx = cf->ctx;
bool verify = !!cf->conn->ssl_config.verifypeer; struct ssl_primary_config *conn_config;
MSH3_ADDR addr = {0}; MSH3_ADDR addr = {0};
CURLcode result; CURLcode result;
bool verify;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
verify = !!conn_config->verifypeer;
memcpy(&addr, &ctx->addr.sa_addr, ctx->addr.addrlen); memcpy(&addr, &ctx->addr.sa_addr, ctx->addr.addrlen);
MSH3_SET_PORT(&addr, (uint16_t)cf->conn->remote_port); MSH3_SET_PORT(&addr, (uint16_t)cf->conn->remote_port);
if(verify && (cf->conn->ssl_config.CAfile || cf->conn->ssl_config.CApath)) { if(verify && (conn_config->CAfile || conn_config->CApath)) {
/* TODO: need a way to provide trust anchors to MSH3 */ /* TODO: need a way to provide trust anchors to MSH3 */
#ifdef DEBUGBUILD #ifdef DEBUGBUILD
/* we need this for our test cases to run */ /* we need this for our test cases to run */

View File

@ -440,14 +440,19 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
struct Curl_cfilter *cf, struct Curl_easy *data) struct Curl_cfilter *cf, struct Curl_easy *data)
{ {
struct cf_ngtcp2_ctx *ctx = cf->ctx; struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct connectdata *conn = cf->conn; struct ssl_primary_config *conn_config;
CURLcode result = CURLE_FAILED_INIT; CURLcode result = CURLE_FAILED_INIT;
SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
if(!ssl_ctx) { if(!ssl_ctx) {
result = CURLE_OUT_OF_MEMORY; result = CURLE_OUT_OF_MEMORY;
goto out; goto out;
} }
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config) {
result = CURLE_FAILED_INIT;
goto out;
}
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) { if(ngtcp2_crypto_boringssl_configure_client_context(ssl_ctx) != 0) {
@ -464,8 +469,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
SSL_CTX_set_default_verify_paths(ssl_ctx); SSL_CTX_set_default_verify_paths(ssl_ctx);
{ {
const char *curves = conn->ssl_config.curves ? const char *curves = conn_config->curves ?
conn->ssl_config.curves : QUIC_GROUPS; conn_config->curves : QUIC_GROUPS;
if(!SSL_CTX_set1_curves_list(ssl_ctx, curves)) { if(!SSL_CTX_set1_curves_list(ssl_ctx, curves)) {
failf(data, "failed setting curves list for QUIC: '%s'", curves); failf(data, "failed setting curves list for QUIC: '%s'", curves);
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
@ -474,8 +479,8 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
#ifndef OPENSSL_IS_BORINGSSL #ifndef OPENSSL_IS_BORINGSSL
{ {
const char *ciphers13 = conn->ssl_config.cipher_list13 ? const char *ciphers13 = conn_config->cipher_list13 ?
conn->ssl_config.cipher_list13 : QUIC_CIPHERS; conn_config->cipher_list13 : QUIC_CIPHERS;
if(SSL_CTX_set_ciphersuites(ssl_ctx, ciphers13) != 1) { if(SSL_CTX_set_ciphersuites(ssl_ctx, ciphers13) != 1) {
failf(data, "failed setting QUIC cipher suite: %s", ciphers13); failf(data, "failed setting QUIC cipher suite: %s", ciphers13);
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
@ -494,7 +499,7 @@ static CURLcode quic_ssl_ctx(SSL_CTX **pssl_ctx,
* fail to connect if the verification fails, or if it should continue * fail to connect if the verification fails, or if it should continue
* anyway. In the latter case the result of the verification is checked with * anyway. In the latter case the result of the verification is checked with
* SSL_get_verify_result() below. */ * SSL_get_verify_result() below. */
SSL_CTX_set_verify(ssl_ctx, conn->ssl_config.verifypeer ? SSL_CTX_set_verify(ssl_ctx, conn_config->verifypeer ?
SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
/* give application a chance to interfere with SSL set up. */ /* give application a chance to interfere with SSL set up. */
@ -533,7 +538,7 @@ static CURLcode quic_set_client_cert(struct Curl_cfilter *cf,
SSL_CTX *ssl_ctx = ctx->sslctx; SSL_CTX *ssl_ctx = ctx->sslctx;
const struct ssl_config_data *ssl_config; const struct ssl_config_data *ssl_config;
ssl_config = Curl_ssl_get_config(data, FIRSTSOCKET); ssl_config = Curl_ssl_cf_get_config(cf, data);
DEBUGASSERT(ssl_config); DEBUGASSERT(ssl_config);
if(ssl_config->primary.clientcert || ssl_config->primary.cert_blob if(ssl_config->primary.clientcert || ssl_config->primary.cert_blob
@ -591,6 +596,7 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
{ {
struct cf_ngtcp2_ctx *ctx = cf->ctx; struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
CURLcode result; CURLcode result;
gnutls_datum_t alpn[2]; gnutls_datum_t alpn[2];
/* this will need some attention when HTTPS proxy over QUIC get fixed */ /* this will need some attention when HTTPS proxy over QUIC get fixed */
@ -598,12 +604,16 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
long * const pverifyresult = &data->set.ssl.certverifyresult; long * const pverifyresult = &data->set.ssl.certverifyresult;
int rc; int rc;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
DEBUGASSERT(ctx->gtls == NULL); DEBUGASSERT(ctx->gtls == NULL);
ctx->gtls = calloc(1, sizeof(*(ctx->gtls))); ctx->gtls = calloc(1, sizeof(*(ctx->gtls)));
if(!ctx->gtls) if(!ctx->gtls)
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
result = gtls_client_init(data, &cf->conn->ssl_config, &data->set.ssl, result = gtls_client_init(data, conn_config, &data->set.ssl,
hostname, ctx->gtls, pverifyresult); hostname, ctx->gtls, pverifyresult);
if(result) if(result)
return result; return result;
@ -644,10 +654,17 @@ static CURLcode quic_init_ssl(struct Curl_cfilter *cf,
static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx, static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx,
struct Curl_cfilter *cf, struct Curl_easy *data) struct Curl_cfilter *cf, struct Curl_easy *data)
{ {
struct connectdata *conn = cf->conn;
CURLcode result = CURLE_FAILED_INIT; CURLcode result = CURLE_FAILED_INIT;
WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); struct ssl_primary_config *conn_config;
WOLFSSL_CTX *ssl_ctx = NULL;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config) {
result = CURLE_FAILED_INIT;
goto out;
}
ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
if(!ssl_ctx) { if(!ssl_ctx) {
result = CURLE_OUT_OF_MEMORY; result = CURLE_OUT_OF_MEMORY;
goto out; goto out;
@ -655,13 +672,14 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx,
if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) { if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) {
failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed"); failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
result = CURLE_FAILED_INIT;
goto out; goto out;
} }
wolfSSL_CTX_set_default_verify_paths(ssl_ctx); wolfSSL_CTX_set_default_verify_paths(ssl_ctx);
if(wolfSSL_CTX_set_cipher_list(ssl_ctx, conn->ssl_config.cipher_list13 ? if(wolfSSL_CTX_set_cipher_list(ssl_ctx, conn_config->cipher_list13 ?
conn->ssl_config.cipher_list13 : conn_config->cipher_list13 :
QUIC_CIPHERS) != 1) { QUIC_CIPHERS) != 1) {
char error_buffer[256]; char error_buffer[256];
ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer));
@ -669,8 +687,8 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx,
goto out; goto out;
} }
if(wolfSSL_CTX_set1_groups_list(ssl_ctx, conn->ssl_config.curves ? if(wolfSSL_CTX_set1_groups_list(ssl_ctx, conn_config->curves ?
conn->ssl_config.curves : conn_config->curves :
(char *)QUIC_GROUPS) != 1) { (char *)QUIC_GROUPS) != 1) {
failf(data, "wolfSSL failed to set curves"); failf(data, "wolfSSL failed to set curves");
goto out; goto out;
@ -687,9 +705,9 @@ static CURLcode quic_ssl_ctx(WOLFSSL_CTX **pssl_ctx,
#endif #endif
} }
if(conn->ssl_config.verifypeer) { if(conn_config->verifypeer) {
const char * const ssl_cafile = conn->ssl_config.CAfile; const char * const ssl_cafile = conn_config->CAfile;
const char * const ssl_capath = conn->ssl_config.CApath; const char * const ssl_capath = conn_config->CApath;
wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
if(ssl_cafile || ssl_capath) { if(ssl_cafile || ssl_capath) {
@ -1912,11 +1930,16 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
{ {
struct cf_ngtcp2_ctx *ctx = cf->ctx; struct cf_ngtcp2_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
const char *hostname, *disp_hostname; const char *hostname, *disp_hostname;
int port; int port;
char *snihost; char *snihost;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
Curl_conn_get_host(data, cf->sockindex, &hostname, &disp_hostname, &port); Curl_conn_get_host(data, cf->sockindex, &hostname, &disp_hostname, &port);
snihost = Curl_ssl_snihost(data, hostname, NULL); snihost = Curl_ssl_snihost(data, hostname, NULL);
if(!snihost) if(!snihost)
@ -1926,7 +1949,7 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
cf->conn->httpversion = 30; cf->conn->httpversion = 30;
cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
if(cf->conn->ssl_config.verifyhost) { if(conn_config->verifyhost) {
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
X509 *server_cert; X509 *server_cert;
server_cert = SSL_get_peer_certificate(ctx->ssl); server_cert = SSL_get_peer_certificate(ctx->ssl);
@ -1939,7 +1962,7 @@ static CURLcode qng_verify_peer(struct Curl_cfilter *cf,
return result; return result;
#elif defined(USE_GNUTLS) #elif defined(USE_GNUTLS)
result = Curl_gtls_verifyserver(data, ctx->gtls->session, result = Curl_gtls_verifyserver(data, ctx->gtls->session,
&cf->conn->ssl_config, &data->set.ssl, conn_config, &data->set.ssl,
hostname, disp_hostname, hostname, disp_hostname,
data->set.str[STRING_SSL_PINNEDPUBLICKEY]); data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
if(result) if(result)

View File

@ -139,11 +139,16 @@ static CURLcode quic_x509_store_setup(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
{ {
struct cf_quiche_ctx *ctx = cf->ctx; struct cf_quiche_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
if(!ctx->x509_store_setup) { if(!ctx->x509_store_setup) {
if(cf->conn->ssl_config.verifypeer) { if(conn_config->verifypeer) {
const char * const ssl_cafile = cf->conn->ssl_config.CAfile; const char * const ssl_cafile = conn_config->CAfile;
const char * const ssl_capath = cf->conn->ssl_config.CApath; const char * const ssl_capath = conn_config->CApath;
if(ssl_cafile || ssl_capath) { if(ssl_cafile || ssl_capath) {
SSL_CTX_set_verify(ctx->sslctx, SSL_VERIFY_PEER, NULL); SSL_CTX_set_verify(ctx->sslctx, SSL_VERIFY_PEER, NULL);
/* tell OpenSSL where to find CA certificates that are used to verify /* tell OpenSSL where to find CA certificates that are used to verify
@ -176,9 +181,12 @@ static CURLcode quic_x509_store_setup(struct Curl_cfilter *cf,
static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data) static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
{ {
struct cf_quiche_ctx *ctx = cf->ctx; struct cf_quiche_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
unsigned char checkip[16]; unsigned char checkip[16];
struct connectdata *conn = data->conn;
const char *curves = conn->ssl_config.curves; conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
DEBUGASSERT(!ctx->sslctx); DEBUGASSERT(!ctx->sslctx);
ctx->sslctx = SSL_CTX_new(TLS_method()); ctx->sslctx = SSL_CTX_new(TLS_method());
@ -197,8 +205,10 @@ static CURLcode quic_ssl_setup(struct Curl_cfilter *cf, struct Curl_easy *data)
SSL_CTX_set_keylog_callback(ctx->sslctx, keylog_callback); SSL_CTX_set_keylog_callback(ctx->sslctx, keylog_callback);
} }
if(curves && !SSL_CTX_set1_curves_list(ctx->sslctx, curves)) { if(conn_config->curves &&
failf(data, "failed setting curves list for QUIC: '%s'", curves); !SSL_CTX_set1_curves_list(ctx->sslctx, conn_config->curves)) {
failf(data, "failed setting curves list for QUIC: '%s'",
conn_config->curves);
return CURLE_SSL_CIPHER; return CURLE_SSL_CIPHER;
} }
@ -1239,13 +1249,18 @@ static CURLcode cf_verify_peer(struct Curl_cfilter *cf,
struct Curl_easy *data) struct Curl_easy *data)
{ {
struct cf_quiche_ctx *ctx = cf->ctx; struct cf_quiche_ctx *ctx = cf->ctx;
struct ssl_primary_config *conn_config;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
conn_config = Curl_ssl_cf_get_primary_config(cf);
if(!conn_config)
return CURLE_FAILED_INIT;
cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
cf->conn->httpversion = 30; cf->conn->httpversion = 30;
cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX; cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
if(cf->conn->ssl_config.verifyhost) { if(conn_config->verifyhost) {
X509 *server_cert; X509 *server_cert;
server_cert = SSL_get_peer_certificate(ctx->ssl); server_cert = SSL_get_peer_certificate(ctx->ssl);
if(!server_cert) { if(!server_cert) {

View File

@ -4628,22 +4628,9 @@ static ssize_t ossl_send(struct Curl_cfilter *cf,
case SSL_ERROR_SSL: { case SSL_ERROR_SSL: {
/* A failure in the SSL library occurred, usually a protocol error. /* A failure in the SSL library occurred, usually a protocol error.
The OpenSSL error queue contains more information on the error. */ The OpenSSL error queue contains more information on the error. */
struct Curl_cfilter *cf_ssl_next = Curl_ssl_cf_get_ssl(cf->next);
struct ssl_connect_data *connssl_next = cf_ssl_next?
cf_ssl_next->ctx : NULL;
sslerror = ERR_get_error(); sslerror = ERR_get_error();
if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL && failf(data, "SSL_write() error: %s",
ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET && ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
connssl->state == ssl_connection_complete &&
(connssl_next && connssl_next->state == ssl_connection_complete)
) {
char ver[120];
(void)ossl_version(ver, sizeof(ver));
failf(data, "Error: %s does not support double SSL tunneling.", ver);
}
else
failf(data, "SSL_write() error: %s",
ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
*curlcode = CURLE_SEND_ERROR; *curlcode = CURLE_SEND_ERROR;
rc = -1; rc = -1;
goto out; goto out;

View File

@ -158,40 +158,67 @@ static const struct alpn_spec *alpn_get_spec(int httpwant, bool use_alpn)
#endif /* USE_SSL */ #endif /* USE_SSL */
bool void Curl_ssl_easy_config_init(struct Curl_easy *data)
Curl_ssl_config_matches(struct ssl_primary_config *data,
struct ssl_primary_config *needle)
{ {
if((data->version == needle->version) && /*
(data->version_max == needle->version_max) && * libcurl 7.10 introduced SSL verification *by default*! This needs to be
(data->ssl_options == needle->ssl_options) && * switched off unless wanted.
(data->verifypeer == needle->verifypeer) && */
(data->verifyhost == needle->verifyhost) && data->set.ssl.primary.verifypeer = TRUE;
(data->verifystatus == needle->verifystatus) && data->set.ssl.primary.verifyhost = TRUE;
blobcmp(data->cert_blob, needle->cert_blob) && data->set.ssl.primary.sessionid = TRUE; /* session ID caching by default */
blobcmp(data->ca_info_blob, needle->ca_info_blob) && #ifndef CURL_DISABLE_PROXY
blobcmp(data->issuercert_blob, needle->issuercert_blob) && data->set.proxy_ssl = data->set.ssl;
Curl_safecmp(data->CApath, needle->CApath) &&
Curl_safecmp(data->CAfile, needle->CAfile) &&
Curl_safecmp(data->issuercert, needle->issuercert) &&
Curl_safecmp(data->clientcert, needle->clientcert) &&
#ifdef USE_TLS_SRP
!Curl_timestrcmp(data->username, needle->username) &&
!Curl_timestrcmp(data->password, needle->password) &&
#endif #endif
strcasecompare(data->cipher_list, needle->cipher_list) && }
strcasecompare(data->cipher_list13, needle->cipher_list13) &&
strcasecompare(data->curves, needle->curves) && static bool
strcasecompare(data->CRLfile, needle->CRLfile) && match_ssl_primary_config(struct Curl_easy *data,
strcasecompare(data->pinned_key, needle->pinned_key)) struct ssl_primary_config *c1,
struct ssl_primary_config *c2)
{
(void)data;
if((c1->version == c2->version) &&
(c1->version_max == c2->version_max) &&
(c1->ssl_options == c2->ssl_options) &&
(c1->verifypeer == c2->verifypeer) &&
(c1->verifyhost == c2->verifyhost) &&
(c1->verifystatus == c2->verifystatus) &&
blobcmp(c1->cert_blob, c2->cert_blob) &&
blobcmp(c1->ca_info_blob, c2->ca_info_blob) &&
blobcmp(c1->issuercert_blob, c2->issuercert_blob) &&
Curl_safecmp(c1->CApath, c2->CApath) &&
Curl_safecmp(c1->CAfile, c2->CAfile) &&
Curl_safecmp(c1->issuercert, c2->issuercert) &&
Curl_safecmp(c1->clientcert, c2->clientcert) &&
#ifdef USE_TLS_SRP
!Curl_timestrcmp(c1->username, c2->username) &&
!Curl_timestrcmp(c1->password, c2->password) &&
#endif
strcasecompare(c1->cipher_list, c2->cipher_list) &&
strcasecompare(c1->cipher_list13, c2->cipher_list13) &&
strcasecompare(c1->curves, c2->curves) &&
strcasecompare(c1->CRLfile, c2->CRLfile) &&
strcasecompare(c1->pinned_key, c2->pinned_key))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
bool bool Curl_ssl_conn_config_match(struct Curl_easy *data,
Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct connectdata *conn,
struct ssl_primary_config *dest) struct connectdata *candidate,
bool proxy)
{
if(proxy)
return match_ssl_primary_config(data, &conn->proxy_ssl_config,
&candidate->proxy_ssl_config);
return match_ssl_primary_config(data, &conn->ssl_config,
&candidate->ssl_config);
}
static bool clone_ssl_primary_config(struct ssl_primary_config *source,
struct ssl_primary_config *dest)
{ {
dest->version = source->version; dest->version = source->version;
dest->version_max = source->version_max; dest->version_max = source->version_max;
@ -221,7 +248,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
return TRUE; return TRUE;
} }
void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) static void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
{ {
Curl_safefree(sslc->CApath); Curl_safefree(sslc->CApath);
Curl_safefree(sslc->CAfile); Curl_safefree(sslc->CAfile);
@ -241,6 +268,117 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
#endif #endif
} }
static CURLcode Curl_ssl_init_ssl_config(struct Curl_easy *data,
struct ssl_primary_config *config)
{
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH];
data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE];
data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT];
data->set.ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST];
data->set.ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST];
data->set.ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY];
data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT];
data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO];
data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES];
#ifdef USE_TLS_SRP
data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
#endif
data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
data->set.ssl.key = data->set.str[STRING_KEY];
data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY];
if(!clone_ssl_primary_config(&data->set.ssl.primary, config))
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
#ifndef CURL_DISABLE_PROXY
static CURLcode
Curl_ssl_init_proxy_ssl_config(struct Curl_easy *data,
struct ssl_primary_config *config)
{
data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.proxy_ssl.primary.cipher_list =
data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
data->set.proxy_ssl.primary.cipher_list13 =
data->set.str[STRING_SSL_CIPHER13_LIST_PROXY];
data->set.proxy_ssl.primary.pinned_key =
data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY];
data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY];
data->set.proxy_ssl.primary.ca_info_blob =
data->set.blobs[BLOB_CAINFO_PROXY];
data->set.proxy_ssl.primary.issuercert =
data->set.str[STRING_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.primary.issuercert_blob =
data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
data->set.proxy_ssl.primary.CRLfile =
data->set.str[STRING_SSL_CRLFILE_PROXY];
data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
#ifdef USE_TLS_SRP
data->set.proxy_ssl.primary.username =
data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
data->set.proxy_ssl.primary.password =
data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif
if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, config))
return CURLE_OUT_OF_MEMORY;
return CURLE_OK;
}
#endif /* !CURL_DISABLE_PROXY */
CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data,
struct connectdata *conn)
{
CURLcode result;
/* Get a cloned copy of the SSL config situation for use in
* the connection. `data` might have a shorter lifetime than `conn`*/
result = Curl_ssl_init_ssl_config(data, &conn->ssl_config);
if(result)
goto out;
#ifndef CURL_DISABLE_PROXY
result = Curl_ssl_init_proxy_ssl_config(data, &conn->proxy_ssl_config);
#endif
out:
return result;
}
void Curl_ssl_conn_config_cleanup(struct connectdata *conn)
{
Curl_free_primary_ssl_config(&conn->ssl_config);
#ifndef CURL_DISABLE_PROXY
Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
#endif
}
void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy)
{
/* May be called on an easy that has no connection yet */
if(data->conn) {
struct ssl_primary_config *src, *dest;
src = for_proxy? &data->set.proxy_ssl.primary : &data->set.ssl.primary;
dest = for_proxy? &data->conn->proxy_ssl_config : &data->conn->ssl_config;
dest->verifyhost = src->verifyhost;
dest->verifypeer = src->verifypeer;
dest->verifystatus = src->verifystatus;
}
}
#ifdef USE_SSL #ifdef USE_SSL
static int multissl_setup(const struct Curl_ssl *backend); static int multissl_setup(const struct Curl_ssl *backend);
#endif #endif
@ -441,7 +579,7 @@ bool Curl_ssl_getsessionid(struct Curl_cfilter *cf,
cf->conn->conn_to_port == check->conn_to_port)) && cf->conn->conn_to_port == check->conn_to_port)) &&
(connssl->port == check->remote_port) && (connssl->port == check->remote_port) &&
strcasecompare(cf->conn->handler->scheme, check->scheme) && strcasecompare(cf->conn->handler->scheme, check->scheme) &&
Curl_ssl_config_matches(conn_config, &check->ssl_config)) { match_ssl_primary_config(data, conn_config, &check->ssl_config)) {
/* yes, we have a session ID! */ /* yes, we have a session ID! */
(*general_age)++; /* increase general age */ (*general_age)++; /* increase general age */
check->age = *general_age; /* set this as used in this age */ check->age = *general_age; /* set this as used in this age */
@ -590,7 +728,7 @@ CURLcode Curl_ssl_addsessionid(struct Curl_cfilter *cf,
store->remote_port = connssl->port; store->remote_port = connssl->port;
store->scheme = cf->conn->handler->scheme; store->scheme = cf->conn->handler->scheme;
if(!Curl_clone_primary_ssl_config(conn_config, &store->ssl_config)) { if(!clone_ssl_primary_config(conn_config, &store->ssl_config)) {
Curl_free_primary_ssl_config(&store->ssl_config); Curl_free_primary_ssl_config(&store->ssl_config);
store->sessionid = NULL; /* let caller free sessionid */ store->sessionid = NULL; /* let caller free sessionid */
free(clone_host); free(clone_host);
@ -1831,6 +1969,16 @@ bool Curl_ssl_supports(struct Curl_easy *data, int option)
return (Curl_ssl->supports & option)? TRUE : FALSE; return (Curl_ssl->supports & option)? TRUE : FALSE;
} }
static struct Curl_cfilter *get_ssl_filter(struct Curl_cfilter *cf)
{
for(; cf; cf = cf->next) {
if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy)
return cf;
}
return NULL;
}
void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex,
CURLINFO info, int n) CURLINFO info, int n)
{ {
@ -1838,8 +1986,8 @@ void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex,
(void)n; (void)n;
if(data->conn) { if(data->conn) {
struct Curl_cfilter *cf; struct Curl_cfilter *cf;
/* get first filter in chain, if any is present */ /* get first SSL filter in chain, if any is present */
cf = Curl_ssl_cf_get_ssl(data->conn->cfilter[sockindex]); cf = get_ssl_filter(data->conn->cfilter[sockindex]);
if(cf) { if(cf) {
struct cf_call_data save; struct cf_call_data save;
CF_DATA_SAVE(save, cf, data); CF_DATA_SAVE(save, cf, data);
@ -1869,23 +2017,6 @@ CURLcode Curl_ssl_cfilter_remove(struct Curl_easy *data,
return result; return result;
} }
static struct Curl_cfilter *get_ssl_cf_engaged(struct connectdata *conn,
int sockindex)
{
struct Curl_cfilter *cf, *lowest_ssl_cf = NULL;
for(cf = conn->cfilter[sockindex]; cf; cf = cf->next) {
if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy) {
lowest_ssl_cf = cf;
if(cf->connected || (cf->next && cf->next->connected)) {
/* connected or about to start */
return cf;
}
}
}
return lowest_ssl_cf;
}
bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf) bool Curl_ssl_cf_is_proxy(struct Curl_cfilter *cf)
{ {
return (cf->cft == &Curl_cft_ssl_proxy); return (cf->cft == &Curl_cft_ssl_proxy);
@ -1902,17 +2033,6 @@ Curl_ssl_cf_get_config(struct Curl_cfilter *cf, struct Curl_easy *data)
#endif #endif
} }
struct ssl_config_data *
Curl_ssl_get_config(struct Curl_easy *data, int sockindex)
{
struct Curl_cfilter *cf;
(void)data;
DEBUGASSERT(data->conn);
cf = get_ssl_cf_engaged(data->conn, sockindex);
return cf? Curl_ssl_cf_get_config(cf, data) : &data->set.ssl;
}
struct ssl_primary_config * struct ssl_primary_config *
Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf) Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf)
{ {
@ -1924,15 +2044,6 @@ Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf)
#endif #endif
} }
struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf)
{
for(; cf; cf = cf->next) {
if(cf->cft == &Curl_cft_ssl || cf->cft == &Curl_cft_ssl_proxy)
return cf;
}
return NULL;
}
CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf, CURLcode Curl_alpn_to_proto_buf(struct alpn_proto_buf *buf,
const struct alpn_spec *spec) const struct alpn_spec *spec)
{ {

View File

@ -66,14 +66,41 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name,
#endif #endif
char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen); char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen);
bool Curl_ssl_config_matches(struct ssl_primary_config *data,
struct ssl_primary_config *needle);
bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
struct ssl_primary_config *dest);
void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc);
curl_sslbackend Curl_ssl_backend(void); curl_sslbackend Curl_ssl_backend(void);
/**
* Init ssl config for a new easy handle.
*/
void Curl_ssl_easy_config_init(struct Curl_easy *data);
/**
* Init SSL configs (main + proxy) for a new connection from the easy handle.
*/
CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data,
struct connectdata *conn);
/**
* Free allocated resources in SSL configs (main + proxy) for
* the given connection.
*/
void Curl_ssl_conn_config_cleanup(struct connectdata *conn);
/**
* Return TRUE iff SSL configuration from `conn` is functionally the
* same as the one on `candidate`.
* @param proxy match the proxy SSL config or the main one
*/
bool Curl_ssl_conn_config_match(struct Curl_easy *data,
struct connectdata *conn,
struct connectdata *candidate,
bool proxy);
/* Update certain connection SSL config flags after they have
* been changed on the easy handle. Will work for `verifypeer`,
* `verifyhost` and `verifystatus`. */
void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy);
#ifdef USE_SSL #ifdef USE_SSL
int Curl_ssl_init(void); int Curl_ssl_init(void);
void Curl_ssl_cleanup(void); void Curl_ssl_cleanup(void);
@ -159,18 +186,6 @@ CURLcode Curl_cf_ssl_proxy_insert_after(struct Curl_cfilter *cf_at,
struct Curl_easy *data); struct Curl_easy *data);
#endif /* !CURL_DISABLE_PROXY */ #endif /* !CURL_DISABLE_PROXY */
/**
* Get the SSL configuration that is used on the connection.
* This returns NULL if no SSL is configured.
* Otherwise it returns the config of the first (highest) one that is
* either connected, in handshake or about to start
* (e.g. all filters below it are connected). If SSL filters are present,
* but neither can start operating, return the config of the lowest one
* that will first come into effect when connecting.
*/
struct ssl_config_data *Curl_ssl_get_config(struct Curl_easy *data,
int sockindex);
/** /**
* True iff the underlying SSL implementation supports the option. * True iff the underlying SSL implementation supports the option.
* Option is one of the defined SSLSUPP_* values. * Option is one of the defined SSLSUPP_* values.
@ -188,6 +203,18 @@ bool Curl_ssl_supports(struct Curl_easy *data, int ssl_option);
void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex, void *Curl_ssl_get_internals(struct Curl_easy *data, int sockindex,
CURLINFO info, int n); CURLINFO info, int n);
/**
* Get the ssl_config_data in `data` that is relevant for cfilter `cf`.
*/
struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf,
struct Curl_easy *data);
/**
* Get the primary config relevant for the filter from its connection.
*/
struct ssl_primary_config *
Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf);
extern struct Curl_cftype Curl_cft_ssl; extern struct Curl_cftype Curl_cft_ssl;
extern struct Curl_cftype Curl_cft_ssl_proxy; extern struct Curl_cftype Curl_cft_ssl_proxy;
@ -209,8 +236,9 @@ extern struct Curl_cftype Curl_cft_ssl_proxy;
#define Curl_ssl_get_internals(a,b,c,d) NULL #define Curl_ssl_get_internals(a,b,c,d) NULL
#define Curl_ssl_supports(a,b) FALSE #define Curl_ssl_supports(a,b) FALSE
#define Curl_ssl_cfilter_add(a,b,c) CURLE_NOT_BUILT_IN #define Curl_ssl_cfilter_add(a,b,c) CURLE_NOT_BUILT_IN
#define Curl_ssl_get_config(a,b) NULL
#define Curl_ssl_cfilter_remove(a,b) CURLE_OK #define Curl_ssl_cfilter_remove(a,b) CURLE_OK
#define Curl_ssl_cf_get_config(a,b) NULL
#define Curl_ssl_cf_get_primary_config(a) NULL
#endif #endif
#endif /* HEADER_CURL_VTLS_H */ #endif /* HEADER_CURL_VTLS_H */

View File

@ -169,23 +169,6 @@ bool Curl_none_false_start(void);
void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data, void Curl_ssl_adjust_pollset(struct Curl_cfilter *cf, struct Curl_easy *data,
struct easy_pollset *ps); struct easy_pollset *ps);
/**
* Get the ssl_config_data in `data` that is relevant for cfilter `cf`.
*/
struct ssl_config_data *Curl_ssl_cf_get_config(struct Curl_cfilter *cf,
struct Curl_easy *data);
/**
* Get the primary config relevant for the filter from its connection.
*/
struct ssl_primary_config *
Curl_ssl_cf_get_primary_config(struct Curl_cfilter *cf);
/**
* Get the first SSL filter in the chain starting with `cf`, or NULL.
*/
struct Curl_cfilter *Curl_ssl_cf_get_ssl(struct Curl_cfilter *cf);
/** /**
* Get the SSL filter below the given one or NULL if there is none. * Get the SSL filter below the given one or NULL if there is none.
*/ */