TLS: Fix switching off SSL session id when client cert is used
Move the sessionid flag to ssl_primary_config so that ssl and proxy_ssl will each have their own sessionid flag. Regression since HTTPS-Proxy support was added incb4e2be. Prior to that this issue had been fixed in247d890, CVE-2016-5419. Bug: https://github.com/curl/curl/issues/1341 Reported-by: lijian996@users.noreply.github.com The new incarnation of this bug is called CVE-2017-7468 and is documented here: https://curl.haxx.se/docs/adv_20170419.html
This commit is contained in:
parent
997504ea50
commit
33cfcfd9f0
@ -546,7 +546,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
|
||||
#endif
|
||||
set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
|
||||
type */
|
||||
set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
|
||||
set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
|
||||
default */
|
||||
set->proxy_ssl = set->ssl;
|
||||
|
||||
@ -2499,8 +2499,9 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
|
||||
break;
|
||||
|
||||
case CURLOPT_SSL_SESSIONID_CACHE:
|
||||
data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
|
||||
data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
|
||||
TRUE : FALSE;
|
||||
data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
|
||||
break;
|
||||
|
||||
#ifdef USE_LIBSSH2
|
||||
|
||||
@ -360,6 +360,7 @@ struct ssl_primary_config {
|
||||
char *random_file; /* path to file containing "random" data */
|
||||
char *egdsocket; /* path to file containing the EGD daemon socket */
|
||||
char *cipher_list; /* list of ciphers to use */
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
};
|
||||
|
||||
struct ssl_config_data {
|
||||
@ -389,7 +390,6 @@ struct ssl_config_data {
|
||||
};
|
||||
|
||||
struct ssl_general_config {
|
||||
bool sessionid; /* cache session IDs or not */
|
||||
size_t max_ssl_sessions; /* SSL session id cache size */
|
||||
};
|
||||
|
||||
|
||||
@ -262,7 +262,7 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex)
|
||||
* 2) setting up callbacks. these seem gnutls specific
|
||||
*/
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
const uint8_t *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
|
||||
@ -392,7 +392,7 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex)
|
||||
conn->send[sockindex] = axtls_send;
|
||||
|
||||
/* Put our freshly minted SSL session in cache */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
|
||||
size_t ssl_idsize = ssl_get_session_id_size(ssl);
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
|
||||
@ -398,7 +398,7 @@ cyassl_connect_step1(struct connectdata *conn,
|
||||
#endif /* HAVE_ALPN */
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@ -618,7 +618,7 @@ cyassl_connect_step3(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
bool incache;
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
@ -1644,7 +1644,7 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn,
|
||||
#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
char *ssl_sessionid;
|
||||
size_t ssl_sessionid_len;
|
||||
|
||||
|
||||
@ -873,7 +873,7 @@ gtls_connect_step1(struct connectdata *conn,
|
||||
|
||||
/* This might be a reconnect, so we check for a session ID in the cache
|
||||
to speed up things */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *ssl_sessionid;
|
||||
size_t ssl_idsize;
|
||||
|
||||
@ -1404,7 +1404,7 @@ gtls_connect_step3(struct connectdata *conn,
|
||||
conn->recv[sockindex] = gtls_recv;
|
||||
conn->send[sockindex] = gtls_send;
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
/* we always unconditionally get the session id here, as even if we
|
||||
already got it from the cache and asked to use it in the connection, it
|
||||
might've been rejected and then a new one is in use now and we need to
|
||||
|
||||
@ -430,7 +430,7 @@ mbed_connect_step1(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *old_session = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@ -684,7 +684,7 @@ mbed_connect_step3(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
int ret;
|
||||
mbedtls_ssl_session *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
@ -1720,7 +1720,7 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
|
||||
goto error;
|
||||
|
||||
/* do not use SSL cache if disabled or we are not going to verify peer */
|
||||
ssl_no_cache = (data->set.general_ssl.sessionid
|
||||
ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
|
||||
&& SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
|
||||
if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
|
||||
goto error;
|
||||
|
||||
@ -2235,7 +2235,7 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
|
||||
#endif
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *ssl_sessionid = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@ -2965,7 +2965,7 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
bool incache;
|
||||
SSL_SESSION *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
@ -375,7 +375,7 @@ polarssl_connect_step1(struct connectdata *conn,
|
||||
ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
|
||||
|
||||
/* Check if there's a cached ID we can/should use here! */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
void *old_session = NULL;
|
||||
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
@ -603,7 +603,7 @@ polarssl_connect_step3(struct connectdata *conn,
|
||||
|
||||
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
|
||||
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
int ret;
|
||||
ssl_session *our_ssl_sessionid;
|
||||
void *old_ssl_sessionid = NULL;
|
||||
|
||||
@ -188,7 +188,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
|
||||
connssl->cred = NULL;
|
||||
|
||||
/* check for an existing re-usable credential handle */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
Curl_ssl_sessionid_lock(conn);
|
||||
if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
|
||||
connssl->cred = old_cred;
|
||||
@ -757,7 +757,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
|
||||
#endif
|
||||
|
||||
/* save the current session data for possible re-use */
|
||||
if(data->set.general_ssl.sessionid) {
|
||||
if(SSL_SET_OPTION(primary.sessionid)) {
|
||||
bool incache;
|
||||
struct curl_schannel_cred *old_cred = NULL;
|
||||
|
||||
|
||||
@ -122,6 +122,9 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
|
||||
CLONE_STRING(egdsocket);
|
||||
CLONE_STRING(random_file);
|
||||
CLONE_STRING(clientcert);
|
||||
|
||||
/* Disable dest sessionid cache if a client cert is used, CVE-2016-5419. */
|
||||
dest->sessionid = (dest->clientcert ? false : source->sessionid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -308,9 +311,9 @@ bool Curl_ssl_getsessionid(struct connectdata *conn,
|
||||
int port = isProxy ? (int)conn->port : conn->remote_port;
|
||||
*ssl_sessionid = NULL;
|
||||
|
||||
DEBUGASSERT(data->set.general_ssl.sessionid);
|
||||
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
|
||||
|
||||
if(!data->set.general_ssl.sessionid)
|
||||
if(!SSL_SET_OPTION(primary.sessionid))
|
||||
/* session ID re-use is disabled */
|
||||
return TRUE;
|
||||
|
||||
@ -412,7 +415,7 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
|
||||
&conn->proxy_ssl_config :
|
||||
&conn->ssl_config;
|
||||
|
||||
DEBUGASSERT(data->set.general_ssl.sessionid);
|
||||
DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
|
||||
|
||||
clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
|
||||
if(!clone_host)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user