]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
disable adding keys to keytable; only DS trust anchors can now be added
authorEvan Hunt <each@isc.org>
Fri, 20 Dec 2019 19:37:11 +0000 (11:37 -0800)
committerEvan Hunt <each@isc.org>
Tue, 14 Jan 2020 17:24:22 +0000 (09:24 -0800)
the internal keytable structure has not yet been changed, but
insertion of DS anchors is the only method now available.

NOTE: the keytable unit test is currently failing because of tests
that expect individual keynode objects to contain single DST key
objects.

bin/named/server.c
bin/tests/system/dnssec/tests.sh
lib/dns/client.c
lib/dns/ds.c
lib/dns/include/dns/ds.h
lib/dns/include/dns/keytable.h
lib/dns/keytable.c
lib/dns/tests/keytable_test.c
lib/dns/win32/libdns.def.in
lib/dns/zone.c

index 1b8ee399c4d48a153474bc9f36a75c7e95751bf0..14088fb3c6e87acd322005bc76f283a67db56304 100644 (file)
@@ -700,11 +700,12 @@ 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 **keyp,
-             dns_rdata_ds_t **dsp, const char **namestrp, isc_mem_t *mctx)
+ta_fromconfig(const cfg_obj_t *key, bool *initialp, const char **namestrp,
+             unsigned char *digest, dns_rdata_ds_t *ds)
 {
+       isc_result_t result;
        dns_rdata_dnskey_t keystruct;
-       dns_rdata_ds_t *ds = NULL;
+       dns_rdata_t rdata = DNS_RDATA_INIT;
        uint32_t rdata1, rdata2, rdata3;
        const char *datastr = NULL, *namestr = NULL;
        unsigned char data[4096];
@@ -715,8 +716,6 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
        dns_fixedname_t fname;
        dns_name_t *name = NULL;
        isc_buffer_t namebuf;
-       isc_result_t result;
-       dst_key_t *dstkey = NULL;
        const char *atstr = NULL;
        enum {
                INIT_DNSKEY,
@@ -726,9 +725,8 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
                TRUSTED
        } anchortype;
 
-       REQUIRE(keyp != NULL && *keyp == NULL);
-       REQUIRE(dsp != NULL && *dsp == NULL);
        REQUIRE(namestrp != NULL && *namestrp == NULL);
+       REQUIRE(ds != NULL);
 
        /* if DNSKEY, flags; if DS, key tag */
        rdata1 = cfg_obj_asuint32(cfg_tuple_get(key, "rdata1"));
@@ -775,6 +773,13 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
        isc_buffer_init(&databuf, data, sizeof(data));
        isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
 
+       *ds = (dns_rdata_ds_t){
+               .common.rdclass = dns_rdataclass_in,
+               .common.rdtype = dns_rdatatype_ds
+       };
+
+       ISC_LINK_INIT(&ds->common, link);
+
        switch(anchortype) {
        case INIT_DNSKEY:
        case STATIC_DNSKEY:
@@ -802,7 +807,7 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
                if (rdata2 > 0xff) {
                        CHECKM(ISC_R_RANGE, "key protocol");
                }
-               if (rdata3> 0xff) {
+               if (rdata3 > 0xff) {
                        CHECKM(ISC_R_RANGE, "key algorithm");
                }
 
@@ -810,30 +815,25 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
                keystruct.protocol = (uint8_t)rdata2;
                keystruct.algorithm = (uint8_t)rdata3;
 
+               if (!dst_algorithm_supported(keystruct.algorithm)) {
+                       CHECK(DST_R_UNSUPPORTEDALG);
+               }
+
                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;
 
-               CHECK(dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
+               CHECK(dns_rdata_fromstruct(&rdata, keystruct.common.rdclass,
                                           keystruct.common.rdtype,
                                           &keystruct, &rrdatabuf));
-               CHECK(dst_key_fromdns(name, dns_rdataclass_in,
-                                     &rrdatabuf, mctx, &dstkey));
-
-               *keyp = dstkey;
+               CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
+                                         digest, ds));
                break;
 
        case INIT_DS:
        case STATIC_DS:
-               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 (rdata1 > 0xffff) {
                        CHECKM(ISC_R_RANGE, "key tag");
                }
@@ -878,13 +878,10 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
                        break;
                }
 
-               ds->mctx = mctx;
                ds->length = r.length;
-               ds->digest = isc_mem_allocate(mctx, r.length);
+               ds->digest = digest;
                memmove(ds->digest, r.base, r.length);
 
-               *dsp = ds;
-               ds = NULL;
                break;
 
        default:
@@ -895,15 +892,6 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
        return (ISC_R_SUCCESS);
 
  cleanup:
-       if (dstkey != NULL) {
-               dst_key_free(&dstkey);
-       }
-
-       if (ds != NULL) {
-               dns_rdata_freestruct(ds);
-               isc_mem_put(mctx, ds, sizeof(*ds));
-       }
-
        return (result);
 }
 
