Home / os / linux

Curl TLS session resumption client cert bypass

Posted on 30 November -0001

<HTML><HEAD><TITLE>curl TLS session resumption client cert bypass</TITLE><META http-equiv="Content-Type" content="text/html; charset=utf-8"></HEAD><BODY>TLS session resumption client cert bypass ========================================= Project cURL Security Advisory, August 3rd 2016 - [Permalink](https://curl.haxx.se/docs/adv_20160803A.html) VULNERABILITY ------------- libcurl would attempt to resume a TLS session even if the client certificate had changed. That is unacceptable since a server by specification is allowed to skip the client certificate check on resume, and may instead use the old identity which was established by the previous certificate (or no certificate). libcurl supports by default the use of TLS session id/ticket to resume previous TLS sessions to speed up subsequent TLS handshakes. They are used when for any reason an existing TLS connection couldn't be kept alive to make the next handshake faster. We are not aware of any exploit of this flaw. INFO ---- This flaw also affects the curl command line tool. The Common Vulnerabilities and Exposures (CVE) project has assigned the name CVE-2016-5419 to this issue. AFFECTED VERSIONS ----------------- This flaw is relevant for all versions of curl and libcurl that support TLS and client certificates. - Affected versions: libcurl 7.1 to and including 7.50.0 - Not affected versions: libcurl >= 7.50.1 libcurl is used by many applications, but not always advertised as such! THE SOLUTION ------------ In version 7.50.1, TLS session resumption is disabled when a client certificate is used so that a subsequent connection attempt to the same server cannot risk getting a previously authenticated session resumed. A [patch for CVE-2016-5419](https://curl.haxx.se/CVE-2016-5419.patch) is available. Reported-by: Bru Rom Contributions-by: Eric Rescorla and Ray Satiro --- lib/url.c | 1 + lib/urldata.h | 1 + lib/vtls/vtls.c | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/lib/url.c b/lib/url.c index 258a286..e547e5c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -6121,10 +6121,11 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; + data->set.ssl.clientcert = data->set.str[STRING_CERT]; #ifdef USE_TLS_SRP data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; #endif diff --git a/lib/urldata.h b/lib/urldata.h index 611c5a7..3cf7ed9 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -349,10 +349,11 @@ struct ssl_config_data { bool verifystatus; /* set TRUE if certificate status must be checked */ char *CApath; /* certificate dir (doesn't work on windows) */ char *CAfile; /* certificate to verify peer against */ const char *CRLfile; /* CRL to check certificate revocation */ const char *issuercert;/* optional issuer certificate filename */ + char *clientcert; 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 */ size_t max_ssl_sessions; /* SSL session id cache size */ curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index d3e41cd..33e209d 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -154,20 +154,30 @@ Curl_clone_ssl_config(struct ssl_config_data *source, return FALSE; } else dest->random_file = NULL; + if(source->clientcert) { + dest->clientcert = strdup(source->clientcert); + if(!dest->clientcert) + return FALSE; + dest->sessionid = FALSE; + } + else + dest->clientcert = NULL; + return TRUE; } void Curl_free_ssl_config(struct ssl_config_data* sslc) { Curl_safefree(sslc->CAfile); Curl_safefree(sslc->CApath); Curl_safefree(sslc->cipher_list); Curl_safefree(sslc->egdsocket); Curl_safefree(sslc->random_file); + Curl_safefree(sslc->clientcert); } /* * Curl_rand() returns a random unsigned integer, 32bit. -- 2.8.1 RECOMMENDATIONS --------------- We suggest you take one of the following actions immediately, in order of preference: A - Upgrade curl and libcurl to version 7.50.1 B - Apply the patch to your version and rebuild C - Set `CURLOPT_SSL_SESSIONID_CACHE` to 0L when using client certificates TIME LINE --------- It was first reported to the curl project in April 2016 by Bru Rom. We contacted distros@openwall on July 31. libcurl 7.50.1 was released on August 3 2016, coordinated with the publication of this advisory. CREDITS ------- Contributions by Eric Rescorla and Ray Satiro. Patch by Daniel Stenberg. Thanks a lot! -- / daniel.haxx.se</BODY></HTML>

 

TOP