From: Evan Hunt Date: Mon, 16 Sep 2019 06:14:51 +0000 (-0700) Subject: read DS trust anchors in named.conf X-Git-Tag: v9.15.6~7^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=feba480527202908299768244335d60d7983a69f;p=thirdparty%2Fbind9.git read DS trust anchors in named.conf (but they aren't used for anything yet) --- diff --git a/bin/named/server.c b/bin/named/server.c index d68d01ae7e4..d6f912cbfbc 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -698,19 +698,20 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, } static isc_result_t -ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, - const char **keynamestrp, isc_mem_t *mctx) +ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp, + dns_rdata_ds_t **dsp, const char **namestrp, isc_mem_t *mctx) { dns_rdata_dnskey_t keystruct; + dns_rdata_ds_t *ds = NULL; uint32_t n1, n2, n3; - const char *datastr = NULL, *keynamestr = NULL; + const char *datastr = NULL, *namestr = NULL; unsigned char data[4096]; isc_buffer_t databuf; unsigned char rrdata[4096]; isc_buffer_t rrdatabuf; isc_region_t r; - dns_fixedname_t fkeyname; - dns_name_t *keyname = NULL; + dns_fixedname_t fname; + dns_name_t *name = NULL; isc_buffer_t namebuf; isc_result_t result; dst_key_t *dstkey = NULL; @@ -723,8 +724,9 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, TRUSTED } anchortype; - REQUIRE(target != NULL && *target == NULL); - REQUIRE(keynamestrp != NULL && *keynamestrp == NULL); + REQUIRE(keyp != NULL && *keyp == NULL); + REQUIRE(dsp != NULL && *dsp == NULL); + REQUIRE(namestrp != NULL && *namestrp == NULL); /* if DNSKEY, flags; if DS, key tag */ n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1")); @@ -735,13 +737,13 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, /* if DNSKEY, algorithm; if DS, digest type */ n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3")); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); - *keynamestrp = keynamestr; + namestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); + *namestrp = namestr; - keyname = dns_fixedname_initname(&fkeyname); - isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL)); + name = dns_fixedname_initname(&fname); + isc_buffer_constinit(&namebuf, namestr, strlen(namestr)); + isc_buffer_add(&namebuf, strlen(namestr)); + CHECK(dns_name_fromtext(name, &namebuf, dns_rootname, 0, NULL)); if (*initialp) { atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype")); @@ -760,7 +762,7 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "key '%s': " "invalid initialization method '%s'", - keynamestr, atstr); + namestr, atstr); result = ISC_R_FAILURE; goto cleanup; } @@ -768,6 +770,9 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, anchortype = TRUSTED; } + isc_buffer_init(&databuf, data, sizeof(data)); + isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); + switch(anchortype) { case INIT_DNSKEY: case STATIC_DNSKEY: @@ -803,9 +808,6 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, keystruct.protocol = (uint8_t)n2; keystruct.algorithm = (uint8_t)n3; - isc_buffer_init(&databuf, data, sizeof(data)); - isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - datastr = cfg_obj_asstring(cfg_tuple_get(key, "data")); CHECK(isc_base64_decodestring(datastr, &databuf)); isc_buffer_usedregion(&databuf, &r); @@ -815,20 +817,65 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass, keystruct.common.rdtype, &keystruct, &rrdatabuf)); - CHECK(dst_key_fromdns(keyname, dns_rdataclass_in, + CHECK(dst_key_fromdns(name, dns_rdataclass_in, &rrdatabuf, mctx, &dstkey)); - *target = dstkey; + *keyp = dstkey; break; case INIT_DS: case STATIC_DS: - cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, - "key '%s': " - "initialization method '%s' is " - "not yet supported", keynamestr, atstr); - result = ISC_R_FAILURE; - goto cleanup; + ds = isc_mem_get(mctx, sizeof(*ds)); + ds->common.rdclass = dns_rdataclass_in; + ds->common.rdtype = dns_rdatatype_ds; + ds->mctx = NULL; + + ISC_LINK_INIT(&ds->common, link); + + if (n1 > 0xffff) { + CHECKM(ISC_R_RANGE, "key tag"); + } + if (n2 > 0xff) { + CHECKM(ISC_R_RANGE, "key algorithm"); + } + if (n3 > 0xff) { + CHECKM(ISC_R_RANGE, "digest type"); + } + + ds->key_tag = (uint16_t)n1; + ds->algorithm = (uint8_t)n2; + ds->digest_type = (uint8_t)n3; + + datastr = cfg_obj_asstring(cfg_tuple_get(key, "data")); + CHECK(isc_hex_decodestring(datastr, &databuf)); + isc_buffer_usedregion(&databuf, &r); + + switch (ds->digest_type) { + case DNS_DSDIGEST_SHA1: + if (r.length != ISC_SHA1_DIGESTLENGTH) { + CHECK(ISC_R_UNEXPECTEDEND); + } + break; + case DNS_DSDIGEST_SHA256: + if (r.length != ISC_SHA256_DIGESTLENGTH) { + CHECK(ISC_R_UNEXPECTEDEND); + } + break; + case DNS_DSDIGEST_SHA384: + if (r.length != ISC_SHA384_DIGESTLENGTH) { + CHECK(ISC_R_UNEXPECTEDEND); + } + break; + } + + ds->mctx = mctx; + ds->length = r.length; + ds->digest = isc_mem_allocate(mctx, r.length); + memmove(ds->digest, r.base, r.length); + + *dsp = ds; + ds = NULL; + break; default: INSIST(0); @@ -842,6 +889,11 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **target, dst_key_free(&dstkey); } + if (ds != NULL) { + dns_rdata_freestruct(ds); + isc_mem_put(mctx, ds, sizeof(*ds)); + } + return (result); } @@ -861,23 +913,45 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, const dns_name_t *keyname_match, dns_resolver_t *resolver, bool managed, isc_mem_t *mctx) { - const dns_name_t *keyname = NULL; - const char *keynamestr = NULL; + dns_fixedname_t fkeyname; + dns_name_t *keyname = NULL; + const char *namestr = NULL; dst_key_t *dstkey = NULL; + dns_rdata_ds_t *ds = NULL; unsigned int keyalg; isc_result_t result; bool initializing = managed; - result = ta_fromconfig(key, &initializing, &dstkey, &keynamestr, mctx); + result = ta_fromconfig(key, &initializing, &dstkey, &ds, + &namestr, mctx); switch (result) { case ISC_R_SUCCESS: /* - * Key was parsed correctly, its algorithm is supported by the - * crypto library, and it is not revoked. + * Trust anchor was parsed correctly. If dstkey is + * not NULL, then it was a key anchor, its algorithm + * is supported by the crypto library, and it is not + * revoked. If dstkey is NULL, then it was a DS + * trust anchor instead. */ - keyname = dst_key_name(dstkey); - keyalg = dst_key_alg(dstkey); + if (dstkey != NULL) { + keyname = dst_key_name(dstkey); + keyalg = dst_key_alg(dstkey); + } else { + isc_buffer_t b; + + INSIST(ds != NULL); + + isc_buffer_constinit(&b, namestr, strlen(namestr)); + isc_buffer_add(&b, strlen(namestr)); + keyname = dns_fixedname_initname(&fkeyname); + result = dns_name_fromtext(keyname, &b, + dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) { + return (result); + } + keyalg = ds->algorithm; + } break; case DST_R_UNSUPPORTEDALG: case DST_R_BADKEYTYPE: @@ -889,7 +963,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, "ignoring %s for '%s': %s", initializing ? "initial-key" : "static-key", - keynamestr, isc_result_totext(result)); + namestr, isc_result_totext(result)); return (ISC_R_SUCCESS); case DST_R_NOCRYPTO: /* @@ -898,7 +972,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "ignoring %s for '%s': no crypto support", initializing ? "initial-key" : "static-key", - keynamestr); + namestr); return (result); default: /* @@ -909,7 +983,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "configuring %s for '%s': %s", initializing ? "initial-key" : "static-key", - keynamestr, isc_result_totext(result)); + namestr, isc_result_totext(result)); return (ISC_R_FAILURE); } @@ -931,7 +1005,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, "ignoring %s for '%s': algorithm is disabled", initializing ? "initial-key" : "static-key", - keynamestr); + namestr); goto done; } @@ -955,6 +1029,14 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, dst_key_free(&dstkey); } + /* + * Ensure 'ds' does not leak. + */ + if (ds != NULL) { + dns_rdata_freestruct(ds); + isc_mem_put(mctx, ds, sizeof(*ds)); + } + return (result); } diff --git a/bin/tests/system/checkconf/bad-static-initial-1.conf b/bin/tests/system/checkconf/bad-static-initial-1.conf new file mode 100644 index 00000000000..406b12b8a16 --- /dev/null +++ b/bin/tests/system/checkconf/bad-static-initial-1.conf @@ -0,0 +1,15 @@ +/* + * 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-keys { + example. initial-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3"; + example. static-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6"; +}; diff --git a/bin/tests/system/checkconf/bad-static-initial-2.conf b/bin/tests/system/checkconf/bad-static-initial-2.conf new file mode 100644 index 00000000000..a8805b56a0c --- /dev/null +++ b/bin/tests/system/checkconf/bad-static-initial-2.conf @@ -0,0 +1,15 @@ +/* + * 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-keys { + example. initial-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3"; + example. static-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU="; +}; diff --git a/bin/tests/system/checkconf/bad-static-initial-3.conf b/bin/tests/system/checkconf/bad-static-initial-3.conf new file mode 100644 index 00000000000..53bdc2cf8e6 --- /dev/null +++ b/bin/tests/system/checkconf/bad-static-initial-3.conf @@ -0,0 +1,15 @@ +/* + * 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-keys { + example. static-ds 60724 5 1 "D74CF845955A0DFE604AF215E948E67D2EA94FF3"; + example. initial-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU="; +}; diff --git a/bin/tests/system/checkconf/bad-static-initial-4.conf b/bin/tests/system/checkconf/bad-static-initial-4.conf new file mode 100644 index 00000000000..bc2996236b5 --- /dev/null +++ b/bin/tests/system/checkconf/bad-static-initial-4.conf @@ -0,0 +1,15 @@ +/* + * 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-keys { + example. initial-key 257 3 5 "AwEAAawvFp8GlBx8Qt6yaIqXkDe+nMkSk2HkTAG7qlVBo++AQwZ1j3Xl25IN4jsw0VTMbKUbafw9DYsVzztIwx1sNkKRLo6qP9SSkBL8RicQaafGtURtsYI3oqte5qqLve1CUpRD8J06Pg1xkOxsDlz9sQAyiQrOyvMbykJYkYrFYGLzYAgl/JtMyVVYlBl9pqxQuAPKYPOuO1axaad/wLN3+wTy/hcJfpvJpqzXlDF9bI5RmpoX/7geZ06vpcYJEoT0xkkmPlEl0ZjEDrm/WIaSWG0/CEDpHcOXFz4OEczMVpY+lnuFfKybwF1WHFn2BwVEOS6cMM6ukIjINQyrszHhWUU="; + example. static-key 257 3 5 "AwEAAZtP9+RAA+W33A97e+HnnH8WTXzCWiEICyWj1B6rvZ9hd50ysbody0NLx7b3vZ1bzMLxLSRAr/n3Wi0TDZ1fvCKZhennfW8Wlc7ulCvHntSQYfKHUP0YWEo84sQAqIi850N1aiddj6CidwFo9JNW/HQ+8yarfrnGMFhX2STtkE0hNJ/R6JYKmD2EH7k1nyqJd08ibrEt55DuV4BiUjyyERdVbsuwE60jVqAwCKyVBYXb2sI+zv1yPNDBIANd6KTgnq6YWzx5ZodQP3W4K7Z/Bk3EKmVCvrTKZK/ADLAKaL0/6DD07+1jXA4BiNyoZTLTapkudkGad+Rn6zqCkwuMmrU="; +}; diff --git a/bin/tests/system/checkconf/check-root-static-ds.conf b/bin/tests/system/checkconf/check-root-static-ds.conf new file mode 100644 index 00000000000..42af9ba801f --- /dev/null +++ b/bin/tests/system/checkconf/check-root-static-ds.conf @@ -0,0 +1,14 @@ +/* + * 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-keys { + . static-ds 20326 8 2 "E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D"; +}; diff --git a/bin/tests/system/checkconf/good-initial-ds.conf b/bin/tests/system/checkconf/good-initial-ds.conf new file mode 100644 index 00000000000..31939c26dd9 --- /dev/null +++ b/bin/tests/system/checkconf/good-initial-ds.conf @@ -0,0 +1,14 @@ +/* + * 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-keys { + example. initial-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6"; +}; diff --git a/bin/tests/system/checkconf/good-static-ds.conf b/bin/tests/system/checkconf/good-static-ds.conf new file mode 100644 index 00000000000..fd5b393bfe5 --- /dev/null +++ b/bin/tests/system/checkconf/good-static-ds.conf @@ -0,0 +1,14 @@ +/* + * 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-keys { + example. static-ds 60724 5 2 "29E79B9064EE1A11DF3BFF19581DDFED7952C22CC204ACE17B6007EB1437E9E6"; +}; diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 45e6cefb421..a25753e1bf2 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -437,7 +437,15 @@ n=`expr $n + 1` echo_i "check that a static root key generates a warning ($n)" ret=0 $CHECKCONF check-root-static-key.conf > checkconf.out$n 2>/dev/null || ret=1 -grep "static-key entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1 +grep "static entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo_i "check that a static root DS trust anchor generates a warning ($n)" +ret=0 +$CHECKCONF check-root-static-ds.conf > checkconf.out$n 2>/dev/null || ret=1 +grep "static entry for the root zone WILL FAIL" checkconf.out$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi status=`expr $status + $ret` diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 302c3dcc007..020d49982c9 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -3119,10 +3119,10 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions, #define ROOT_KSK_2017 0x08 static isc_result_t -check_trusted_key(const cfg_obj_t *key, bool managed, - unsigned int *keyflags, isc_log_t *logctx) +check_trust_anchor(const cfg_obj_t *key, bool managed, + unsigned int *flagsp, isc_log_t *logctx) { - const char *keystr = NULL, *keynamestr = NULL; + const char *str = NULL, *namestr = NULL; dns_fixedname_t fkeyname; dns_name_t *keyname = NULL; isc_buffer_t b; @@ -3130,7 +3130,7 @@ check_trusted_key(const cfg_obj_t *key, bool managed, isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; uint32_t n1, n2, n3; - unsigned char keydata[4096]; + unsigned char data[4096]; const char *atstr = NULL; enum { INIT_DNSKEY, @@ -3142,8 +3142,8 @@ check_trusted_key(const cfg_obj_t *key, bool managed, /* * The 2010 and 2017 IANA root keys - these are used below - * to check the contents of trusted-key, initial-key and - * static-key configurations. + * to check the contents of trusted, initial and + * static trust anchor configurations. */ static const unsigned char root_ksk_2010[] = { 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9, @@ -3215,7 +3215,17 @@ check_trusted_key(const cfg_obj_t *key, bool managed, 0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51, 0x35, 0x7b, 0xe1, 0xb5 }; - + static const unsigned char root_ds_1_2017[] = { + 0xae, 0x1e, 0xa5, 0xb9, 0x74, 0xd4, 0xc8, 0x58, + 0xb7, 0x40, 0xbd, 0x03, 0xe3, 0xce, 0xd7, 0xeb, + 0xfc, 0xbd, 0x17, 0x24 + }; + static const unsigned char root_ds_2_2017[] = { + 0xe0, 0x6d, 0x44, 0xb8, 0x0b, 0x8f, 0x1d, 0x39, + 0xa9, 0x5c, 0x0b, 0x0d, 0x7c, 0x65, 0xd0, 0x84, + 0x58, 0xe8, 0x80, 0x40, 0x9b, 0xbc, 0x68, 0x34, + 0x57, 0x10, 0x42, 0x37, 0xc7, 0xf8, 0xec, 0x8D + }; /* if DNSKEY, flags; if DS, key tag */ n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1")); @@ -3226,11 +3236,11 @@ check_trusted_key(const cfg_obj_t *key, bool managed, /* if DNSKEY, algorithm; if DS, digest type */ n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3")); - keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); + namestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); keyname = dns_fixedname_initname(&fkeyname); - isc_buffer_constinit(&b, keynamestr, strlen(keynamestr)); - isc_buffer_add(&b, strlen(keynamestr)); + isc_buffer_constinit(&b, namestr, strlen(namestr)); + isc_buffer_add(&b, strlen(namestr)); result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); if (result != ISC_R_SUCCESS) { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "bad key name: %s\n", @@ -3255,7 +3265,7 @@ check_trusted_key(const cfg_obj_t *key, bool managed, cfg_obj_log(key, logctx, ISC_LOG_ERROR, "key '%s': " "invalid initialization method '%s'", - keynamestr, atstr); + namestr, atstr); result = ISC_R_FAILURE; /* @@ -3282,7 +3292,7 @@ check_trusted_key(const cfg_obj_t *key, bool managed, cfg_obj_log(key, logctx, ISC_LOG_WARNING, "key flags revoke bit set"); } - if (n2 > 0xff) { + if (n2 > 0xff) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, "protocol too big: %u", n2); result = ISC_R_RANGE; @@ -3293,10 +3303,10 @@ check_trusted_key(const cfg_obj_t *key, bool managed, result = ISC_R_RANGE; } - isc_buffer_init(&b, keydata, sizeof(keydata)); + isc_buffer_init(&b, data, sizeof(data)); - keystr = cfg_obj_asstring(cfg_tuple_get(key, "data")); - tresult = isc_base64_decodestring(keystr, &b); + str = cfg_obj_asstring(cfg_tuple_get(key, "data")); + tresult = isc_base64_decodestring(str, &b); if (tresult != ISC_R_SUCCESS) { cfg_obj_log(key, logctx, ISC_LOG_ERROR, @@ -3310,7 +3320,7 @@ check_trusted_key(const cfg_obj_t *key, bool managed, { cfg_obj_log(key, logctx, ISC_LOG_WARNING, "%s '%s' has a weak exponent", - atstr, keynamestr); + atstr, namestr); } } @@ -3319,36 +3329,85 @@ check_trusted_key(const cfg_obj_t *key, bool managed, /* * Flag any use of a root key, regardless of content. */ - *keyflags |= + *flagsp |= (managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC); + if (n1 == 257 && n2 == 3 && n3 == 8 && (isc_buffer_usedlength(&b) == sizeof(root_ksk_2010)) && - memcmp(keydata, root_ksk_2010, + memcmp(data, root_ksk_2010, sizeof(root_ksk_2010)) == 0) { - *keyflags |= ROOT_KSK_2010; + *flagsp |= ROOT_KSK_2010; } if (n1 == 257 && n2 == 3 && n3 == 8 && (isc_buffer_usedlength(&b) == sizeof(root_ksk_2017)) && - memcmp(keydata, root_ksk_2017, + memcmp(data, root_ksk_2017, sizeof(root_ksk_2017)) == 0) { - *keyflags |= ROOT_KSK_2017; + *flagsp |= ROOT_KSK_2017; } } break; case INIT_DS: case STATIC_DS: - cfg_obj_log(key, logctx, ISC_LOG_ERROR, - "key '%s': " - "initialization method '%s' is " - "not yet supported", keynamestr, atstr); - result = ISC_R_FAILURE; + if (n1 > 0xffff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "key tag too big: %u", n1); + result = ISC_R_RANGE; + } + if (n2 > 0xff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "algorithm too big: %u\n", n2); + result = ISC_R_RANGE; + } + if (n3 > 0xff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "digest type too big: %u", 32); + result = ISC_R_RANGE; + } + + isc_buffer_init(&b, data, sizeof(data)); + + str = cfg_obj_asstring(cfg_tuple_get(key, "data")); + tresult = isc_hex_decodestring(str, &b); + + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "%s", isc_result_totext(tresult)); + result = ISC_R_FAILURE; + } + if (result == ISC_R_SUCCESS && + dns_name_equal(keyname, dns_rootname)) { + /* + * Flag any use of a root key, regardless of content. + */ + *flagsp |= + (managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC); + + if (n1 == 20326 && n2 == 8 && n3 == 1 && + (isc_buffer_usedlength(&b) == + sizeof(root_ds_1_2017)) && + memcmp(data, root_ds_1_2017, + sizeof(root_ds_1_2017)) == 0) + { + *flagsp |= ROOT_KSK_2017; + } + + if (n1 == 20326 && n2 == 8 && n3 == 2 && + (isc_buffer_usedlength(&b) == + sizeof(root_ds_2_2017)) && + memcmp(data, root_ds_2_2017, + sizeof(root_ds_2_2017)) == 0) + { + *flagsp |= ROOT_KSK_2017; + } + } + break; } cleanup: @@ -3964,8 +4023,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, element2 = cfg_list_next(element2)) { obj = cfg_listelt_value(element2); - tresult = check_trusted_key(obj, - false, + tresult = check_trust_anchor(obj, false, &flags, logctx); if (tresult != ISC_R_SUCCESS) { @@ -3980,7 +4038,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, "trusted-keys entry for the root " "zone WILL FAIL after key " "rollover - use dnssec-keys " - "with initial-key instead."); + "with initial-key " + "or initial-ds instead."); } tflags |= flags; @@ -4024,8 +4083,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, element2 = cfg_list_next(element2)) { obj = cfg_listelt_value(element2); - tresult = check_trusted_key(obj, - true, + tresult = check_trust_anchor(obj, true, &flags, logctx); if (tresult != ISC_R_SUCCESS) { @@ -4037,10 +4095,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, if ((flags & ROOT_KSK_STATIC) != 0) { cfg_obj_log(check_keys[i], logctx, ISC_LOG_WARNING, - "static-key entry for the root " + "static entry for the root " "zone WILL FAIL after key " "rollover - use dnssec-keys " - "with initial-key instead."); + "with initial-key " + "or initial-ds instead."); } if ((flags & ROOT_KSK_2010) != 0 && @@ -4067,7 +4126,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, if ((dflags & ROOT_KSK_ANY) == ROOT_KSK_ANY) { keys = (view_dkeys != NULL) ? view_dkeys : global_dkeys; cfg_obj_log(keys, logctx, ISC_LOG_WARNING, - "both initial-key and static-key entries for the " + "both initial and static entries for the " "root zone are present"); }