@@ -921,46 +909,30 @@ ta_fromconfig(const cfg_obj_t *key, bool *initialp, dst_key_t **keyp,
 static isc_result_t
 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)
+           bool managed)
 {
        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;
+       dns_rdata_ds_t ds;
        isc_result_t result;
        bool initializing = managed;
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       isc_buffer_t b;
 
-       result = ta_fromconfig(key, &initializing, &dstkey, &ds,
-                              &namestr, mctx);
+       result = ta_fromconfig(key, &initializing, &namestr, digest, &ds);
 
        switch (result) {
        case ISC_R_SUCCESS:
                /*
-                * 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.
+                * Trust anchor was parsed correctly.
                 */
-               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;
+               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);
                }
                break;
        case DST_R_UNSUPPORTEDALG:
@@ -1011,7 +983,8 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
         * its owner name.  If it does not, do not load the key and log a
         * warning, but do not prevent further keys from being processed.
         */
-       if (!dns_resolver_algorithm_supported(resolver, keyname, keyalg)) {
+       if (!dns_resolver_algorithm_supported(resolver, keyname, ds.algorithm))
+       {
                cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING,
                            "ignoring %s for '%s': algorithm is disabled",
                            initializing ? "initial-key" : "static-key",
@@ -1026,29 +999,10 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
         * managed, so we use 'initializing' twice here, for both the
         * 'managed' and 'initializing' arguments to dns_keytable_add().
         */
-       result = dns_keytable_add(secroots, initializing,
-                                 initializing, keyname,
-                                 dstkey != NULL ? &dstkey : NULL,
-                                 ds);
+       result = dns_keytable_add(secroots, initializing, initializing,
+                                 keyname, &ds);
 
  done:
-       /*
-        * Ensure 'dstkey' does not leak.  Note that if dns_keytable_add()
-        * succeeds, ownership of the key structure is transferred to the key
-        * table, i.e. 'dstkey' is set to NULL.
-        */
-       if (dstkey != NULL) {
-               dst_key_free(&dstkey);
-       }
-
-       /*
-        * Free 'ds'.
-        */
-       if (ds != NULL) {
-               dns_rdata_freestruct(ds);
-               isc_mem_put(mctx, ds, sizeof(*ds));
-       }
-
        return (result);
 }
 
@@ -1059,7 +1013,7 @@ process_key(const cfg_obj_t *key, dns_keytable_t *secroots,
  */
 static isc_result_t
 load_view_keys(const cfg_obj_t *keys, dns_view_t *view, bool managed,
-              const dns_name_t *keyname, isc_mem_t *mctx)
+              const dns_name_t *keyname)
 {
        const cfg_listelt_t *elt, *elt2;
        const cfg_obj_t *keylist;
@@ -1078,9 +1032,8 @@ load_view_keys(const cfg_obj_t *keys, dns_view_t *view, bool managed,
                     elt2 != NULL;
                     elt2 = cfg_list_next(elt2))
                {
-                       CHECK(process_key(cfg_listelt_value(elt2),
-                                         secroots, keyname, view->resolver,
-                                         managed, mctx));
+                       CHECK(process_key(cfg_listelt_value(elt2), secroots,
+                                         keyname, view->resolver, managed));
                }
        }
 
@@ -1238,7 +1191,7 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
 
                if (builtin_keys != NULL) {
                        CHECK(load_view_keys(builtin_keys, view, true,
-                                            dns_rootname, mctx));
+                                            dns_rootname));
                }
 
                if (!keyloaded(view, dns_rootname)) {
@@ -1251,17 +1204,13 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
        }
 
        if (view->rdclass == dns_rdataclass_in) {
-               CHECK(load_view_keys(view_keys, view, false, NULL, mctx));
-               CHECK(load_view_keys(view_trust_anchors, 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_trust_anchors, view, true,
-                                    NULL, mctx));
-               CHECK(load_view_keys(global_managed_keys, view, true,
-                                    NULL, mctx));
+               CHECK(load_view_keys(view_keys, view, false, NULL));
+               CHECK(load_view_keys(view_trust_anchors, view, true, NULL));
+               CHECK(load_view_keys(view_managed_keys, view, true, NULL));
+
+               CHECK(load_view_keys(global_keys, view, false, NULL));
+               CHECK(load_view_keys(global_trust_anchors, view, true, NULL));
+               CHECK(load_view_keys(global_managed_keys, view, true, NULL));
        }
 
        /*
index e959412961b3ecd88c1ef0f3c9728d79b670caab..0d14b737f79e2baa2ecd398210bc7ece0171aac2 100644 (file)
@@ -3700,12 +3700,12 @@ status=$((status+ret))
 # DNSSEC tests related to unsupported, disabled and revoked trust anchors.
 #
 
-# This nameserver (ns8) is loaded with a bunch of trust anchors.  Some of them
-# are good (enabled.managed, enabled.trusted, secure.managed, secure.trusted),
-# and some of them are bad (disabled.managed, revoked.managed, unsupported.managed,
-# disabled.trusted, revoked.trusted, unsupported.trusted).  Make sure that the bad
-# trust anchors are ignored.  This is tested by looking for the corresponding
-# lines in the logfile.
+# This nameserver (ns8) is loaded with a bunch of trust anchors.  Some of
+# them are good (enabled.managed, enabled.trusted, secure.managed,
+# secure.trusted), and some of them are bad (disabled.managed,
+# revoked.managed, unsupported.managed, disabled.trusted, revoked.trusted,
+# unsupported.trusted).  Make sure that the bad trust anchors are ignored.
+# This is tested by looking for the corresponding lines in the logfile.
 echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)"
 ret=0
 grep -q "ignoring static-key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1
index 4ffbd6ff296d579458c9e7673f126ad1ec23bb89..54e14ce1110182959fc23869397e83707deb363b 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <isc/app.h>
 #include <isc/buffer.h>
+#include <isc/md.h>
 #include <isc/mem.h>
 #include <isc/mutex.h>
 #include <isc/portset.h>
@@ -1498,6 +1499,7 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
        dns_keytable_t *secroots = NULL;
        dns_name_t *name = NULL;
        char dsbuf[DNS_DS_BUFFERSIZE];
+       unsigned char digest[ISC_MAX_MD_SIZE];
        dns_rdata_ds_t ds;
        dns_decompress_t dctx;
        dns_rdata_t rdata;
@@ -1515,33 +1517,28 @@ dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
 
        DE_CONST(keyname, name);
 
-       switch (rdtype) {
-       case dns_rdatatype_dnskey:
-               result = dst_key_fromdns(keyname, rdclass, databuf,
-                                        client->mctx, &dstkey);
-               if (result != ISC_R_SUCCESS) {
-                       goto cleanup;
-               }
-               CHECK(dns_keytable_add(secroots, false, false,
-                                      name, &dstkey, NULL));
-               break;
-       case dns_rdatatype_ds:
-               isc_buffer_init(&b, dsbuf, sizeof(dsbuf));
-               dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
-               dns_rdata_init(&rdata);
-               isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
-               CHECK(dns_rdata_fromwire(&rdata, rdclass, rdtype,
-                                        databuf, &dctx, 0, &b));
-               dns_decompress_invalidate(&dctx);
-               CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
-               CHECK(dns_keytable_add(secroots, false, false,
-                                      name, NULL, &ds));
-               break;
-
-       default:
+       if (rdtype != dns_rdatatype_dnskey && rdtype != dns_rdatatype_ds) {
                result = ISC_R_NOTIMPLEMENTED;
+               goto cleanup;
        }
 
+       isc_buffer_init(&b, dsbuf, sizeof(dsbuf));
+       dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
+       dns_rdata_init(&rdata);
+       isc_buffer_setactive(databuf, isc_buffer_usedlength(databuf));
+       CHECK(dns_rdata_fromwire(&rdata, rdclass, rdtype,
+                                databuf, &dctx, 0, &b));
+       dns_decompress_invalidate(&dctx);
+
+       if (rdtype == dns_rdatatype_ds) {
+               CHECK(dns_rdata_tostruct(&rdata, &ds, NULL));
+       } else {
+               CHECK(dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
+                                         digest, &ds));
+       }
+
+       CHECK(dns_keytable_add(secroots, false, false, name, &ds));
+
  cleanup:
        if (dstkey != NULL) {
                dst_key_free(&dstkey);
index 8958fb89cf2b4fa98d28efe7341fc6997608bb50..7a9c911544e307ab12a32618fa373a31e4aa451c 100644 (file)
 #include <dst/dst.h>
 
 isc_result_t
-dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
-                 dns_dsdigest_t digest_type, unsigned char *buffer,
-                 dns_rdata_t *rdata)
+dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
+                   dns_dsdigest_t digest_type, unsigned char *digest,
+                   dns_rdata_ds_t *dsrdata)
 {
+       isc_result_t result;
        dns_fixedname_t fname;
        dns_name_t *name;
-       unsigned char digest[ISC_MAX_MD_SIZE];
        unsigned int digestlen;
        isc_region_t r;
-       isc_buffer_t b;
-       dns_rdata_ds_t ds;
        isc_md_t *md;
        isc_md_type_t md_type = 0;
-       isc_result_t ret;
 
        REQUIRE(key != NULL);
        REQUIRE(key->type == dns_rdatatype_dnskey ||
@@ -73,51 +70,68 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
        name = dns_fixedname_initname(&fname);
        (void)dns_name_downcase(owner, name, NULL);
 
-       memset(buffer, 0, DNS_DS_BUFFERSIZE);
-       isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
-
        md = isc_md_new();
        if (md == NULL) {
                return (ISC_R_NOMEMORY);
        }
 
-       ret = isc_md_init(md, md_type);
-       if (ret != ISC_R_SUCCESS) {
+       result = isc_md_init(md, md_type);
+       if (result != ISC_R_SUCCESS) {
                goto end;
        }
 
        dns_name_toregion(name, &r);
 
-       ret = isc_md_update(md, r.base, r.length);
-       if (ret != ISC_R_SUCCESS) {
+       result = isc_md_update(md, r.base, r.length);
+       if (result != ISC_R_SUCCESS) {
                goto end;
        }
 
        dns_rdata_toregion(key, &r);
        INSIST(r.length >= 4);
 
-       ret = isc_md_update(md, r.base, r.length);
-       if (ret != ISC_R_SUCCESS) {
+       result = isc_md_update(md, r.base, r.length);
+       if (result != ISC_R_SUCCESS) {
                goto end;
        }
 
-       ret = isc_md_final(md, digest, &digestlen);
-       if (ret != ISC_R_SUCCESS) {
+       result = isc_md_final(md, digest, &digestlen);
+       if (result != ISC_R_SUCCESS) {
                goto end;
        }
 
-       ds.mctx = NULL;
-       ds.common.rdclass = key->rdclass;
-       ds.common.rdtype = dns_rdatatype_ds;
-       ds.algorithm = r.base[3];
-       ds.key_tag = dst_region_computeid(&r);
-       ds.digest_type = digest_type;
-       ds.digest = digest;
-       ds.length = digestlen;
-
-       ret = dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
-                                  &ds, &b);
+       dsrdata->mctx = NULL;
+       dsrdata->common.rdclass = key->rdclass;
+       dsrdata->common.rdtype = dns_rdatatype_ds;
+       dsrdata->algorithm = r.base[3];
+       dsrdata->key_tag = dst_region_computeid(&r);
+       dsrdata->digest_type = digest_type;
+       dsrdata->digest = digest;
+       dsrdata->length = digestlen;
+
 end:
        isc_md_free(md);
-       return (ret);
+       return (result);
+}
+
+isc_result_t
+dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
+                 dns_dsdigest_t digest_type, unsigned char *buffer,
+                 dns_rdata_t *rdata)
+{
+       isc_result_t result;
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       dns_rdata_ds_t ds;
+       isc_buffer_t b;
+
+       result = dns_ds_fromkeyrdata(owner, key, digest_type, digest, &ds);
+       if (result != ISC_R_SUCCESS) {
+               return (result);
+       }
+
+       memset(buffer, 0, DNS_DS_BUFFERSIZE);
+       isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE);
+       result = dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds,
+                                     &ds, &b);
+       return (result);
 }
index a1df4a5d5766ce083bfa30a0369445cafd8e34e1..ae610dae8236ff0c446bad6422bc0f65c3915181 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <isc/lang.h>
 
+#include <dns/rdatastruct.h>
 #include <dns/types.h>
 
 #define DNS_DSDIGEST_SHA1 (1)
 
 ISC_LANG_BEGINDECLS
 
+isc_result_t
+dns_ds_fromkeyrdata(dns_name_t *owner, dns_rdata_t *key,
+                   dns_dsdigest_t digest_type, unsigned char *digest,
+                   dns_rdata_ds_t *dsrdata);
+/*%<
+ * Build a DS rdata structure from a key.
+ *
+ * Requires:
+ *\li  key     Points to a valid DNSKEY or CDNSKEY record.
+ *\li  buffer  Points to a buffer of at least
+ *             #ISC_MAX_MD_SIZE bytes.
+ */
+
 isc_result_t
 dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
                  dns_dsdigest_t digest_type, unsigned char *buffer,
                  dns_rdata_t *rdata);
 /*%<
- * Build the rdata of a DS record.
+ * Similar to dns_ds_fromkeyrdata(), but copies the DS into a
+ * dns_rdata object.
  *
  * Requires:
  *\li  key     Points to a valid DNSKEY or CDNSKEY record.
- *\li  buffer  Points to a temporary buffer of at least
+ *\li  buffer  Points to a buffer of at least
  *             #DNS_DS_BUFFERSIZE bytes.
  *\li  rdata   Points to an initialized dns_rdata_t.
  *
index 4edba81a5b4b03b8bb641332e25720f6f65f8923..bf4c414d72f8761f66d5593ecf933a9adaa93231 100644 (file)
@@ -106,13 +106,11 @@ dns_keytable_detach(dns_keytable_t **keytablep);
  */
 
 isc_result_t
