89a891
From 38ae0949251e7bd228858120d8eaa2a697f84f1a 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
89a891
index 1afb461226..8116cab0cb 100644
89a891
--- a/bin/named/server.c
89a891
+++ b/bin/named/server.c
89a891
@@ -1530,12 +1530,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) {
89a891
 			isc_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
89a891
index 1a3d534799..545e3c6a5e 100644
89a891
--- a/lib/bind9/check.c
89a891
+++ b/lib/bind9/check.c
89a891
@@ -298,6 +298,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
89a891
index d1fa8d5870..d57a798e29 100644
89a891
--- a/lib/dns/rcode.c
89a891
+++ b/lib/dns/rcode.c
89a891
@@ -124,7 +124,6 @@
89a891
 #endif
89a891
 
89a891
 #define SECALGNAMES \
89a891
-	MD5_SECALGNAMES \
89a891
 	DH_SECALGNAMES \
89a891
 	DSA_SECALGNAMES \
89a891
 	{ DNS_KEYALG_ECC, "ECC", 0 }, \
89a891
@@ -176,6 +175,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 };
89a891
@@ -348,33 +348,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
89a891
-	if (isc_md5_available() == ISC_FALSE) {
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,
89a891
+	        	                       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