Blame SOURCES/gnutls-3.6.16-tls12-cert-type.patch

c8a18e
From 339bef12f478b3a12c59571c53645e31280baf7e Mon Sep 17 00:00:00 2001
c8a18e
From: Daiki Ueno <ueno@gnu.org>
c8a18e
Date: Fri, 14 May 2021 15:59:37 +0200
c8a18e
Subject: [PATCH] cert auth: filter out unsupported cert types from TLS 1.2 CR
c8a18e
c8a18e
When the server is advertising signature algorithms in TLS 1.2
c8a18e
CertificateRequest, it shouldn't send certificate_types not backed by
c8a18e
any of those algorithms.
c8a18e
c8a18e
Signed-off-by: Daiki Ueno <ueno@gnu.org>
c8a18e
---
c8a18e
 lib/auth/cert.c                         | 76 +++++++++++++++++++++++--
c8a18e
 tests/suite/tls-fuzzer/gnutls-cert.json | 19 +++++++
c8a18e
 2 files changed, 89 insertions(+), 6 deletions(-)
c8a18e
c8a18e
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
c8a18e
index 3073a33d3..0b0f04b2b 100644
c8a18e
--- a/lib/auth/cert.c
c8a18e
+++ b/lib/auth/cert.c
c8a18e
@@ -64,6 +64,16 @@ typedef enum CertificateSigType { RSA_SIGN = 1, DSA_SIGN = 2, ECDSA_SIGN = 64,
c8a18e
 #endif
c8a18e
 } CertificateSigType;
c8a18e
 
c8a18e
+enum CertificateSigTypeFlags {
c8a18e
+	RSA_SIGN_FLAG = 1,
c8a18e
+	DSA_SIGN_FLAG = 1 << 1,
c8a18e
+	ECDSA_SIGN_FLAG = 1 << 2,
c8a18e
+#ifdef ENABLE_GOST
c8a18e
+	GOSTR34102012_256_SIGN_FLAG = 1 << 3,
c8a18e
+	GOSTR34102012_512_SIGN_FLAG = 1 << 4
c8a18e
+#endif
c8a18e
+};
c8a18e
+
c8a18e
 /* Moves data from an internal certificate struct (gnutls_pcert_st) to
c8a18e
  * another internal certificate struct (cert_auth_info_t), and deinitializes
c8a18e
  * the former.
c8a18e
@@ -1281,6 +1291,7 @@ _gnutls_gen_cert_server_cert_req(gnutls_session_t session,
c8a18e
 	uint8_t tmp_data[CERTTYPE_SIZE];
c8a18e
 	const version_entry_st *ver = get_version(session);
c8a18e
 	unsigned init_pos = data->length;
c8a18e
+	enum CertificateSigTypeFlags flags;
c8a18e
 
c8a18e
 	if (unlikely(ver == NULL))
c8a18e
 		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
c8a18e
@@ -1297,18 +1308,71 @@ _gnutls_gen_cert_server_cert_req(gnutls_session_t session,
c8a18e
 		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
c8a18e
 	}
c8a18e
 
c8a18e
-	i = 1;
c8a18e
+	if (_gnutls_version_has_selectable_sighash(ver)) {
c8a18e
+		size_t j;
c8a18e
+
c8a18e
+		flags = 0;
c8a18e
+		for (j = 0; j < session->internals.priorities->sigalg.size; j++) {
c8a18e
+			const gnutls_sign_entry_st *se =
c8a18e
+				session->internals.priorities->sigalg.entry[j];
c8a18e
+			switch (se->pk) {
c8a18e
+			case GNUTLS_PK_RSA:
c8a18e
+			case GNUTLS_PK_RSA_PSS:
c8a18e
+				flags |= RSA_SIGN_FLAG;
c8a18e
+				break;
c8a18e
+			case GNUTLS_PK_DSA:
c8a18e
+				flags |= DSA_SIGN_FLAG;
c8a18e
+				break;
c8a18e
+			case GNUTLS_PK_ECDSA:
c8a18e
+				flags |= ECDSA_SIGN_FLAG;
c8a18e
+				break;
c8a18e
 #ifdef ENABLE_GOST
c8a18e
-	if (_gnutls_kx_is_vko_gost(session->security_parameters.cs->kx_algorithm)) {
c8a18e
-		tmp_data[i++] = GOSTR34102012_256_SIGN;
c8a18e
-		tmp_data[i++] = GOSTR34102012_512_SIGN;
c8a18e
-	} else
c8a18e
+			case GNUTLS_PK_GOST_12_256:
c8a18e
+				flags |= GOSTR34102012_256_SIGN_FLAG;
c8a18e
+				break;
c8a18e
+			case GNUTLS_PK_GOST_12_512:
c8a18e
+				flags |= GOSTR34102012_512_SIGN_FLAG;
c8a18e
+				break;
c8a18e
+#endif
c8a18e
+			default:
c8a18e
+				gnutls_assert();
c8a18e
+				_gnutls_debug_log(
c8a18e
+					"%s is unsupported for cert request\n",
c8a18e
+					gnutls_pk_get_name(se->pk));
c8a18e
+			}
c8a18e
+		}
c8a18e
+
c8a18e
+	} else {
c8a18e
+#ifdef ENABLE_GOST
c8a18e
+		if (_gnutls_kx_is_vko_gost(session->security_parameters.
c8a18e
+					   cs->kx_algorithm)) {
c8a18e
+			flags = GOSTR34102012_256_SIGN_FLAG |
c8a18e
+				GOSTR34102012_512_SIGN_FLAG;
c8a18e
+		} else
c8a18e
 #endif
c8a18e
-	{
c8a18e
+		{
c8a18e
+			flags = RSA_SIGN_FLAG | DSA_SIGN_FLAG | ECDSA_SIGN_FLAG;
c8a18e
+		}
c8a18e
+	}
c8a18e
+
c8a18e
+	i = 1;
c8a18e
+	if (flags & RSA_SIGN_FLAG) {
c8a18e
 		tmp_data[i++] = RSA_SIGN;
c8a18e
+	}
c8a18e
+	if (flags & DSA_SIGN_FLAG) {
c8a18e
 		tmp_data[i++] = DSA_SIGN;
c8a18e
+	}
c8a18e
+	if (flags & ECDSA_SIGN_FLAG) {
c8a18e
 		tmp_data[i++] = ECDSA_SIGN;
c8a18e
 	}
c8a18e
+#ifdef ENABLE_GOST
c8a18e
+	if (flags & GOSTR34102012_256_SIGN_FLAG) {
c8a18e
+		tmp_data[i++] = GOSTR34102012_256_SIGN;
c8a18e
+	}
c8a18e
+	if (flags & GOSTR34102012_512_SIGN_FLAG) {
c8a18e
+		tmp_data[i++] = GOSTR34102012_512_SIGN;
c8a18e
+	}
c8a18e
+#endif
c8a18e
 	tmp_data[0] = i - 1;
c8a18e
 
c8a18e
 	ret = _gnutls_buffer_append_data(data, tmp_data, i);
c8a18e
-- 
c8a18e
2.31.1
c8a18e