-dns_keytable_add(dns_keytable_t *keytable,
-                bool managed, bool initial,
-                dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds);
+dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
+                dns_name_t *name, dns_rdata_ds_t *ds);
 /*%<
  * Add a key to 'keytable'. The keynode associated with 'name'
- * is updated with either the key referenced in '*keyp'
- * or with the DS specified in 'ds'.
+ * is updated with the DS specified in 'ds'.
  *
  * The value of keynode->managed is set to 'managed', and the
  * value of keynode->initial is set to 'initial'. (Note: 'initial'
@@ -123,28 +121,15 @@ dns_keytable_add(dns_keytable_t *keytable,
  *
  * Notes:
  *
- *\li  Ownership of *keyp is transferred to the keytable.
- *\li  If 'keyp' is not NULL and DS-style keys already exist
- *     in the table for this name, they are freed before adding
- *     the new key.
- *\li  If 'ds' is not NULL and key-style keys already exist
- *     in the table for this name, return ISC_R_EXISTS. DS keys
- *     can be updated to key-style, but not vice versa.
- *\li   If the key already exists in the table, ISC_R_EXISTS is
- *      returned and the new key is freed.
+ *\li   If the key already exists in the table, adding it again
+ *      has no effect and ISC_R_SUCCESS is returned.
  *
  * Requires:
  *
  *\li  'keytable' points to a valid keytable.
- *
+ *\li  'ds' is not NULL.
  *\li  if 'initial' is true then 'managed' must also be true.
  *
- *\li  keyp != NULL && *keyp is a valid dst_key_t *.
- *
- * Ensures:
- *
- *\li  On success, *keyp == NULL
- *
  * Returns:
  *
  *\li  ISC_R_SUCCESS
index 2a65c7caabaf216991dae2c7f8e01945790d4abd..91afb052ddcf23bf584aaa8318ea91e71259380c 100644 (file)
@@ -364,14 +364,12 @@ insert(dns_keytable_t *keytable, bool managed, bool initial,
 }
 
 isc_result_t
-dns_keytable_add(dns_keytable_t *keytable,
-                bool managed, bool initial,
-                dns_name_t *name, dst_key_t **keyp, dns_rdata_ds_t *ds)
+dns_keytable_add(dns_keytable_t *keytable, bool managed, bool initial,
+                dns_name_t *name, dns_rdata_ds_t *ds)
 {
-       REQUIRE(keyp == NULL || *keyp != NULL);
-       REQUIRE(keyp != NULL || ds != NULL);
+       REQUIRE(ds != NULL);
        REQUIRE(!initial || managed);
-       return (insert(keytable, managed, initial, name, keyp, ds));
+       return (insert(keytable, managed, initial, name, NULL, ds));
 }
 
 isc_result_t
index ac3066eafdb05ee029fbcecdf9b4871bdb6e1614..3f5d2eb210241a9855516da7ace1231bc26afd45 100644 (file)
 
 #include <isc/base64.h>
 #include <isc/buffer.h>
+#include <isc/md.h>
 #include <isc/util.h>
 
-#include <dns/name.h>
 #include <dns/fixedname.h>
 #include <dns/keytable.h>
+#include <dns/name.h>
 #include <dns/nta.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatastruct.h>
@@ -129,44 +130,48 @@ create_keystruct(uint16_t flags, uint8_t proto, uint8_t alg,
 }
 
 static void
-create_key(uint16_t flags, uint8_t proto, uint8_t alg,
-          const char *keynamestr, const char *keystr, dst_key_t **target)
+create_dsstruct(dns_name_t *name, uint16_t flags,
+               uint8_t proto, uint8_t alg, const char *keystr,
+               unsigned char *digest, dns_rdata_ds_t *dsstruct)
 {
        isc_result_t result;
-       dns_rdata_dnskey_t keystruct;
        unsigned char rrdata[4096];
        isc_buffer_t rrdatabuf;
-       const dns_rdataclass_t rdclass = dns_rdataclass_in;
+       dns_rdata_t rdata = DNS_RDATA_INIT;
+       dns_rdata_dnskey_t dnskey;
 
        /*
         * Populate DNSKEY rdata structure.
         */
