diff -Nru curl-7.52.1/debian/changelog curl-7.52.1/debian/changelog --- curl-7.52.1/debian/changelog 2017-04-09 11:10:06.000000000 +0000 +++ curl-7.52.1/debian/changelog 2017-04-17 20:20:57.000000000 +0000 @@ -1,3 +1,13 @@ +curl (7.52.1-4ubuntu1.1) zesty-security; urgency=medium + + * SECURITY UPDATE: TLS session resumption client cert bypass + - debian/patches/CVE-2017-7468: Move the sessionid flag to + ssl_primary_config so that ssl and proxy_ssl will each have + their own sessionid flag. + - CVE-2017-7468 + + -- Steve Beattie Mon, 17 Apr 2017 13:20:57 -0700 + curl (7.52.1-4ubuntu1) zesty; urgency=low * Merge from Debian unstable. Remaining changes: diff -Nru curl-7.52.1/debian/patches/16_CVE-2017-7468.patch curl-7.52.1/debian/patches/16_CVE-2017-7468.patch --- curl-7.52.1/debian/patches/16_CVE-2017-7468.patch 1970-01-01 00:00:00.000000000 +0000 +++ curl-7.52.1/debian/patches/16_CVE-2017-7468.patch 2017-04-17 20:20:38.000000000 +0000 @@ -0,0 +1,387 @@ +From 8166b637bce299f4ac64d371c20cd5afea72c364 Mon Sep 17 00:00:00 2001 +From: Jay Satiro +Date: Wed, 22 Mar 2017 01:59:49 -0400 +Subject: [PATCH] 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 in cb4e2be. Prior to that +this issue had been fixed in 247d890, CVE-2016-5419. + +Bug: https://github.com/curl/curl/issues/1341 +Reported-by: lijian996@users.noreply.github.com + +CVE-2017-7468 +[Ubuntu note: patch touched up to apply to curl 7.52.1 -- sbeattie] + +--- + lib/url.c | 5 +++-- + lib/urldata.h | 2 +- + lib/vtls/axtls.c | 4 ++-- + lib/vtls/cyassl.c | 4 ++-- + lib/vtls/darwinssl.c | 2 +- + lib/vtls/gtls.c | 4 ++-- + lib/vtls/mbedtls.c | 4 ++-- + lib/vtls/nss.c | 2 +- + lib/vtls/openssl.c | 4 ++-- + lib/vtls/polarssl.c | 4 ++-- + lib/vtls/schannel.c | 4 ++-- + lib/vtls/vtls.c | 9 ++++++--- + 12 files changed, 26 insertions(+), 22 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index 4609f4fda..caa28f5d4 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -544,11 +544,11 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) + #ifdef USE_TLS_SRP + set->ssl.authtype = CURL_TLSAUTH_NONE; + #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; + + set->new_file_perms = 0644; /* Default permissions */ + set->new_directory_perms = 0755; /* Default permissions */ +@@ -2497,12 +2497,13 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, + */ + data->set.closesocket_client = va_arg(param, void *); + 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 + /* we only include SSH options if explicitly built to support SSH */ + case CURLOPT_SSH_AUTH_TYPES: +diff --git a/lib/urldata.h b/lib/urldata.h +index bd7d25d2f..3c94553a1 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -358,10 +358,11 @@ struct ssl_primary_config { + char *CAfile; /* certificate to verify peer against */ + 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 */ ++ bool sessionid; /* cache session IDs or not */ + }; + + struct ssl_config_data { + struct ssl_primary_config primary; + bool enable_beast; /* especially allow this flaw for interoperability's +@@ -387,11 +388,10 @@ struct ssl_config_data { + enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ + #endif + }; + + struct ssl_general_config { +- bool sessionid; /* cache session IDs or not */ + size_t max_ssl_sessions; /* SSL session id cache size */ + }; + + /* information stored about one single SSL session */ + struct curl_ssl_session { +diff --git a/lib/vtls/axtls.c b/lib/vtls/axtls.c +index af01fe314..f0e376640 100644 +--- a/lib/vtls/axtls.c ++++ b/lib/vtls/axtls.c +@@ -260,11 +260,11 @@ static CURLcode connect_prep(struct connectdata *conn, int sockindex) + * 1) set session credentials. can probably ignore since axtls puts this + * info in the ssl_ctx struct + * 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; + + /* In axTLS, handshaking happens inside ssl_client_new. */ + Curl_ssl_sessionid_lock(conn); +@@ -390,11 +390,11 @@ static CURLcode connect_finish(struct connectdata *conn, int sockindex) + conn->ssl[sockindex].state = ssl_connection_complete; + conn->recv[sockindex] = axtls_recv; + 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_size(ssl); + size_t ssl_idsize = ssl_get_session_id(ssl); + Curl_ssl_sessionid_lock(conn); + if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize, + sockindex) != CURLE_OK) +diff --git a/lib/vtls/cyassl.c b/lib/vtls/cyassl.c +index 2dfd79dce..5f51ad5f9 100644 +--- a/lib/vtls/cyassl.c ++++ b/lib/vtls/cyassl.c +@@ -396,11 +396,11 @@ 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); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ +@@ -616,11 +616,11 @@ cyassl_connect_step3(struct connectdata *conn, + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[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; + + our_ssl_sessionid = SSL_get_session(connssl->handle); +diff --git a/lib/vtls/darwinssl.c b/lib/vtls/darwinssl.c +index f8697cc79..5533dfe2f 100644 +--- a/lib/vtls/darwinssl.c ++++ b/lib/vtls/darwinssl.c +@@ -1642,11 +1642,11 @@ static CURLcode darwinssl_connect_step1(struct connectdata *conn, + data->set.ssl.falsestart); /* false start support */ + } + #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; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index 51a5aa85b..0230778e2 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -871,11 +871,11 @@ gtls_connect_step1(struct connectdata *conn, + } + #endif + + /* 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; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) { +@@ -1402,11 +1402,11 @@ gtls_connect_step3(struct connectdata *conn, + + conn->ssl[sockindex].state = ssl_connection_complete; + 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 + detect that. */ + bool incache; +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index 7cd2d6d0f..033482b49 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -428,11 +428,11 @@ mbed_connect_step1(struct connectdata *conn, + + mbedtls_ssl_conf_ciphersuites(&connssl->config, + mbedtls_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); + if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { + ret = mbedtls_ssl_set_session(&connssl->ssl, old_session); +@@ -682,11 +682,11 @@ mbed_connect_step3(struct connectdata *conn, + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + + 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; + + our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index 0149d7e37..b14ce14fe 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -1718,11 +1718,11 @@ static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) + goto error; + if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess) + 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; + + /* enable/disable the requested SSL version(s) */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index be264662a..0a59f7209 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -2209,11 +2209,11 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) + infof(data, "WARNING: failed to configure server name indication (SNI) " + "TLS extension\n"); + #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); + if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ +@@ -2965,11 +2965,11 @@ static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex) + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[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; + + our_ssl_sessionid = SSL_get1_session(connssl->handle); +diff --git a/lib/vtls/polarssl.c b/lib/vtls/polarssl.c +index b2fea8a54..1534d7b0d 100644 +--- a/lib/vtls/polarssl.c ++++ b/lib/vtls/polarssl.c +@@ -373,11 +373,11 @@ polarssl_connect_step1(struct connectdata *conn, + net_send, &conn->sock[sockindex]); + + 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); + if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { + ret = ssl_set_session(&connssl->ssl, old_session); +@@ -601,11 +601,11 @@ polarssl_connect_step3(struct connectdata *conn, + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct Curl_easy *data = conn->data; + + 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; + + our_ssl_sessionid = malloc(sizeof(ssl_session)); +diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c +index e0fb2d5f6..c9b513230 100644 +--- a/lib/vtls/schannel.c ++++ b/lib/vtls/schannel.c +@@ -186,11 +186,11 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) + #endif + + 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; + infof(data, "schannel: re-using existing credential handle\n"); + +@@ -755,11 +755,11 @@ schannel_connect_step3(struct connectdata *conn, int sockindex) + infof(data, "ALPN, server did not agree to a protocol\n"); + } + #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; + + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index c6935b5e6..d5d0971c4 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -120,10 +120,13 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + CLONE_STRING(CApath); + CLONE_STRING(cipher_list); + 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; + } + + void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc) + { +@@ -306,13 +309,13 @@ bool Curl_ssl_getsessionid(struct connectdata *conn, + const char * const name = isProxy ? conn->http_proxy.host.name : + conn->host.name; + 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; + + /* Lock if shared */ + if(SSLSESSION_SHARED(data)) +@@ -410,11 +413,11 @@ CURLcode Curl_ssl_addsessionid(struct connectdata *conn, + const bool isProxy = CONNECT_PROXY_SSL(); + struct ssl_primary_config * const ssl_config = isProxy ? + &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) + return CURLE_OUT_OF_MEMORY; /* bail out */ + +-- +2.11.0 + diff -Nru curl-7.52.1/debian/patches/series curl-7.52.1/debian/patches/series --- curl-7.52.1/debian/patches/series 2017-04-09 03:43:11.000000000 +0000 +++ curl-7.52.1/debian/patches/series 2017-04-17 19:30:56.000000000 +0000 @@ -10,6 +10,7 @@ 13_CVE-2017-2629.patch 14_fix-connect-regression.patch 15_CVE-2017-7407.patch +16_CVE-2017-7468.patch # do not add patches below 90_gnutls.patch