From: Evan Hunt Date: Mon, 16 Sep 2019 05:15:29 +0000 (-0700) Subject: add "static-ds" and "initial-ds" keywords to config parser X-Git-Tag: v9.15.6~7^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3fede8a7e9964eb47116ea3a191491d4dbc71909;p=thirdparty%2Fbind9.git add "static-ds" and "initial-ds" keywords to config parser --- diff --git a/bin/delv/delv.c b/bin/delv/delv.c index f3127ab9e85..c02dfb99055 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -609,7 +609,7 @@ convert_name(dns_fixedname_t *fn, dns_name_t **name, const char *text) { static isc_result_t key_fromconfig(const cfg_obj_t *key, dns_client_t *client) { dns_rdata_dnskey_t keystruct; - uint32_t flags, proto, alg; + uint32_t n1, n2, n3; const char *keystr, *keynamestr; unsigned char keydata[4096]; isc_buffer_t keydatabuf; @@ -642,9 +642,14 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) { delv_log(ISC_LOG_DEBUG(3), "adding trust anchor %s", trust_anchor); - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); + /* if DNSKEY, flags; if DS, key tag */ + n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1")); + + /* if DNSKEY, protocol; if DS, algorithm */ + n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2")); + + /* if DNSKEY, algorithm; if DS, digest type */ + n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3")); keystruct.common.rdclass = dns_rdataclass_in; keystruct.common.rdtype = dns_rdatatype_dnskey; @@ -655,28 +660,30 @@ key_fromconfig(const cfg_obj_t *key, dns_client_t *client) { ISC_LINK_INIT(&keystruct.common, link); - if (flags > 0xffff) + if (n1 > 0xffff) { CHECK(ISC_R_RANGE); - if (proto > 0xff) + } + if (n2 > 0xff) { CHECK(ISC_R_RANGE); - if (alg > 0xff) + } + if (n3 > 0xff) { CHECK(ISC_R_RANGE); + } - keystruct.flags = (uint16_t)flags; - keystruct.protocol = (uint8_t)proto; - keystruct.algorithm = (uint8_t)alg; + keystruct.flags = (uint16_t)n1; + keystruct.protocol = (uint8_t)n2; + keystruct.algorithm = (uint8_t)n3; isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); + keystr = cfg_obj_asstring(cfg_tuple_get(key, "data")); CHECK(isc_base64_decodestring(keystr, &keydatabuf)); isc_buffer_usedregion(&keydatabuf, &r); keystruct.datalen = r.length; keystruct.data = r.base; - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, + CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass, keystruct.common.rdtype, &keystruct, &rrdatabuf)); diff --git a/bin/named/server.c b/bin/named/server.c index 337471dd9dd..d68d01ae7e4 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -698,104 +698,143 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, } static isc_result_t -dstkey_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 **target, + const char **keynamestrp, isc_mem_t *mctx) { dns_rdata_dnskey_t keystruct; - uint32_t flags, proto, alg; - const char *keystr, *keynamestr; - unsigned char keydata[4096]; - isc_buffer_t keydatabuf; + uint32_t n1, n2, n3; + const char *datastr = NULL, *keynamestr = 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; + dns_name_t *keyname = NULL; isc_buffer_t namebuf; isc_result_t result; dst_key_t *dstkey = NULL; + const char *atstr = NULL; + enum { + INIT_DNSKEY, + STATIC_DNSKEY, + INIT_DS, + STATIC_DS, + TRUSTED + } anchortype; + + REQUIRE(target != NULL && *target == NULL); + REQUIRE(keynamestrp != NULL && *keynamestrp == NULL); - INSIST(target != NULL && *target == NULL); - INSIST(keynamestrp != NULL && *keynamestrp == NULL); + /* if DNSKEY, flags; if DS, key tag */ + n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1")); + + /* if DNSKEY, protocol; if DS, algorithm */ + n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2")); + + /* if DNSKEY, algorithm; if DS, digest type */ + n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3")); - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); - keyname = dns_fixedname_name(&fkeyname); keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name")); *keynamestrp = keynamestr; + 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)); + if (*initialp) { - const char *initmethod; - initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init")); + atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype")); - if (strcasecmp(initmethod, "static-key") == 0) { + if (strcasecmp(atstr, "static-key") == 0) { *initialp = false; - } else if (strcasecmp(initmethod, "initial-key") != 0) { + anchortype = STATIC_DNSKEY; + } else if (strcasecmp(atstr, "static-ds") == 0) { + *initialp = false; + anchortype = STATIC_DS; + } else if (strcasecmp(atstr, "initial-key") == 0) { + anchortype = INIT_DNSKEY; + } else if (strcasecmp(atstr, "initial-ds") == 0) { + anchortype = INIT_DS; + } else { cfg_obj_log(key, named_g_lctx, ISC_LOG_ERROR, "key '%s': " "invalid initialization method '%s'", - keynamestr, initmethod); + keynamestr, atstr); result = ISC_R_FAILURE; goto cleanup; } + } else { + anchortype = TRUSTED; } - /* - * This function should never be reached for non-IN classes. - */ - keystruct.common.rdclass = dns_rdataclass_in; - keystruct.common.rdtype = dns_rdatatype_dnskey; + switch(anchortype) { + case INIT_DNSKEY: + case STATIC_DNSKEY: + case TRUSTED: + /* + * This function should never be reached for view + * class other than IN + */ + keystruct.common.rdclass = dns_rdataclass_in; + keystruct.common.rdtype = dns_rdatatype_dnskey; - /* - * The key data in keystruct is not dynamically allocated. - */ - keystruct.mctx = NULL; + /* + * The key data in keystruct is not dynamically allocated. + */ + keystruct.mctx = NULL; + + ISC_LINK_INIT(&keystruct.common, link); + + if (n1 > 0xffff) { + CHECKM(ISC_R_RANGE, "key flags"); + } + if (n1 & DNS_KEYFLAG_REVOKE) { + CHECKM(DST_R_BADKEYTYPE, "key flags revoke bit set"); + } + if (n2 > 0xff) { + CHECKM(ISC_R_RANGE, "key protocol"); + } + if (n3> 0xff) { + CHECKM(ISC_R_RANGE, "key algorithm"); + } - ISC_LINK_INIT(&keystruct.common, link); + keystruct.flags = (uint16_t)n1; + keystruct.protocol = (uint8_t)n2; + keystruct.algorithm = (uint8_t)n3; - if (flags > 0xffff) - CHECKM(ISC_R_RANGE, "key flags"); - if (flags & DNS_KEYFLAG_REVOKE) - CHECKM(DST_R_BADKEYTYPE, "key flags revoke bit set"); - if (proto > 0xff) - CHECKM(ISC_R_RANGE, "key protocol"); - if (alg > 0xff) - CHECKM(ISC_R_RANGE, "key algorithm"); - keystruct.flags = (uint16_t)flags; - keystruct.protocol = (uint8_t)proto; - keystruct.algorithm = (uint8_t)alg; + isc_buffer_init(&databuf, data, sizeof(data)); + isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata)); - isc_buffer_init(&keydatabuf, keydata, sizeof(keydata)); - 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); + keystruct.datalen = r.length; + keystruct.data = r.base; - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - CHECK(isc_base64_decodestring(keystr, &keydatabuf)); - isc_buffer_usedregion(&keydatabuf, &r); - keystruct.datalen = r.length; - keystruct.data = r.base; + CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass, + keystruct.common.rdtype, + &keystruct, &rrdatabuf)); + CHECK(dst_key_fromdns(keyname, dns_rdataclass_in, + &rrdatabuf, mctx, &dstkey)); - if ((keystruct.algorithm == DST_ALG_RSASHA1) && - r.length > 1 && r.base[0] == 1 && r.base[1] == 3) - { - cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, - "%s '%s' has a weak exponent", - *initialp ? "initial-key" : "static-key", - keynamestr); - } + *target = dstkey; + break; - CHECK(dns_rdata_fromstruct(NULL, - keystruct.common.rdclass, - keystruct.common.rdtype, - &keystruct, &rrdatabuf)); - dns_fixedname_init(&fkeyname); - isc_buffer_constinit(&namebuf, keynamestr, strlen(keynamestr)); - isc_buffer_add(&namebuf, strlen(keynamestr)); - CHECK(dns_name_fromtext(keyname, &namebuf, dns_rootname, 0, NULL)); - CHECK(dst_key_fromdns(keyname, dns_rdataclass_in, &rrdatabuf, - mctx, &dstkey)); + 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; + + default: + INSIST(0); + ISC_UNREACHABLE(); + } - *target = dstkey; return (ISC_R_SUCCESS); cleanup: @@ -829,8 +868,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots, isc_result_t result; bool initializing = managed; - result = dstkey_fromconfig(key, &initializing, - &dstkey, &keynamestr, mctx); + result = ta_fromconfig(key, &initializing, &dstkey, &keynamestr, mctx); switch (result) { case ISC_R_SUCCESS: @@ -1117,16 +1155,18 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig, } } - CHECK(load_view_keys(view_keys, view, false, NULL, mctx)); - CHECK(load_view_keys(view_managed_keys, view, true, NULL, mctx)); - CHECK(load_view_keys(view_dnssec_keys, view, true, NULL, mctx)); - if (view->rdclass == dns_rdataclass_in) { + CHECK(load_view_keys(view_keys, view, false, NULL, mctx)); + CHECK(load_view_keys(view_dnssec_keys, view, true, NULL, + mctx)); + CHECK(load_view_keys(view_managed_keys, view, true, NULL, + mctx)); + CHECK(load_view_keys(global_keys, view, false, NULL, mctx)); - CHECK(load_view_keys(global_managed_keys, view, true, - NULL, mctx)); CHECK(load_view_keys(global_dnssec_keys, view, true, NULL, mctx)); + CHECK(load_view_keys(global_managed_keys, view, true, + NULL, mctx)); } /* diff --git a/bin/tests/system/dnssec/ns8/named.conf.in b/bin/tests/system/dnssec/ns8/named.conf.in index de95e263018..4cf0753e96c 100644 --- a/bin/tests/system/dnssec/ns8/named.conf.in +++ b/bin/tests/system/dnssec/ns8/named.conf.in @@ -20,7 +20,6 @@ options { listen-on { 10.53.0.8; }; listen-on-v6 { none; }; recursion yes; - dnssec-enable yes; dnssec-validation yes; minimal-responses no; disable-algorithms "disabled.managed." { @DISABLED_ALGORITHM@; }; diff --git a/bin/tests/system/dnssec/ns9/named.conf.in b/bin/tests/system/dnssec/ns9/named.conf.in index d655112a70e..1933c767000 100644 --- a/bin/tests/system/dnssec/ns9/named.conf.in +++ b/bin/tests/system/dnssec/ns9/named.conf.in @@ -20,7 +20,6 @@ options { listen-on { 10.53.0.9; }; listen-on-v6 { none; }; recursion yes; - dnssec-enable yes; dnssec-validation yes; forward only; forwarders { 10.53.0.4; }; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 402a6790534..302c3dcc007 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include +#include #include #include @@ -3120,23 +3122,113 @@ static isc_result_t check_trusted_key(const cfg_obj_t *key, bool managed, unsigned int *keyflags, isc_log_t *logctx) { - const char *keystr, *keynamestr; + const char *keystr = NULL, *keynamestr = NULL; dns_fixedname_t fkeyname; - dns_name_t *keyname; + dns_name_t *keyname = NULL; isc_buffer_t b; isc_region_t r; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; - uint32_t flags, proto, alg; + uint32_t n1, n2, n3; unsigned char keydata[4096]; + const char *atstr = NULL; + enum { + INIT_DNSKEY, + STATIC_DNSKEY, + INIT_DS, + STATIC_DS, + TRUSTED + } anchortype; - flags = cfg_obj_asuint32(cfg_tuple_get(key, "flags")); - proto = cfg_obj_asuint32(cfg_tuple_get(key, "protocol")); - alg = cfg_obj_asuint32(cfg_tuple_get(key, "algorithm")); + /* + * The 2010 and 2017 IANA root keys - these are used below + * to check the contents of trusted-key, initial-key and + * static-key configurations. + */ + static const unsigned char root_ksk_2010[] = { + 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9, + 0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80, + 0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, 0x6d, 0xbd, + 0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec, + 0x90, 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70, + 0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf, + 0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82, + 0x34, 0x13, 0x3a, 0xc0, 0x71, 0x0a, 0x81, 0x18, + 0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc, + 0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32, + 0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, 0x51, + 0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb, + 0x35, 0x95, 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5, + 0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8, + 0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4, + 0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, 0x5f, 0xa4, + 0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e, + 0xcb, 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33, + 0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9, + 0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04, + 0x1b, 0x6e, 0x03, 0xa1, 0xb7, 0x2d, 0x0a, 0x73, + 0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33, + 0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9, + 0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, 0x2e, + 0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e, + 0xce, 0xc9, 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad, + 0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9, + 0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14, + 0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, 0x9c, 0x2e, + 0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5, + 0x75, 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49, + 0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52, + 0x4d, 0x62, 0x87, 0x3d + }; + static const unsigned char root_ksk_2017[] = { + 0x03, 0x01, 0x00, 0x01, 0xac, 0xff, 0xb4, 0x09, + 0xbc, 0xc9, 0x39, 0xf8, 0x31, 0xf7, 0xa1, 0xe5, + 0xec, 0x88, 0xf7, 0xa5, 0x92, 0x55, 0xec, 0x53, + 0x04, 0x0b, 0xe4, 0x32, 0x02, 0x73, 0x90, 0xa4, + 0xce, 0x89, 0x6d, 0x6f, 0x90, 0x86, 0xf3, 0xc5, + 0xe1, 0x77, 0xfb, 0xfe, 0x11, 0x81, 0x63, 0xaa, + 0xec, 0x7a, 0xf1, 0x46, 0x2c, 0x47, 0x94, 0x59, + 0x44, 0xc4, 0xe2, 0xc0, 0x26, 0xbe, 0x5e, 0x98, + 0xbb, 0xcd, 0xed, 0x25, 0x97, 0x82, 0x72, 0xe1, + 0xe3, 0xe0, 0x79, 0xc5, 0x09, 0x4d, 0x57, 0x3f, + 0x0e, 0x83, 0xc9, 0x2f, 0x02, 0xb3, 0x2d, 0x35, + 0x13, 0xb1, 0x55, 0x0b, 0x82, 0x69, 0x29, 0xc8, + 0x0d, 0xd0, 0xf9, 0x2c, 0xac, 0x96, 0x6d, 0x17, + 0x76, 0x9f, 0xd5, 0x86, 0x7b, 0x64, 0x7c, 0x3f, + 0x38, 0x02, 0x9a, 0xbd, 0xc4, 0x81, 0x52, 0xeb, + 0x8f, 0x20, 0x71, 0x59, 0xec, 0xc5, 0xd2, 0x32, + 0xc7, 0xc1, 0x53, 0x7c, 0x79, 0xf4, 0xb7, 0xac, + 0x28, 0xff, 0x11, 0x68, 0x2f, 0x21, 0x68, 0x1b, + 0xf6, 0xd6, 0xab, 0xa5, 0x55, 0x03, 0x2b, 0xf6, + 0xf9, 0xf0, 0x36, 0xbe, 0xb2, 0xaa, 0xa5, 0xb3, + 0x77, 0x8d, 0x6e, 0xeb, 0xfb, 0xa6, 0xbf, 0x9e, + 0xa1, 0x91, 0xbe, 0x4a, 0xb0, 0xca, 0xea, 0x75, + 0x9e, 0x2f, 0x77, 0x3a, 0x1f, 0x90, 0x29, 0xc7, + 0x3e, 0xcb, 0x8d, 0x57, 0x35, 0xb9, 0x32, 0x1d, + 0xb0, 0x85, 0xf1, 0xb8, 0xe2, 0xd8, 0x03, 0x8f, + 0xe2, 0x94, 0x19, 0x92, 0x54, 0x8c, 0xee, 0x0d, + 0x67, 0xdd, 0x45, 0x47, 0xe1, 0x1d, 0xd6, 0x3a, + 0xf9, 0xc9, 0xfc, 0x1c, 0x54, 0x66, 0xfb, 0x68, + 0x4c, 0xf0, 0x09, 0xd7, 0x19, 0x7c, 0x2c, 0xf7, + 0x9e, 0x79, 0x2a, 0xb5, 0x01, 0xe6, 0xa8, 0xa1, + 0xca, 0x51, 0x9a, 0xf2, 0xcb, 0x9b, 0x5f, 0x63, + 0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51, + 0x35, 0x7b, 0xe1, 0xb5 + }; + + + /* if DNSKEY, flags; if DS, key tag */ + n1 = cfg_obj_asuint32(cfg_tuple_get(key, "n1")); + + /* if DNSKEY, protocol; if DS, algorithm */ + n2 = cfg_obj_asuint32(cfg_tuple_get(key, "n2")); + + /* if DNSKEY, algorithm; if DS, digest type */ + n3 = cfg_obj_asuint32(cfg_tuple_get(key, "n3")); - keyname = dns_fixedname_initname(&fkeyname); keynamestr = 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)); result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL); @@ -3146,151 +3238,120 @@ check_trusted_key(const cfg_obj_t *key, bool managed, result = ISC_R_FAILURE; } - if (flags > 0xffff) { - cfg_obj_log(key, logctx, ISC_LOG_WARNING, - "flags too big: %u\n", flags); - result = ISC_R_FAILURE; - } - if (proto > 0xff) { - cfg_obj_log(key, logctx, ISC_LOG_WARNING, - "protocol too big: %u\n", proto); - result = ISC_R_FAILURE; - } - if (alg > 0xff) { - cfg_obj_log(key, logctx, ISC_LOG_WARNING, - "algorithm too big: %u\n", alg); - result = ISC_R_FAILURE; - } - if (managed) { - const char *initmethod; - initmethod = cfg_obj_asstring(cfg_tuple_get(key, "init")); + atstr = cfg_obj_asstring(cfg_tuple_get(key, "anchortype")); - if (strcasecmp(initmethod, "static-key") == 0) { + if (strcasecmp(atstr, "static-key") == 0) { + managed = false; + anchortype = STATIC_DNSKEY; + } else if (strcasecmp(atstr, "static-ds") == 0) { managed = false; - } else if (strcasecmp(initmethod, "initial-key") != 0) { + anchortype = STATIC_DS; + } else if (strcasecmp(atstr, "initial-key") == 0) { + anchortype = INIT_DNSKEY; + } else if (strcasecmp(atstr, "initial-ds") == 0) { + anchortype = INIT_DS; + } else { cfg_obj_log(key, logctx, ISC_LOG_ERROR, - "managed key '%s': " + "key '%s': " "invalid initialization method '%s'", - keynamestr, initmethod); + keynamestr, atstr); result = ISC_R_FAILURE; + + /* + * We can't interpret the trust anchor, so + * we skip all other checks. + */ + goto cleanup; } + } else { + atstr = "trusted-key"; + anchortype = TRUSTED; } - isc_buffer_init(&b, keydata, sizeof(keydata)); - - keystr = cfg_obj_asstring(cfg_tuple_get(key, "key")); - tresult = isc_base64_decodestring(keystr, &b); + switch(anchortype) { + case INIT_DNSKEY: + case STATIC_DNSKEY: + case TRUSTED: + if (n1 > 0xffff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "flags too big: %u", n1); + result = ISC_R_RANGE; + } + if (n1 & DNS_KEYFLAG_REVOKE) { + cfg_obj_log(key, logctx, ISC_LOG_WARNING, + "key flags revoke bit set"); + } + if (n2 > 0xff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "protocol too big: %u", n2); + result = ISC_R_RANGE; + } + if (n3 > 0xff) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "algorithm too big: %u\n", n3); + result = ISC_R_RANGE; + } - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(key, logctx, ISC_LOG_ERROR, - "%s", isc_result_totext(tresult)); - result = ISC_R_FAILURE; - } else { - isc_buffer_usedregion(&b, &r); + isc_buffer_init(&b, keydata, sizeof(keydata)); - if ((alg == DST_ALG_RSASHA1) && - r.length > 1 && r.base[0] == 1 && r.base[1] == 3) - { - cfg_obj_log(key, logctx, ISC_LOG_WARNING, - "%s key '%s' has a weak exponent", - managed ? "initializing" : "static", - keynamestr); - } - } - - if (result == ISC_R_SUCCESS && dns_name_equal(keyname, dns_rootname)) { - static const unsigned char root_ksk_2010[] = { - 0x03, 0x01, 0x00, 0x01, 0xa8, 0x00, 0x20, 0xa9, - 0x55, 0x66, 0xba, 0x42, 0xe8, 0x86, 0xbb, 0x80, - 0x4c, 0xda, 0x84, 0xe4, 0x7e, 0xf5, 0x6d, 0xbd, - 0x7a, 0xec, 0x61, 0x26, 0x15, 0x55, 0x2c, 0xec, - 0x90, 0x6d, 0x21, 0x16, 0xd0, 0xef, 0x20, 0x70, - 0x28, 0xc5, 0x15, 0x54, 0x14, 0x4d, 0xfe, 0xaf, - 0xe7, 0xc7, 0xcb, 0x8f, 0x00, 0x5d, 0xd1, 0x82, - 0x34, 0x13, 0x3a, 0xc0, 0x71, 0x0a, 0x81, 0x18, - 0x2c, 0xe1, 0xfd, 0x14, 0xad, 0x22, 0x83, 0xbc, - 0x83, 0x43, 0x5f, 0x9d, 0xf2, 0xf6, 0x31, 0x32, - 0x51, 0x93, 0x1a, 0x17, 0x6d, 0xf0, 0xda, 0x51, - 0xe5, 0x4f, 0x42, 0xe6, 0x04, 0x86, 0x0d, 0xfb, - 0x35, 0x95, 0x80, 0x25, 0x0f, 0x55, 0x9c, 0xc5, - 0x43, 0xc4, 0xff, 0xd5, 0x1c, 0xbe, 0x3d, 0xe8, - 0xcf, 0xd0, 0x67, 0x19, 0x23, 0x7f, 0x9f, 0xc4, - 0x7e, 0xe7, 0x29, 0xda, 0x06, 0x83, 0x5f, 0xa4, - 0x52, 0xe8, 0x25, 0xe9, 0xa1, 0x8e, 0xbc, 0x2e, - 0xcb, 0xcf, 0x56, 0x34, 0x74, 0x65, 0x2c, 0x33, - 0xcf, 0x56, 0xa9, 0x03, 0x3b, 0xcd, 0xf5, 0xd9, - 0x73, 0x12, 0x17, 0x97, 0xec, 0x80, 0x89, 0x04, - 0x1b, 0x6e, 0x03, 0xa1, 0xb7, 0x2d, 0x0a, 0x73, - 0x5b, 0x98, 0x4e, 0x03, 0x68, 0x73, 0x09, 0x33, - 0x23, 0x24, 0xf2, 0x7c, 0x2d, 0xba, 0x85, 0xe9, - 0xdb, 0x15, 0xe8, 0x3a, 0x01, 0x43, 0x38, 0x2e, - 0x97, 0x4b, 0x06, 0x21, 0xc1, 0x8e, 0x62, 0x5e, - 0xce, 0xc9, 0x07, 0x57, 0x7d, 0x9e, 0x7b, 0xad, - 0xe9, 0x52, 0x41, 0xa8, 0x1e, 0xbb, 0xe8, 0xa9, - 0x01, 0xd4, 0xd3, 0x27, 0x6e, 0x40, 0xb1, 0x14, - 0xc0, 0xa2, 0xe6, 0xfc, 0x38, 0xd1, 0x9c, 0x2e, - 0x6a, 0xab, 0x02, 0x64, 0x4b, 0x28, 0x13, 0xf5, - 0x75, 0xfc, 0x21, 0x60, 0x1e, 0x0d, 0xee, 0x49, - 0xcd, 0x9e, 0xe9, 0x6a, 0x43, 0x10, 0x3e, 0x52, - 0x4d, 0x62, 0x87, 0x3d - }; - static const unsigned char root_ksk_2017[] = { - 0x03, 0x01, 0x00, 0x01, 0xac, 0xff, 0xb4, 0x09, - 0xbc, 0xc9, 0x39, 0xf8, 0x31, 0xf7, 0xa1, 0xe5, - 0xec, 0x88, 0xf7, 0xa5, 0x92, 0x55, 0xec, 0x53, - 0x04, 0x0b, 0xe4, 0x32, 0x02, 0x73, 0x90, 0xa4, - 0xce, 0x89, 0x6d, 0x6f, 0x90, 0x86, 0xf3, 0xc5, - 0xe1, 0x77, 0xfb, 0xfe, 0x11, 0x81, 0x63, 0xaa, - 0xec, 0x7a, 0xf1, 0x46, 0x2c, 0x47, 0x94, 0x59, - 0x44, 0xc4, 0xe2, 0xc0, 0x26, 0xbe, 0x5e, 0x98, - 0xbb, 0xcd, 0xed, 0x25, 0x97, 0x82, 0x72, 0xe1, - 0xe3, 0xe0, 0x79, 0xc5, 0x09, 0x4d, 0x57, 0x3f, - 0x0e, 0x83, 0xc9, 0x2f, 0x02, 0xb3, 0x2d, 0x35, - 0x13, 0xb1, 0x55, 0x0b, 0x82, 0x69, 0x29, 0xc8, - 0x0d, 0xd0, 0xf9, 0x2c, 0xac, 0x96, 0x6d, 0x17, - 0x76, 0x9f, 0xd5, 0x86, 0x7b, 0x64, 0x7c, 0x3f, - 0x38, 0x02, 0x9a, 0xbd, 0xc4, 0x81, 0x52, 0xeb, - 0x8f, 0x20, 0x71, 0x59, 0xec, 0xc5, 0xd2, 0x32, - 0xc7, 0xc1, 0x53, 0x7c, 0x79, 0xf4, 0xb7, 0xac, - 0x28, 0xff, 0x11, 0x68, 0x2f, 0x21, 0x68, 0x1b, - 0xf6, 0xd6, 0xab, 0xa5, 0x55, 0x03, 0x2b, 0xf6, - 0xf9, 0xf0, 0x36, 0xbe, 0xb2, 0xaa, 0xa5, 0xb3, - 0x77, 0x8d, 0x6e, 0xeb, 0xfb, 0xa6, 0xbf, 0x9e, - 0xa1, 0x91, 0xbe, 0x4a, 0xb0, 0xca, 0xea, 0x75, - 0x9e, 0x2f, 0x77, 0x3a, 0x1f, 0x90, 0x29, 0xc7, - 0x3e, 0xcb, 0x8d, 0x57, 0x35, 0xb9, 0x32, 0x1d, - 0xb0, 0x85, 0xf1, 0xb8, 0xe2, 0xd8, 0x03, 0x8f, - 0xe2, 0x94, 0x19, 0x92, 0x54, 0x8c, 0xee, 0x0d, - 0x67, 0xdd, 0x45, 0x47, 0xe1, 0x1d, 0xd6, 0x3a, - 0xf9, 0xc9, 0xfc, 0x1c, 0x54, 0x66, 0xfb, 0x68, - 0x4c, 0xf0, 0x09, 0xd7, 0x19, 0x7c, 0x2c, 0xf7, - 0x9e, 0x79, 0x2a, 0xb5, 0x01, 0xe6, 0xa8, 0xa1, - 0xca, 0x51, 0x9a, 0xf2, 0xcb, 0x9b, 0x5f, 0x63, - 0x67, 0xe9, 0x4c, 0x0d, 0x47, 0x50, 0x24, 0x51, - 0x35, 0x7b, 0xe1, 0xb5 - }; + keystr = cfg_obj_asstring(cfg_tuple_get(key, "data")); + tresult = isc_base64_decodestring(keystr, &b); - /* - * Flag any use of a root key, regardless of content. - */ - *keyflags |= (managed ? ROOT_KSK_MANAGED : ROOT_KSK_STATIC); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(key, logctx, ISC_LOG_ERROR, + "%s", isc_result_totext(tresult)); + result = ISC_R_FAILURE; + } else { + isc_buffer_usedregion(&b, &r); - if (flags == 257 && proto == 3 && alg == 8 && - isc_buffer_usedlength(&b) == sizeof(root_ksk_2010) && - !memcmp(keydata, root_ksk_2010, sizeof(root_ksk_2010))) - { - *keyflags |= ROOT_KSK_2010; + if ((n3 == DST_ALG_RSASHA1) && + r.length > 1 && r.base[0] == 1 && r.base[1] == 3) + { + cfg_obj_log(key, logctx, ISC_LOG_WARNING, + "%s '%s' has a weak exponent", + atstr, keynamestr); + } } - if (flags == 257 && proto == 3 && alg == 8 && - isc_buffer_usedlength(&b) == sizeof(root_ksk_2017) && - !memcmp(keydata, root_ksk_2017, sizeof(root_ksk_2017))) - { - *keyflags |= ROOT_KSK_2017; + if (result == ISC_R_SUCCESS && + dns_name_equal(keyname, dns_rootname)) { + /* + * Flag any use of a root key, regardless of content. + */ + *keyflags |= + (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, + sizeof(root_ksk_2010)) == 0) + { + *keyflags |= ROOT_KSK_2010; + } + + if (n1 == 257 && n2 == 3 && n3 == 8 && + (isc_buffer_usedlength(&b) == + sizeof(root_ksk_2017)) && + memcmp(keydata, root_ksk_2017, + sizeof(root_ksk_2017)) == 0) + { + *keyflags |= 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; } + cleanup: return (result); } @@ -3322,13 +3383,17 @@ record_static_keys(isc_symtab_t *symtab, isc_mem_t *mctx, continue; } - init = cfg_tuple_get(obj, "init"); + init = cfg_tuple_get(obj, "anchortype"); if (!cfg_obj_isvoid(init)) { initmethod = cfg_obj_asstring(init); if (strcasecmp(initmethod, "initial-key") == 0) { /* initializing key, skip it */ continue; } + if (strcasecmp(initmethod, "initial-ds") == 0) { + /* initializing key, skip it */ + continue; + } } dns_name_format(name, namebuf, sizeof(namebuf)); @@ -3346,7 +3411,7 @@ record_static_keys(isc_symtab_t *symtab, isc_mem_t *mctx, if (autovalidation && dns_name_equal(name, dns_rootname)) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "static key for root zone " + "static trust anchor for root zone " "cannot be used with " "'dnssec-validation auto'."); ret = ISC_R_FAILURE; @@ -3378,9 +3443,10 @@ check_initializing_keys(isc_symtab_t *symtab, const cfg_obj_t *keylist, const char *str; isc_symvalue_t symvalue; - init = cfg_tuple_get(obj, "init"); + init = cfg_tuple_get(obj, "anchortype"); if (cfg_obj_isvoid(init) || - strcasecmp(cfg_obj_asstring(init), "static-key") == 0) + strcasecmp(cfg_obj_asstring(init), "static-key") == 0 || + strcasecmp(cfg_obj_asstring(init), "static-ds") == 0) { /* static key, skip it */ continue; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index e0e5217d559..8628cfdaa63 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -445,11 +445,11 @@ static cfg_type_t cfg_type_category = { */ static cfg_tuplefielddef_t dnsseckey_fields[] = { { "name", &cfg_type_astring, 0 }, - { "init", &cfg_type_void, 0 }, - { "flags", &cfg_type_uint32, 0 }, - { "protocol", &cfg_type_uint32, 0 }, - { "algorithm", &cfg_type_uint32, 0 }, - { "key", &cfg_type_qstring, 0 }, + { "anchortype", &cfg_type_void, 0 }, + { "n1", &cfg_type_uint32, 0 }, + { "n2", &cfg_type_uint32, 0 }, + { "n3", &cfg_type_uint32, 0 }, + { "data", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_dnsseckey = { @@ -461,19 +461,20 @@ static cfg_type_t cfg_type_dnsseckey = { * A key initialization specifier, as used in the * "dnssec-keys" (or synonymous "managed-keys") statement. */ -static const char *init_enums[] = { "static-key", "initial-key", NULL }; -static cfg_type_t cfg_type_keyinit = { - "keyinit", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &init_enums +static const char *anchortype_enums[] = { + "static-key", "initial-key", "static-ds", "initial-ds", NULL +}; +static cfg_type_t cfg_type_anchortype = { + "anchortype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, + &cfg_rep_string, anchortype_enums }; - static cfg_tuplefielddef_t managedkey_fields[] = { { "name", &cfg_type_astring, 0 }, - { "init", &cfg_type_keyinit, 0 }, - { "flags", &cfg_type_uint32, 0 }, - { "protocol", &cfg_type_uint32, 0 }, - { "algorithm", &cfg_type_uint32, 0 }, - { "key", &cfg_type_qstring, 0 }, + { "anchortype", &cfg_type_anchortype, 0 }, + { "n1", &cfg_type_uint32, 0 }, + { "n2", &cfg_type_uint32, 0 }, + { "n3", &cfg_type_uint32, 0 }, + { "data", &cfg_type_qstring, 0 }, { NULL, NULL, 0 } }; static cfg_type_t cfg_type_managedkey = { @@ -692,10 +693,9 @@ static cfg_type_t cfg_type_trustedkeys = { }; /*% - * A list of key entries, as in "trusted-keys". This has a format similar - * to dnssec keys, except the keyname is followed by keyword, either - * "initial-key" or "static-key". If "initial-key", then the key is - * RFC 5011 managed; if "static-key", then the key never changes. + * A list of managed trust anchors. Each entry contains a name, a keyword + * ("static-key", initial-key", "static-ds" or "initial-ds"), and the + * fields associated with either a DNSKEY or a DS record. */ static cfg_type_t cfg_type_dnsseckeys = { "dnsseckeys", cfg_parse_bracketed_list, cfg_print_bracketed_list,