diff options
| author | Mingli Yu <mingli.yu@windriver.com> | 2021-08-04 12:04:48 +0800 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-08-14 12:01:44 +0100 |
| commit | 178756ee53a019b41dcc42574372f1c4fe112314 (patch) | |
| tree | fae8fff566ebbae746866103164fc612de2fbbda | |
| parent | f897796b0958d6c696b81f9f1d9cb7cb9a892a57 (diff) | |
| download | poky-178756ee53a019b41dcc42574372f1c4fe112314.tar.gz | |
curl: fix CVES
Backport patches to fix below CVEs:
CVE-2021-22901
CVE-2021-22924
CVE-2021-22926
(From OE-Core rev: 8a01fe853c151ba787802b8d5895273c6da8bc78)
Signed-off-by: Mingli Yu <mingli.yu@windriver.com>
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22901.patch | 453 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22924.patch | 298 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22926.patch | 79 | ||||
| -rw-r--r-- | meta/recipes-support/curl/curl_7.75.0.bb | 3 |
4 files changed, 833 insertions, 0 deletions
diff --git a/meta/recipes-support/curl/curl/CVE-2021-22901.patch b/meta/recipes-support/curl/curl/CVE-2021-22901.patch new file mode 100644 index 0000000000..c5775c6306 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22901.patch | |||
| @@ -0,0 +1,453 @@ | |||
| 1 | From a801ebdc2b1c008fa72c31f1bf7773d99e6e2a2d Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Harry Sintonen <sintonen@iki.fi> | ||
| 3 | Date: Tue, 3 Aug 2021 08:41:45 +0000 | ||
| 4 | Subject: [PATCH] openssl: associate/detach the transfer from connection | ||
| 5 | |||
| 6 | CVE-2021-22901 | ||
| 7 | |||
| 8 | Bug: https://curl.se/docs/CVE-2021-22901.html | ||
| 9 | |||
| 10 | CVE: CVE-2021-22901 | ||
| 11 | |||
| 12 | Upstream-Status: Backport [https://github.com/curl/curl/commit/7f4a9a9b2a49547eae24d2e19bc5c346e9026479] | ||
| 13 | |||
| 14 | Signed-off-by: Mingli Yu <mingli.yu@windriver.com> | ||
| 15 | --- | ||
| 16 | lib/multi.c | 5 +- | ||
| 17 | lib/vtls/gskit.c | 4 +- | ||
| 18 | lib/vtls/gtls.c | 4 +- | ||
| 19 | lib/vtls/mbedtls.c | 4 +- | ||
| 20 | lib/vtls/mesalink.c | 4 +- | ||
| 21 | lib/vtls/nss.c | 4 +- | ||
| 22 | lib/vtls/openssl.c | 146 +++++++++++++++++++++++++++++++------------ | ||
| 23 | lib/vtls/schannel.c | 6 +- | ||
| 24 | lib/vtls/sectransp.c | 4 +- | ||
| 25 | lib/vtls/vtls.c | 23 ++++++- | ||
| 26 | lib/vtls/vtls.h | 12 ++++ | ||
| 27 | lib/vtls/wolfssl.c | 4 +- | ||
| 28 | 12 files changed, 170 insertions(+), 50 deletions(-) | ||
| 29 | |||
| 30 | diff --git a/lib/multi.c b/lib/multi.c | ||
| 31 | index 85707a1..a4ff9ac 100644 | ||
| 32 | --- a/lib/multi.c | ||
| 33 | +++ b/lib/multi.c | ||
| 34 | @@ -875,8 +875,10 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi) | ||
| 35 | void Curl_detach_connnection(struct Curl_easy *data) | ||
| 36 | { | ||
| 37 | struct connectdata *conn = data->conn; | ||
| 38 | - if(conn) | ||
| 39 | + if(conn) { | ||
| 40 | Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); | ||
| 41 | + Curl_ssl_detach_conn(data, conn); | ||
| 42 | + } | ||
| 43 | data->conn = NULL; | ||
| 44 | } | ||
| 45 | |||
| 46 | @@ -893,6 +895,7 @@ void Curl_attach_connnection(struct Curl_easy *data, | ||
| 47 | data->conn = conn; | ||
| 48 | Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, | ||
| 49 | &data->conn_queue); | ||
| 50 | + Curl_ssl_associate_conn(data, conn); | ||
| 51 | } | ||
| 52 | |||
| 53 | static int waitconnect_getsock(struct connectdata *conn, | ||
| 54 | diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c | ||
| 55 | index 9b5f649..bd9c602 100644 | ||
| 56 | --- a/lib/vtls/gskit.c | ||
| 57 | +++ b/lib/vtls/gskit.c | ||
| 58 | @@ -1282,7 +1282,9 @@ const struct Curl_ssl Curl_ssl_gskit = { | ||
| 59 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 60 | Curl_none_engines_list, /* engines_list */ | ||
| 61 | Curl_none_false_start, /* false_start */ | ||
| 62 | - NULL /* sha256sum */ | ||
| 63 | + NULL, /* sha256sum */ | ||
| 64 | + NULL, /* associate_connection */ | ||
| 65 | + NULL /* disassociate_connection */ | ||
| 66 | }; | ||
| 67 | |||
| 68 | #endif /* USE_GSKIT */ | ||
| 69 | diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c | ||
| 70 | index 28ca528..24e036b 100644 | ||
| 71 | --- a/lib/vtls/gtls.c | ||
| 72 | +++ b/lib/vtls/gtls.c | ||
| 73 | @@ -1683,7 +1683,9 @@ const struct Curl_ssl Curl_ssl_gnutls = { | ||
| 74 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 75 | Curl_none_engines_list, /* engines_list */ | ||
| 76 | Curl_none_false_start, /* false_start */ | ||
| 77 | - gtls_sha256sum /* sha256sum */ | ||
| 78 | + gtls_sha256sum, /* sha256sum */ | ||
| 79 | + NULL, /* associate_connection */ | ||
| 80 | + NULL /* disassociate_connection */ | ||
| 81 | }; | ||
| 82 | |||
| 83 | #endif /* USE_GNUTLS */ | ||
| 84 | diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c | ||
| 85 | index bd0e080..fc973c7 100644 | ||
| 86 | --- a/lib/vtls/mbedtls.c | ||
| 87 | +++ b/lib/vtls/mbedtls.c | ||
| 88 | @@ -1112,7 +1112,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = { | ||
| 89 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 90 | Curl_none_engines_list, /* engines_list */ | ||
| 91 | Curl_none_false_start, /* false_start */ | ||
| 92 | - mbedtls_sha256sum /* sha256sum */ | ||
| 93 | + mbedtls_sha256sumi, /* sha256sum */ | ||
| 94 | + NULL, /* associate_connection */ | ||
| 95 | + NULL /* disassociate_connection */ | ||
| 96 | }; | ||
| 97 | |||
| 98 | #endif /* USE_MBEDTLS */ | ||
| 99 | diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c | ||
| 100 | index ad807d3..8a91487 100644 | ||
| 101 | --- a/lib/vtls/mesalink.c | ||
| 102 | +++ b/lib/vtls/mesalink.c | ||
| 103 | @@ -666,7 +666,9 @@ const struct Curl_ssl Curl_ssl_mesalink = { | ||
| 104 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 105 | Curl_none_engines_list, /* engines_list */ | ||
| 106 | Curl_none_false_start, /* false_start */ | ||
| 107 | - NULL /* sha256sum */ | ||
| 108 | + NULL, /* sha256sum */ | ||
| 109 | + NULL, /* associate_connection */ | ||
| 110 | + NULL /* disassociate_connection */ | ||
| 111 | }; | ||
| 112 | |||
| 113 | #endif | ||
| 114 | diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c | ||
| 115 | index e5ab71c..fb9f763 100644 | ||
| 116 | --- a/lib/vtls/nss.c | ||
| 117 | +++ b/lib/vtls/nss.c | ||
| 118 | @@ -2444,7 +2444,9 @@ const struct Curl_ssl Curl_ssl_nss = { | ||
| 119 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 120 | Curl_none_engines_list, /* engines_list */ | ||
| 121 | nss_false_start, /* false_start */ | ||
| 122 | - nss_sha256sum /* sha256sum */ | ||
| 123 | + nss_sha256sum, /* sha256sum */ | ||
| 124 | + NULL, /* associate_connection */ | ||
| 125 | + NULL /* disassociate_connection */ | ||
| 126 | }; | ||
| 127 | |||
| 128 | #endif /* USE_NSS */ | ||
| 129 | diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c | ||
| 130 | index 8304264..946b4c5 100644 | ||
| 131 | --- a/lib/vtls/openssl.c | ||
| 132 | +++ b/lib/vtls/openssl.c | ||
| 133 | @@ -244,6 +244,10 @@ struct ssl_backend_data { | ||
| 134 | #endif | ||
| 135 | }; | ||
| 136 | |||
| 137 | +static void ossl_associate_connection(struct Curl_easy *data, | ||
| 138 | + struct connectdata *conn, | ||
| 139 | + int sockindex); | ||
| 140 | + | ||
| 141 | /* | ||
| 142 | * Number of bytes to read from the random number seed file. This must be | ||
| 143 | * a finite value (because some entropy "files" like /dev/urandom have | ||
| 144 | @@ -2527,6 +2531,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, | ||
| 145 | curl_socket_t sockfd = conn->sock[sockindex]; | ||
| 146 | struct ssl_connect_data *connssl = &conn->ssl[sockindex]; | ||
| 147 | ctx_option_t ctx_options = 0; | ||
| 148 | + void *ssl_sessionid = NULL; | ||
| 149 | |||
| 150 | #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME | ||
| 151 | bool sni; | ||
| 152 | @@ -3224,46 +3229,23 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, | ||
| 153 | } | ||
| 154 | #endif | ||
| 155 | |||
| 156 | - /* Check if there's a cached ID we can/should use here! */ | ||
| 157 | - if(SSL_SET_OPTION(primary.sessionid)) { | ||
| 158 | - void *ssl_sessionid = NULL; | ||
| 159 | - int data_idx = ossl_get_ssl_data_index(); | ||
| 160 | - int connectdata_idx = ossl_get_ssl_conn_index(); | ||
| 161 | - int sockindex_idx = ossl_get_ssl_sockindex_index(); | ||
| 162 | - int proxy_idx = ossl_get_proxy_index(); | ||
| 163 | - | ||
| 164 | - if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && | ||
| 165 | - proxy_idx >= 0) { | ||
| 166 | - /* Store the data needed for the "new session" callback. | ||
| 167 | - * The sockindex is stored as a pointer to an array element. */ | ||
| 168 | - SSL_set_ex_data(backend->handle, data_idx, data); | ||
| 169 | - SSL_set_ex_data(backend->handle, connectdata_idx, conn); | ||
| 170 | - SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); | ||
| 171 | -#ifndef CURL_DISABLE_PROXY | ||
| 172 | - SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: | ||
| 173 | - NULL); | ||
| 174 | -#else | ||
| 175 | - SSL_set_ex_data(backend->handle, proxy_idx, NULL); | ||
| 176 | -#endif | ||
| 177 | - | ||
| 178 | - } | ||
| 179 | + ossl_associate_connection(data, conn, sockindex); | ||
| 180 | |||
| 181 | - Curl_ssl_sessionid_lock(data); | ||
| 182 | - if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, | ||
| 183 | - &ssl_sessionid, NULL, sockindex)) { | ||
| 184 | - /* we got a session id, use it! */ | ||
| 185 | - if(!SSL_set_session(backend->handle, ssl_sessionid)) { | ||
| 186 | - Curl_ssl_sessionid_unlock(data); | ||
| 187 | - failf(data, "SSL: SSL_set_session failed: %s", | ||
| 188 | - ossl_strerror(ERR_get_error(), error_buffer, | ||
| 189 | - sizeof(error_buffer))); | ||
| 190 | - return CURLE_SSL_CONNECT_ERROR; | ||
| 191 | - } | ||
| 192 | - /* Informational message */ | ||
| 193 | - infof(data, "SSL re-using session ID\n"); | ||
| 194 | + Curl_ssl_sessionid_lock(data); | ||
| 195 | + if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, | ||
| 196 | + &ssl_sessionid, NULL, sockindex)) { | ||
| 197 | + /* we got a session id, use it! */ | ||
| 198 | + if(!SSL_set_session(backend->handle, ssl_sessionid)) { | ||
| 199 | + Curl_ssl_sessionid_unlock(data); | ||
| 200 | + failf(data, "SSL: SSL_set_session failed: %s", | ||
| 201 | + ossl_strerror(ERR_get_error(), error_buffer, | ||
| 202 | + sizeof(error_buffer))); | ||
| 203 | + return CURLE_SSL_CONNECT_ERROR; | ||
| 204 | } | ||
| 205 | - Curl_ssl_sessionid_unlock(data); | ||
| 206 | + /* Informational message */ | ||
| 207 | + infof(data, "SSL re-using session ID\n"); | ||
| 208 | } | ||
| 209 | + Curl_ssl_sessionid_unlock(data); | ||
| 210 | |||
| 211 | #ifndef CURL_DISABLE_PROXY | ||
| 212 | if(conn->proxy_ssl[sockindex].use) { | ||
| 213 | @@ -4481,6 +4463,90 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl, | ||
| 214 | (void *)backend->ctx : (void *)backend->handle; | ||
| 215 | } | ||
| 216 | |||
| 217 | +static void ossl_associate_connection(struct Curl_easy *data, | ||
| 218 | + struct connectdata *conn, | ||
| 219 | + int sockindex) | ||
| 220 | +{ | ||
| 221 | + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; | ||
| 222 | + struct ssl_backend_data *backend = connssl->backend; | ||
| 223 | + | ||
| 224 | + /* If we don't have SSL context, do nothing. */ | ||
| 225 | + if(!backend->handle) | ||
| 226 | + return; | ||
| 227 | + | ||
| 228 | + if(SSL_SET_OPTION(primary.sessionid)) { | ||
| 229 | + int data_idx = ossl_get_ssl_data_index(); | ||
| 230 | + int connectdata_idx = ossl_get_ssl_conn_index(); | ||
| 231 | + int sockindex_idx = ossl_get_ssl_sockindex_index(); | ||
| 232 | + int proxy_idx = ossl_get_proxy_index(); | ||
| 233 | + | ||
| 234 | + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && | ||
| 235 | + proxy_idx >= 0) { | ||
| 236 | + /* Store the data needed for the "new session" callback. | ||
| 237 | + * The sockindex is stored as a pointer to an array element. */ | ||
| 238 | + SSL_set_ex_data(backend->handle, data_idx, data); | ||
| 239 | + SSL_set_ex_data(backend->handle, connectdata_idx, conn); | ||
| 240 | + SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); | ||
| 241 | +#ifndef CURL_DISABLE_PROXY | ||
| 242 | + SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: | ||
| 243 | + NULL); | ||
| 244 | +#else | ||
| 245 | + SSL_set_ex_data(backend->handle, proxy_idx, NULL); | ||
| 246 | +#endif | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | +} | ||
| 250 | + | ||
| 251 | +/* | ||
| 252 | + * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after | ||
| 253 | + * the handshake. If the transfer that sets up the callback gets killed before | ||
| 254 | + * this callback arrives, we must make sure to properly clear the data to | ||
| 255 | + * avoid UAF problems. A future optimization could be to instead store another | ||
| 256 | + * transfer that might still be using the same connection. | ||
| 257 | + */ | ||
| 258 | + | ||
| 259 | +static void ossl_disassociate_connection(struct Curl_easy *data, | ||
| 260 | + int sockindex) | ||
| 261 | +{ | ||
| 262 | + struct connectdata *conn = data->conn; | ||
| 263 | + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; | ||
| 264 | + struct ssl_backend_data *backend = connssl->backend; | ||
| 265 | + | ||
| 266 | + /* If we don't have SSL context, do nothing. */ | ||
| 267 | + if(!backend->handle) | ||
| 268 | + return; | ||
| 269 | + | ||
| 270 | + if(SSL_SET_OPTION(primary.sessionid)) { | ||
| 271 | + bool isproxy = FALSE; | ||
| 272 | + bool incache; | ||
| 273 | + void *old_ssl_sessionid = NULL; | ||
| 274 | + int data_idx = ossl_get_ssl_data_index(); | ||
| 275 | + int connectdata_idx = ossl_get_ssl_conn_index(); | ||
| 276 | + int sockindex_idx = ossl_get_ssl_sockindex_index(); | ||
| 277 | + int proxy_idx = ossl_get_proxy_index(); | ||
| 278 | + | ||
| 279 | + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && | ||
| 280 | + proxy_idx >= 0) { | ||
| 281 | + /* Invalidate the session cache entry, if any */ | ||
| 282 | + isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE; | ||
| 283 | + | ||
| 284 | + /* Disable references to data in "new session" callback to avoid | ||
| 285 | + * accessing a stale pointer. */ | ||
| 286 | + SSL_set_ex_data(backend->handle, data_idx, NULL); | ||
| 287 | + SSL_set_ex_data(backend->handle, connectdata_idx, NULL); | ||
| 288 | + SSL_set_ex_data(backend->handle, sockindex_idx, NULL); | ||
| 289 | + SSL_set_ex_data(backend->handle, proxy_idx, NULL); | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + Curl_ssl_sessionid_lock(data); | ||
| 293 | + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, | ||
| 294 | + &old_ssl_sessionid, NULL, sockindex)); | ||
| 295 | + if(incache) | ||
| 296 | + Curl_ssl_delsessionid(data, old_ssl_sessionid); | ||
| 297 | + Curl_ssl_sessionid_unlock(data); | ||
| 298 | + } | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | const struct Curl_ssl Curl_ssl_openssl = { | ||
| 302 | { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ | ||
| 303 | |||
| 304 | @@ -4514,10 +4580,12 @@ const struct Curl_ssl Curl_ssl_openssl = { | ||
| 305 | ossl_engines_list, /* engines_list */ | ||
| 306 | Curl_none_false_start, /* false_start */ | ||
| 307 | #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) | ||
| 308 | - ossl_sha256sum /* sha256sum */ | ||
| 309 | + ossl_sha256sum, /* sha256sum */ | ||
| 310 | #else | ||
| 311 | - NULL /* sha256sum */ | ||
| 312 | + NULL, /* sha256sum */ | ||
| 313 | #endif | ||
| 314 | + ossl_associate_connection, /* associate_connection */ | ||
| 315 | + ossl_disassociate_connection /* disassociate_connection */ | ||
| 316 | }; | ||
| 317 | |||
| 318 | #endif /* USE_OPENSSL */ | ||
| 319 | diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c | ||
| 320 | index 670310d..596106a 100644 | ||
| 321 | --- a/lib/vtls/schannel.c | ||
| 322 | +++ b/lib/vtls/schannel.c | ||
| 323 | @@ -325,7 +325,7 @@ get_alg_id_by_name(char *name) | ||
| 324 | |||
| 325 | static CURLcode | ||
| 326 | set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, | ||
| 327 | - int *algIds) | ||
| 328 | + ALG_ID *algIds) | ||
| 329 | { | ||
| 330 | char *startCur = ciphers; | ||
| 331 | int algCount = 0; | ||
| 332 | @@ -2429,7 +2429,9 @@ const struct Curl_ssl Curl_ssl_schannel = { | ||
| 333 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 334 | Curl_none_engines_list, /* engines_list */ | ||
| 335 | Curl_none_false_start, /* false_start */ | ||
| 336 | - schannel_sha256sum /* sha256sum */ | ||
| 337 | + schannel_sha256sum, /* sha256sum */ | ||
| 338 | + NULL, /* associate_connection */ | ||
| 339 | + NULL /* disassociate_connection */ | ||
| 340 | }; | ||
| 341 | |||
| 342 | #endif /* USE_SCHANNEL */ | ||
| 343 | diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c | ||
| 344 | index 6d1ea7e..37b41f8 100644 | ||
| 345 | --- a/lib/vtls/sectransp.c | ||
| 346 | +++ b/lib/vtls/sectransp.c | ||
| 347 | @@ -3311,7 +3311,9 @@ const struct Curl_ssl Curl_ssl_sectransp = { | ||
| 348 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 349 | Curl_none_engines_list, /* engines_list */ | ||
| 350 | sectransp_false_start, /* false_start */ | ||
| 351 | - sectransp_sha256sum /* sha256sum */ | ||
| 352 | + sectransp_sha256sum, /* sha256sum */ | ||
| 353 | + NULL, /* associate_connection */ | ||
| 354 | + NULL /* disassociate_connection */ | ||
| 355 | }; | ||
| 356 | |||
| 357 | #ifdef __clang__ | ||
| 358 | diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c | ||
| 359 | index 00b6268..59a7efb 100644 | ||
| 360 | --- a/lib/vtls/vtls.c | ||
| 361 | +++ b/lib/vtls/vtls.c | ||
| 362 | @@ -579,6 +579,25 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, | ||
| 363 | return CURLE_OK; | ||
| 364 | } | ||
| 365 | |||
| 366 | +void Curl_ssl_associate_conn(struct Curl_easy *data, | ||
| 367 | + struct connectdata *conn) | ||
| 368 | +{ | ||
| 369 | + if(Curl_ssl->associate_connection) { | ||
| 370 | + Curl_ssl->associate_connection(data, conn, FIRSTSOCKET); | ||
| 371 | + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) | ||
| 372 | + Curl_ssl->associate_connection(data, conn, SECONDARYSOCKET); | ||
| 373 | + } | ||
| 374 | +} | ||
| 375 | + | ||
| 376 | +void Curl_ssl_detach_conn(struct Curl_easy *data, | ||
| 377 | + struct connectdata *conn) | ||
| 378 | +{ | ||
| 379 | + if(Curl_ssl->disassociate_connection) { | ||
| 380 | + Curl_ssl->disassociate_connection(data, FIRSTSOCKET); | ||
| 381 | + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) | ||
| 382 | + Curl_ssl->disassociate_connection(data, SECONDARYSOCKET); | ||
| 383 | + } | ||
| 384 | +} | ||
| 385 | |||
| 386 | void Curl_ssl_close_all(struct Curl_easy *data) | ||
| 387 | { | ||
| 388 | @@ -1212,7 +1231,9 @@ static const struct Curl_ssl Curl_ssl_multi = { | ||
| 389 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 390 | Curl_none_engines_list, /* engines_list */ | ||
| 391 | Curl_none_false_start, /* false_start */ | ||
| 392 | - NULL /* sha256sum */ | ||
| 393 | + NULL, /* sha256sum */ | ||
| 394 | + NULL, /* associate_connection */ | ||
| 395 | + NULL /* disassociate_connection */ | ||
| 396 | }; | ||
| 397 | |||
| 398 | const struct Curl_ssl *Curl_ssl = | ||
| 399 | diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h | ||
| 400 | index 1351215..94049f9 100644 | ||
| 401 | --- a/lib/vtls/vtls.h | ||
| 402 | +++ b/lib/vtls/vtls.h | ||
| 403 | @@ -75,6 +75,11 @@ struct Curl_ssl { | ||
| 404 | bool (*false_start)(void); | ||
| 405 | CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, | ||
| 406 | unsigned char *sha256sum, size_t sha256sumlen); | ||
| 407 | + | ||
| 408 | + void (*associate_connection)(struct Curl_easy *data, | ||
| 409 | + struct connectdata *conn, | ||
| 410 | + int sockindex); | ||
| 411 | + void (*disassociate_connection)(struct Curl_easy *data, int sockindex); | ||
| 412 | }; | ||
| 413 | |||
| 414 | #ifdef USE_SSL | ||
| 415 | @@ -264,6 +269,11 @@ bool Curl_ssl_cert_status_request(void); | ||
| 416 | |||
| 417 | bool Curl_ssl_false_start(void); | ||
| 418 | |||
| 419 | +void Curl_ssl_associate_conn(struct Curl_easy *data, | ||
| 420 | + struct connectdata *conn); | ||
| 421 | +void Curl_ssl_detach_conn(struct Curl_easy *data, | ||
| 422 | + struct connectdata *conn); | ||
| 423 | + | ||
| 424 | #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ | ||
| 425 | |||
| 426 | #else /* if not USE_SSL */ | ||
| 427 | @@ -290,6 +300,8 @@ bool Curl_ssl_false_start(void); | ||
| 428 | #define Curl_ssl_cert_status_request() FALSE | ||
| 429 | #define Curl_ssl_false_start() FALSE | ||
| 430 | #define Curl_ssl_tls13_ciphersuites() FALSE | ||
| 431 | +#define Curl_ssl_associate_conn(a,b) Curl_nop_stmt | ||
| 432 | +#define Curl_ssl_detach_conn(a,b) Curl_nop_stmt | ||
| 433 | #endif | ||
| 434 | |||
| 435 | #endif /* HEADER_CURL_VTLS_H */ | ||
| 436 | diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c | ||
| 437 | index f1b12b1..f734a84 100644 | ||
| 438 | --- a/lib/vtls/wolfssl.c | ||
| 439 | +++ b/lib/vtls/wolfssl.c | ||
| 440 | @@ -1165,7 +1165,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = { | ||
| 441 | Curl_none_set_engine_default, /* set_engine_default */ | ||
| 442 | Curl_none_engines_list, /* engines_list */ | ||
| 443 | Curl_none_false_start, /* false_start */ | ||
| 444 | - wolfssl_sha256sum /* sha256sum */ | ||
| 445 | + wolfssl_sha256sum, /* sha256sum */ | ||
| 446 | + NULL, /* associate_connection */ | ||
| 447 | + NULL /* disassociate_connection */ | ||
| 448 | }; | ||
| 449 | |||
| 450 | #endif | ||
| 451 | -- | ||
| 452 | 2.31.1 | ||
| 453 | |||
diff --git a/meta/recipes-support/curl/curl/CVE-2021-22924.patch b/meta/recipes-support/curl/curl/CVE-2021-22924.patch new file mode 100644 index 0000000000..f09704c8a9 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22924.patch | |||
| @@ -0,0 +1,298 @@ | |||
| 1 | From 205cf19fc374ee8eb848c5448e31fa703392832e Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Wed, 4 Aug 2021 01:52:40 +0000 | ||
| 4 | Subject: [PATCH] vtls: fix connection reuse checks for issuer cert and case | ||
| 5 | sensitivity | ||
| 6 | |||
| 7 | CVE-2021-22924 | ||
| 8 | |||
| 9 | Reported-by: Harry Sintonen | ||
| 10 | Bug: https://curl.se/docs/CVE-2021-22924.html | ||
| 11 | |||
| 12 | CVE: CVE-2021-22924 | ||
| 13 | |||
| 14 | Upstream-Status: Backport [https://github.com/curl/curl/commit/5ea3145850ebff1dc2b13d17440300a01ca38161] | ||
| 15 | |||
| 16 | Signed-off-by: Mingli Yu <mingli.yu@windriver.com> | ||
| 17 | --- | ||
| 18 | lib/url.c | 10 ++++++---- | ||
| 19 | lib/urldata.h | 6 ++++-- | ||
| 20 | lib/vtls/gtls.c | 10 +++++----- | ||
| 21 | lib/vtls/nss.c | 4 ++-- | ||
| 22 | lib/vtls/openssl.c | 18 +++++++++--------- | ||
| 23 | lib/vtls/vtls.c | 26 +++++++++++++++++++++----- | ||
| 24 | 6 files changed, 47 insertions(+), 27 deletions(-) | ||
| 25 | |||
| 26 | diff --git a/lib/url.c b/lib/url.c | ||
| 27 | index c02d2c2..474c53b 100644 | ||
| 28 | --- a/lib/url.c | ||
| 29 | +++ b/lib/url.c | ||
| 30 | @@ -3695,6 +3695,8 @@ static CURLcode create_conn(struct Curl_easy *data, | ||
| 31 | */ | ||
| 32 | data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; | ||
| 33 | data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; | ||
| 34 | + data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; | ||
| 35 | + data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; | ||
| 36 | data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; | ||
| 37 | data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; | ||
| 38 | data->set.ssl.primary.cipher_list = | ||
| 39 | @@ -3719,8 +3721,11 @@ static CURLcode create_conn(struct Curl_easy *data, | ||
| 40 | data->set.proxy_ssl.primary.pinned_key = | ||
| 41 | data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; | ||
| 42 | data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; | ||
| 43 | + data->set.proxy_ssl.primary.issuercert = | ||
| 44 | + data->set.str[STRING_SSL_ISSUERCERT_PROXY]; | ||
| 45 | + data->set.proxy_ssl.primary.issuercert_blob = | ||
| 46 | + data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; | ||
| 47 | data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; | ||
| 48 | - data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; | ||
| 49 | data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; | ||
| 50 | data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; | ||
| 51 | data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; | ||
| 52 | @@ -3729,7 +3734,6 @@ static CURLcode create_conn(struct Curl_easy *data, | ||
| 53 | data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; | ||
| 54 | #endif | ||
| 55 | data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; | ||
| 56 | - data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; | ||
| 57 | data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; | ||
| 58 | data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; | ||
| 59 | data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; | ||
| 60 | @@ -3743,9 +3747,7 @@ static CURLcode create_conn(struct Curl_easy *data, | ||
| 61 | data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; | ||
| 62 | #endif | ||
| 63 | #endif | ||
| 64 | - | ||
| 65 | data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG]; | ||
| 66 | - data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG]; | ||
| 67 | |||
| 68 | if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, | ||
| 69 | &conn->ssl_config)) { | ||
| 70 | diff --git a/lib/urldata.h b/lib/urldata.h | ||
| 71 | index f7d60b2..7d01874 100644 | ||
| 72 | --- a/lib/urldata.h | ||
| 73 | +++ b/lib/urldata.h | ||
| 74 | @@ -246,6 +246,7 @@ struct ssl_primary_config { | ||
| 75 | long version_max; /* max supported version the client wants to use*/ | ||
| 76 | char *CApath; /* certificate dir (doesn't work on windows) */ | ||
| 77 | char *CAfile; /* certificate to verify peer against */ | ||
| 78 | + char *issuercert; /* optional issuer certificate filename */ | ||
| 79 | char *clientcert; | ||
| 80 | char *random_file; /* path to file containing "random" data */ | ||
| 81 | char *egdsocket; /* path to file containing the EGD daemon socket */ | ||
| 82 | @@ -253,6 +254,7 @@ struct ssl_primary_config { | ||
| 83 | char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ | ||
| 84 | char *pinned_key; | ||
| 85 | struct curl_blob *cert_blob; | ||
| 86 | + struct curl_blob *issuercert_blob; | ||
| 87 | char *curves; /* list of curves to use */ | ||
| 88 | BIT(verifypeer); /* set TRUE if this is desired */ | ||
| 89 | BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ | ||
| 90 | @@ -264,8 +266,6 @@ struct ssl_config_data { | ||
| 91 | struct ssl_primary_config primary; | ||
| 92 | long certverifyresult; /* result from the certificate verification */ | ||
| 93 | char *CRLfile; /* CRL to check certificate revocation */ | ||
| 94 | - char *issuercert;/* optional issuer certificate filename */ | ||
| 95 | - struct curl_blob *issuercert_blob; | ||
| 96 | curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ | ||
| 97 | void *fsslctxp; /* parameter for call back */ | ||
| 98 | char *cert_type; /* format for certificate (default: PEM)*/ | ||
| 99 | @@ -1545,6 +1545,7 @@ enum dupstring { | ||
| 100 | STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ | ||
| 101 | STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ | ||
| 102 | STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ | ||
| 103 | + STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ | ||
| 104 | STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ | ||
| 105 | STRING_SSL_ENGINE, /* name of ssl engine */ | ||
| 106 | STRING_USERNAME, /* <username>, if used */ | ||
| 107 | @@ -1600,6 +1601,7 @@ enum dupblob { | ||
| 108 | BLOB_CERT_PROXY, | ||
| 109 | BLOB_KEY_ORIG, | ||
| 110 | BLOB_KEY_PROXY, | ||
| 111 | + BLOB_SSL_ISSUERCERT, | ||
| 112 | BLOB_SSL_ISSUERCERT_ORIG, | ||
| 113 | BLOB_SSL_ISSUERCERT_PROXY, | ||
| 114 | BLOB_LAST | ||
| 115 | diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c | ||
| 116 | index 2c65ba0..d1c3919 100644 | ||
| 117 | --- a/lib/vtls/gtls.c | ||
| 118 | +++ b/lib/vtls/gtls.c | ||
| 119 | @@ -855,7 +855,7 @@ gtls_connect_step3(struct Curl_easy *data, | ||
| 120 | if(!chainp) { | ||
| 121 | if(SSL_CONN_CONFIG(verifypeer) || | ||
| 122 | SSL_CONN_CONFIG(verifyhost) || | ||
| 123 | - SSL_SET_OPTION(issuercert)) { | ||
| 124 | + SSL_CONN_CONFIG(issuercert)) { | ||
| 125 | #ifdef HAVE_GNUTLS_SRP | ||
| 126 | if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP | ||
| 127 | && SSL_SET_OPTION(username) != NULL | ||
| 128 | @@ -1039,21 +1039,21 @@ gtls_connect_step3(struct Curl_easy *data, | ||
| 129 | gnutls_x509_crt_t format */ | ||
| 130 | gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); | ||
| 131 | |||
| 132 | - if(SSL_SET_OPTION(issuercert)) { | ||
| 133 | + if(SSL_CONN_CONFIG(issuercert)) { | ||
| 134 | gnutls_x509_crt_init(&x509_issuer); | ||
| 135 | - issuerp = load_file(SSL_SET_OPTION(issuercert)); | ||
| 136 | + issuerp = load_file(SSL_CONN_CONFIG(issuercert)); | ||
| 137 | gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); | ||
| 138 | rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); | ||
| 139 | gnutls_x509_crt_deinit(x509_issuer); | ||
| 140 | unload_file(issuerp); | ||
| 141 | if(rc <= 0) { | ||
| 142 | failf(data, "server certificate issuer check failed (IssuerCert: %s)", | ||
| 143 | - SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); | ||
| 144 | + SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); | ||
| 145 | gnutls_x509_crt_deinit(x509_cert); | ||
| 146 | return CURLE_SSL_ISSUER_ERROR; | ||
| 147 | } | ||
| 148 | infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", | ||
| 149 | - SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); | ||
| 150 | + SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); | ||
| 151 | } | ||
| 152 | |||
| 153 | size = sizeof(certname); | ||
| 154 | diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c | ||
| 155 | index fb9f763..dab12b6 100644 | ||
| 156 | --- a/lib/vtls/nss.c | ||
| 157 | +++ b/lib/vtls/nss.c | ||
| 158 | @@ -2159,9 +2159,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data, | ||
| 159 | if(result) | ||
| 160 | goto error; | ||
| 161 | |||
| 162 | - if(SSL_SET_OPTION(issuercert)) { | ||
| 163 | + if(SSL_CONN_CONFIG(issuercert)) { | ||
| 164 | SECStatus ret = SECFailure; | ||
| 165 | - char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); | ||
| 166 | + char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); | ||
| 167 | if(nickname) { | ||
| 168 | /* we support only nicknames in case of issuercert for now */ | ||
| 169 | ret = check_issuer_cert(backend->handle, nickname); | ||
| 170 | diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c | ||
| 171 | index 946b4c5..85e1ee5 100644 | ||
| 172 | --- a/lib/vtls/openssl.c | ||
| 173 | +++ b/lib/vtls/openssl.c | ||
| 174 | @@ -3881,10 +3881,10 @@ static CURLcode servercert(struct Curl_easy *data, | ||
| 175 | deallocating the certificate. */ | ||
| 176 | |||
| 177 | /* e.g. match issuer name with provided issuer certificate */ | ||
| 178 | - if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) { | ||
| 179 | - if(SSL_SET_OPTION(issuercert_blob)) | ||
| 180 | - fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data, | ||
| 181 | - (int)SSL_SET_OPTION(issuercert_blob)->len); | ||
| 182 | + if(SSL_CONN_CONFIG(issuercert) || SSL_CONN_CONFIG(issuercert_blob)) { | ||
| 183 | + if(SSL_CONN_CONFIG(issuercert_blob)) | ||
| 184 | + fp = BIO_new_mem_buf(SSL_CONN_CONFIG(issuercert_blob)->data, | ||
| 185 | + (int)SSL_CONN_CONFIG(issuercert_blob)->len); | ||
| 186 | else { | ||
| 187 | fp = BIO_new(BIO_s_file()); | ||
| 188 | if(fp == NULL) { | ||
| 189 | @@ -3898,10 +3898,10 @@ static CURLcode servercert(struct Curl_easy *data, | ||
| 190 | return CURLE_OUT_OF_MEMORY; | ||
| 191 | } | ||
| 192 | |||
| 193 | - if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { | ||
| 194 | + if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) { | ||
| 195 | if(strict) | ||
| 196 | failf(data, "SSL: Unable to open issuer cert (%s)", | ||
| 197 | - SSL_SET_OPTION(issuercert)); | ||
| 198 | + SSL_CONN_CONFIG(issuercert)); | ||
| 199 | BIO_free(fp); | ||
| 200 | X509_free(backend->server_cert); | ||
| 201 | backend->server_cert = NULL; | ||
| 202 | @@ -3913,7 +3913,7 @@ static CURLcode servercert(struct Curl_easy *data, | ||
| 203 | if(!issuer) { | ||
| 204 | if(strict) | ||
| 205 | failf(data, "SSL: Unable to read issuer cert (%s)", | ||
| 206 | - SSL_SET_OPTION(issuercert)); | ||
| 207 | + SSL_CONN_CONFIG(issuercert)); | ||
| 208 | BIO_free(fp); | ||
| 209 | X509_free(issuer); | ||
| 210 | X509_free(backend->server_cert); | ||
| 211 | @@ -3924,7 +3924,7 @@ static CURLcode servercert(struct Curl_easy *data, | ||
| 212 | if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { | ||
| 213 | if(strict) | ||
| 214 | failf(data, "SSL: Certificate issuer check failed (%s)", | ||
| 215 | - SSL_SET_OPTION(issuercert)); | ||
| 216 | + SSL_CONN_CONFIG(issuercert)); | ||
| 217 | BIO_free(fp); | ||
| 218 | X509_free(issuer); | ||
| 219 | X509_free(backend->server_cert); | ||
| 220 | @@ -3933,7 +3933,7 @@ static CURLcode servercert(struct Curl_easy *data, | ||
| 221 | } | ||
| 222 | |||
| 223 | infof(data, " SSL certificate issuer check ok (%s)\n", | ||
| 224 | - SSL_SET_OPTION(issuercert)); | ||
| 225 | + SSL_CONN_CONFIG(issuercert)); | ||
| 226 | BIO_free(fp); | ||
| 227 | X509_free(issuer); | ||
| 228 | } | ||
| 229 | diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c | ||
| 230 | index 59a7efb..eb885da 100644 | ||
| 231 | --- a/lib/vtls/vtls.c | ||
| 232 | +++ b/lib/vtls/vtls.c | ||
| 233 | @@ -125,6 +125,16 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second) | ||
| 234 | return !memcmp(first->data, second->data, first->len); /* same data */ | ||
| 235 | } | ||
| 236 | |||
| 237 | +static bool safecmp(char *a, char *b) | ||
| 238 | +{ | ||
| 239 | + if(a && b) | ||
| 240 | + return !strcmp(a, b); | ||
| 241 | + else if(!a && !b) | ||
| 242 | + return TRUE; /* match */ | ||
| 243 | + return FALSE; /* no match */ | ||
| 244 | +} | ||
| 245 | + | ||
| 246 | + | ||
| 247 | bool | ||
| 248 | Curl_ssl_config_matches(struct ssl_primary_config *data, | ||
| 249 | struct ssl_primary_config *needle) | ||
| 250 | @@ -135,11 +145,13 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, | ||
| 251 | (data->verifyhost == needle->verifyhost) && | ||
| 252 | (data->verifystatus == needle->verifystatus) && | ||
| 253 | blobcmp(data->cert_blob, needle->cert_blob) && | ||
| 254 | - Curl_safe_strcasecompare(data->CApath, needle->CApath) && | ||
| 255 | - Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && | ||
| 256 | - Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && | ||
| 257 | - Curl_safe_strcasecompare(data->random_file, needle->random_file) && | ||
| 258 | - Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && | ||
| 259 | + blobcmp(data->issuercert_blob, needle->issuercert_blob) && | ||
| 260 | + safecmp(data->CApath, needle->CApath) && | ||
| 261 | + safecmp(data->CAfile, needle->CAfile) && | ||
| 262 | + safecmp(data->issuercert, needle->issuercert) && | ||
| 263 | + safecmp(data->clientcert, needle->clientcert) && | ||
| 264 | + safecmp(data->random_file, needle->random_file) && | ||
| 265 | + safecmp(data->egdsocket, needle->egdsocket) && | ||
| 266 | Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && | ||
| 267 | Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && | ||
| 268 | Curl_safe_strcasecompare(data->curves, needle->curves) && | ||
| 269 | @@ -161,8 +173,10 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, | ||
| 270 | dest->sessionid = source->sessionid; | ||
| 271 | |||
| 272 | CLONE_BLOB(cert_blob); | ||
| 273 | + CLONE_BLOB(issuercert_blob); | ||
| 274 | CLONE_STRING(CApath); | ||
| 275 | CLONE_STRING(CAfile); | ||
| 276 | + CLONE_STRING(issuercert); | ||
| 277 | CLONE_STRING(clientcert); | ||
| 278 | CLONE_STRING(random_file); | ||
| 279 | CLONE_STRING(egdsocket); | ||
| 280 | @@ -178,6 +192,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) | ||
| 281 | { | ||
| 282 | Curl_safefree(sslc->CApath); | ||
| 283 | Curl_safefree(sslc->CAfile); | ||
| 284 | + Curl_safefree(sslc->issuercert); | ||
| 285 | Curl_safefree(sslc->clientcert); | ||
| 286 | Curl_safefree(sslc->random_file); | ||
| 287 | Curl_safefree(sslc->egdsocket); | ||
| 288 | @@ -185,6 +200,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) | ||
| 289 | Curl_safefree(sslc->cipher_list13); | ||
| 290 | Curl_safefree(sslc->pinned_key); | ||
| 291 | Curl_safefree(sslc->cert_blob); | ||
| 292 | + Curl_safefree(sslc->issuercert_blob); | ||
| 293 | Curl_safefree(sslc->curves); | ||
| 294 | } | ||
| 295 | |||
| 296 | -- | ||
| 297 | 2.31.1 | ||
| 298 | |||
diff --git a/meta/recipes-support/curl/curl/CVE-2021-22926.patch b/meta/recipes-support/curl/curl/CVE-2021-22926.patch new file mode 100644 index 0000000000..3a803bcc98 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22926.patch | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | From 6180ef7c19defa9f77ae166acb8b63ed98a9c09a Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Daniel Stenberg <daniel@haxx.se> | ||
| 3 | Date: Wed, 4 Aug 2021 03:05:45 +0000 | ||
| 4 | Subject: [PATCH] sectransp: check for client certs by name first, then file | ||
| 5 | |||
| 6 | CVE-2021-22926 | ||
| 7 | |||
| 8 | Bug: https://curl.se/docs/CVE-2021-22926.html | ||
| 9 | |||
| 10 | Assisted-by: Daniel Gustafsson | ||
| 11 | Reported-by: Harry Sintonen | ||
| 12 | |||
| 13 | CVE: CVE-2021-22926 | ||
| 14 | |||
| 15 | Upstream-Status: Backport [https://github.com/curl/curl/commit/fd9b40bf8dfd43edcbc0d254d613d95a11061c05] | ||
| 16 | |||
| 17 | Signed-off-by: Mingli Yu <mingli.yu@windriver.com> | ||
| 18 | --- | ||
| 19 | lib/vtls/sectransp.c | 33 +++++++++++++++++++-------------- | ||
| 20 | 1 file changed, 19 insertions(+), 14 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c | ||
| 23 | index 37b41f8..f8effde 100644 | ||
| 24 | --- a/lib/vtls/sectransp.c | ||
| 25 | +++ b/lib/vtls/sectransp.c | ||
| 26 | @@ -32,6 +32,7 @@ | ||
| 27 | #include "curl_base64.h" | ||
| 28 | #include "strtok.h" | ||
| 29 | #include "multiif.h" | ||
| 30 | +#include "strcase.h" | ||
| 31 | |||
| 32 | #ifdef USE_SECTRANSP | ||
| 33 | |||
| 34 | @@ -1648,24 +1649,28 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, | ||
| 35 | bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); | ||
| 36 | SecIdentityRef cert_and_key = NULL; | ||
| 37 | |||
| 38 | - /* User wants to authenticate with a client cert. Look for it: | ||
| 39 | - If we detect that this is a file on disk, then let's load it. | ||
| 40 | - Otherwise, assume that the user wants to use an identity loaded | ||
| 41 | - from the Keychain. */ | ||
| 42 | - if(is_cert_file || is_cert_data) { | ||
| 43 | + /* User wants to authenticate with a client cert. Look for it. Assume that | ||
| 44 | + the user wants to use an identity loaded from the Keychain. If not, try | ||
| 45 | + it as a file on disk */ | ||
| 46 | + | ||
| 47 | + if(!is_cert_data) | ||
| 48 | + err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); | ||
| 49 | + else | ||
| 50 | + err = !noErr; | ||
| 51 | + if((err != noErr) && (is_cert_file || is_cert_data)) { | ||
| 52 | if(!SSL_SET_OPTION(cert_type)) | ||
| 53 | - infof(data, "WARNING: SSL: Certificate type not set, assuming " | ||
| 54 | - "PKCS#12 format.\n"); | ||
| 55 | - else if(strncmp(SSL_SET_OPTION(cert_type), "P12", | ||
| 56 | - strlen(SSL_SET_OPTION(cert_type))) != 0) | ||
| 57 | - infof(data, "WARNING: SSL: The Security framework only supports " | ||
| 58 | - "loading identities that are in PKCS#12 format.\n"); | ||
| 59 | + infof(data, "SSL: Certificate type not set, assuming " | ||
| 60 | + "PKCS#12 format."); | ||
| 61 | + else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) { | ||
| 62 | + failf(data, "SSL: The Security framework only supports " | ||
| 63 | + "loading identities that are in PKCS#12 format."); | ||
| 64 | + return CURLE_SSL_CERTPROBLEM; | ||
| 65 | + } | ||
| 66 | |||
| 67 | err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, | ||
| 68 | - SSL_SET_OPTION(key_passwd), &cert_and_key); | ||
| 69 | + SSL_SET_OPTION(key_passwd), | ||
| 70 | + &cert_and_key); | ||
| 71 | } | ||
| 72 | - else | ||
| 73 | - err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); | ||
| 74 | |||
| 75 | if(err == noErr && cert_and_key) { | ||
| 76 | SecCertificateRef cert = NULL; | ||
| 77 | -- | ||
| 78 | 2.31.1 | ||
| 79 | |||
diff --git a/meta/recipes-support/curl/curl_7.75.0.bb b/meta/recipes-support/curl/curl_7.75.0.bb index b2aad0bbc2..d64e5e1f79 100644 --- a/meta/recipes-support/curl/curl_7.75.0.bb +++ b/meta/recipes-support/curl/curl_7.75.0.bb | |||
| @@ -18,6 +18,9 @@ SRC_URI = "https://curl.haxx.se/download/curl-${PV}.tar.bz2 \ | |||
| 18 | file://CVE-2021-22898.patch \ | 18 | file://CVE-2021-22898.patch \ |
| 19 | file://CVE-2021-22897.patch \ | 19 | file://CVE-2021-22897.patch \ |
| 20 | file://CVE-2021-22925.patch \ | 20 | file://CVE-2021-22925.patch \ |
| 21 | file://CVE-2021-22901.patch \ | ||
| 22 | file://CVE-2021-22924.patch \ | ||
| 23 | file://CVE-2021-22926.patch \ | ||
| 21 | " | 24 | " |
| 22 | 25 | ||
| 23 | SRC_URI[sha256sum] = "50552d4501c178e4cc68baaecc487f466a3d6d19bbf4e50a01869effb316d026" | 26 | SRC_URI[sha256sum] = "50552d4501c178e4cc68baaecc487f466a3d6d19bbf4e50a01869effb316d026" |
