dnssec-signzone.c revision 2162c1ed3dbf02459e753f7f407bc6dfc24b0bee
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Portions Copyright (C) 1999-2003 Internet Software Consortium.
7c74e180c206e6ed99e8beb820da5f399d845c3eDavid Lawrence * Permission to use, copy, modify, and/or distribute this software for any
7c74e180c206e6ed99e8beb820da5f399d845c3eDavid Lawrence * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
866d106459313499d0ca7bfccb4b2d23d5e4377cDavid Lawrence * Permission to use, copy, modify, and/or distribute this software for any
7c74e180c206e6ed99e8beb820da5f399d845c3eDavid Lawrence * purpose with or without fee is hereby granted, provided that the above
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews * copyright notice and this permission notice appear in all copies.
866d106459313499d0ca7bfccb4b2d23d5e4377cDavid Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
be801b0fdbcf9b55b3a8cc6bf042ff6c86be6b11Mark Andrews * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff/* $Id: dnssec-signzone.c,v 1.252 2009/11/03 01:31:17 marka Exp $ */
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic int nsec_datatype = dns_rdatatype_nsec;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic unsigned int keycount = 0;
ae4cbb69eef32ced103fe4561e8d2031ee4c3497David Lawrencestatic isc_stdtime_t starttime = 0, endtime = 0, now;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic int jitter = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_masterformat_t inputformat = dns_masterformat_text;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_masterformat_t outputformat = dns_masterformat_text;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic unsigned int nsigned = 0, nretained = 0, ndropped = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic unsigned int nverified = 0, nverifyfailed = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic const char *directory = NULL, *dsdir = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_dbversion_t *gversion; /* The database version */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_dbiterator_t *gdbiter; /* The database iterator */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_name_t *gorigin; /* The database origin */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic int nsec3flags = 0;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic unsigned int ntasks = 0;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t ignore_kskflag = ISC_FALSE;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic isc_boolean_t keyset_kskonly = ISC_FALSE;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic unsigned int serialformat = SOA_SERIAL_KEEP;
1ce985ab3c6670662d555c108b35fed84a6a1001David Lawrencestatic unsigned int hash_length = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_boolean_t disable_zone_check = ISC_FALSE;
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence#define check_dns_dbiterator_current(result) \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence "dns_dbiterator_current()")
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrencedumpnode(dns_name_t *name, dns_dbnode_t *node) {
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name,
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff check_result(result, "dns_master_dumpnodetostream");
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * Sign the given RRset with given key, and add the signature record to the
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * given tuple.
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrewssignwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime,
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews result = dns_dnssec_verify(name, rdataset, key,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &trdata,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson check_result(result, "dns_difftuple_create");
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson return (key->force_sign || key->hint_sign);
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews * Find the key that generated an RRSIG, if it is in the key list. If
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews * so, return a pointer to it, otherwise return NULL.
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews * No locking is performed here, this must be done by the caller.
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrewskeythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews * Finds the key that generated a RRSIG, if possible. First look at the keys
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews * that we've loaded already, and then see if there's a key on disk.
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews * We did not find the key in our list. Get a write lock now, since
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews * we may be modifying the bits. We could do the tryupgrade() dance,
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews * but instead just get a write lock and check once again to see if
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews * it is on our list. It's possible someone else may have added it
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews * after all.
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
963c48ba4d06a112c70d50328e827749e95f58dbMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson dns_dnsseckey_create(mctx, &privkey, &key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson dns_dnsseckey_create(mctx, &pubkey, &key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * Check to see if we expect to find a key at this name. If we see a RRSIG
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * and can't find the signing key that we expect to find, we drop the rrsig.
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * I'm not sure if this is completely correct, but it seems to work.
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson unsigned int options = DNS_DBFIND_NOWILD;
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options,
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff 0, NULL, dns_fixedname_name(&fname), NULL, NULL);
3d8dfd44a3be708f00380064411c16b2fa28303aMark Andrews dns_name_format(name, namestr, sizeof(namestr));
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff fatal("failure looking for '%s DNSKEY' in database: %s",
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews /* NOTREACHED */
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrewssetverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews * Signs a set. Goes through contortions to decide if each RRSIG should
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews * be dropped or retained, and then determines if any new SIGs need to
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington * be generated.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewssignset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson isc_boolean_t *wassignedby, *nowsignedby;
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews dns_name_format(name, namestr, sizeof(namestr));
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews type_format(set->type, typestr, sizeof(typestr));
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig,
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews fatal("failed while looking for '%s RRSIG %s': %s",
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson arraysize += dns_rdataset_count(&sigset);
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson if (wassignedby == NULL || nowsignedby == NULL)
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson for (i = 0; i < arraysize; i++)
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson wassignedby[i] = nowsignedby[i] = ISC_FALSE;
2995f8205eaa0d4bc3a57900a413b5cfdb83564fAndreas Gustafsson isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE;
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews expired = isc_serial_gt(now + cycle, rrsig.timeexpire);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews expired = isc_serial_gt(now, rrsig.timeexpire);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) {
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews /* rrsig is dropped and not replaced */
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews "invalid validity period\n",
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews /* rrsig is dropped and not replaced */
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews "private dnskey not found\n",
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
919caa020b8f9b856d77b3a72e0c9301dfa495c7Andreas Gustafsson expired ? "retained" : "dropped", sigstr);
6805e4e2c46ad3c5a4aa941b5e9a29d34579641eMark Andrews if (!expired && setverifies(name, set, key->key,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews vbprintf(2, "\trrsig by %s retained\n", sigstr);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "failed to verify");
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews if (!expired && setverifies(name, set, key->key,
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews vbprintf(2, "\trrsig by %s retained\n", sigstr);
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews "failed to verify");
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews } else if (!expired) {
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson vbprintf(2, "\trrsig by %s retained\n", sigstr);
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington vbprintf(2, "\trrsig by %s expired\n", sigstr);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "resigning with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_rdataset_first/next");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "signing with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "signing with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char *hashbuf;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_add(hashlist_t *l, const unsigned char *hash, size_t len)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->hashbuf = realloc(l->hashbuf, l->size * l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews memset(l->hashbuf + l->entries * l->length, 0, l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews memcpy(l->hashbuf + l->entries * l->length, hash, len);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned int len;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews len = isc_iterated_hash(hash, hashalg, iterations, salt, salt_length,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_format(name, nametext, sizeof nametext);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews for (i = 0 ; i < len; i++)
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellingtonhashlist_comp(const void *a, const void *b) {
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington qsort(l->hashbuf, l->entries, l->length, hashlist_comp);
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington unsigned char *current;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * Skip initial speculative wild card hashs.
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington while (entries > 0U && next[l->length-1] != 0U) {
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington if (memcmp(current, next, l->length - 1) == 0)
529ff4b4959fb157194f985394951108ff5286e4Brian Wellingtonstatic const unsigned char *
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews const unsigned char *next = bsearch(hash, l->hashbuf, l->entries,
9738408dcbd4c1f7eb2b105c83388608fafd7808Mark Andrews if (next < l->hashbuf + (l->entries - 1) * l->length)
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp))
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsaddnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews result = dns_name_concatenate(dns_wildcardname, name, wild, NULL);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews check_result(result,"addnowildcardhash: dns_name_concatenate()");
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews result = dns_db_findnode(gdb, wild, ISC_FALSE, &node);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_name_format(wild, namestr, sizeof(namestr));
2271edc0b4ba96e69a283eced420b94ffb678beeBrian Wellington fprintf(stderr, "adding no-wildcardhash for %s\n", namestr);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_length,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsopendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
3184ff5e45c8f821e5165ea60d674bfb87faf5b8Mark Andrews isc_buffer_init(&b, filename, sizeof(filename));
3184ff5e45c8f821e5165ea60d674bfb87faf5b8Mark Andrews /* allow room for a trailing slash */
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (strlen(dsdir) >= isc_buffer_availablelength(&b))
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (strlen(prefix) > isc_buffer_availablelength(&b))
70e854766f5304f43e94212dc38ebaefe214148cMark Andrews result = dns_name_tofilenametext(name, ISC_FALSE, &b);
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews check_result(result, "dns_name_tofilenametext()");
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews dns_name_format(name, namestr, sizeof(namestr));
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson * Load the DS set for a child zone, if a dsset-* file can be found.
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson * If not, try to find a keyset-* file from an earlier version of
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson * dnssec-signzone, and build DS records from that.
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafssonloadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
3fafd7c0c42134ff2964b74a31500465a96dee90Andreas Gustafsson result = dns_db_findnode(db, name, ISC_FALSE, &node);
9ceaa92a8ca8a0270ba296d44599e94d95033759Andreas Gustafsson result = dns_db_findrdataset(db, node, NULL,
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /* No DS records found; try again, looking for DNSKEY records */
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_db_findnode(db, name, ISC_FALSE, &node);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256,
23ac30603a7639bea1d331537634b079b046b122Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0,
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencedelegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns,
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencesecure(dns_name_t *name, dns_dbnode_t *node) {
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds,
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrews * Signs all records at a name.
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrewssignname(dns_dbnode_t *node, dns_name_t *name) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_name_format(name, namestr, sizeof(namestr));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Determine if this is a delegation point.
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence * Now iterate through the rdatasets.
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /* If this is a RRSIG set, skip it. */
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence * If this name is a delegation point, skip all records
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence * except NSEC and DS sets. Otherwise check that there
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence * isn't a DS record.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else if (rdataset.type == dns_rdatatype_ds) {
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews dns_name_format(name, namebuf, sizeof(namebuf));
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence fatal("'%s': found DS RRset without NS RRset\n",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley fatal("rdataset iteration for name '%s' failed: %s",
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence result = dns_diff_applysilently(&del, gdb, gversion);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence fatal("failed to delete SIGs at node '%s': %s",
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence result = dns_diff_applysilently(&add, gdb, gversion);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob check_result(result, "dns_db_allrdatasets()");
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob if (!active && nsec_datatype == dns_rdatatype_nsec) {
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob * The node is empty of everything but NSEC / RRSIG records.
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob for (result = dns_rdatasetiter_first(rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_db_deleterdataset(gdb, node, gversion,
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob check_result(result, "dns_db_deleterdataset()");
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Delete RRSIGs for types that no longer exist.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2);
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews * Delete the NSEC chain if we are signing with
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley "dns_db_deleterdataset(nsec/rrsig)");
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews for (result = dns_rdatasetiter_first(rdsiter2);
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson dns_rdatasetiter_current(rdsiter2, &rdataset);
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson result = dns_db_deleterdataset(gdb, node,
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews "dns_db_deleterdataset(rrsig)");
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa,
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington fatal("failed to find an SOA at the zone apex: %s",
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington check_result(result, "dns_rdataset_first");
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence zone_soa_min_ttl = dns_soa_getminimum(&rdata);
c0ef1acf49b383d8b6d3742cb963f7d08f5762e3Andreas Gustafsson * Increment (or set if nonzero) the SOA serial
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_findrdataset(gdb, node, gversion,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence /* Set SOA serial to the value provided. */
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence /* Increment SOA serial using RFC 1982 arithmetics */
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence /* If the new serial is not likely to cause a zone transfer
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence * (a/ixfr) from servers having the old serial, warn the user.
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence * RFC1982 section 7 defines the maximum increment to be
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence * comparison. (5 - 6 == (2^32)-1, not negative-one)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence fprintf(stderr, "%s: warning: Serial number not advanced, "
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence check_result(result, "dns_db_deleterdataset");
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_addrdataset(gdb, node, gversion,
3fafd7c0c42134ff2964b74a31500465a96dee90Andreas Gustafsson * Delete any RRSIG records at a node.
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrewscleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence if (outputformat != dns_masterformat_text || !disable_zone_check)
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews dresult = dns_db_deleterdataset(db, node, version,
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews check_result(dresult, "dns_db_deleterdataset");
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews * Set up the iterator and global state before starting the tasks.
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews result = dns_db_createiterator(gdb, 0, &gdbiter);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews check_result(result, "dns_db_createiterator()");
435532822dc571a904207d8176e063cc8731eef5Bob Halley * Clean up the iterator and global state after the tasks complete.
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafssongoodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
7c014c5bf41dc38802e8889c0a9110204eb1a552Andreas Gustafsson dns_rdata_tostruct(sigrdata, &sig, NULL);
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson for (result = dns_rdataset_first(keyrdataset);
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson result = dns_rdataset_next(keyrdataset)) {
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdataset_current(keyrdataset, &rdata);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graffverifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
163bf7444f140c9201cc093c31431a56d4665af7Michael Graff dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence unsigned char *bad_algorithms)
9ac79ef3f89b23d80f9649abf71fdc65bb7a8b62David Lawrence result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_allrdatasets()");
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff for (result = dns_rdatasetiter_first(rdsiter);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence dns_rdatasetiter_current(rdsiter, &sigrdataset);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence if (sigrdataset.type == dns_rdatatype_rrsig &&
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley type_format(rdataset->type, typebuf, sizeof(typebuf));
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence for (i = 0; i < 256; i++)
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence memset(set_algorithms, 0, sizeof(set_algorithms));
2f330bed30b752451b8a5258c7551b22ba602337Andreas Gustafsson for (result = dns_rdataset_first(&sigrdataset);
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews if (goodsig(&rdata, name, keyrdataset, rdataset))
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews dns_name_format(name, namebuf, sizeof(namebuf));
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews type_format(rdataset->type, typebuf, sizeof(typebuf));
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews for (i = 0; i < 256; i++)
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews if ((ksk_algorithms[i] != 0) &&
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrewsverifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence unsigned char *bad_algorithms)
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews (!delegation || rdataset.type == dns_rdatatype_ds ||
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews * Verify that certain things are sane:
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson * The apex has a DNSKEY record with at least one KSK, and at least
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews * one ZSK if the -x flag was not used.
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence * The DNSKEY record was signed with at least one of the KSKs in this
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson * The rest of the zone was signed with at least one of the ZSKs
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews * present in the DNSKEY RRSET.
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("failed to find the zone's origin: %s",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_db_findrdataset(gdb, node, gversion,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!dns_rdataset_isassociated(&sigrdataset))
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(bad_algorithms, 0, sizeof(bad_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(self_algorithms, 0, sizeof(self_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * Check that the DNSKEY RR has at least one self signing KSK
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * and one ZSK per algorithm in it (or, if -x was used, one
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * self-signing KSK).
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence !dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_buffer_init(&buf, buffer, sizeof(buffer));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_rdata_totext(&rdata, NULL, &buf);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
c4157085cd215999883eb3de41bf16ce798379ceAndreas Gustafsson } else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "No self signing KSK found. Using "
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence "self signed ZSK's for active "
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence "algorithm list.\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "warning: not all ZSK's are self "
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence "signed.\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "Verifying the zone using the following algorithms:");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_secalg_format(i, algbuf, sizeof(algbuf));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
3aa5ecb8f7081d831bb267d45437e46c61a41f25Brian Wellington * The counts should both be zero or both be non-zero.
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * Mark the algorithm as bad if this is not met.
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if ((ksk_algorithms[i] != 0) ==
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_secalg_format(i, algbuf, sizeof(algbuf));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "Missing %s for algorithm %s\n",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence : "self signing KSK",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * Check that all the other records were signed by keys that are
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * present in the DNSKEY RRSET.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_db_createiterator()");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_dbiterator_first()");
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews verifynode(name, node, isdelegation, &rdataset,
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
8ca42f6318be756354b70260050132545aa680d3Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
8ca42f6318be756354b70260050132545aa680d3Mark Andrews fatal("iterating through the database failed: %s",
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_db_createiterator()");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_dbiterator_current(dbiter, &node, name);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * If we made it this far, we have what we consider a properly signed
be0e075ac2c10ade3e80edef7fa14ac0fda92690Mark Andrews * zone. Set the good flag.
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "The zone is not fully signed "
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson "for the following algorithms:");
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson dns_secalg_format(i, algbuf, sizeof(algbuf));
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson fatal("DNSSEC completeness test failed.");
21f1794606dce19928cf455029e173321f166380Mark Andrews * Print the success summary.
21f1794606dce19928cf455029e173321f166380Mark Andrews for (i = 0; i < 256; i++) {
21f1794606dce19928cf455029e173321f166380Mark Andrews if ((ksk_algorithms[i] != 0) ||
21f1794606dce19928cf455029e173321f166380Mark Andrews "%u active, %u stand-by, %u revoked\n",
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews "%u active, %u %s, %u revoked\n",
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews * Sign the apex of the zone.
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews * Note the origin may not be the first node if there are out of zone
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews result = dns_dbiterator_seek(gdbiter, gorigin);
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews result = dns_dbiterator_current(gdbiter, &node, name);
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence * Assigns a node to a worker thread. This is protected by the master task's
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsassignwork(isc_task_t *task, isc_task_t *worker) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews static dns_name_t *zonecut = NULL; /* Protected by namelock. */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews static dns_fixedname_t fzonecut; /* Protected by namelock. */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews static unsigned int ended = 0; /* Protected by namelock. */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fname = isc_mem_get(mctx, sizeof(dns_fixedname_t));
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews result = dns_dbiterator_current(gdbiter, &node, name);
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * The origin was handled by signapex().
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * Sort the zone data from the glue and out-of-zone data.
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * For NSEC zones nodes with zone data have NSEC records.
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * For NSEC3 zones the NSEC3 nodes are zone data but
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * outside of the zone name space. For the rest we need
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * to track the bottom of zone cuts.
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * Nodes which don't need to be signed are dumped here.
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson result = dns_db_findrdataset(gdb, node, gversion,
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews } else if (nsec_datatype == dns_rdatatype_nsec3) {
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_mem_put(mctx, fname, sizeof(dns_fixedname_t));
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews isc_event_allocate(mctx, task, SIGNER_EVENT_WORK,
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence * Start a worker task
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrencestartworker(isc_task_t *task, isc_event_t *event) {
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson * Write a node to the output file, and restart the worker task.
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrewswritenode(isc_task_t *task, isc_event_t *event) {
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews dumpnode(dns_fixedname_name(sevent->fname), sevent->node);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t));
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews * Sign a database node.
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE,
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews * Update / remove the DS RRset. Preserve RRSIG(DS) if possible.
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrewsadd_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews result = dns_db_findrdataset(gdb, node, gversion,
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence check_result(result, "dns_db_deleterdataset");
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence result = dns_db_addrdataset(gdb, node, gversion, 0,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence } else if (dns_rdataset_isassociated(&sigdsset)) {
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_deleterdataset");
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records.
9c9cf3a8d063b0255dbc8679dab588708e9b6f1cAndreas Gustafsson dns_fixedname_t fname, fnextname, fzonecut;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence * Remove any NSEC3 chains.
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_createiterator()");
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_dbiterator_current(dbiter, &node, name);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_allrdatasets()");
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence for (result = dns_rdatasetiter_first(rdsiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence "dns_db_deleterdataset(nsec3param/rrsig)");
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_result(result, "dns_db_createiterator()");
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_result(result, "dns_dbiterator_first()");
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Delete any NSEC3PARAM records at the apex.
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 "dns_db_deleterdataset(nsec3param/rrsig)");
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_dbiterator_current(dbiter, &node, name);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_dbiterator_current(dbiter, &nextnode,
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
161835380928f2ff8abff8930078152a71340b65Tatuya JINMEI 神明達哉 fatal("iterating through the database failed: %s",
78ff0e94eae96f2cf8bf94454d8ff01ba280d30dMark Andrews result = dns_nsec_build(gdb, gversion, node, nextname,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉addnsec3param(const unsigned char *salt, size_t salt_length,
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.common.rdtype = dns_rdatatype_nsec3param;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf));
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 check_result(result, "dns_rdatalist_tordataset()");
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 check_result(result, "dns_db_find(gorigin)");
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews * Delete any current NSEC3PARAM records.
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_deleterdataset(gdb, node, gversion,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 check_result(result, "dddnsec3param: dns_db_deleterdataset()");
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews check_result(result, "addnsec3param: dns_db_addrdataset()");
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉addnsec3(dns_name_t *name, dns_dbnode_t *node,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 const unsigned char *salt, size_t salt_length,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned int iterations, hashlist_t *hashlist,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 const unsigned char *nexthash;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE];
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_name_format(name, namebuf, sizeof(namebuf));
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_nsec3_hashname(&hashname, hash, &hash_length,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 name, gorigin, dns_hash_sha1, iterations,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 check_result(result, "addnsec3: dns_nsec3_hashname()");
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 nexthash = hashlist_findnext(hashlist, hash);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_nsec3_buildrdata(gdb, gversion, node,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 check_result(result, "addnsec3: dns_nsec3_buildrdata()");
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews check_result(result, "dns_rdatalist_tordataset()");
2e3203a08c2b8f305bac3519ea7cd9873b7fcd5aMark Andrews result = dns_db_findnsec3node(gdb, dns_fixedname_name(&hashname),
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews check_result(result, "addnsec3: dns_db_findnode()");
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset,
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews check_result(result, "addnsec3: dns_db_addrdataset()");
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list.
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * Extract the hash from the first label of 'name' then see if it
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * is in hashlist. If 'name' is not in the hashlist then delete the
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * any NSEC3 records which have the same parameters as the chain we
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * are building.
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * XXXMPA Should we also check that it of the form <hash>.<origin>?
f252f91e2725f2b505d12da6c049896e1de74112Andreas Gustafssonnsec3clean(dns_name_t *name, dns_dbnode_t *node,
f252f91e2725f2b505d12da6c049896e1de74112Andreas Gustafsson unsigned int hashalg, unsigned int iterations,
26bc09bc89c2a96f36147be4e664c552efe78fa2Andreas Gustafsson const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
26bc09bc89c2a96f36147be4e664c552efe78fa2Andreas Gustafsson unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein * Get the first label.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * We want just the label contents.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Decode base32hex string.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_buffer_init(&target, hash, sizeof(hash) - 1);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = isc_base32hex_decoderegion(&label, &target);
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews * Verify that the NSEC3 parameters match the current ones
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews * otherwise we are dealing with a different NSEC3 chain.
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3,
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson * Delete any NSEC3 records which are not part of the current
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson * NSEC3 chain.
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson for (result = dns_rdataset_first(&rdataset);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson check_result(result, "dns_rdata_tostruct");
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson ISC_LIST_APPEND(rdatalist.rdata, &delrdata, link);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_rdatalist_tordataset(&rdatalist, &delrdataset);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson check_result(result, "dns_rdatalist_tordataset()");
35ae209f35b5df8515ad4ef1578c8f8b1922a3d5Brian Wellington result = dns_db_subtractrdataset(gdb, node, gversion,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein check_result(result, "dns_db_subtractrdataset(NSEC3)");
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson check_result(result, "dns_rdataset_first/next");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Delete the NSEC3 RRSIGs
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_deleterdataset(gdb, node, gversion,
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Generate NSEC3 records for the zone.
45fca822d565a2c600b04330a1dd25a9db7e2974Andreas Gustafssonnsec3ify(unsigned int hashalg, unsigned int iterations,
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
60084a1a5a9e570842b8147ff4c34b68ce4de7f8Andreas Gustafsson dns_dbnode_t *node = NULL, *nextnode = NULL;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Walk the zone generating the hash names.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein check_result(result, "dns_db_createiterator()");
23dd0aa5d54bd459dbb5e73f1213fb103114945cAndreas Gustafsson check_result(result, "dns_dbiterator_first()");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * Delete any NSEC records at the apex.
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews "to update to NSEC3.");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews "dns_db_deleterdataset(nsec3param/rrsig)");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews fatal("iterating through the database failed: %s",
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence hashlist_add_dns_name(hashlist, name, hashalg, iterations,
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley * Add hashs for empty nodes. Use closest encloser logic.
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley * The closest encloser either has data or is a empty
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley * node for another <name,nextname> span so we don't add
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington * it here. Empty labels on nextname are within the span.
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff dns_name_fullcompare(name, nextname, &order, &nlabels);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews addnowildcardhash(hashlist, name, hashalg, iterations,
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff hashlist_add_dns_name(hashlist, nextname, hashalg,
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley * We have all the hashes now so we can sort them.
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley * Check for duplicate hashes. If found the salt needs to
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * be changed.
2180f41c907e013715cbc54c64545b26fc3c0dbaMichael Graff fatal("Duplicate hash detected. Pick a different salt.");
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Generate the nsec3 records.
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson addnsec3param(salt, salt_length, iterations);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Clean out NSEC3 records which don't match this chain.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews check_result(result, "dns_db_createiterator()");
b2f85baf7905bad89781f8ef73003d4cfa955257Michael Graff result = dns_dbiterator_current(dbiter, &node, name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews nsec3clean(name, node, hashalg, iterations, salt, salt_length,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Generate / complete the new chain.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_result(result, "dns_db_createiterator()");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_result(result, "dns_dbiterator_first()");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("iterating through the database failed: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * We need to pause here to release the lock on the database.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews addnsec3(name, node, salt, salt_length, iterations,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Add NSEC3's for empty nodes. Use closest encloser logic.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_fullcompare(name, nextname, &order, &nlabels);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_split(nextname, count, NULL, nextname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Load the zone file from disk
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsloadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("failed converting name '%s' to dns format: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Finds all public zone keys in the zone, and attempts to load the
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * private keys from disk.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsloadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews /* Make note of the keys which signed the SOA, if any */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_db_findrdataset(gdb, node, currentversion,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /* Preserve the TTL of the DNSKEY RRset, if any */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_findrdataset(gdb, node, currentversion,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein fprintf(stderr, "User-specified TTL (%d) conflicts "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "with existing DNSKEY RRset TTL.\n",
9fbc1afb8b08432e3a1adda1f41d5575620e9785Bob Halley fprintf(stderr, "Imported keys will use the RRSet "
694c897b20f06f8a5349fd9ac5df93947f6f5a2aBob Halley "TTL (%d) instead.\n",
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley /* Load keys corresponding to the existing DNSKEY RRset */
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews dns_db_closeversion(gdb, ¤tversion, ISC_FALSE);
c68fa795a1c87fd5d0386e0503dc5666490ac77fMichael Graffloadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley for (i = 0; i < n; i++) {
34729dbcb3526974cf98ee03ec20a107d9458417Andreas Gustafsson result = dst_key_fromnamedfile(keyfiles[i], directory,
fa67ca21f6d5033221d9893b3c38a7bf8fecdb18Mark Andrews fatal("cannot load dnskey %s: %s", keyfiles[i],
12ccbb032ec1b5f6b93aac923f2645a19fc90c75David Lawrence if (!dns_name_equal(gorigin, dst_key_name(newkey)))
44aae046c38e796e581110b7ecdf4478167d684dBob Halley fatal("cannot sign zone with non-private dnskey %s",
44aae046c38e796e581110b7ecdf4478167d684dBob Halley /* Skip any duplicates */
65c4736d9c0ebc6d9b1d991593b55566909da9cdBrian Wellington if (dst_key_id(key->key) == dst_key_id(newkey) &&
39469093ea30f42ee3fcc6c457688cf8577432c6Brian Wellington /* We haven't seen this key before */
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews * Find keys that match this zone in the key repository.
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews result = dns_dnssec_findmatchingkeys(gorigin, directory,
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews check_result(result, "dns_dnssec_findmatchingkeys");
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence * Update keylist with information from from the key repository.
NULL);
if (disable_zone_check)
program);
&orig_saltlen);
goto cleanup;
} else if (!set_salt) {
} else if (!set_iter)
goto cleanup;
goto cleanup;
} else if (!set_optout)
char *filename;
isc_buffer_t b;
isc_region_t r;
unsigned int filenamelen;
filename[0] = 0;
unsigned int labels;
isc_buffer_usedregion(&b, &r);
ISC_PLATFORM_NORETURN_PRE static void
usage(void) {
#ifdef USE_PKCS11
exit(0);
removetempfile(void) {
if (removefile)
if (runtime_us > 0) {
int i, ch;
int ndskeys = 0;
char *endp;
#ifdef USE_PKCS11
unsigned int eflags;
int tempfilelen;
isc_buffer_t b;
int len;
#define CMDLINE_FLAGS \
switch (ch) {
switch (ch) {
char *sarg;
sizeof(saltbuf));
usage();
NULL);
usage();
if (!pseudorandom)
if (ntasks == 0)
usage();
get_soa_ttls();
if (!set_keyttl)
if (IS_NSEC3) {
if (answer)
if (smartsign)
if (keycount == 0) {
if (disable_zone_check)
if (IS_NSEC3) {
unsigned int max;
switch (serialformat) {
case SOA_SERIAL_INCREMENT:
setsoaserial(0);
case SOA_SERIAL_UNIXTIME:
case SOA_SERIAL_KEEP:
if (IS_NSEC3)
&hashlist);
nsecify();
if (!nokeys) {
if (make_keyset)
for (i = 0; i < (int)ntasks; i++) {
if (printstats)
presign();
signapex();
if (!finished) {
for (i = 0; i < (int)ntasks; i++) {
tasks[i]);
(void)isc_app_run();
if (!finished)
for (i = 0; i < (int)ntasks; i++)
postsign();
verifyzone();
fp);
if (printstats)
if (free_output)
(void) isc_app_finish();
if (printstats) {