File 0001-_gnutls_verify_crt_status-apply-algorithm-checks-to-.patch of Package gnutls.18749

From 1abb4298398ec6a942dc77384a19b3e3a2392341 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date: Thu, 19 Dec 2019 09:37:34 +0100
Subject: [PATCH] _gnutls_verify_crt_status: apply algorithm checks to trusted
 CAs

If a CA is found in the trusted list, check in addition to
time validity, whether the algorithms comply to the expected
level. This addresses the problem of accepting CAs which would
have been marked as insecure otherwise.

Resolves: #877

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
---
 NEWS                      |  5 +++
 lib/x509/verify.c         | 68 ++++++++++++++++++++++--------------
 tests/Makefile.am         |  5 +--
 tests/certs/rsa-512.pem   | 20 +++++++++++
 tests/server-weak-keys.sh | 72 +++++++++++++++++++++++++++++++++++++++
 tests/test-chains.h       | 18 +++++++++-
 6 files changed, 160 insertions(+), 28 deletions(-)
 create mode 100644 tests/certs/rsa-512.pem
 create mode 100755 tests/server-weak-keys.sh

Index: gnutls-3.6.7/lib/x509/verify.c
===================================================================
--- gnutls-3.6.7.orig/lib/x509/verify.c	2020-06-05 11:45:24.359554720 +0200
+++ gnutls-3.6.7/lib/x509/verify.c	2020-06-05 11:45:38.007648125 +0200
@@ -855,6 +855,36 @@ gnutls_x509_crt_check_issuer(gnutls_x509
 	return is_issuer(cert, issuer);
 }
 
+static
+unsigned check_ca_sanity(const gnutls_x509_crt_t issuer,
+			 time_t now, unsigned int flags)
+{
+	unsigned int status = 0;
+	unsigned sigalg;
+	int ret;
+
+	/* explicit time check for trusted CA that we remove from
+	 * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
+	 */
+	if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
+	    !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
+		status |= check_time_status(issuer, now);
+	}
+
+	ret =
+	    _gnutls_x509_get_signature_algorithm(issuer->cert, "signatureAlgorithm");
+	sigalg = ret;
+
+	/* we explicitly allow CAs which we do not support their self-algorithms
+	 * to pass. */
+	if (ret >= 0 && !is_level_acceptable(issuer, NULL, sigalg, flags)) {
+		status |= GNUTLS_CERT_INSECURE_ALGORITHM|GNUTLS_CERT_INVALID;
+	}
+
+	return status;
+
+}
+
 /* Verify X.509 certificate chain.
  *
  * Note that the return value is an OR of GNUTLS_CERT_* elements.
@@ -913,25 +943,17 @@ _gnutls_verify_crt_status(const gnutls_x
 			 * CA to self-signed CA at some point. */
 			if (_gnutls_check_if_same_key
 			    (certificate_list[i], trusted_cas[j], i) != 0) {
-				/* explicit time check for trusted CA that we remove from
-				 * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
-				 */
-
-				if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
-					!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
-					status |=
-					    check_time_status(trusted_cas[j],
-						       now);
-					if (status != 0) {
-						if (func)
-							func(certificate_list[i], trusted_cas[j], NULL, status);
-						return status;
-					}
-				}
+
+				status |= check_ca_sanity(trusted_cas[j], now, flags);
 
 				if (func)
 					func(certificate_list[i],
 					     trusted_cas[j], NULL, status);
+
+				if (status != 0) {
+					return gnutls_assert_val(status);
+				}
+
 				clist_size = i;
 				break;
 			}
@@ -1161,20 +1183,16 @@ _gnutls_pkcs11_verify_crt_status(const c
 
 		if (gnutls_pkcs11_crt_is_known (url, certificate_list[i], vflags) != 0) {
 
-			if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
-				!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
-				status |=
-				    check_time_status(certificate_list[i], now);
-				if (status != 0) {
-					if (func)
-						func(certificate_list[i], certificate_list[i], NULL, status);
-					return status;
-				}
-			}
+			status |= check_ca_sanity(certificate_list[i], now, flags);
+
 			if (func)
 				func(certificate_list[i],
 				     certificate_list[i], NULL, status);
 
+			if (status != 0) {
+				return gnutls_assert_val(status);
+			}
+
 			clist_size = i;
 			break;
 		}
