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

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