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