-       create_keystruct(flags, proto, alg, keystr, &keystruct);
+       create_keystruct(flags, proto, alg, keystr, &dnskey);
 
        /*
         * Convert to wire format.
         */
        isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
-       result = dns_rdata_fromstruct(NULL, keystruct.common.rdclass,
-                                    keystruct.common.rdtype,
-                                    &keystruct, &rrdatabuf),
+       result = dns_rdata_fromstruct(&rdata, dnskey.common.rdclass,
+                                    dnskey.common.rdtype,
+                                    &dnskey, &rrdatabuf);
        assert_int_equal(result, ISC_R_SUCCESS);
 
        /*
-        * Convert wire format to DST key.
+        * Build DS rdata struct.
         */
-       result = dst_key_fromdns(str2name(keynamestr), rdclass,
-                                &rrdatabuf, dt_mctx, target),
+       result = dns_ds_fromkeyrdata(name, &rdata, DNS_DSDIGEST_SHA256,
+                                    digest, dsstruct);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       dns_rdata_freestruct(&keystruct);
+       dns_rdata_freestruct(&dnskey);
 }
 
 /* Common setup: create a keytable and ntatable to test with a few keys */
 static void
 create_tables() {
        isc_result_t result;
-       dst_key_t *key = NULL;
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       dns_rdata_ds_t ds;
+       dns_fixedname_t fn;
+       dns_name_t *keyname = dns_fixedname_name(&fn);
        isc_stdtime_t now;
 
        result = dns_test_makeview("view", &view);
@@ -178,15 +183,15 @@ create_tables() {
                                             &ntatable), ISC_R_SUCCESS);
 
        /* Add a normal key */
