summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch
diff options
context:
space:
mode:
authorZhixiong Chi <zhixiong.chi@windriver.com>2020-09-07 19:56:38 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-09-10 13:21:31 +0100
commit7a9969fe8cb8b039976bcd482d7b815922ae54ea (patch)
tree8471d5db165e94ae5d9a0a1d536cbaeda78819d3 /meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch
parent794dfa173adbce781c9fe609d58d3ed9b8cbd501 (diff)
downloadopenembedded-core-contrib-7a9969fe8cb8b039976bcd482d7b815922ae54ea.tar.gz
gnutls: CVE-2020-24659
Backport the CVE patch from the usptream: https://gitlab.com/gnutls/gnutls.git commit 29ee67c205855e848a0a26e6d0e4f65b6b943e0a Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Diffstat (limited to 'meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch')
-rw-r--r--meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch117
1 files changed, 117 insertions, 0 deletions
diff --git a/meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch b/meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch
new file mode 100644
index 0000000000..1702325e66
--- /dev/null
+++ b/meta/recipes-support/gnutls/gnutls/CVE-2020-24659.patch
@@ -0,0 +1,117 @@
+From 29ee67c205855e848a0a26e6d0e4f65b6b943e0a Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno@gnu.org>
+Date: Sat, 22 Aug 2020 17:19:39 +0200
+Subject: [PATCH] handshake: reject no_renegotiation alert if handshake is
+ incomplete
+
+If the initial handshake is incomplete and the server sends a
+no_renegotiation alert, the client should treat it as a fatal error
+even if its level is warning. Otherwise the same handshake
+state (e.g., DHE parameters) are reused in the next gnutls_handshake
+call, if it is called in the loop idiom:
+
+ do {
+ ret = gnutls_handshake(session);
+ } while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
+
+Signed-off-by: Daiki Ueno <ueno@gnu.org>
+CVE: CVE-2020-24659
+Upstream-Status: Backport [https://gitlab.com/gnutls/gnutls.git]
+Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com>
+---
+ lib/gnutls_int.h | 1 +
+ lib/handshake.c | 48 +++++++++++++-----
+ 2 files changed, 36 insertions(+), 13 deletions(-)
+
+diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
+index bb6c19713..31cec5c0c 100644
+--- a/lib/gnutls_int.h
++++ b/lib/gnutls_int.h
+@@ -1370,6 +1370,7 @@ typedef struct {
+ #define HSK_RECORD_SIZE_LIMIT_RECEIVED (1<<26) /* server: record_size_limit extension was seen but not accepted yet */
+ #define HSK_OCSP_REQUESTED (1<<27) /* server: client requested OCSP stapling */
+ #define HSK_CLIENT_OCSP_REQUESTED (1<<28) /* client: server requested OCSP stapling */
++#define HSK_SERVER_HELLO_RECEIVED (1<<29) /* client: Server Hello message has been received */
+
+ /* The hsk_flags are for use within the ongoing handshake;
+ * they are reset to zero prior to handshake start by gnutls_handshake. */
+diff --git a/lib/handshake.c b/lib/handshake.c
+index b40f84b3d..ce2d160e2 100644
+--- a/lib/handshake.c
++++ b/lib/handshake.c
+@@ -2051,6 +2051,8 @@ read_server_hello(gnutls_session_t session,
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
++ session->internals.hsk_flags |= HSK_SERVER_HELLO_RECEIVED;
++
+ return 0;
+ }
+
+@@ -2575,16 +2577,42 @@ int gnutls_rehandshake(gnutls_session_t session)
+ return 0;
+ }
+
++/* This function checks whether the error code should be treated fatal
++ * or not, and also does the necessary state transition. In
++ * particular, in the case of a rehandshake abort it resets the
++ * handshake's internal state.
++ */
+ inline static int
+ _gnutls_abort_handshake(gnutls_session_t session, int ret)
+ {
+- if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
+- (gnutls_alert_get(session) == GNUTLS_A_NO_RENEGOTIATION))
+- || ret == GNUTLS_E_GOT_APPLICATION_DATA)
+- return 0;
++ switch (ret) {
++ case GNUTLS_E_WARNING_ALERT_RECEIVED:
++ if (gnutls_alert_get(session) == GNUTLS_A_NO_RENEGOTIATION) {
++ /* The server always toleretes a "no_renegotiation" alert. */
++ if (session->security_parameters.entity == GNUTLS_SERVER) {
++ STATE = STATE0;
++ return ret;
++ }
++
++ /* The client should tolerete a "no_renegotiation" alert only if:
++ * - the initial handshake has completed, or
++ * - a Server Hello is not yet received
++ */
++ if (session->internals.initial_negotiation_completed ||
++ !(session->internals.hsk_flags & HSK_SERVER_HELLO_RECEIVED)) {
++ STATE = STATE0;
++ return ret;
++ }
+
+- /* this doesn't matter */
+- return GNUTLS_E_INTERNAL_ERROR;
++ return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
++ }
++ return ret;
++ case GNUTLS_E_GOT_APPLICATION_DATA:
++ STATE = STATE0;
++ return ret;
++ default:
++ return ret;
++ }
+ }
+
+
+@@ -2747,13 +2774,7 @@ int gnutls_handshake(gnutls_session_t session)
+ }
+
+ if (ret < 0) {
+- /* In the case of a rehandshake abort
+- * we should reset the handshake's internal state.
+- */
+- if (_gnutls_abort_handshake(session, ret) == 0)
+- STATE = STATE0;
+-
+- return ret;
++ return _gnutls_abort_handshake(session, ret);
+ }
+
+ /* clear handshake buffer */
+--
+2.17.0
+