10d019
From 83b889c238282b210f874a3ad81bb56299767495 Mon Sep 17 00:00:00 2001
89a891
From: Petr Mensik <pemensik@redhat.com>
89a891
Date: Mon, 5 Aug 2019 11:54:03 +0200
89a891
Subject: [PATCH] Allow explicit disabling of autodisabled MD5
89a891
89a891
Default security policy might include explicitly disabled RSAMD5
89a891
algorithm. Current FIPS code automatically disables in FIPS mode. But if
89a891
RSAMD5 is included in security policy, it fails to start, because that
89a891
algorithm is not recognized. Allow it disabled, but fail on any
89a891
other usage.
89a891
---
89a891
 bin/named/server.c |  4 ++--
89a891
 lib/bind9/check.c  |  4 ++++
89a891
 lib/dns/rcode.c    | 33 +++++++++++++++------------------
89a891
 3 files changed, 21 insertions(+), 20 deletions(-)
89a891
89a891
diff --git a/bin/named/server.c b/bin/named/server.c
10d019
index 5b57371..51702ab 100644
89a891
--- a/bin/named/server.c
89a891
+++ b/bin/named/server.c
10d019
@@ -1547,12 +1547,12 @@ disable_algorithms(const cfg_obj_t *disabled, dns_resolver_t *resolver) {
89a891
 		r.length = strlen(r.base);
89a891
 
89a891
 		result = dns_secalg_fromtext(&alg, &r);
89a891
-		if (result != ISC_R_SUCCESS) {
89a891
+		if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) {
10d019
 			uint8_t ui;
89a891
 			result = isc_parse_uint8(&ui, r.base, 10);
89a891
 			alg = ui;
89a891
 		}
89a891
-		if (result != ISC_R_SUCCESS) {
89a891
+		if (result != ISC_R_SUCCESS && result != ISC_R_DISABLED) {
89a891
 			cfg_obj_log(cfg_listelt_value(element),
89a891
 				    ns_g_lctx, ISC_LOG_ERROR,
89a891
 				    "invalid algorithm");
89a891
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
10d019
index e0803d4..8023784 100644
89a891
--- a/lib/bind9/check.c
89a891
+++ b/lib/bind9/check.c
10d019
@@ -302,6 +302,10 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
89a891
 		r.length = strlen(r.base);
89a891
 
89a891
 		tresult = dns_secalg_fromtext(&alg, &r);
89a891
+		if (tresult == ISC_R_DISABLED) {
89a891
+			// Recognize disabled algorithms, disable it explicitly
89a891
+			tresult = ISC_R_SUCCESS;
89a891
+		}
89a891
 		if (tresult != ISC_R_SUCCESS) {
89a891
 			cfg_obj_log(cfg_listelt_value(element), logctx,
89a891
 				    ISC_LOG_ERROR, "invalid algorithm '%s'",
89a891
diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c
10d019
index f51d548..c49b8d1 100644
89a891
--- a/lib/dns/rcode.c
89a891
+++ b/lib/dns/rcode.c
10d019
@@ -126,7 +126,6 @@
89a891
 #endif
89a891
 
89a891
 #define SECALGNAMES \
89a891
-	MD5_SECALGNAMES \
89a891
 	DH_SECALGNAMES \
89a891
 	DSA_SECALGNAMES \
89a891
 	{ DNS_KEYALG_ECC, "ECC", 0 }, \
10d019
@@ -178,6 +177,7 @@ static struct tbl rcodes[] = { RCODENAMES ERCODENAMES };
89a891
 static struct tbl tsigrcodes[] = { RCODENAMES TSIGRCODENAMES };
89a891
 static struct tbl certs[] = { CERTNAMES };
89a891
 static struct tbl secalgs[] = { SECALGNAMES };
89a891
+static struct tbl md5_secalgs[] = { MD5_SECALGNAMES };
89a891
 static struct tbl secprotos[] = { SECPROTONAMES };
89a891
 static struct tbl hashalgs[] = { HASHALGNAMES };
89a891
 static struct tbl dsdigests[] = { DSDIGESTNAMES };
10d019
@@ -358,33 +358,30 @@ dns_cert_totext(dns_cert_t cert, isc_buffer_t *target) {
89a891
 	return (dns_mnemonic_totext(cert, target, certs));
89a891
 }
89a891
 
89a891
-static inline struct tbl *
89a891
-secalgs_tbl_start() {
89a891
-	struct tbl *algs = secalgs;
89a891
-
89a891
-#ifndef PK11_MD5_DISABLE
10d019
-	if (!isc_md5_available()) {
89a891
-		while (algs->name != NULL &&
89a891
-		       algs->value == DNS_KEYALG_RSAMD5)
89a891
-			++algs;
89a891
-	}
89a891
-#endif
89a891
-	return algs;
89a891
-}
89a891
-
89a891
 isc_result_t
89a891
 dns_secalg_fromtext(dns_secalg_t *secalgp, isc_textregion_t *source) {
89a891
 	unsigned int value;
89a891
+	isc_result_t result;
89a891
 
89a891
-	RETERR(dns_mnemonic_fromtext(&value, source,
89a891
-	                             secalgs_tbl_start(), 0xff));
89a891
+	result = dns_mnemonic_fromtext(&value, source,
89a891
+	                               secalgs, 0xff);
89a891
+	if (result != ISC_R_SUCCESS) {
89a891
+		result = dns_mnemonic_fromtext(&value, source,
10d019
+	                                       md5_secalgs, 0xff);
89a891
+		if (result != ISC_R_SUCCESS) {
89a891
+			return (result);
89a891
+		} else if (!isc_md5_available()) {
89a891
+			*secalgp = value;
89a891
+			return (ISC_R_DISABLED);
89a891
+		}
89a891
+	}
89a891
 	*secalgp = value;
89a891
 	return (ISC_R_SUCCESS);
89a891
 }
89a891
 
89a891
 isc_result_t
89a891
 dns_secalg_totext(dns_secalg_t secalg, isc_buffer_t *target) {
89a891
-	return (dns_mnemonic_totext(secalg, target, secalgs_tbl_start()));
89a891
+	return (dns_mnemonic_totext(secalg, target, secalgs));
89a891
 }
89a891
 
89a891
 void
89a891
-- 
89a891
2.20.1
89a891