summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-support/curl/curl')
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22901.patch453
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22924.patch298
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22925.patch50
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22926.patch79
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22945.patch35
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22946.patch333
-rw-r--r--meta/recipes-support/curl/curl/CVE-2021-22947.patch357
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
+