From: Evan Hunt Date: Thu, 6 Feb 2020 20:13:20 +0000 (-0800) Subject: add support for key algorithm mnemonics in dnssec-policy X-Git-Tag: v9.16.0~18^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58aa084edc96ce00b58060a983c5cea86e470d29;p=thirdparty%2Fbind9.git add support for key algorithm mnemonics in dnssec-policy --- diff --git a/bin/tests/system/checkconf/bad-kasp-key1.conf b/bin/tests/system/checkconf/bad-kasp-key1.conf new file mode 100644 index 00000000000..628788c3495 --- /dev/null +++ b/bin/tests/system/checkconf/bad-kasp-key1.conf @@ -0,0 +1,22 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +dnssec-policy "badalg" { + keys { + csk lifetime unlimited algorithm ceasarscipher; + }; +}; + +zone "example.net" { + type master; + file "example.db"; + dnssec-policy "badalg"; +}; diff --git a/bin/tests/system/checkconf/bad-kasp-key2.conf b/bin/tests/system/checkconf/bad-kasp-key2.conf new file mode 100644 index 00000000000..b6f513f18d4 --- /dev/null +++ b/bin/tests/system/checkconf/bad-kasp-key2.conf @@ -0,0 +1,22 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +dnssec-policy "badalg" { + keys { + csk lifetime unlimited algorithm 8 4097; + }; +}; + +zone "example.net" { + type master; + file "example.db"; + dnssec-policy "badalg"; +}; diff --git a/bin/tests/system/checkconf/bad-kasp-key3.conf b/bin/tests/system/checkconf/bad-kasp-key3.conf new file mode 100644 index 00000000000..5a93301e458 --- /dev/null +++ b/bin/tests/system/checkconf/bad-kasp-key3.conf @@ -0,0 +1,22 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +dnssec-policy "badalg" { + keys { + csk lifetime unlimited algorithm rsasha512 1023; + }; +}; + +zone "example.net" { + type master; + file "example.db"; + dnssec-policy "badalg"; +}; diff --git a/bin/tests/system/checkconf/bad-kasp-key4.conf b/bin/tests/system/checkconf/bad-kasp-key4.conf new file mode 100644 index 00000000000..785b3ca831e --- /dev/null +++ b/bin/tests/system/checkconf/bad-kasp-key4.conf @@ -0,0 +1,22 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +dnssec-policy "badalg" { + keys { + csk lifetime unlimited algorithm 5 511; + }; +}; + +zone "example.net" { + type master; + file "example.db"; + dnssec-policy "badalg"; +}; diff --git a/bin/tests/system/checkconf/good-kasp.conf b/bin/tests/system/checkconf/good-kasp.conf index 6dcc404559d..ae4c319e088 100644 --- a/bin/tests/system/checkconf/good-kasp.conf +++ b/bin/tests/system/checkconf/good-kasp.conf @@ -17,9 +17,9 @@ dnssec-policy "test" { dnskey-ttl 3600; keys { - ksk key-directory lifetime P1Y algorithm 13; + ksk key-directory lifetime P1Y algorithm ecdsa256; zsk lifetime P30D algorithm 13; - csk key-directory lifetime unlimited algorithm 8 2048; + csk key-directory lifetime unlimited algorithm rsasha256 2048; }; max-zone-ttl 86400; parent-ds-ttl 7200; diff --git a/bin/tests/system/checkconf/kasp-ignore-keylen.conf b/bin/tests/system/checkconf/kasp-ignore-keylen.conf index 5874bdb8873..b2680bd74df 100644 --- a/bin/tests/system/checkconf/kasp-ignore-keylen.conf +++ b/bin/tests/system/checkconf/kasp-ignore-keylen.conf @@ -12,9 +12,7 @@ dnssec-policy "warn-length" { keys { // Algorithm 13 has predefined length, warn about length param. - csk lifetime unlimited algorithm 13 2048; - // Algorithm 5 length out of range, warn about length param. - csk lifetime unlimited algorithm 5 4097; + csk lifetime unlimited algorithm ecdsa256 2048; }; }; diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 814b3b761b3..07fc06cd1f0 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -475,9 +475,9 @@ if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "checking named-checkconf kasp warnings ($n)" +echo_i "checking named-checkconf kasp errors ($n)" ret=0 -$CHECKCONF kasp-and-other-dnssec-options.conf > checkconf.out$n 2>&1 +$CHECKCONF kasp-and-other-dnssec-options.conf > checkconf.out$n 2>&1 && ret=1 grep "'auto-dnssec maintain;' cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1 grep "dnskey-sig-validity: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1 grep "dnssec-dnskey-kskonly: cannot be configured if dnssec-policy is also set" < checkconf.out$n > /dev/null || ret=1 @@ -490,11 +490,10 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` n=`expr $n + 1` -echo_i "checking named-checkconf kasp key warnings ($n)" +echo_i "checking named-checkconf kasp predefined key lengths ($n)" ret=0 -$CHECKCONF kasp-ignore-keylen.conf > checkconf.out$n 2>&1 -grep "dnssec-policy: key algorithm 13 has predefined length, ignoring length value 2048" < checkconf.out$n > /dev/null || ret=1 -grep "dnssec-policy: key with algorithm 5 has invalid key length, ignoring length value 4097" < checkconf.out$n > /dev/null || ret=1 +$CHECKCONF kasp-ignore-keylen.conf > checkconf.out$n 2>&1 || ret=1 +grep "dnssec-policy: key algorithm ecdsa256 has predefined length; ignoring length value 2048" < checkconf.out$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 28f88f89da0..77445bd79ee 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -11113,9 +11113,9 @@ example.com CNAME rpz-tcp-only. keys { - ksk key-directory lifetime unlimited algorithm 8 2048; + ksk key-directory lifetime unlimited algorithm rsasha1 2048; zsk key-directory lifetime P30D algorithm 8; - csk key-directory lifetime P6MT12H3M15S algorithm 13; + csk key-directory lifetime P6MT12H3M15S algorithm ecdsa256; }; @@ -11150,10 +11150,11 @@ example.com CNAME rpz-tcp-only. The algorithm parameter(s) are the key's - algorithm, expressed numerically, and its size in bits. The - size may be omitted, as shown in the example for the - second and third keys; in this case an appropriate - default size will be used. + algorithm, expressed either as a string ("rsasha256", + "ecdsa384", etc) or as a decimal number, and the key's + size in bits. The size may be omitted, as shown in + the example for the second and third keys; in this case + an appropriate default size will be used. diff --git a/lib/bind9/check.c b/lib/bind9/check.c index f085dd2a33b..f34b1132faa 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -976,11 +976,12 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, if (obj != NULL) { bool bad_kasp = false; bool bad_name = false; + if (optlevel != optlevel_config && !cfg_obj_isstring(obj)) { bad_kasp = true; } else if (optlevel == optlevel_config) { dns_kasplist_t list; - dns_kasp_t* kasp, *kasp_next; + dns_kasp_t *kasp = NULL, *kasp_next = NULL; ISC_LIST_INIT(list); @@ -989,11 +990,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, element != NULL; element = cfg_list_next(element)) { + isc_result_t ret; cfg_obj_t *kconfig = cfg_listelt_value(element); - if (!cfg_obj_istuple(kconfig)) - { + if (!cfg_obj_istuple(kconfig)) { bad_kasp = true; continue; } @@ -1001,17 +1002,24 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, bad_name = true; continue; } - kasp = NULL; - (void)cfg_kasp_fromconfig(kconfig, mctx, + + ret = cfg_kasp_fromconfig(kconfig, mctx, logctx, &list, &kasp); + if (ret != ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS) { + result = ret; + } + } + if (kasp != NULL) { dns_kasp_detach(&kasp); } } } - for (kasp = ISC_LIST_HEAD(list); kasp != NULL; + for (kasp = ISC_LIST_HEAD(list); + kasp != NULL; kasp = kasp_next) { kasp_next = ISC_LIST_NEXT(kasp, link); diff --git a/lib/dns/include/dns/kasp.h b/lib/dns/include/dns/kasp.h index e98a486e068..c9fd8ba8d60 100644 --- a/lib/dns/include/dns/kasp.h +++ b/lib/dns/include/dns/kasp.h @@ -45,7 +45,7 @@ struct dns_kasp_key { /* Configuration */ uint32_t lifetime; - uint32_t algorithm; + uint8_t algorithm; int length; uint8_t role; }; diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 9538be6376a..76fc5d050bd 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -25,6 +26,8 @@ #include #include #include +#include +#include /* @@ -65,7 +68,7 @@ get_duration(const cfg_obj_t **maps, const char* option, uint32_t dfl) * Create a new kasp key derived from configuration. */ static isc_result_t -cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, +cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, isc_log_t *logctx) { isc_result_t result; @@ -86,6 +89,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, } else { const char *rolestr = NULL; const cfg_obj_t *obj = NULL; + isc_consttextregion_t alg; rolestr = cfg_obj_asstring(cfg_tuple_get(config, "role")); if (strcmp(rolestr, "ksk") == 0) { @@ -104,7 +108,17 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, } obj = cfg_tuple_get(config, "algorithm"); - key->algorithm = cfg_obj_asuint32(obj); + alg.base = cfg_obj_asstring(obj); + alg.length = strlen(alg.base); + result = dns_secalg_fromtext(&key->algorithm, + (isc_textregion_t *) &alg); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: bad algorithm %s", + alg.base); + result = DNS_R_BADALG; + goto cleanup; + } obj = cfg_tuple_get(config, "length"); if (cfg_obj_isuint32(obj)) { @@ -121,10 +135,11 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-policy: key with " - "algorithm %u has invalid " - "key length", - key->algorithm); - return (ISC_R_RANGE); + "algorithm %s has invalid " + "key length %u", + alg.base, size); + result = ISC_R_RANGE; + goto cleanup; } break; case DNS_KEYALG_ECDSA256: @@ -132,10 +147,9 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, case DNS_KEYALG_ED25519: case DNS_KEYALG_ED448: cfg_obj_log(obj, logctx, ISC_LOG_WARNING, - "dnssec-policy: key algorithm %u " + "dnssec-policy: key algorithm %s " "has predefined length; ignoring " - "length value %u", key->algorithm, - size); + "length value %u", alg.base, size); default: break; } @@ -145,7 +159,13 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t* kasp, } dns_kasp_addkey(kasp, key); + return (ISC_R_SUCCESS); + +cleanup: + + dns_kasp_key_destroy(key); return (result); + } isc_result_t diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 0753819090c..b0216d45317 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -540,10 +540,10 @@ static cfg_type_t cfg_type_dnsseckeystore = { /*% * A dnssec key, as used in the "keys" statement in a "dnssec-policy". */ -static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_uint32 }; +static keyword_type_t algorithm_kw = { "algorithm", &cfg_type_ustring }; static cfg_type_t cfg_type_algorithm = { "algorithm", parse_keyvalue, print_keyvalue, - doc_keyvalue, &cfg_rep_uint32, &algorithm_kw + doc_keyvalue, &cfg_rep_string, &algorithm_kw }; static keyword_type_t lifetime_kw = { "lifetime",