Index: gnutls-3.6.7/tests/Makefile.am
===================================================================
--- gnutls-3.6.7.orig/tests/Makefile.am	2020-06-05 11:45:24.359554720 +0200
+++ gnutls-3.6.7/tests/Makefile.am	2020-06-05 11:46:39.168069978 +0200
@@ -38,7 +38,7 @@ EXTRA_DIST = suppressions.valgrind eagai
 	certs/ca-ecc.pem certs/cert-ecc384.pem certs/cert-ecc.pem certs/ecc256.pem \
 	certs/ecc521.pem certs/rsa-2432.pem x509cert-dir/ca.pem psk.passwd \
 	certs/rawpk_priv.pem certs/rawpk_pub.pem \
-	certs/ed25519.pem certs/cert-ed25519.pem \
+	certs/ed25519.pem certs/cert-ed25519.pem certs/rsa-512.pem \
 	system.prio pkcs11/softhsm.h pkcs11/pkcs11-pubkey-import.c gnutls-asan.supp \
 	rsa-md5-collision/README safe-renegotiation/README starttls-smtp.txt starttls-ftp.txt \
 	starttls-lmtp.txt starttls-pop3.txt starttls-xmpp.txt starttls-nntp.txt starttls-sieve.txt \
@@ -467,7 +467,7 @@ dist_check_SCRIPTS += fastopen.sh pkgcon
 	ocsp-tests/ocsp-test cipher-listings.sh sni-hostname.sh server-multi-keys.sh \
 	psktool.sh ocsp-tests/ocsp-load-chain gnutls-cli-save-data.sh gnutls-cli-debug.sh \
 	sni-resume.sh ocsp-tests/ocsptool cert-reencoding.sh pkcs7-cat.sh long-crl.sh \
-	serv-udp.sh logfile-option.sh gnutls-cli-resume.sh
+	serv-udp.sh logfile-option.sh gnutls-cli-resume.sh server-weak-keys.sh
 
 dist_check_SCRIPTS += gnutls-cli-self-signed.sh gnutls-cli-invalid-crl.sh
 
Index: gnutls-3.6.7/tests/certs/rsa-512.pem
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gnutls-3.6.7/tests/certs/rsa-512.pem	2020-06-05 11:45:38.007648125 +0200
@@ -0,0 +1,20 @@
+-----BEGIN PRIVATE KEY-----
+MIIBVwIBADANBgkqhkiG9w0BAQEFAASCAUEwggE9AgEAAkEAwZFO/Vz94lR3/TKz
+76qRCV2skqthX7PB6YxeLHH3ifWSYR2qCYTBikaASm6PGDvAliviIjGjKTkdDdqZ
+X2S94QIDAQABAkEAsV+L+FN8OieZBCWwCNBNsz1pY8Uzp1S7Pl3n9eZBJOKNc/tI
+Tr0/zwAR+5C7IE7xjfuYHZDWN+yXg0LhH+GYgQIhAP0rzSdsjuPJ9XA9wpnYLN4O
+fqXnA7mzW5QKzYuzy3RJAiEAw7sCwUSi7030NszYd7A63o2WrzqWRoX1V1vt6FMd
+zNkCIQDmsytXaY0r9bU6eo0CNANutjaiZ0j1x4MD/HQhgc08QQIhALdYYLZF4xKj
+RRZoQIWtURfULciq6sXZCf7xICQ2Z33RAiEA/M/OnKZijdWg13dchmdaXLgNGxJO
+N90VucFVWK8nXzo=
+-----END PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIBTjCB+aADAgECAhQcc65I8jSxWRjcS1czw4MRLIc8qDANBgkqhkiG9w0BAQsF
+ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTkxMjE1MDI1NTU4WhcNMjkxMjEy
+MDI1NTU4WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwXDANBgkqhkiG9w0BAQEFAANL
+ADBIAkEAwZFO/Vz94lR3/TKz76qRCV2skqthX7PB6YxeLHH3ifWSYR2qCYTBikaA
+Sm6PGDvAliviIjGjKTkdDdqZX2S94QIDAQABoyMwITAJBgNVHRMEAjAAMBQGA1Ud
+EQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAANBAHslvfVxod5p+Gt7l4LV
+M2HBxOt4YM8mRCtyNSmJEGAe+aIzXaiSiRnVkVvjQvdxacu2D4yP52BUo1vzNnCq
+2UI=
+-----END CERTIFICATE-----
Index: gnutls-3.6.7/tests/server-weak-keys.sh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gnutls-3.6.7/tests/server-weak-keys.sh	2020-06-05 11:45:38.007648125 +0200
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# Copyright (C) 2017 Nikos Mavrogiannopoulos
+#
+# Author: Nikos Mavrogiannopoulos
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GnuTLS; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+srcdir="${srcdir:-.}"
+SERV="${SERV:-../src/gnutls-serv${EXEEXT}}"
+CLI="${CLI:-../src/gnutls-cli${EXEEXT}}"
+unset RETCODE
+
+if ! test -x "${SERV}"; then
+	exit 77
+fi
+
+if ! test -x "${CLI}"; then
+	exit 77
+fi
+
+if test "${WINDIR}" != ""; then
+	exit 77
+fi
+
+if ! test -z "${VALGRIND}"; then
+	VALGRIND="${LIBTOOL:-libtool} --mode=execute ${VALGRIND} --error-exitcode=15"
+fi
+
+
+SERV="${SERV} -q"
+
+. "${srcdir}/scripts/common.sh"
+
+check_for_datefudge
+
+echo "Checking whether a client will refuse weak but trusted keys"
+
+KEY1=${srcdir}/certs/rsa-512.pem
+CERT1=${srcdir}/certs/rsa-512.pem
+
+eval "${GETPORT}"
+launch_server $$ --echo --priority "NORMAL" --x509keyfile ${KEY1} --x509certfile ${CERT1}
+PID=$!
+wait_server ${PID}
+
+timeout 1800 datefudge "2019-12-20" \
+"${CLI}" -d 4 -p "${PORT}" localhost --x509cafile ${CERT1} --priority NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 </dev/null && \
+	fail ${PID} "1. handshake with RSA should have failed!"
+
+timeout 1800 datefudge "2019-12-20" \
+"${CLI}" -d 4 -p "${PORT}" localhost --x509cafile ${CERT1} --priority NORMAL </dev/null && \
+	fail ${PID} "2. handshake with RSA should have failed!"
+
+kill ${PID}
+wait
+
+exit 0
Index: gnutls-3.6.7/tests/test-chains.h
===================================================================
--- gnutls-3.6.7.orig/tests/test-chains.h	2020-06-05 11:45:24.383554884 +0200
+++ gnutls-3.6.7/tests/test-chains.h	2020-06-05 11:45:38.007648125 +0200
@@ -3978,6 +3978,20 @@ static const char *gost12_512[] = {
 };
 #endif
 
