diff options
Diffstat (limited to 'meta/recipes-support/curl/curl')
-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-22925.patch | 50 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22926.patch | 79 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22945.patch | 35 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22946.patch | 333 | ||||
-rw-r--r-- | meta/recipes-support/curl/curl/CVE-2021-22947.patch | 357 |
7 files changed, 1605 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 @@ +From a801ebdc2b1c008fa72c31f1bf7773d99e6e2a2d Mon Sep 17 00:00:00 2001 +From: Harry Sintonen <sintonen@iki.fi> +Date: Tue, 3 Aug 2021 08:41:45 +0000 +Subject: [PATCH] openssl: associate/detach the transfer from connection + +CVE-2021-22901 + +Bug: https://curl.se/docs/CVE-2021-22901.html + +CVE: CVE-2021-22901 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/7f4a9a9b2a49547eae24d2e19bc5c346e9026479] + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + lib/multi.c | 5 +- + lib/vtls/gskit.c | 4 +- + lib/vtls/gtls.c | 4 +- + lib/vtls/mbedtls.c | 4 +- + lib/vtls/mesalink.c | 4 +- + lib/vtls/nss.c | 4 +- + lib/vtls/openssl.c | 146 +++++++++++++++++++++++++++++++------------ + lib/vtls/schannel.c | 6 +- + lib/vtls/sectransp.c | 4 +- + lib/vtls/vtls.c | 23 ++++++- + lib/vtls/vtls.h | 12 ++++ + lib/vtls/wolfssl.c | 4 +- + 12 files changed, 170 insertions(+), 50 deletions(-) + +diff --git a/lib/multi.c b/lib/multi.c +index 85707a1..a4ff9ac 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -875,8 +875,10 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi) + void Curl_detach_connnection(struct Curl_easy *data) + { + struct connectdata *conn = data->conn; +- if(conn) ++ if(conn) { + Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); ++ Curl_ssl_detach_conn(data, conn); ++ } + data->conn = NULL; + } + +@@ -893,6 +895,7 @@ void Curl_attach_connnection(struct Curl_easy *data, + data->conn = conn; + Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, + &data->conn_queue); ++ Curl_ssl_associate_conn(data, conn); + } + + static int waitconnect_getsock(struct connectdata *conn, +diff --git a/lib/vtls/gskit.c b/lib/vtls/gskit.c +index 9b5f649..bd9c602 100644 +--- a/lib/vtls/gskit.c ++++ b/lib/vtls/gskit.c +@@ -1282,7 +1282,9 @@ const struct Curl_ssl Curl_ssl_gskit = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- NULL /* sha256sum */ ++ NULL, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif /* USE_GSKIT */ +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index 28ca528..24e036b 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -1683,7 +1683,9 @@ const struct Curl_ssl Curl_ssl_gnutls = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- gtls_sha256sum /* sha256sum */ ++ gtls_sha256sum, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif /* USE_GNUTLS */ +diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c +index bd0e080..fc973c7 100644 +--- a/lib/vtls/mbedtls.c ++++ b/lib/vtls/mbedtls.c +@@ -1112,7 +1112,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- mbedtls_sha256sum /* sha256sum */ ++ mbedtls_sha256sumi, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif /* USE_MBEDTLS */ +diff --git a/lib/vtls/mesalink.c b/lib/vtls/mesalink.c +index ad807d3..8a91487 100644 +--- a/lib/vtls/mesalink.c ++++ b/lib/vtls/mesalink.c +@@ -666,7 +666,9 @@ const struct Curl_ssl Curl_ssl_mesalink = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- NULL /* sha256sum */ ++ NULL, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index e5ab71c..fb9f763 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2444,7 +2444,9 @@ const struct Curl_ssl Curl_ssl_nss = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + nss_false_start, /* false_start */ +- nss_sha256sum /* sha256sum */ ++ nss_sha256sum, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif /* USE_NSS */ +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 8304264..946b4c5 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -244,6 +244,10 @@ struct ssl_backend_data { + #endif + }; + ++static void ossl_associate_connection(struct Curl_easy *data, ++ struct connectdata *conn, ++ int sockindex); ++ + /* + * Number of bytes to read from the random number seed file. This must be + * a finite value (because some entropy "files" like /dev/urandom have +@@ -2527,6 +2531,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, + curl_socket_t sockfd = conn->sock[sockindex]; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + ctx_option_t ctx_options = 0; ++ void *ssl_sessionid = NULL; + + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + bool sni; +@@ -3224,46 +3229,23 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, + } + #endif + +- /* Check if there's a cached ID we can/should use here! */ +- if(SSL_SET_OPTION(primary.sessionid)) { +- void *ssl_sessionid = NULL; +- int data_idx = ossl_get_ssl_data_index(); +- int connectdata_idx = ossl_get_ssl_conn_index(); +- int sockindex_idx = ossl_get_ssl_sockindex_index(); +- int proxy_idx = ossl_get_proxy_index(); +- +- if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && +- proxy_idx >= 0) { +- /* Store the data needed for the "new session" callback. +- * The sockindex is stored as a pointer to an array element. */ +- SSL_set_ex_data(backend->handle, data_idx, data); +- SSL_set_ex_data(backend->handle, connectdata_idx, conn); +- SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); +-#ifndef CURL_DISABLE_PROXY +- SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: +- NULL); +-#else +- SSL_set_ex_data(backend->handle, proxy_idx, NULL); +-#endif +- +- } ++ ossl_associate_connection(data, conn, sockindex); + +- Curl_ssl_sessionid_lock(data); +- if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, +- &ssl_sessionid, NULL, sockindex)) { +- /* we got a session id, use it! */ +- if(!SSL_set_session(backend->handle, ssl_sessionid)) { +- Curl_ssl_sessionid_unlock(data); +- failf(data, "SSL: SSL_set_session failed: %s", +- ossl_strerror(ERR_get_error(), error_buffer, +- sizeof(error_buffer))); +- return CURLE_SSL_CONNECT_ERROR; +- } +- /* Informational message */ +- infof(data, "SSL re-using session ID\n"); ++ Curl_ssl_sessionid_lock(data); ++ if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, ++ &ssl_sessionid, NULL, sockindex)) { ++ /* we got a session id, use it! */ ++ if(!SSL_set_session(backend->handle, ssl_sessionid)) { ++ Curl_ssl_sessionid_unlock(data); ++ failf(data, "SSL: SSL_set_session failed: %s", ++ ossl_strerror(ERR_get_error(), error_buffer, ++ sizeof(error_buffer))); ++ return CURLE_SSL_CONNECT_ERROR; + } +- Curl_ssl_sessionid_unlock(data); ++ /* Informational message */ ++ infof(data, "SSL re-using session ID\n"); + } ++ Curl_ssl_sessionid_unlock(data); + + #ifndef CURL_DISABLE_PROXY + if(conn->proxy_ssl[sockindex].use) { +@@ -4481,6 +4463,90 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl, + (void *)backend->ctx : (void *)backend->handle; + } + ++static void ossl_associate_connection(struct Curl_easy *data, ++ struct connectdata *conn, ++ int sockindex) ++{ ++ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ++ struct ssl_backend_data *backend = connssl->backend; ++ ++ /* If we don't have SSL context, do nothing. */ ++ if(!backend->handle) ++ return; ++ ++ if(SSL_SET_OPTION(primary.sessionid)) { ++ int data_idx = ossl_get_ssl_data_index(); ++ int connectdata_idx = ossl_get_ssl_conn_index(); ++ int sockindex_idx = ossl_get_ssl_sockindex_index(); ++ int proxy_idx = ossl_get_proxy_index(); ++ ++ if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && ++ proxy_idx >= 0) { ++ /* Store the data needed for the "new session" callback. ++ * The sockindex is stored as a pointer to an array element. */ ++ SSL_set_ex_data(backend->handle, data_idx, data); ++ SSL_set_ex_data(backend->handle, connectdata_idx, conn); ++ SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); ++#ifndef CURL_DISABLE_PROXY ++ SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: ++ NULL); ++#else ++ SSL_set_ex_data(backend->handle, proxy_idx, NULL); ++#endif ++ } ++ } ++} ++ ++/* ++ * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after ++ * the handshake. If the transfer that sets up the callback gets killed before ++ * this callback arrives, we must make sure to properly clear the data to ++ * avoid UAF problems. A future optimization could be to instead store another ++ * transfer that might still be using the same connection. ++ */ ++ ++static void ossl_disassociate_connection(struct Curl_easy *data, ++ int sockindex) ++{ ++ struct connectdata *conn = data->conn; ++ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ++ struct ssl_backend_data *backend = connssl->backend; ++ ++ /* If we don't have SSL context, do nothing. */ ++ if(!backend->handle) ++ return; ++ ++ if(SSL_SET_OPTION(primary.sessionid)) { ++ bool isproxy = FALSE; ++ bool incache; ++ void *old_ssl_sessionid = NULL; ++ int data_idx = ossl_get_ssl_data_index(); ++ int connectdata_idx = ossl_get_ssl_conn_index(); ++ int sockindex_idx = ossl_get_ssl_sockindex_index(); ++ int proxy_idx = ossl_get_proxy_index(); ++ ++ if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && ++ proxy_idx >= 0) { ++ /* Invalidate the session cache entry, if any */ ++ isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE; ++ ++ /* Disable references to data in "new session" callback to avoid ++ * accessing a stale pointer. */ ++ SSL_set_ex_data(backend->handle, data_idx, NULL); ++ SSL_set_ex_data(backend->handle, connectdata_idx, NULL); ++ SSL_set_ex_data(backend->handle, sockindex_idx, NULL); ++ SSL_set_ex_data(backend->handle, proxy_idx, NULL); ++ } ++ ++ Curl_ssl_sessionid_lock(data); ++ incache = !(Curl_ssl_getsessionid(data, conn, isproxy, ++ &old_ssl_sessionid, NULL, sockindex)); ++ if(incache) ++ Curl_ssl_delsessionid(data, old_ssl_sessionid); ++ Curl_ssl_sessionid_unlock(data); ++ } ++} ++ + const struct Curl_ssl Curl_ssl_openssl = { + { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ + +@@ -4514,10 +4580,12 @@ const struct Curl_ssl Curl_ssl_openssl = { + ossl_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) +- ossl_sha256sum /* sha256sum */ ++ ossl_sha256sum, /* sha256sum */ + #else +- NULL /* sha256sum */ ++ NULL, /* sha256sum */ + #endif ++ ossl_associate_connection, /* associate_connection */ ++ ossl_disassociate_connection /* disassociate_connection */ + }; + + #endif /* USE_OPENSSL */ +diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c +index 670310d..596106a 100644 +--- a/lib/vtls/schannel.c ++++ b/lib/vtls/schannel.c +@@ -325,7 +325,7 @@ get_alg_id_by_name(char *name) + + static CURLcode + set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, +- int *algIds) ++ ALG_ID *algIds) + { + char *startCur = ciphers; + int algCount = 0; +@@ -2429,7 +2429,9 @@ const struct Curl_ssl Curl_ssl_schannel = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- schannel_sha256sum /* sha256sum */ ++ schannel_sha256sum, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif /* USE_SCHANNEL */ +diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c +index 6d1ea7e..37b41f8 100644 +--- a/lib/vtls/sectransp.c ++++ b/lib/vtls/sectransp.c +@@ -3311,7 +3311,9 @@ const struct Curl_ssl Curl_ssl_sectransp = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + sectransp_false_start, /* false_start */ +- sectransp_sha256sum /* sha256sum */ ++ sectransp_sha256sum, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #ifdef __clang__ +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index 00b6268..59a7efb 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -579,6 +579,25 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, + return CURLE_OK; + } + ++void Curl_ssl_associate_conn(struct Curl_easy *data, ++ struct connectdata *conn) ++{ ++ if(Curl_ssl->associate_connection) { ++ Curl_ssl->associate_connection(data, conn, FIRSTSOCKET); ++ if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) ++ Curl_ssl->associate_connection(data, conn, SECONDARYSOCKET); ++ } ++} ++ ++void Curl_ssl_detach_conn(struct Curl_easy *data, ++ struct connectdata *conn) ++{ ++ if(Curl_ssl->disassociate_connection) { ++ Curl_ssl->disassociate_connection(data, FIRSTSOCKET); ++ if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) ++ Curl_ssl->disassociate_connection(data, SECONDARYSOCKET); ++ } ++} + + void Curl_ssl_close_all(struct Curl_easy *data) + { +@@ -1212,7 +1231,9 @@ static const struct Curl_ssl Curl_ssl_multi = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- NULL /* sha256sum */ ++ NULL, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + const struct Curl_ssl *Curl_ssl = +diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h +index 1351215..94049f9 100644 +--- a/lib/vtls/vtls.h ++++ b/lib/vtls/vtls.h +@@ -75,6 +75,11 @@ struct Curl_ssl { + bool (*false_start)(void); + CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, + unsigned char *sha256sum, size_t sha256sumlen); ++ ++ void (*associate_connection)(struct Curl_easy *data, ++ struct connectdata *conn, ++ int sockindex); ++ void (*disassociate_connection)(struct Curl_easy *data, int sockindex); + }; + + #ifdef USE_SSL +@@ -264,6 +269,11 @@ bool Curl_ssl_cert_status_request(void); + + bool Curl_ssl_false_start(void); + ++void Curl_ssl_associate_conn(struct Curl_easy *data, ++ struct connectdata *conn); ++void Curl_ssl_detach_conn(struct Curl_easy *data, ++ struct connectdata *conn); ++ + #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ + + #else /* if not USE_SSL */ +@@ -290,6 +300,8 @@ bool Curl_ssl_false_start(void); + #define Curl_ssl_cert_status_request() FALSE + #define Curl_ssl_false_start() FALSE + #define Curl_ssl_tls13_ciphersuites() FALSE ++#define Curl_ssl_associate_conn(a,b) Curl_nop_stmt ++#define Curl_ssl_detach_conn(a,b) Curl_nop_stmt + #endif + + #endif /* HEADER_CURL_VTLS_H */ +diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c +index f1b12b1..f734a84 100644 +--- a/lib/vtls/wolfssl.c ++++ b/lib/vtls/wolfssl.c +@@ -1165,7 +1165,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = { + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ +- wolfssl_sha256sum /* sha256sum */ ++ wolfssl_sha256sum, /* sha256sum */ ++ NULL, /* associate_connection */ ++ NULL /* disassociate_connection */ + }; + + #endif +-- +2.31.1 + 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 @@ +From 205cf19fc374ee8eb848c5448e31fa703392832e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Wed, 4 Aug 2021 01:52:40 +0000 +Subject: [PATCH] vtls: fix connection reuse checks for issuer cert and case + sensitivity + +CVE-2021-22924 + +Reported-by: Harry Sintonen +Bug: https://curl.se/docs/CVE-2021-22924.html + +CVE: CVE-2021-22924 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/5ea3145850ebff1dc2b13d17440300a01ca38161] + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + lib/url.c | 10 ++++++---- + lib/urldata.h | 6 ++++-- + lib/vtls/gtls.c | 10 +++++----- + lib/vtls/nss.c | 4 ++-- + lib/vtls/openssl.c | 18 +++++++++--------- + lib/vtls/vtls.c | 26 +++++++++++++++++++++----- + 6 files changed, 47 insertions(+), 27 deletions(-) + +diff --git a/lib/url.c b/lib/url.c +index c02d2c2..474c53b 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -3695,6 +3695,8 @@ static CURLcode create_conn(struct Curl_easy *data, + */ + data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; ++ data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; ++ data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; + data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.ssl.primary.cipher_list = +@@ -3719,8 +3721,11 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.primary.pinned_key = + data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; + data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; ++ data->set.proxy_ssl.primary.issuercert = ++ data->set.str[STRING_SSL_ISSUERCERT_PROXY]; ++ data->set.proxy_ssl.primary.issuercert_blob = ++ data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; + data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; +- data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; + data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; + data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; +@@ -3729,7 +3734,6 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; + #endif + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; +- data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; + data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; + data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; +@@ -3743,9 +3747,7 @@ static CURLcode create_conn(struct Curl_easy *data, + data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; + #endif + #endif +- + data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG]; +- data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG]; + + if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, + &conn->ssl_config)) { +diff --git a/lib/urldata.h b/lib/urldata.h +index f7d60b2..7d01874 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -246,6 +246,7 @@ struct ssl_primary_config { + long version_max; /* max supported version the client wants to use*/ + char *CApath; /* certificate dir (doesn't work on windows) */ + char *CAfile; /* certificate to verify peer against */ ++ 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 */ +@@ -253,6 +254,7 @@ struct ssl_primary_config { + char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ + char *pinned_key; + struct curl_blob *cert_blob; ++ struct curl_blob *issuercert_blob; + char *curves; /* list of curves to use */ + BIT(verifypeer); /* set TRUE if this is desired */ + BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ +@@ -264,8 +266,6 @@ struct ssl_config_data { + struct ssl_primary_config primary; + long certverifyresult; /* result from the certificate verification */ + char *CRLfile; /* CRL to check certificate revocation */ +- char *issuercert;/* optional issuer certificate filename */ +- struct curl_blob *issuercert_blob; + curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ + void *fsslctxp; /* parameter for call back */ + char *cert_type; /* format for certificate (default: PEM)*/ +@@ -1545,6 +1545,7 @@ enum dupstring { + STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ + STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ + STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ ++ STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ + STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ + STRING_SSL_ENGINE, /* name of ssl engine */ + STRING_USERNAME, /* <username>, if used */ +@@ -1600,6 +1601,7 @@ enum dupblob { + BLOB_CERT_PROXY, + BLOB_KEY_ORIG, + BLOB_KEY_PROXY, ++ BLOB_SSL_ISSUERCERT, + BLOB_SSL_ISSUERCERT_ORIG, + BLOB_SSL_ISSUERCERT_PROXY, + BLOB_LAST +diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c +index 2c65ba0..d1c3919 100644 +--- a/lib/vtls/gtls.c ++++ b/lib/vtls/gtls.c +@@ -855,7 +855,7 @@ gtls_connect_step3(struct Curl_easy *data, + if(!chainp) { + if(SSL_CONN_CONFIG(verifypeer) || + SSL_CONN_CONFIG(verifyhost) || +- SSL_SET_OPTION(issuercert)) { ++ SSL_CONN_CONFIG(issuercert)) { + #ifdef HAVE_GNUTLS_SRP + if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP + && SSL_SET_OPTION(username) != NULL +@@ -1039,21 +1039,21 @@ gtls_connect_step3(struct Curl_easy *data, + gnutls_x509_crt_t format */ + gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + gnutls_x509_crt_init(&x509_issuer); +- issuerp = load_file(SSL_SET_OPTION(issuercert)); ++ issuerp = load_file(SSL_CONN_CONFIG(issuercert)); + gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); + rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); + gnutls_x509_crt_deinit(x509_issuer); + unload_file(issuerp); + if(rc <= 0) { + failf(data, "server certificate issuer check failed (IssuerCert: %s)", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + gnutls_x509_crt_deinit(x509_cert); + return CURLE_SSL_ISSUER_ERROR; + } + infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", +- SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); ++ SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); + } + + size = sizeof(certname); +diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c +index fb9f763..dab12b6 100644 +--- a/lib/vtls/nss.c ++++ b/lib/vtls/nss.c +@@ -2159,9 +2159,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data, + if(result) + goto error; + +- if(SSL_SET_OPTION(issuercert)) { ++ if(SSL_CONN_CONFIG(issuercert)) { + SECStatus ret = SECFailure; +- char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); ++ char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); + if(nickname) { + /* we support only nicknames in case of issuercert for now */ + ret = check_issuer_cert(backend->handle, nickname); +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 946b4c5..85e1ee5 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3881,10 +3881,10 @@ static CURLcode servercert(struct Curl_easy *data, + deallocating the certificate. */ + + /* e.g. match issuer name with provided issuer certificate */ +- if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) { +- if(SSL_SET_OPTION(issuercert_blob)) +- fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data, +- (int)SSL_SET_OPTION(issuercert_blob)->len); ++ if(SSL_CONN_CONFIG(issuercert) || SSL_CONN_CONFIG(issuercert_blob)) { ++ if(SSL_CONN_CONFIG(issuercert_blob)) ++ fp = BIO_new_mem_buf(SSL_CONN_CONFIG(issuercert_blob)->data, ++ (int)SSL_CONN_CONFIG(issuercert_blob)->len); + else { + fp = BIO_new(BIO_s_file()); + if(fp == NULL) { +@@ -3898,10 +3898,10 @@ static CURLcode servercert(struct Curl_easy *data, + return CURLE_OUT_OF_MEMORY; + } + +- if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { ++ if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) { + if(strict) + failf(data, "SSL: Unable to open issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(backend->server_cert); + backend->server_cert = NULL; +@@ -3913,7 +3913,7 @@ static CURLcode servercert(struct Curl_easy *data, + if(!issuer) { + if(strict) + failf(data, "SSL: Unable to read issuer cert (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(backend->server_cert); +@@ -3924,7 +3924,7 @@ static CURLcode servercert(struct Curl_easy *data, + if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { + if(strict) + failf(data, "SSL: Certificate issuer check failed (%s)", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + X509_free(backend->server_cert); +@@ -3933,7 +3933,7 @@ static CURLcode servercert(struct Curl_easy *data, + } + + infof(data, " SSL certificate issuer check ok (%s)\n", +- SSL_SET_OPTION(issuercert)); ++ SSL_CONN_CONFIG(issuercert)); + BIO_free(fp); + X509_free(issuer); + } +diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c +index 59a7efb..eb885da 100644 +--- a/lib/vtls/vtls.c ++++ b/lib/vtls/vtls.c +@@ -125,6 +125,16 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second) + return !memcmp(first->data, second->data, first->len); /* same data */ + } + ++static bool safecmp(char *a, char *b) ++{ ++ if(a && b) ++ return !strcmp(a, b); ++ else if(!a && !b) ++ return TRUE; /* match */ ++ return FALSE; /* no match */ ++} ++ ++ + bool + Curl_ssl_config_matches(struct ssl_primary_config *data, + struct ssl_primary_config *needle) +@@ -135,11 +145,13 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, + (data->verifyhost == needle->verifyhost) && + (data->verifystatus == needle->verifystatus) && + blobcmp(data->cert_blob, needle->cert_blob) && +- Curl_safe_strcasecompare(data->CApath, needle->CApath) && +- Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && +- Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && +- Curl_safe_strcasecompare(data->random_file, needle->random_file) && +- Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && ++ blobcmp(data->issuercert_blob, needle->issuercert_blob) && ++ safecmp(data->CApath, needle->CApath) && ++ safecmp(data->CAfile, needle->CAfile) && ++ safecmp(data->issuercert, needle->issuercert) && ++ safecmp(data->clientcert, needle->clientcert) && ++ safecmp(data->random_file, needle->random_file) && ++ safecmp(data->egdsocket, needle->egdsocket) && + Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && + Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && + Curl_safe_strcasecompare(data->curves, needle->curves) && +@@ -161,8 +173,10 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, + dest->sessionid = source->sessionid; + + CLONE_BLOB(cert_blob); ++ CLONE_BLOB(issuercert_blob); + CLONE_STRING(CApath); + CLONE_STRING(CAfile); ++ CLONE_STRING(issuercert); + CLONE_STRING(clientcert); + CLONE_STRING(random_file); + CLONE_STRING(egdsocket); +@@ -178,6 +192,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) + { + Curl_safefree(sslc->CApath); + Curl_safefree(sslc->CAfile); ++ Curl_safefree(sslc->issuercert); + Curl_safefree(sslc->clientcert); + Curl_safefree(sslc->random_file); + Curl_safefree(sslc->egdsocket); +@@ -185,6 +200,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) + Curl_safefree(sslc->cipher_list13); + Curl_safefree(sslc->pinned_key); + Curl_safefree(sslc->cert_blob); ++ Curl_safefree(sslc->issuercert_blob); + Curl_safefree(sslc->curves); + } + +-- +2.31.1 + diff --git a/meta/recipes-support/curl/curl/CVE-2021-22925.patch b/meta/recipes-support/curl/curl/CVE-2021-22925.patch new file mode 100644 index 0000000000..e3009c9533 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22925.patch @@ -0,0 +1,50 @@ +From 894f6ec730597eb243618d33cc84d71add8d6a8a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Sat, 12 Jun 2021 18:25:15 +0200 +Subject: [PATCH] telnet: fix option parser to not send uninitialized contents + +CVE-2021-22925 + +Reported-by: Red Hat Product Security +Bug: https://curl.se/docs/CVE-2021-22925.html + +CVE: CVE-2021-22925 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/894f6ec730597eb243618d33cc84d71add8d6a8a] + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + lib/telnet.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/lib/telnet.c b/lib/telnet.c +index 1d3024ec4..a81bb81c3 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -920,12 +920,17 @@ static void suboption(struct Curl_easy *data) + size_t tmplen = (strlen(v->data) + 1); + /* Add the variable only if it fits */ + if(len + tmplen < (int)sizeof(temp)-6) { +- if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { +- msnprintf((char *)&temp[len], sizeof(temp) - len, +- "%c%s%c%s", CURL_NEW_ENV_VAR, varname, +- CURL_NEW_ENV_VALUE, varval); +- len += tmplen; +- } ++ int rv; ++ char sep[2] = ""; ++ varval[0] = 0; ++ rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval); ++ if(rv == 1) ++ len += msnprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s", CURL_NEW_ENV_VAR, varname); ++ else if(rv >= 2) ++ len += msnprintf((char *)&temp[len], sizeof(temp) - len, ++ "%c%s%c%s", CURL_NEW_ENV_VAR, varname, ++ CURL_NEW_ENV_VALUE, varval); + } + } + msnprintf((char *)&temp[len], sizeof(temp) - len, +-- +2.17.1 + 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 @@ +From 6180ef7c19defa9f77ae166acb8b63ed98a9c09a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg <daniel@haxx.se> +Date: Wed, 4 Aug 2021 03:05:45 +0000 +Subject: [PATCH] sectransp: check for client certs by name first, then file + +CVE-2021-22926 + +Bug: https://curl.se/docs/CVE-2021-22926.html + +Assisted-by: Daniel Gustafsson +Reported-by: Harry Sintonen + +CVE: CVE-2021-22926 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/fd9b40bf8dfd43edcbc0d254d613d95a11061c05] + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + lib/vtls/sectransp.c | 33 +++++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 14 deletions(-) + +diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c +index 37b41f8..f8effde 100644 +--- a/lib/vtls/sectransp.c ++++ b/lib/vtls/sectransp.c +@@ -32,6 +32,7 @@ + #include "curl_base64.h" + #include "strtok.h" + #include "multiif.h" ++#include "strcase.h" + + #ifdef USE_SECTRANSP + +@@ -1648,24 +1649,28 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, + bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); + SecIdentityRef cert_and_key = NULL; + +- /* User wants to authenticate with a client cert. Look for it: +- If we detect that this is a file on disk, then let's load it. +- Otherwise, assume that the user wants to use an identity loaded +- from the Keychain. */ +- if(is_cert_file || is_cert_data) { ++ /* User wants to authenticate with a client cert. Look for it. Assume that ++ the user wants to use an identity loaded from the Keychain. If not, try ++ it as a file on disk */ ++ ++ if(!is_cert_data) ++ err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); ++ else ++ err = !noErr; ++ if((err != noErr) && (is_cert_file || is_cert_data)) { + if(!SSL_SET_OPTION(cert_type)) +- infof(data, "WARNING: SSL: Certificate type not set, assuming " +- "PKCS#12 format.\n"); +- else if(strncmp(SSL_SET_OPTION(cert_type), "P12", +- strlen(SSL_SET_OPTION(cert_type))) != 0) +- infof(data, "WARNING: SSL: The Security framework only supports " +- "loading identities that are in PKCS#12 format.\n"); ++ infof(data, "SSL: Certificate type not set, assuming " ++ "PKCS#12 format."); ++ else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) { ++ failf(data, "SSL: The Security framework only supports " ++ "loading identities that are in PKCS#12 format."); ++ return CURLE_SSL_CERTPROBLEM; ++ } + + err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, +- SSL_SET_OPTION(key_passwd), &cert_and_key); ++ SSL_SET_OPTION(key_passwd), ++ &cert_and_key); + } +- else +- err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); + + if(err == noErr && cert_and_key) { + SecCertificateRef cert = NULL; +-- +2.31.1 + diff --git a/meta/recipes-support/curl/curl/CVE-2021-22945.patch b/meta/recipes-support/curl/curl/CVE-2021-22945.patch new file mode 100644 index 0000000000..44c42632ed --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22945.patch @@ -0,0 +1,35 @@ +From 43157490a5054bd24256fe12876931e8abc9df49 Mon Sep 17 00:00:00 2001 +From: z2_ on hackerone <> +Date: Tue, 24 Aug 2021 09:50:33 +0200 +Subject: [PATCH] mqtt: clear the leftovers pointer when sending succeeds + +CVE-2021-22945 + +Bug: https://curl.se/docs/CVE-2021-22945.html + +Upstream-Status: Backport [https://github.com/curl/curl/commit/43157490a5054bd24256fe12876931e8abc9df49] + +Signed-off-by: Robert Joslyn <robert.joslyn@redrectangle.org> + +--- + lib/mqtt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/mqtt.c b/lib/mqtt.c +index f077e6c3d..fcd40b41e 100644 +--- a/lib/mqtt.c ++++ b/lib/mqtt.c +@@ -128,6 +128,10 @@ static CURLcode mqtt_send(struct Curl_easy *data, + mq->sendleftovers = sendleftovers; + mq->nsend = nsend; + } ++ else { ++ mq->sendleftovers = NULL; ++ mq->nsend = 0; ++ } + return result; + } + +-- +2.34.1 + diff --git a/meta/recipes-support/curl/curl/CVE-2021-22946.patch b/meta/recipes-support/curl/curl/CVE-2021-22946.patch new file mode 100644 index 0000000000..1cb95f0ea7 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22946.patch @@ -0,0 +1,333 @@ +From 7c6e072216001fb1280d1868adfdcb54e3372ce7 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat <patrick@monnerat.net> +Date: Wed, 8 Sep 2021 11:56:22 +0200 +Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd + +In imap and pop3, check if TLS is required even when capabilities +request has failed. + +In ftp, ignore preauthentication (230 status of server greeting) if TLS +is required. + +Bug: https://curl.se/docs/CVE-2021-22946.html + +CVE-2021-22946 + +Upstream-Status: Backport [https://github.com/curl/curl/commit/364f174724ef115c63d5e5dc1d3342c8a43b1cca] + +Signed-off-by: Robert Joslyn <robert.joslyn@redrectangle.org> + +--- + lib/ftp.c | 9 ++++--- + lib/imap.c | 24 ++++++++---------- + lib/pop3.c | 33 +++++++++++------------- + tests/data/Makefile.inc | 2 ++ + tests/data/test984 | 56 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test985 | 54 +++++++++++++++++++++++++++++++++++++++ + tests/data/test986 | 53 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 195 insertions(+), 36 deletions(-) + create mode 100644 tests/data/test984 + create mode 100644 tests/data/test985 + create mode 100644 tests/data/test986 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 3818a9e..8b3fe1d 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2665,9 +2665,12 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: +- if(ftpcode == 230) +- /* 230 User logged in - already! */ +- return ftp_state_user_resp(data, ftpcode, ftpc->state); ++ if(ftpcode == 230) { ++ /* 230 User logged in - already! Take as 220 if TLS required. */ ++ if(data->set.use_ssl <= CURLUSESSL_TRY || ++ conn->bits.ftp_use_control_ssl) ++ return ftp_state_user_resp(data, ftpcode, ftpc->state); ++ } + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); +diff --git a/lib/imap.c b/lib/imap.c +index 2d80699..b056208 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -933,22 +933,18 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data, + line += wordlen; + } + } +- else if(imapcode == IMAP_RESP_OK) { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(imapc->tls_supported) +- /* Switch to TLS connection now */ +- result = imap_perform_starttls(data, conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = imap_perform_authentication(data, conn); +- else { +- failf(data, "STARTTLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } ++ else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { ++ /* PREAUTH is not compatible with STARTTLS. */ ++ if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { ++ /* Switch to TLS connection now */ ++ result = imap_perform_starttls(data, conn); + } +- else ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) + result = imap_perform_authentication(data, conn); ++ else { ++ failf(data, "STARTTLS not available."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + else + result = imap_perform_authentication(data, conn); +diff --git a/lib/pop3.c b/lib/pop3.c +index 0ed3d3e..018fda1 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -738,28 +738,23 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code, + } + } + } +- else if(pop3code == '+') { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(pop3c->tls_supported) +- /* Switch to TLS connection now */ +- result = pop3_perform_starttls(data, conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = pop3_perform_authentication(data, conn); +- else { +- failf(data, "STLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } +- } +- else +- result = pop3_perform_authentication(data, conn); +- } + else { + /* Clear text is supported when CAPA isn't recognised */ +- pop3c->authtypes |= POP3_TYPE_CLEARTEXT; ++ if(pop3code != '+') ++ pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + +- result = pop3_perform_authentication(data, conn); ++ if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use) ++ result = pop3_perform_authentication(data, conn); ++ else if(pop3code == '+' && pop3c->tls_supported) ++ /* Switch to TLS connection now */ ++ result = pop3_perform_starttls(data, conn); ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) ++ /* Fallback and carry on with authentication */ ++ result = pop3_perform_authentication(data, conn); ++ else { ++ failf(data, "STLS not supported."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + + return result; +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index e08cfc7..e6e2551 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -115,6 +115,8 @@ test945 test946 test947 test948 test949 test950 test951 test952 test953 \ + test954 test955 test956 test957 test958 test959 test960 test961 test962 \ + test963 test964 test965 test966 test967 test968 test969 test970 test971 \ + \ ++test984 test985 test986 \ ++\ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ + test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ +diff --git a/tests/data/test984 b/tests/data/test984 +new file mode 100644 +index 0000000..e573f23 +--- /dev/null ++++ b/tests/data/test984 +@@ -0,0 +1,56 @@ ++<testcase> ++<info> ++<keywords> ++IMAP ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++REPLY CAPABILITY A001 BAD Not implemented ++</servercmd> ++</reply> ++ ++# ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++imap ++</server> ++ <name> ++IMAP require STARTTLS with failing capabilities ++ </name> ++ <command> ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd ++</command> ++<file name="log/upload%TESTNUMBER"> ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar <foobar@example.COM> ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: <B27397-0100000@example.COM> ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++</file> ++</client> ++ ++# ++# Verify data after the test has been "shot" ++<verify> ++# 64 is CURLE_USE_SSL_FAILED ++<errorcode> ++64 ++</errorcode> ++<protocol> ++A001 CAPABILITY
++</protocol> ++</verify> ++</testcase> +diff --git a/tests/data/test985 b/tests/data/test985 +new file mode 100644 +index 0000000..d0db4aa +--- /dev/null ++++ b/tests/data/test985 +@@ -0,0 +1,54 @@ ++<testcase> ++<info> ++<keywords> ++POP3 ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++REPLY CAPA -ERR Not implemented ++</servercmd> ++<data nocheck="yes"> ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++</data> ++</reply> ++ ++# ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++pop3 ++</server> ++ <name> ++POP3 require STARTTLS with failing capabilities ++ </name> ++ <command> ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd ++ </command> ++</client> ++ ++# ++# Verify data after the test has been "shot" ++<verify> ++# 64 is CURLE_USE_SSL_FAILED ++<errorcode> ++64 ++</errorcode> ++<protocol> ++CAPA
++</protocol> ++</verify> ++</testcase> +diff --git a/tests/data/test986 b/tests/data/test986 +new file mode 100644 +index 0000000..a709437 +--- /dev/null ++++ b/tests/data/test986 +@@ -0,0 +1,53 @@ ++<testcase> ++<info> ++<keywords> ++FTP ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++REPLY welcome 230 Welcome ++REPLY AUTH 500 unknown command ++</servercmd> ++</reply> ++ ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++ftp ++</server> ++ <name> ++FTP require STARTTLS while preauthenticated ++ </name> ++<file name="log/test%TESTNUMBER.txt"> ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++</file> ++ <command> ++--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret ++</command> ++</client> ++ ++# Verify data after the test has been "shot" ++<verify> ++# 64 is CURLE_USE_SSL_FAILED ++<errorcode> ++64 ++</errorcode> ++<protocol> ++AUTH SSL
++AUTH TLS
++</protocol> ++</verify> ++</testcase> +-- +2.34.1 + diff --git a/meta/recipes-support/curl/curl/CVE-2021-22947.patch b/meta/recipes-support/curl/curl/CVE-2021-22947.patch new file mode 100644 index 0000000000..9bd9890d72 --- /dev/null +++ b/meta/recipes-support/curl/curl/CVE-2021-22947.patch @@ -0,0 +1,357 @@ +From f3f2d2554d09ca0e13039e4915b83faaa55961c4 Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat <patrick@monnerat.net> +Date: Tue, 7 Sep 2021 13:26:42 +0200 +Subject: [PATCH] ftp,imap,pop3,smtp: reject STARTTLS server response + + pipelining + +If a server pipelines future responses within the STARTTLS response, the +former are preserved in the pingpong cache across TLS negotiation and +used as responses to the encrypted commands. + +This fix detects pipelined STARTTLS responses and rejects them with an +error. + +CVE-2021-22947 + +Bug: https://curl.se/docs/CVE-2021-22947.html + +Upstream-Status: Backport [https://github.com/curl/curl/commit/8ef147c43646e91fdaad5d0e7b60351f842e5c68] + +Signed-off-by: Robert Joslyn <robert.joslyn@redrectangle.org> + +--- + lib/ftp.c | 3 +++ + lib/imap.c | 4 +++ + lib/pop3.c | 4 +++ + lib/smtp.c | 4 +++ + tests/data/Makefile.inc | 2 +- + tests/data/test980 | 52 ++++++++++++++++++++++++++++++++++++ + tests/data/test981 | 59 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test982 | 57 +++++++++++++++++++++++++++++++++++++++ + tests/data/test983 | 52 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 236 insertions(+), 1 deletion(-) + create mode 100644 tests/data/test980 + create mode 100644 tests/data/test981 + create mode 100644 tests/data/test982 + create mode 100644 tests/data/test983 + +diff --git a/lib/ftp.c b/lib/ftp.c +index 8b3fe1d..a55566a 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2727,6 +2727,9 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + ++ if(pp->cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */ ++ + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, +diff --git a/lib/imap.c b/lib/imap.c +index b056208..9230f17 100644 +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -962,6 +962,10 @@ static CURLcode imap_state_starttls_resp(struct Curl_easy *data, + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.imapc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(imapcode != IMAP_RESP_OK) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/pop3.c b/lib/pop3.c +index 018fda1..4f953f7 100644 +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -769,6 +769,10 @@ static CURLcode pop3_state_starttls_resp(struct Curl_easy *data, + CURLcode result = CURLE_OK; + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.pop3c.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(pop3code != '+') { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +diff --git a/lib/smtp.c b/lib/smtp.c +index 1fc8800..51445f6 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -832,6 +832,10 @@ static CURLcode smtp_state_starttls_resp(struct Curl_easy *data, + CURLcode result = CURLE_OK; + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.smtpc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(smtpcode != 220) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied, code %d", smtpcode); +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index e6e2551..22d7a0b 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -115,7 +115,7 @@ test945 test946 test947 test948 test949 test950 test951 test952 test953 \ + test954 test955 test956 test957 test958 test959 test960 test961 test962 \ + test963 test964 test965 test966 test967 test968 test969 test970 test971 \ + \ +-test984 test985 test986 \ ++test980 test981 test982 test983 test984 test985 test986 \ + \ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ +diff --git a/tests/data/test980 b/tests/data/test980 +new file mode 100644 +index 0000000..97567f8 +--- /dev/null ++++ b/tests/data/test980 +@@ -0,0 +1,52 @@ ++<testcase> ++<info> ++<keywords> ++SMTP ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++CAPA STARTTLS ++AUTH PLAIN ++REPLY STARTTLS 454 currently unavailable\r\n235 Authenticated\r\n250 2.1.0 Sender ok\r\n250 2.1.5 Recipient ok\r\n354 Enter mail\r\n250 2.0.0 Accepted ++REPLY AUTH 535 5.7.8 Authentication credentials invalid ++</servercmd> ++</reply> ++ ++# ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++smtp ++</server> ++ <name> ++SMTP STARTTLS pipelined server response ++ </name> ++<stdin> ++mail body ++</stdin> ++ <command> ++smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret --ssl --sasl-ir -T - ++</command> ++</client> ++ ++# ++# Verify data after the test has been "shot" ++<verify> ++# 8 is CURLE_WEIRD_SERVER_REPLY ++<errorcode> ++8 ++</errorcode> ++<protocol> ++EHLO %TESTNUMBER
++STARTTLS
++</protocol> ++</verify> ++</testcase> +diff --git a/tests/data/test981 b/tests/data/test981 +new file mode 100644 +index 0000000..2b98ce4 +--- /dev/null ++++ b/tests/data/test981 +@@ -0,0 +1,59 @@ ++<testcase> ++<info> ++<keywords> ++IMAP ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++CAPA STARTTLS ++REPLY STARTTLS A002 BAD currently unavailable\r\nA003 OK Authenticated\r\nA004 OK Accepted ++REPLY LOGIN A003 BAD Authentication credentials invalid ++</servercmd> ++</reply> ++ ++# ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++imap ++</server> ++ <name> ++IMAP STARTTLS pipelined server response ++ </name> ++ <command> ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl ++</command> ++<file name="log/upload%TESTNUMBER"> ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar <foobar@example.COM> ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: <B27397-0100000@example.COM> ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++</file> ++</client> ++ ++# ++# Verify data after the test has been "shot" ++<verify> ++# 8 is CURLE_WEIRD_SERVER_REPLY ++<errorcode> ++8 ++</errorcode> ++<protocol> ++A001 CAPABILITY
++A002 STARTTLS
++</protocol> ++</verify> ++</testcase> +diff --git a/tests/data/test982 b/tests/data/test982 +new file mode 100644 +index 0000000..9e07cc0 +--- /dev/null ++++ b/tests/data/test982 +@@ -0,0 +1,57 @@ ++<testcase> ++<info> ++<keywords> ++POP3 ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++CAPA STLS USER ++REPLY STLS -ERR currently unavailable\r\n+OK user accepted\r\n+OK authenticated ++REPLY PASS -ERR Authentication credentials invalid ++</servercmd> ++<data nocheck="yes"> ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++</data> ++</reply> ++ ++# ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++pop3 ++</server> ++ <name> ++POP3 STARTTLS pipelined server response ++ </name> ++ <command> ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl ++ </command> ++</client> ++ ++# ++# Verify data after the test has been "shot" ++<verify> ++# 8 is CURLE_WEIRD_SERVER_REPLY ++<errorcode> ++8 ++</errorcode> ++<protocol> ++CAPA
++STLS
++</protocol> ++</verify> ++</testcase> +diff --git a/tests/data/test983 b/tests/data/test983 +new file mode 100644 +index 0000000..300ec45 +--- /dev/null ++++ b/tests/data/test983 +@@ -0,0 +1,52 @@ ++<testcase> ++<info> ++<keywords> ++FTP ++STARTTLS ++</keywords> ++</info> ++ ++# ++# Server-side ++<reply> ++<servercmd> ++REPLY AUTH 500 unknown command\r\n500 unknown command\r\n331 give password\r\n230 Authenticated\r\n257 "/"\r\n200 OK\r\n200 OK\r\n200 OK\r\n226 Transfer complete ++REPLY PASS 530 Login incorrect ++</servercmd> ++</reply> ++ ++# Client-side ++<client> ++<features> ++SSL ++</features> ++<server> ++ftp ++</server> ++ <name> ++FTP STARTTLS pipelined server response ++ </name> ++<file name="log/test%TESTNUMBER.txt"> ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++</file> ++ <command> ++--ssl --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret -P %CLIENTIP ++</command> ++</client> ++ ++# Verify data after the test has been "shot" ++<verify> ++# 8 is CURLE_WEIRD_SERVER_REPLY ++<errorcode> ++8 ++</errorcode> ++<protocol> ++AUTH SSL
++</protocol> ++</verify> ++</testcase> +-- +2.34.1 + |