-       create_key(257, 3, 5, "example.com", keystr1, &key);
-       assert_int_equal(dns_keytable_add(keytable, false, false,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("example.com", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
                         ISC_R_SUCCESS);
 
        /* Add an initializing managed key */
-       create_key(257, 3, 5, "managed.com", keystr1, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, true,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("managed.com", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
                         ISC_R_SUCCESS);
 
        /* Add a null key */
@@ -217,9 +222,12 @@ destroy_tables() {
 /* add keys to the keytable */
 static void
 add_test(void **state) {
-       dst_key_t *key = NULL;
        dns_keynode_t *keynode = NULL;
        dns_keynode_t *null_keynode = NULL;
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       dns_rdata_ds_t ds;
+       dns_fixedname_t fn;
+       dns_name_t *keyname = dns_fixedname_name(&fn);
 
        UNUSED(state);
 
@@ -236,9 +244,9 @@ add_test(void **state) {
         * Try to add the same key.  This should have no effect but
         * report success.
         */
-       create_key(257, 3, 5, "example.com", keystr1, &key);
-       assert_int_equal(dns_keytable_add(keytable, false, false,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("example.com", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
                         ISC_R_SUCCESS);
        dns_keytable_detachkeynode(keytable, &keynode);
        assert_int_equal(dns_keytable_find(keytable, str2name("example.com"),
@@ -247,9 +255,8 @@ add_test(void **state) {
 
        /* Add another key (different keydata) */
        dns_keytable_detachkeynode(keytable, &keynode);
-       create_key(257, 3, 5, "example.com", keystr2, &key);
-       assert_int_equal(dns_keytable_add(keytable, false, false,
-                                         dst_key_name(key), &key, NULL),
+       create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("example.com"),
                                           &keynode),
@@ -273,9 +280,9 @@ add_test(void **state) {
         * Add a different managed key for managed.com, marking it as an
         * initializing key.
         */
-       create_key(257, 3, 5, "managed.com", keystr2, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, true,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("managed.com", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
                                           &keynode),
@@ -289,9 +296,7 @@ add_test(void **state) {
         * to a non-initializing key and make sure there are still two key
         * nodes for managed.com, both containing non-initializing keys.
         */
-       create_key(257, 3, 5, "managed.com", keystr2, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, false,
-                                         dst_key_name(key), &key, NULL),
+       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("managed.com"),
                                           &keynode),
@@ -303,9 +308,9 @@ add_test(void **state) {
         * Add a managed key at a new node, two.com, marking it as an
         * initializing key.
         */
-       create_key(257, 3, 5, "two.com", keystr1, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, true,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("two.com", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, true, true, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
                                           &keynode),
@@ -317,9 +322,8 @@ add_test(void **state) {
         * Add a different managed key for two.com, marking it as a
         * non-initializing key.
         */
-       create_key(257, 3, 5, "two.com", keystr2, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, false,
-                                         dst_key_name(key), &key, NULL),
+       create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
                                           &keynode),
@@ -333,9 +337,8 @@ add_test(void **state) {
         * to a non-initializing key and make sure there are still two key
         * nodes for two.com, both containing non-initializing keys.
         */
-       create_key(257, 3, 5, "two.com", keystr1, &key);
-       assert_int_equal(dns_keytable_add(keytable, true, false,
-                                         dst_key_name(key), &key, NULL),
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, true, false, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("two.com"),
                                           &keynode),
@@ -350,9 +353,9 @@ add_test(void **state) {
        assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
                                           &null_keynode),
                         ISC_R_SUCCESS);
-       create_key(257, 3, 5, "null.example", keystr2, &key);
-       assert_int_equal(dns_keytable_add(keytable, false, false,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("null.example", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr2, digest, &ds);
+       assert_int_equal(dns_keytable_add(keytable, false, false, keyname, &ds),
                         ISC_R_SUCCESS);
        assert_int_equal(dns_keytable_find(keytable, str2name("null.example"),
                                           &keynode),
@@ -595,8 +598,11 @@ dump_test(void **state) {
 static void
 nta_test(void **state) {
        isc_result_t result;
-       dst_key_t *key = NULL;
        bool issecure, covered;
+       dns_fixedname_t fn;
+       dns_name_t *keyname = dns_fixedname_name(&fn);
+       unsigned char digest[ISC_MAX_MD_SIZE];
+       dns_rdata_ds_t ds;
        dns_view_t *myview = NULL;
        isc_stdtime_t now;
 
@@ -618,14 +624,13 @@ nta_test(void **state) {
        result = dns_view_getntatable(myview, &ntatable);
        assert_int_equal(result, ISC_R_SUCCESS);
 
-       create_key(257, 3, 5, "example", keystr1, &key);
-       result = dns_keytable_add(keytable, false, false,
-                                         dst_key_name(key), &key, NULL),
+       dns_test_namefromstring("example", &fn);
+       create_dsstruct(keyname, 257, 3, 5, keystr1, digest, &ds);
+       result = dns_keytable_add(keytable, false, false, keyname, &ds),
        assert_int_equal(result, ISC_R_SUCCESS);
 
        isc_stdtime_get(&now);
-       result = dns_ntatable_add(ntatable,
-                                 str2name("insecure.example"),
+       result = dns_ntatable_add(ntatable, str2name("insecure.example"),
                                  false, now, 1);
        assert_int_equal(result, ISC_R_SUCCESS);
 
index 42e8ab222afa6ea70fda5788c21149b5891b83a3..3de3985573a19779b0eec810c2224b76c576614c 100644 (file)
@@ -336,6 +336,7 @@ dns_dnssecsignstats_create
 dns_dnssecsignstats_dump
 dns_dnssecsignstats_increment
 dns_ds_buildrdata
+dns_ds_fromkeyrdata
 dns_dsdigest_format
 dns_dsdigest_fromtext
 dns_dsdigest_totext
index 80e3085a45116092fda5fd7c4ad48640a3370a83..f7de8e7fdf7df90807bd1a37d57a41e92ab15e6f 100644 (file)
@@ -18,6 +18,7 @@
 #include <isc/atomic.h>
 #include <isc/file.h>
 #include <isc/hex.h>
+#include <isc/md.h>
 #include <isc/mutex.h>
 #include <isc/pool.h>
 #include <isc/print.h>
@@ -3942,35 +3943,34 @@ compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
  */
 static void
 trust_key(dns_zone_t *zone, dns_name_t *keyname,
-         dns_rdata_dnskey_t *dnskey, bool initial,
-         isc_mem_t *mctx)
+         dns_rdata_dnskey_t *dnskey, bool initial)
 {
        isc_result_t result;
        dns_rdata_t rdata = DNS_RDATA_INIT;
-       unsigned char data[4096];
+       unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
        isc_buffer_t buffer;
        dns_keytable_t *sr = NULL;
-       dst_key_t *dstkey = NULL;
+       dns_rdata_ds_t ds;
+
+       result = dns_view_getsecroots(zone->view, &sr);
+       if (result != ISC_R_SUCCESS) {
+               return;
+       }
 
-       /* Convert dnskey to DST key. */
+       /* Build DS record for key. */
        isc_buffer_init(&buffer, data, sizeof(data));
        dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
                             dns_rdatatype_dnskey, dnskey, &buffer);
+       CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256,
+                                 digest, &ds));
+       CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
 
-       result = dns_view_getsecroots(zone->view, &sr);
-       if (result != ISC_R_SUCCESS)
-               goto failure;
-
-       CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
-       CHECK(dns_keytable_add(sr, true, initial,
-                              dst_key_name(dstkey), &dstkey, NULL));
        dns_keytable_detach(&sr);
 
   failure:
-       if (dstkey != NULL)
-               dst_key_free(&dstkey);
-       if (sr != NULL)
+       if (sr != NULL) {
                dns_keytable_detach(&sr);
+       }
        return;
 }
 
@@ -4000,7 +4000,6 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
        dns_rdata_t rdata = DNS_RDATA_INIT;
        dns_rdata_keydata_t keydata;
        dns_rdata_dnskey_t dnskey;
-       isc_mem_t *mctx = zone->mctx;
        int trusted = 0, revoked = 0, pending = 0;
        isc_stdtime_t now;
        dns_keytable_t *sr = NULL;
@@ -4051,7 +4050,7 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
 
                /* Add to keytables. */
                trusted++;
-               trust_key(zone, name, &dnskey, (keydata.addhd == 0), mctx);
+               trust_key(zone, name, &dnskey, (keydata.addhd == 0));
        }
 
        if (trusted == 0 && pending != 0) {
@@ -10271,7 +10270,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                        /* Trust this key. */
                        result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
-                       trust_key(zone, keyname, &dnskey, false, mctx);
+                       trust_key(zone, keyname, &dnskey, false);
                }
 
                if (secure && !deletekey) {