+static const char *rsa_512[] = {
+	"-----BEGIN CERTIFICATE-----\n"
+	"MIIBTjCB+aADAgECAhQcc65I8jSxWRjcS1czw4MRLIc8qDANBgkqhkiG9w0BAQsF\n"
+	"ADAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMTkxMjE1MDI1NTU4WhcNMjkxMjEy\n"
+	"MDI1NTU4WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwXDANBgkqhkiG9w0BAQEFAANL\n"
+	"ADBIAkEAwZFO/Vz94lR3/TKz76qRCV2skqthX7PB6YxeLHH3ifWSYR2qCYTBikaA\n"
+	"Sm6PGDvAliviIjGjKTkdDdqZX2S94QIDAQABoyMwITAJBgNVHRMEAjAAMBQGA1Ud\n"
+	"EQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAANBAHslvfVxod5p+Gt7l4LV\n"
+	"M2HBxOt4YM8mRCtyNSmJEGAe+aIzXaiSiRnVkVvjQvdxacu2D4yP52BUo1vzNnCq\n"
+	"2UI=\n"
+	"-----END CERTIFICATE-----\n",
+	NULL
+};
+
 #if defined __clang__ || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
 #  pragma GCC diagnostic push
 #  pragma GCC diagnostic ignored "-Wunused-variable"
@@ -4138,10 +4152,12 @@ static struct
 #ifdef ENABLE_GOST
   { "gost 34.10-01 - ok", gost01, &gost01[2], 0, 0, 0, 1466612070, 1},
   { "gost 34.10-01 - not ok (due to profile)", gost01, &gost01[2], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_ULTRA),
-	GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1466612070, 1},
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1466612070, 1},
   { "gost 34.10-12-256 - ok", gost12_256, &gost12_256[0], 0, 0, 0, 1466612070, 1},
   { "gost 34.10-12-512 - ok", gost12_512, &gost12_512[0], 0, 0, 0, 1466612070, 1},
 #endif
+  { "rsa-512 - not ok (due to profile)", rsa_512, &rsa_512[0], GNUTLS_PROFILE_TO_VFLAGS(GNUTLS_PROFILE_MEDIUM),
+    GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID, NULL, 1576759855, 1},
   { NULL, NULL, NULL, 0, 0}
 };
openSUSE Build Service is sponsored by