vtls: late clone of connection ssl config

- perform connection cache matching against `data->set.ssl.primary`
  and proxy counterpart
- fully clone connection ssl config only when connection is used

Closes #12237
This commit is contained in:
Stefan Eissing 2023-10-31 15:25:08 +01:00 коммит произвёл Daniel Stenberg
Родитель 5d0b3eda43
Коммит bbdbd4b025
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
3 изменённых файлов: 30 добавлений и 32 удалений

Просмотреть файл

@ -1209,10 +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_conn_config_match(data, needle, check, TRUE)) if(!Curl_ssl_conn_config_match(data, check, TRUE))
continue; continue;
} }
else if(!Curl_ssl_conn_config_match(data, needle, check, FALSE)) else if(!Curl_ssl_conn_config_match(data, check, FALSE))
continue; continue;
} }
} }
@ -1330,7 +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_conn_config_match(data, needle, check, FALSE)) { if(!Curl_ssl_conn_config_match(data, check, FALSE)) {
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",
@ -3562,8 +3562,8 @@ 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;
/* Init the SSL configuration for the connection from settings in data */ /* Complete the easy's SSL configuration for connection cache matching */
result = Curl_ssl_conn_config_init(data, conn); result = Curl_ssl_easy_config_complete(data);
if(result) if(result)
goto out; goto out;
@ -3680,6 +3680,12 @@ static CURLcode create_conn(struct Curl_easy *data,
* This is a brand new connection, so let's store it in the connection * This is a brand new connection, so let's store it in the connection
* cache of ours! * cache of ours!
*/ */
result = Curl_ssl_conn_config_init(data, conn);
if(result) {
DEBUGF(fprintf(stderr, "Error: init connection ssl config\n"));
goto out;
}
result = Curl_resolver_init(data, &conn->resolve_async.resolver); result = Curl_resolver_init(data, &conn->resolve_async.resolver);
if(result) { if(result) {
DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));

Просмотреть файл

@ -206,18 +206,17 @@ match_ssl_primary_config(struct Curl_easy *data,
} }
bool Curl_ssl_conn_config_match(struct Curl_easy *data, bool Curl_ssl_conn_config_match(struct Curl_easy *data,
struct connectdata *conn,
struct connectdata *candidate, struct connectdata *candidate,
bool proxy) bool proxy)
{ {
#ifndef CURL_DISABLE_PROXY #ifndef CURL_DISABLE_PROXY
if(proxy) if(proxy)
return match_ssl_primary_config(data, &conn->proxy_ssl_config, return match_ssl_primary_config(data, &data->set.proxy_ssl.primary,
&candidate->proxy_ssl_config); &candidate->proxy_ssl_config);
#else #else
(void)proxy; (void)proxy;
#endif #endif
return match_ssl_primary_config(data, &conn->ssl_config, return match_ssl_primary_config(data, &data->set.ssl.primary,
&candidate->ssl_config); &candidate->ssl_config);
} }
@ -272,8 +271,7 @@ static void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc)
#endif #endif
} }
static CURLcode Curl_ssl_init_ssl_config(struct Curl_easy *data, CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data)
struct ssl_primary_config *config)
{ {
data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; 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.CAfile = data->set.str[STRING_SSL_CAFILE];
@ -300,16 +298,7 @@ static CURLcode Curl_ssl_init_ssl_config(struct Curl_easy *data,
data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
data->set.ssl.key_blob = data->set.blobs[BLOB_KEY]; 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 #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.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.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
data->set.proxy_ssl.primary.cipher_list = data->set.proxy_ssl.primary.cipher_list =
@ -339,27 +328,25 @@ Curl_ssl_init_proxy_ssl_config(struct Curl_easy *data,
data->set.proxy_ssl.primary.password = data->set.proxy_ssl.primary.password =
data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
#endif #endif
#endif /* CURL_DISABLE_PROXY */
if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, config))
return CURLE_OUT_OF_MEMORY;
return CURLE_OK; return CURLE_OK;
} }
#endif /* !CURL_DISABLE_PROXY */
CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data,
struct connectdata *conn) struct connectdata *conn)
{ {
CURLcode result; /* Clone "primary" SSL configurations from the esay handle to
/* Get a cloned copy of the SSL config situation for use in * the connection. They are used for connection cache matching and
* the connection. `data` might have a shorter lifetime than `conn`*/ * probably outlive the easy handle */
result = Curl_ssl_init_ssl_config(data, &conn->ssl_config); if(!clone_ssl_primary_config(&data->set.ssl.primary, &conn->ssl_config))
if(result) return CURLE_OUT_OF_MEMORY;
goto out;
#ifndef CURL_DISABLE_PROXY #ifndef CURL_DISABLE_PROXY
result = Curl_ssl_init_proxy_ssl_config(data, &conn->proxy_ssl_config); if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary,
&conn->proxy_ssl_config))
return CURLE_OUT_OF_MEMORY;
#endif #endif
out: return CURLE_OK;
return result;
} }
void Curl_ssl_conn_config_cleanup(struct connectdata *conn) void Curl_ssl_conn_config_cleanup(struct connectdata *conn)

Просмотреть файл

@ -74,6 +74,12 @@ curl_sslbackend Curl_ssl_backend(void);
*/ */
void Curl_ssl_easy_config_init(struct Curl_easy *data); void Curl_ssl_easy_config_init(struct Curl_easy *data);
/**
* Init the `data->set.ssl` and `data->set.proxy_ssl` for
* connection matching use.
*/
CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data);
/** /**
* Init SSL configs (main + proxy) for a new connection from the easy handle. * Init SSL configs (main + proxy) for a new connection from the easy handle.
*/ */
@ -92,7 +98,6 @@ void Curl_ssl_conn_config_cleanup(struct connectdata *conn);
* @param proxy match the proxy SSL config or the main one * @param proxy match the proxy SSL config or the main one
*/ */
bool Curl_ssl_conn_config_match(struct Curl_easy *data, bool Curl_ssl_conn_config_match(struct Curl_easy *data,
struct connectdata *conn,
struct connectdata *candidate, struct connectdata *candidate,
bool proxy); bool proxy);