1 From 8166b637bce299f4ac64d371c20cd5afea72c364 Mon Sep 17 00:00:00 2001
2 From: Jay Satiro <raysatiro@yahoo.com>
3 Date: Wed, 22 Mar 2017 01:59:49 -0400
4 Subject: [PATCH] TLS: Fix switching off SSL session id when client cert is
7 - Move the sessionid flag to ssl_primary_config so that ssl and
8 proxy_ssl will each have their own sessionid flag.
10 Regression since HTTPS-Proxy support was added in cb4e2be. Prior to that
11 this issue had been fixed in 247d890, CVE-2016-5419.
13 Bug: https://github.com/curl/curl/issues/1341
14 Reported-by: lijian996@users.noreply.github.com
18 lib/vtls/axtls.c | 4 ++--
19 lib/vtls/cyassl.c | 4 ++--
20 lib/vtls/darwinssl.c | 2 +-
21 lib/vtls/gtls.c | 4 ++--
22 lib/vtls/mbedtls.c | 4 ++--
24 lib/vtls/openssl.c | 4 ++--
25 lib/vtls/polarssl.c | 4 ++--
26 lib/vtls/schannel.c | 4 ++--
27 lib/vtls/vtls.c | 9 ++++++---
28 12 files changed, 26 insertions(+), 22 deletions(-)
32 @@ -548,7 +548,7 @@ CURLcode Curl_init_userdefined(struct Us
34 set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
36 - set->general_ssl.sessionid = TRUE; /* session ID caching enabled by
37 + set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
39 set->proxy_ssl = set->ssl;
41 @@ -2470,8 +2470,9 @@ CURLcode Curl_setopt(struct Curl_easy *d
44 case CURLOPT_SSL_SESSIONID_CACHE:
45 - data->set.general_ssl.sessionid = (0 != va_arg(param, long)) ?
46 + data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
48 + data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
54 @@ -354,6 +354,7 @@ struct ssl_primary_config {
55 char *random_file; /* path to file containing "random" data */
56 char *egdsocket; /* path to file containing the EGD daemon socket */
57 char *cipher_list; /* list of ciphers to use */
58 + bool sessionid; /* cache session IDs or not */
61 struct ssl_config_data {
62 @@ -383,7 +384,6 @@ struct ssl_config_data {
65 struct ssl_general_config {
66 - bool sessionid; /* cache session IDs or not */
67 size_t max_ssl_sessions; /* SSL session id cache size */
70 --- a/lib/vtls/axtls.c
71 +++ b/lib/vtls/axtls.c
72 @@ -256,7 +256,7 @@ static CURLcode connect_prep(struct conn
73 * 2) setting up callbacks. these seem gnutls specific
76 - if(data->set.general_ssl.sessionid) {
77 + if(SSL_SET_OPTION(primary.sessionid)) {
78 const uint8_t *ssl_sessionid;
81 @@ -386,7 +386,7 @@ static CURLcode connect_finish(struct co
82 conn->send[sockindex] = axtls_send;
84 /* Put our freshly minted SSL session in cache */
85 - if(data->set.general_ssl.sessionid) {
86 + if(SSL_SET_OPTION(primary.sessionid)) {
87 const uint8_t *ssl_sessionid = ssl_get_session_id_size(ssl);
88 size_t ssl_idsize = ssl_get_session_id(ssl);
89 Curl_ssl_sessionid_lock(conn);
90 --- a/lib/vtls/cyassl.c
91 +++ b/lib/vtls/cyassl.c
92 @@ -383,7 +383,7 @@ cyassl_connect_step1(struct connectdata
93 #endif /* HAVE_ALPN */
95 /* Check if there's a cached ID we can/should use here! */
96 - if(data->set.general_ssl.sessionid) {
97 + if(SSL_SET_OPTION(primary.sessionid)) {
98 void *ssl_sessionid = NULL;
100 Curl_ssl_sessionid_lock(conn);
101 @@ -597,7 +597,7 @@ cyassl_connect_step3(struct connectdata
103 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
105 - if(data->set.general_ssl.sessionid) {
106 + if(SSL_SET_OPTION(primary.sessionid)) {
108 SSL_SESSION *our_ssl_sessionid;
109 void *old_ssl_sessionid = NULL;
110 --- a/lib/vtls/darwinssl.c
111 +++ b/lib/vtls/darwinssl.c
112 @@ -1541,7 +1541,7 @@ static CURLcode darwinssl_connect_step1(
113 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
115 /* Check if there's a cached ID we can/should use here! */
116 - if(data->set.general_ssl.sessionid) {
117 + if(SSL_SET_OPTION(primary.sessionid)) {
119 size_t ssl_sessionid_len;
121 --- a/lib/vtls/gtls.c
122 +++ b/lib/vtls/gtls.c
123 @@ -782,7 +782,7 @@ gtls_connect_step1(struct connectdata *c
125 /* This might be a reconnect, so we check for a session ID in the cache
126 to speed up things */
127 - if(data->set.general_ssl.sessionid) {
128 + if(SSL_SET_OPTION(primary.sessionid)) {
132 @@ -1311,7 +1311,7 @@ gtls_connect_step3(struct connectdata *c
133 conn->recv[sockindex] = gtls_recv;
134 conn->send[sockindex] = gtls_send;
136 - if(data->set.general_ssl.sessionid) {
137 + if(SSL_SET_OPTION(primary.sessionid)) {
138 /* we always unconditionally get the session id here, as even if we
139 already got it from the cache and asked to use it in the connection, it
140 might've been rejected and then a new one is in use now and we need to
141 --- a/lib/vtls/mbedtls.c
142 +++ b/lib/vtls/mbedtls.c
143 @@ -374,7 +374,7 @@ mbed_connect_step1(struct connectdata *c
144 mbedtls_ssl_list_ciphersuites());
146 /* Check if there's a cached ID we can/should use here! */
147 - if(data->set.general_ssl.sessionid) {
148 + if(SSL_SET_OPTION(primary.sessionid)) {
149 void *old_session = NULL;
151 Curl_ssl_sessionid_lock(conn);
152 @@ -618,7 +618,7 @@ mbed_connect_step3(struct connectdata *c
154 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
156 - if(data->set.general_ssl.sessionid) {
157 + if(SSL_SET_OPTION(primary.sessionid)) {
159 mbedtls_ssl_session *our_ssl_sessionid;
160 void *old_ssl_sessionid = NULL;
163 @@ -1696,7 +1696,7 @@ static CURLcode nss_setup_connect(struct
166 /* do not use SSL cache if disabled or we are not going to verify peer */
167 - ssl_no_cache = (data->set.general_ssl.sessionid
168 + ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
169 && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
170 if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
172 --- a/lib/vtls/openssl.c
173 +++ b/lib/vtls/openssl.c
174 @@ -2161,7 +2161,7 @@ static CURLcode ossl_connect_step1(struc
177 /* Check if there's a cached ID we can/should use here! */
178 - if(data->set.general_ssl.sessionid) {
179 + if(SSL_SET_OPTION(primary.sessionid)) {
180 void *ssl_sessionid = NULL;
182 Curl_ssl_sessionid_lock(conn);
183 @@ -2915,7 +2915,7 @@ static CURLcode ossl_connect_step3(struc
185 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
187 - if(data->set.general_ssl.sessionid) {
188 + if(SSL_SET_OPTION(primary.sessionid)) {
190 SSL_SESSION *our_ssl_sessionid;
191 void *old_ssl_sessionid = NULL;
192 --- a/lib/vtls/polarssl.c
193 +++ b/lib/vtls/polarssl.c
194 @@ -327,7 +327,7 @@ polarssl_connect_step1(struct connectdat
195 ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
197 /* Check if there's a cached ID we can/should use here! */
198 - if(data->set.general_ssl.sessionid) {
199 + if(SSL_SET_OPTION(primary.sessionid)) {
200 void *old_session = NULL;
202 Curl_ssl_sessionid_lock(conn);
203 @@ -555,7 +555,7 @@ polarssl_connect_step3(struct connectdat
205 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
207 - if(data->set.general_ssl.sessionid) {
208 + if(SSL_SET_OPTION(primary.sessionid)) {
210 ssl_session *our_ssl_sessionid;
211 void *old_ssl_sessionid = NULL;
212 --- a/lib/vtls/schannel.c
213 +++ b/lib/vtls/schannel.c
214 @@ -145,7 +145,7 @@ schannel_connect_step1(struct connectdat
215 connssl->cred = NULL;
217 /* check for an existing re-usable credential handle */
218 - if(data->set.general_ssl.sessionid) {
219 + if(SSL_SET_OPTION(primary.sessionid)) {
220 Curl_ssl_sessionid_lock(conn);
221 if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
222 connssl->cred = old_cred;
223 @@ -714,7 +714,7 @@ schannel_connect_step3(struct connectdat
226 /* save the current session data for possible re-use */
227 - if(data->set.general_ssl.sessionid) {
228 + if(SSL_SET_OPTION(primary.sessionid)) {
230 struct curl_schannel_cred *old_cred = NULL;
232 --- a/lib/vtls/vtls.c
233 +++ b/lib/vtls/vtls.c
234 @@ -120,6 +120,9 @@ Curl_clone_primary_ssl_config(struct ssl
235 CLONE_STRING(egdsocket);
236 CLONE_STRING(random_file);
237 CLONE_STRING(clientcert);
239 + /* Disable dest sessionid cache if a client cert is used, CVE-2016-5419. */
240 + dest->sessionid = (dest->clientcert ? false : source->sessionid);
244 @@ -293,9 +296,9 @@ bool Curl_ssl_getsessionid(struct connec
245 int port = isProxy ? (int)conn->port : conn->remote_port;
246 *ssl_sessionid = NULL;
248 - DEBUGASSERT(data->set.general_ssl.sessionid);
249 + DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
251 - if(!data->set.general_ssl.sessionid)
252 + if(!SSL_SET_OPTION(primary.sessionid))
253 /* session ID re-use is disabled */
256 @@ -397,7 +400,7 @@ CURLcode Curl_ssl_addsessionid(struct co
257 &conn->proxy_ssl_config :
260 - DEBUGASSERT(data->set.general_ssl.sessionid);
261 + DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
263 clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);