dnssec-signzone.c revision 2162c1ed3dbf02459e753f7f407bc6dfc24b0bee
f36c85c3cee0b7022d6a99077fab2e5afc4e357dMark Andrews/*
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Portions Copyright (C) 1999-2003 Internet Software Consortium.
7c74e180c206e6ed99e8beb820da5f399d845c3eDavid Lawrence *
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 *
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.
866d106459313499d0ca7bfccb4b2d23d5e4377cDavid Lawrence *
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
866d106459313499d0ca7bfccb4b2d23d5e4377cDavid Lawrence *
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.
ea31416b4fcdf23732355a8002f93f29e3b3d2dbAndreas Gustafsson *
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.
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley */
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff/* $Id: dnssec-signzone.c,v 1.252 2009/11/03 01:31:17 marka Exp $ */
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff
a903095bf4512dae561c7f6fc7854a51bebf334aMark Andrews/*! \file */
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff#include <config.h>
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff#include <stdlib.h>
3d776d762914d1b675b4fd49728ce353ccf6f77eBrian Wellington#include <time.h>
ccdac53c027e8964753b36c4d8c7b0e98af501c2Michael Graff
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/app.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/base32.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/commandline.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/entropy.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/event.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/file.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/hash.h>
75a4dd0d377dca2f85cea44e28bf110314c1fe8cDavid Lawrence#include <isc/hex.h>
75a4dd0d377dca2f85cea44e28bf110314c1fe8cDavid Lawrence#include <isc/mem.h>
75a4dd0d377dca2f85cea44e28bf110314c1fe8cDavid Lawrence#include <isc/mutex.h>
75a4dd0d377dca2f85cea44e28bf110314c1fe8cDavid Lawrence#include <isc/os.h>
75a4dd0d377dca2f85cea44e28bf110314c1fe8cDavid Lawrence#include <isc/print.h>
91306d962f9d147d94b82fb14edb28f8d907cae7Andreas Gustafsson#include <isc/random.h>
91306d962f9d147d94b82fb14edb28f8d907cae7Andreas Gustafsson#include <isc/rwlock.h>
91306d962f9d147d94b82fb14edb28f8d907cae7Andreas Gustafsson#include <isc/serial.h>
91306d962f9d147d94b82fb14edb28f8d907cae7Andreas Gustafsson#include <isc/stdio.h>
91306d962f9d147d94b82fb14edb28f8d907cae7Andreas Gustafsson#include <isc/stdlib.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <isc/string.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <isc/task.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <isc/time.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <isc/util.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <dns/db.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <dns/dbiterator.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <dns/diff.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <dns/dnssec.h>
e893dce91279d7313a579f72caae3941f6dc5a27David Lawrence#include <dns/ds.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/fixedname.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/keyvalues.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/log.h>
8e06cea14c857429ab7e7299af2dce5eeeaa5ff0Michael Graff#include <dns/master.h>
ce8c568e0d6106bb87069453505e09bc66754b40Andreas Gustafsson#include <dns/masterdump.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/nsec.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/nsec3.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdata.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdatalist.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdataset.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdataclass.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdatasetiter.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdatastruct.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/rdatatype.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/result.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/soa.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley#include <dns/time.h>
3b77946b751f39bd4db5a7d1fe48a81e6b1e7a28Bob Halley
8e06cea14c857429ab7e7299af2dce5eeeaa5ff0Michael Graff#include <dst/dst.h>
8e06cea14c857429ab7e7299af2dce5eeeaa5ff0Michael Graff
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson#include "dnssectool.h"
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson#ifndef PATH_MAX
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson#define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson#endif
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrenceconst char *program = "dnssec-signzone";
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrenceint verbose;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
b587e1d83f007ce68a9ae93097c461d8eb7aa373Mark Andrewstypedef struct hashlist hashlist_t;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic int nsec_datatype = dns_rdatatype_nsec;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define BUFSIZE 2048
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define MAXDSKEYS 8
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
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)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence#define SOA_SERIAL_KEEP 0
ae4cbb69eef32ced103fe4561e8d2031ee4c3497David Lawrence#define SOA_SERIAL_INCREMENT 1
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#define SOA_SERIAL_UNIXTIME 2
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewstypedef struct signer_event sevent_t;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstruct signer_event {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews ISC_EVENT_COMMON(sevent_t);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_t *fname;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbnode_t *node;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews};
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_dnsseckeylist_t keylist;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic unsigned int keycount = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsisc_rwlock_t keylist_lock;
ae4cbb69eef32ced103fe4561e8d2031ee4c3497David Lawrencestatic isc_stdtime_t starttime = 0, endtime = 0, now;
ae4cbb69eef32ced103fe4561e8d2031ee4c3497David Lawrencestatic int cycle = -1;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic int jitter = 0;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t tryverify = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t printstats = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_mem_t *mctx = NULL;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_entropy_t *ectx = NULL;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic dns_ttl_t zone_soa_min_ttl;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic dns_ttl_t soa_ttl;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic FILE *fp;
0293ad13207aa29bd5844cdc87d085ffc009d749David Lawrencestatic char *tempfile = NULL;
0293ad13207aa29bd5844cdc87d085ffc009d749David Lawrencestatic const dns_master_style_t *masterstyle;
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 isc_mutex_t namelock, statslock;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_taskmgr_t *taskmgr = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_db_t *gdb; /* The database */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_dbversion_t *gversion; /* The database version */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_dbiterator_t *gdbiter; /* The database iterator */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_rdataclass_t gclass; /* The class */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_name_t *gorigin; /* The database origin */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic int nsec3flags = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_iterations_t nsec3iter = 10U;
0293ad13207aa29bd5844cdc87d085ffc009d749David Lawrencestatic unsigned char saltbuf[255];
0293ad13207aa29bd5844cdc87d085ffc009d749David Lawrencestatic unsigned char *salt = saltbuf;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic size_t salt_length = 0;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_task_t *master = NULL;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic unsigned int ntasks = 0;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t nokeys = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t removefile = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t generateds = ISC_FALSE;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrencestatic isc_boolean_t ignore_kskflag = ISC_FALSE;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic isc_boolean_t keyset_kskonly = ISC_FALSE;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic dns_name_t *dlv = NULL;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic dns_fixedname_t dlv_fixed;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic dns_master_style_t *dsstyle = NULL;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graffstatic unsigned int serialformat = SOA_SERIAL_KEEP;
1ce985ab3c6670662d555c108b35fed84a6a1001David Lawrencestatic unsigned int hash_length = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_boolean_t unknownalg = ISC_FALSE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_boolean_t disable_zone_check = ISC_FALSE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_boolean_t update_chain = ISC_FALSE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic isc_boolean_t set_keyttl = ISC_FALSE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic dns_ttl_t keyttl;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence#define INCSTAT(counter) \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence if (printstats) { \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence LOCK(&statslock); \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence counter++; \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence UNLOCK(&statslock); \
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence }
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrencestatic void
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrencesign(isc_task_t *task, isc_event_t *event);
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrence
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 Lawrence
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrencestatic void
4bcaefbcd3ced942139fdc830e007c6ea2b8d2feDavid Lawrencedumpnode(dns_name_t *name, dns_dbnode_t *node) {
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff isc_result_t result;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff if (outputformat != dns_masterformat_text)
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff return;
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name,
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff masterstyle, fp);
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff check_result(result, "dns_master_dumpnodetostream");
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff}
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff
657ce0b9d84fbd66514df53d61a087e8f1161187Michael Graff/*%
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * Sign the given RRset with given key, and add the signature record to the
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson * given tuple.
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews */
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrewsstatic void
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)
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews{
80badf38c74c326a694e24281ee258aa26984171Mark Andrews isc_result_t result;
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews isc_stdtime_t jendtime;
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews char keystr[DST_KEY_FORMATSIZE];
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews dns_rdata_t trdata = DNS_RDATA_INIT;
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews unsigned char array[BUFSIZE];
641da3ca1184d9951d5cf91538524a345bf5f271Mark Andrews isc_buffer_t b;
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews dns_difftuple_t *tuple;
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews dst_key_format(key, keystr, sizeof(keystr));
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews vbprintf(1, "\t%s %s\n", logmsg, keystr);
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews isc_buffer_init(&b, array, sizeof(array));
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime,
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews mctx, &b, &trdata);
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews isc_entropy_stopcallbacksources(ectx);
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews if (result != ISC_R_SUCCESS) {
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews char keystr[DST_KEY_FORMATSIZE];
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews dst_key_format(key, keystr, sizeof(keystr));
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews fatal("dnskey '%s' failed to sign data: %s",
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews keystr, isc_result_totext(result));
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews }
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews INCSTAT(nsigned);
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews if (tryverify) {
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews result = dns_dnssec_verify(name, rdataset, key,
774c3a62d9adca187b44fe90919bb409a43a2f2aMark Andrews ISC_TRUE, mctx, &trdata);
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews if (result == ISC_R_SUCCESS) {
9fe28a624c659e380d47dbf45527637dab03b998Mark Andrews vbprintf(3, "\tsignature verified\n");
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson INCSTAT(nverified);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson } else {
39b973d8873996c3bfb6e5b4cc69731f6c3b77b5Mark Andrews vbprintf(3, "\tsignature failed to verify\n");
6342df69b05f2f62d060fd4affdf536e51504084Mark Andrews INCSTAT(nverifyfailed);
6342df69b05f2f62d060fd4affdf536e51504084Mark Andrews }
6342df69b05f2f62d060fd4affdf536e51504084Mark Andrews }
6342df69b05f2f62d060fd4affdf536e51504084Mark Andrews
6342df69b05f2f62d060fd4affdf536e51504084Mark Andrews tuple = NULL;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &trdata,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson &tuple);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson check_result(result, "dns_difftuple_create");
c654449ccf403ccd2b81be2038b1013d6fbb06ccMark Andrews dns_diff_append(add, &tuple);
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson}
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafssonstatic inline isc_boolean_t
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafssonissigningkey(dns_dnsseckey_t *key) {
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson return (key->force_sign || key->hint_sign);
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson}
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellingtonstatic inline isc_boolean_t
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellingtoniszonekey(dns_dnsseckey_t *key) {
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington dst_key_iszonekey(key->key)));
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington}
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellingtonstatic inline isc_boolean_t
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellingtonisksk(dns_dnsseckey_t *key) {
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington return (key->ksk);
47fd46791da765e3dbedd987e9b263b3bee25986Brian Wellington}
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafssonstatic inline isc_boolean_t
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsiszsk(dns_dnsseckey_t *key) {
6fcb2f0faad67a6d2cb2e30ec57157d75fbfe58fAndreas Gustafsson return (ignore_kskflag || !key->ksk);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson}
8f3dd8f8e73e4465221a5297819db70e6b383138Mark Andrews
6e9efadbea9febb0494e713e54dfea6f7ef70383Mark Andrews/*%
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 *
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews * No locking is performed here, this must be done by the caller.
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews */
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrewsstatic dns_dnsseckey_t *
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrewskeythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews dns_dnsseckey_t *key;
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews for (key = ISC_LIST_HEAD(keylist);
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews key != NULL;
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews key = ISC_LIST_NEXT(key, link)) {
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews if (rrsig->keyid == dst_key_id(key->key) &&
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews rrsig->algorithm == dst_key_alg(key->key) &&
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews return (key);
43fe2897fc80bbec2115310ca79d432a252f3ea4Mark Andrews }
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson return (NULL);
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews}
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews/*%
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.
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrews */
754cca729dd82ae8363917dc00ad44f9d900635bMark Andrewsstatic dns_dnsseckey_t *
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafssonkeythatsigned(dns_rdata_rrsig_t *rrsig) {
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_result_t result;
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews dst_key_t *pubkey = NULL, *privkey = NULL;
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews dns_dnsseckey_t *key = NULL;
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews key = keythatsigned_unlocked(rrsig);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews if (key != NULL)
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews return (key);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews /*
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 */
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews key = keythatsigned_unlocked(rrsig);
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews if (key != NULL) {
40dd9cb8cc240c33d820fe79f176ed51e4c06a1aMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson return (key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson }
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson rrsig->algorithm, DST_TYPE_PUBLIC,
963c48ba4d06a112c70d50328e827749e95f58dbMark Andrews directory, mctx, &pubkey);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson if (result != ISC_R_SUCCESS) {
963c48ba4d06a112c70d50328e827749e95f58dbMark Andrews isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson return (NULL);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson }
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson rrsig->algorithm,
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
a1898260ad19d02e88ab76c1855d33c67add9defMark Andrews directory, mctx, &privkey);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson if (result == ISC_R_SUCCESS) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dst_key_free(&pubkey);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson dns_dnsseckey_create(mctx, &privkey, &key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson } else {
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson dns_dnsseckey_create(mctx, &pubkey, &key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson }
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson key->force_publish = ISC_TRUE;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson key->force_sign = ISC_FALSE;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson ISC_LIST_APPEND(keylist, key, link);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
a1898260ad19d02e88ab76c1855d33c67add9defMark Andrews return (key);
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson/*%
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 */
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafssonstatic isc_boolean_t
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafssonexpecttofindkey(dns_name_t *name) {
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson unsigned int options = DNS_DBFIND_NOWILD;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson dns_fixedname_t fname;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson isc_result_t result;
5ff133b82082d82f0ba89b7c999c6b62b6298e46Andreas Gustafsson char namestr[DNS_NAME_FORMATSIZE];
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff dns_fixedname_init(&fname);
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options,
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff 0, NULL, dns_fixedname_name(&fname), NULL, NULL);
90407942d3afe50f04ccea361de3b164a5a1702dMichael Graff switch (result) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ISC_R_SUCCESS:
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff case DNS_R_NXDOMAIN:
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff case DNS_R_NXRRSET:
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff return (ISC_TRUE);
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews case DNS_R_DELEGATION:
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson case DNS_R_CNAME:
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff case DNS_R_DNAME:
61d5bfc06be978ea962b1c64309894ac80351771Mark Andrews return (ISC_FALSE);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
3d8dfd44a3be708f00380064411c16b2fa28303aMark Andrews dns_name_format(name, namestr, sizeof(namestr));
13faa8b6a2d0d45e0659049983928366252ab3faMichael Graff fatal("failure looking for '%s DNSKEY' in database: %s",
4cf228853d658a742a826393f341e2486c629f7bMark Andrews namestr, isc_result_totext(result));
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews /* NOTREACHED */
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews return (ISC_FALSE); /* removes a warning */
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews}
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrewsstatic inline isc_boolean_t
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrewssetverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews dns_rdata_t *rrsig)
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews{
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews isc_result_t result;
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews if (result == ISC_R_SUCCESS) {
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington INCSTAT(nverified);
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington return (ISC_TRUE);
3fcf6b956f47405750724bd84e1b2290b61c9186Brian Wellington } else {
3fcf6b956f47405750724bd84e1b2290b61c9186Brian Wellington INCSTAT(nverifyfailed);
3fcf6b956f47405750724bd84e1b2290b61c9186Brian Wellington return (ISC_FALSE);
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington }
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews}
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews/*%
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.
a53259c4cc558f86dd008eccc60cc89b6734a03cMark Andrews */
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafssonstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewssignset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdataset_t *set)
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson{
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdataset_t sigset;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdata_t sigrdata = DNS_RDATA_INIT;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdata_rrsig_t rrsig;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_dnsseckey_t *key;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson isc_result_t result;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson isc_boolean_t nosigs = ISC_FALSE;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson isc_boolean_t *wassignedby, *nowsignedby;
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson int arraysize;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_difftuple_t *tuple;
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson dns_ttl_t ttl;
80f323528ac699026a609a5e3b765dc6e88fe37cAndreas Gustafsson int i;
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson char namestr[DNS_NAME_FORMATSIZE];
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson char typestr[TYPE_FORMATSIZE];
3fcf6b956f47405750724bd84e1b2290b61c9186Brian Wellington char sigstr[SIG_FORMATSIZE];
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews dns_name_format(name, namestr, sizeof(namestr));
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews type_format(set->type, typestr, sizeof(typestr));
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews ttl = ISC_MIN(set->ttl, endtime - starttime);
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews dns_rdataset_init(&sigset);
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig,
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews set->type, 0, &sigset, NULL);
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews if (result == ISC_R_NOTFOUND) {
f8f65e2de40b1e9874b88f392f3abeb057ce6172Mark Andrews result = ISC_R_SUCCESS;
f8f65e2de40b1e9874b88f392f3abeb057ce6172Mark Andrews nosigs = ISC_TRUE;
f8f65e2de40b1e9874b88f392f3abeb057ce6172Mark Andrews }
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews if (result != ISC_R_SUCCESS)
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews fatal("failed while looking for '%s RRSIG %s': %s",
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews namestr, typestr, isc_result_totext(result));
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews
c5826852e6c789f59b301f8197e65a1dd4e09a44Mark Andrews vbprintf(1, "%s/%s:\n", namestr, typestr);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson arraysize = keycount;
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson if (!nosigs)
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 fatal("out of memory");
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson for (i = 0; i < arraysize; i++)
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson wassignedby[i] = nowsignedby[i] = ISC_FALSE;
d906600f7d1e86a4315e65a500f806ca1e4caa9bAndreas Gustafsson
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson if (nosigs)
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson result = ISC_R_NOMORE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews else
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson result = dns_rdataset_first(&sigset);
2995f8205eaa0d4bc3a57900a413b5cfdb83564fAndreas Gustafsson
2995f8205eaa0d4bc3a57900a413b5cfdb83564fAndreas Gustafsson while (result == ISC_R_SUCCESS) {
2995f8205eaa0d4bc3a57900a413b5cfdb83564fAndreas Gustafsson isc_boolean_t expired, future;
2995f8205eaa0d4bc3a57900a413b5cfdb83564fAndreas Gustafsson isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE;
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews dns_rdataset_current(&sigset, &sigrdata);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews check_result(result, "dns_rdata_tostruct");
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews future = isc_serial_lt(now, rrsig.timesigned);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews key = keythatsigned(&rrsig);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews sig_format(&rrsig, sigstr, sizeof(sigstr));
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews if (key != NULL && issigningkey(key))
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews expired = isc_serial_gt(now + cycle, rrsig.timeexpire);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews else
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews expired = isc_serial_gt(now, rrsig.timeexpire);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) {
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews /* rrsig is dropped and not replaced */
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews vbprintf(2, "\trrsig by %s dropped - "
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews "invalid validity period\n",
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews sigstr);
d73de275987d29627dc11d5bd4a22874a29f7874Mark Andrews } else if (key == NULL && !future &&
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews expecttofindkey(&rrsig.signer)) {
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews /* rrsig is dropped and not replaced */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews vbprintf(2, "\trrsig by %s dropped - "
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews "private dnskey not found\n",
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews sigstr);
bc53aacc6e9302b1f8d01467fc39585584652782Andreas Gustafsson } else if (key == NULL || future) {
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
919caa020b8f9b856d77b3a72e0c9301dfa495c7Andreas Gustafsson expired ? "retained" : "dropped", sigstr);
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson if (!expired)
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson keep = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else if (issigningkey(key)) {
6805e4e2c46ad3c5a4aa941b5e9a29d34579641eMark Andrews if (!expired && setverifies(name, set, key->key,
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews &sigrdata)) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews vbprintf(2, "\trrsig by %s retained\n", sigstr);
bd1db480f30e025bba719799f910b34848a9a997Mark Andrews keep = ISC_TRUE;
bd1db480f30e025bba719799f910b34848a9a997Mark Andrews wassignedby[key->index] = ISC_TRUE;
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews nowsignedby[key->index] = ISC_TRUE;
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews } else {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews vbprintf(2, "\trrsig by %s dropped - %s\n",
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson sigstr,
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews expired ? "expired" :
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "failed to verify");
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson wassignedby[key->index] = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews resign = ISC_TRUE;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews }
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews } else if (iszonekey(key)) {
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews if (!expired && setverifies(name, set, key->key,
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews &sigrdata)) {
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews vbprintf(2, "\trrsig by %s retained\n", sigstr);
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews keep = ISC_TRUE;
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews wassignedby[key->index] = ISC_TRUE;
fda0a038810529d6e45b17822ddcc61d82964e83Mark Andrews nowsignedby[key->index] = ISC_TRUE;
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews } else {
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews vbprintf(2, "\trrsig by %s dropped - %s\n",
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews sigstr,
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews expired ? "expired" :
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews "failed to verify");
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews wassignedby[key->index] = ISC_TRUE;
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews }
c0707105f60934d59321c2fccbc254f9e31ff28aMark Andrews } else if (!expired) {
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson vbprintf(2, "\trrsig by %s retained\n", sigstr);
5989aea4bbe79e09290792f04aeb557e2b2da02eAndreas Gustafsson keep = ISC_TRUE;
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington } else {
5f9e583552f53de12062bfff12e47250abce378fBrian Wellington vbprintf(2, "\trrsig by %s expired\n", sigstr);
08a768e82ad64ede97f640c88e02984b59122753Michael Graff }
08a768e82ad64ede97f640c88e02984b59122753Michael Graff
08a768e82ad64ede97f640c88e02984b59122753Michael Graff if (keep) {
08a768e82ad64ede97f640c88e02984b59122753Michael Graff nowsignedby[key->index] = ISC_TRUE;
08a768e82ad64ede97f640c88e02984b59122753Michael Graff INCSTAT(nretained);
08a768e82ad64ede97f640c88e02984b59122753Michael Graff if (sigset.ttl != ttl) {
3fcf6b956f47405750724bd84e1b2290b61c9186Brian Wellington vbprintf(2, "\tfixing ttl %s\n", sigstr);
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington tuple = NULL;
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington result = dns_difftuple_create(mctx,
08a768e82ad64ede97f640c88e02984b59122753Michael Graff DNS_DIFFOP_DEL,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name, sigset.ttl,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews &sigrdata,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews &tuple);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_difftuple_create");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_diff_append(del, &tuple);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_difftuple_create(mctx,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews DNS_DIFFOP_ADD,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name, ttl,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews &sigrdata,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews &tuple);
65cfc4e0e3e24a7410d6fe8505455fc85f62215cMark Andrews check_result(result, "dns_difftuple_create");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_diff_append(add, &tuple);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews tuple = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name, sigset.ttl,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews &sigrdata, &tuple);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_difftuple_create");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_diff_append(del, &tuple);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews INCSTAT(ndropped);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (resign) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews INSIST(!keep);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews signwithkey(name, set, key->key, ttl, add,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "resigning with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews nowsignedby[key->index] = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdata_reset(&sigrdata);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdata_freestruct(&rrsig);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_rdataset_next(&sigset);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result == ISC_R_NOMORE)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = ISC_R_SUCCESS;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_rdataset_first/next");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (dns_rdataset_isassociated(&sigset))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_disassociate(&sigset);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews for (key = ISC_LIST_HEAD(keylist);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews key != NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews key = ISC_LIST_NEXT(key, link))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (nowsignedby[key->index])
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews continue;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (!issigningkey(key))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews continue;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (set->type == dns_rdatatype_dnskey &&
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_equal(name, gorigin)) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t have_ksk;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dnsseckey_t *tmpkey;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews have_ksk = isksk(key);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews for (tmpkey = ISC_LIST_HEAD(keylist);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews tmpkey != NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (dst_key_alg(key->key) !=
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dst_key_alg(tmpkey->key))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews continue;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (REVOKE(tmpkey->key))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews continue;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (isksk(tmpkey))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews have_ksk = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (isksk(key) || !have_ksk ||
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews (iszsk(key) && !keyset_kskonly))
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews signwithkey(name, set, key->key, ttl, add,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "signing with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else if (iszsk(key)) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews signwithkey(name, set, key->key, ttl, add,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews "signing with dnskey");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
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}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstruct hashlist {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char *hashbuf;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews size_t entries;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews size_t size;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews size_t length;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews};
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->entries = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->length = length + 1;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (nodes != 0) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->size = nodes;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->hashbuf = malloc(l->size * l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (l->hashbuf == NULL)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->size = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->size = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->hashbuf = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_add(hashlist_t *l, const unsigned char *hash, size_t len)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews{
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews REQUIRE(len <= l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (l->entries == l->size) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->size = l->size * 2 + 100;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->hashbuf = realloc(l->hashbuf, l->size * l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews memset(l->hashbuf + l->entries * l->length, 0, l->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews memcpy(l->hashbuf + l->entries * l->length, hash, len);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews l->entries++;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned int hashalg, unsigned int iterations,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews const unsigned char *salt, size_t salt_length,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t speculative)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews{
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews char nametext[DNS_NAME_FORMATSIZE];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned int len;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews size_t i;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews len = isc_iterated_hash(hash, hashalg, iterations, salt, salt_length,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name->ndata, name->length);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (verbose) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_format(name, nametext, sizeof nametext);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews for (i = 0 ; i < len; i++)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fprintf(stderr, "%02x", hash[i]);
3ec6b563d7b6cb11a047f23faa2a0f206ccd93e7Brian Wellington fprintf(stderr, " %s\n", nametext);
3ec6b563d7b6cb11a047f23faa2a0f206ccd93e7Brian Wellington }
3ec6b563d7b6cb11a047f23faa2a0f206ccd93e7Brian Wellington hash[len++] = speculative ? 1 : 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews hashlist_add(l, hash, len);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellingtonstatic int
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellingtonhashlist_comp(const void *a, const void *b) {
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington return (memcmp(a, b, hash_length + 1));
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington}
0e40083fdd5445703bd30e46e5bfe7d047bced12Brian Wellington
3ec6b563d7b6cb11a047f23faa2a0f206ccd93e7Brian Wellingtonstatic void
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellingtonhashlist_sort(hashlist_t *l) {
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington qsort(l->hashbuf, l->entries, l->length, hashlist_comp);
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington}
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellingtonstatic isc_boolean_t
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellingtonhashlist_hasdup(hashlist_t *l) {
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington unsigned char *current;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington unsigned char *next = l->hashbuf;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington size_t entries = l->entries;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington /*
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * Skip initial speculative wild card hashs.
d0fbcfeee1c1dbdb079231545de3a0c58248202fMark Andrews */
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington while (entries > 0U && next[l->length-1] != 0U) {
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington next += l->length;
af5ad488cbf17988fbd36a25c908737412ccd382Brian Wellington entries--;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington }
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington
b495fd2992c63472b3ad2d9517ffe9b50118840aAndreas Gustafsson current = next;
af5ad488cbf17988fbd36a25c908737412ccd382Brian Wellington while (entries-- > 1U) {
f317c00e0d5978f29285ea062b34ec73dc419095Brian Wellington next += l->length;
f317c00e0d5978f29285ea062b34ec73dc419095Brian Wellington if (next[l->length-1] != 0)
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington continue;
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington if (memcmp(current, next, l->length - 1) == 0)
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington return (ISC_TRUE);
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington current = next;
dee520f1be8c59e10a55b6995844395e811c310fBrian Wellington }
dee520f1be8c59e10a55b6995844395e811c310fBrian Wellington return (ISC_FALSE);
dee520f1be8c59e10a55b6995844395e811c310fBrian Wellington}
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington
529ff4b4959fb157194f985394951108ff5286e4Brian Wellingtonstatic const unsigned char *
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellingtonhashlist_findnext(const hashlist_t *l,
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington{
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington unsigned int entries = l->entries;
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews const unsigned char *next = bsearch(hash, l->hashbuf, l->entries,
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews l->length, hashlist_comp);
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews INSIST(next != NULL);
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews
5b76a09697bfc76f5acefd65d5b37b1214d271a8Mark Andrews do {
9738408dcbd4c1f7eb2b105c83388608fafd7808Mark Andrews if (next < l->hashbuf + (l->entries - 1) * l->length)
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson next += l->length;
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington else
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington next = l->hashbuf;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (next[l->length - 1] == 0)
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews break;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews } while (entries-- > 1);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews INSIST(entries != 0);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews return (next);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews}
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsstatic isc_boolean_t
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewshashlist_exists(const hashlist_t *l,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews{
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp))
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews return (ISC_TRUE);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews else
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews return (ISC_FALSE);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews}
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsstatic void
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsaddnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews unsigned int hashalg, unsigned int iterations,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews const unsigned char *salt, size_t salt_length)
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews{
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_fixedname_t fixed;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_name_t *wild;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_dbnode_t *node = NULL;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews isc_result_t result;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews char namestr[DNS_NAME_FORMATSIZE];
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_fixedname_init(&fixed);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews wild = dns_fixedname_name(&fixed);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews result = dns_name_concatenate(dns_wildcardname, name, wild, NULL);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (result == ISC_R_NOSPACE)
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews return;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews check_result(result,"addnowildcardhash: dns_name_concatenate()");
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews result = dns_db_findnode(gdb, wild, ISC_FALSE, &node);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (result == ISC_R_SUCCESS) {
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_db_detachnode(gdb, &node);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews return;
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews }
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews if (verbose) {
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_name_format(wild, namestr, sizeof(namestr));
2271edc0b4ba96e69a283eced420b94ffb678beeBrian Wellington fprintf(stderr, "adding no-wildcardhash for %s\n", namestr);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson }
2271edc0b4ba96e69a283eced420b94ffb678beeBrian Wellington
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_length,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews ISC_TRUE);
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews}
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsstatic void
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrewsopendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
be515937febf025ec2a4c381bee58131ab0f32f4Mark Andrews dns_db_t **dbp)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews{
7005cfed8cd3296d356883dcb414979f22e06b13Brian Wellington char filename[PATH_MAX];
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington isc_buffer_t b;
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington isc_result_t result;
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington
3184ff5e45c8f821e5165ea60d674bfb87faf5b8Mark Andrews isc_buffer_init(&b, filename, sizeof(filename));
3184ff5e45c8f821e5165ea60d674bfb87faf5b8Mark Andrews if (dsdir != NULL) {
3184ff5e45c8f821e5165ea60d674bfb87faf5b8Mark Andrews /* allow room for a trailing slash */
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (strlen(dsdir) >= isc_buffer_availablelength(&b))
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson fatal("path '%s' is too long", dsdir);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson isc_buffer_putstr(&b, dsdir);
9ceaa92a8ca8a0270ba296d44599e94d95033759Andreas Gustafsson if (dsdir[strlen(dsdir) - 1] != '/')
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson isc_buffer_putstr(&b, "/");
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson }
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (strlen(prefix) > isc_buffer_availablelength(&b))
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson fatal("path '%s' is too long", dsdir);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson isc_buffer_putstr(&b, prefix);
70e854766f5304f43e94212dc38ebaefe214148cMark Andrews result = dns_name_tofilenametext(name, ISC_FALSE, &b);
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews check_result(result, "dns_name_tofilenametext()");
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews if (isc_buffer_availablelength(&b) == 0) {
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews char namestr[DNS_NAME_FORMATSIZE];
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews dns_name_format(name, namestr, sizeof(namestr));
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews fatal("name '%s' is too long", namestr);
70e854766f5304f43e94212dc38ebaefe214148cMark Andrews }
70e854766f5304f43e94212dc38ebaefe214148cMark Andrews isc_buffer_putuint8(&b, 0);
70e854766f5304f43e94212dc38ebaefe214148cMark Andrews
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson rdclass, 0, NULL, dbp);
fa280ff02ad0c29616a0c3a22ef02cbb3f6db7efDavid Lawrence check_result(result, "dns_db_create()");
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
fa280ff02ad0c29616a0c3a22ef02cbb3f6db7efDavid Lawrence dns_db_detach(dbp);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson}
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson/*%
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 Gustafsson */
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafssonstatic isc_result_t
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafssonloadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_db_t *db = NULL;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_dbversion_t *ver = NULL;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_dbnode_t *node = NULL;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson isc_result_t result;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_rdataset_t keyset;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_rdata_t key, ds;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson unsigned char dsbuf[DNS_DS_BUFFERSIZE];
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_diff_t diff;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_difftuple_t *tuple = NULL;
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson opendb("dsset-", name, gclass, &db);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (db != NULL) {
3fafd7c0c42134ff2964b74a31500465a96dee90Andreas Gustafsson result = dns_db_findnode(db, name, ISC_FALSE, &node);
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews if (result == ISC_R_SUCCESS) {
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews dns_rdataset_init(dsset);
9ceaa92a8ca8a0270ba296d44599e94d95033759Andreas Gustafsson result = dns_db_findrdataset(db, node, NULL,
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_rdatatype_ds, 0, 0,
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dsset, NULL);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dns_db_detachnode(db, &node);
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson if (result == ISC_R_SUCCESS) {
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson vbprintf(2, "found DS records\n");
a1884b96ef53efc8b4e14be173aaee552ca0213aAndreas Gustafsson dsset->ttl = ttl;
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington dns_db_detach(&db);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence return (result);
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington }
620de5a4b1f23dc9b4ec30d30c0607ff389be0daBob Halley }
9ceaa92a8ca8a0270ba296d44599e94d95033759Andreas Gustafsson dns_db_detach(&db);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence }
620de5a4b1f23dc9b4ec30d30c0607ff389be0daBob Halley
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /* No DS records found; try again, looking for DNSKEY records */
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington opendb("keyset-", name, gclass, &db);
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington if (db == NULL) {
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington return (ISC_R_NOTFOUND);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews }
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_db_findnode(db, name, ISC_FALSE, &node);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (result != ISC_R_SUCCESS) {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_db_detach(&db);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews return (result);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews }
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_rdataset_init(&keyset);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews &keyset, NULL);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews if (result != ISC_R_SUCCESS) {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_db_detachnode(db, &node);
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews dns_db_detach(&db);
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews return (result);
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews }
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews vbprintf(2, "found DNSKEY records\n");
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews result = dns_db_newversion(db, &ver);
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews check_result(result, "dns_db_newversion");
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews dns_diff_init(mctx, &diff);
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews
b7945d73bc42499d50d5c4af6a525fe56e4dfacaMark Andrews for (result = dns_rdataset_first(&keyset);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result == ISC_R_SUCCESS;
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_rdataset_next(&keyset))
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews {
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_rdata_init(&key);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_rdata_init(&ds);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_rdataset_current(&keyset, &key);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dsbuf, &ds);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews check_result(result, "dns_ds_buildrdata");
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews ttl, &ds, &tuple);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews check_result(result, "dns_difftuple_create");
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_diff_append(&diff, &tuple);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dns_rdata_reset(&ds);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256,
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews dsbuf, &ds);
186e7f37c9fc985a7a7264cc8170e48a25bed434Mark Andrews check_result(result, "dns_ds_buildrdata");
23ac30603a7639bea1d331537634b079b046b122Mark Andrews
23ac30603a7639bea1d331537634b079b046b122Mark Andrews result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
23ac30603a7639bea1d331537634b079b046b122Mark Andrews ttl, &ds, &tuple);
23ac30603a7639bea1d331537634b079b046b122Mark Andrews check_result(result, "dns_difftuple_create");
23ac30603a7639bea1d331537634b079b046b122Mark Andrews dns_diff_append(&diff, &tuple);
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington }
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington
64b92523f9333ba053f4b2860335583be455b0b3Brian Wellington result = dns_diff_apply(&diff, db, ver);
64b92523f9333ba053f4b2860335583be455b0b3Brian Wellington check_result(result, "dns_diff_apply");
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington dns_diff_clear(&diff);
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington
64b92523f9333ba053f4b2860335583be455b0b3Brian Wellington dns_db_closeversion(db, &ver, ISC_TRUE);
3f123dcc2fe5d2cd08ca91b732741d86a4036906Brian Wellington
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0,
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dsset, NULL);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence check_result(result, "dns_db_findrdataset");
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_disassociate(&keyset);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_db_detachnode(db, &node);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_db_detach(&db);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence return (result);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence}
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencestatic isc_boolean_t
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencedelegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_t nsset;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence isc_result_t result;
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley if (dns_name_equal(name, gorigin))
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley return (ISC_FALSE);
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley dns_rdataset_init(&nsset);
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns,
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley 0, 0, &nsset, NULL);
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley if (dns_rdataset_isassociated(&nsset)) {
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley if (ttlp != NULL)
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley *ttlp = nsset.ttl;
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley dns_rdataset_disassociate(&nsset);
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley }
03f4c76f95f75e2b0d1206e784e35bed6041305cBob Halley
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence return (ISC_TF(result == ISC_R_SUCCESS));
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence}
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencestatic isc_boolean_t
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrencesecure(dns_name_t *name, dns_dbnode_t *node) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_t dsset;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence isc_result_t result;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews if (dns_name_equal(name, gorigin))
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews return (ISC_FALSE);
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews dns_rdataset_init(&dsset);
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds,
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews 0, 0, &dsset, NULL);
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews if (dns_rdataset_isassociated(&dsset))
15bda409010cbf2d3e43baf10f28bae5f7b1abefMark Andrews dns_rdataset_disassociate(&dsset);
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews return (ISC_TF(result == ISC_R_SUCCESS));
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews}
728156dfbdced7bc18b1f88227cced9d426a70e7Mark Andrews
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrews/*%
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrews * Signs all records at a name.
8af4e7aa4e2a6fe84bf4ebe09ca1d4ef1d8ab593Mark Andrews */
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrewsstatic void
3ea6d4dc33482a752553c59ed94bcecd23d254b0Mark Andrewssignname(dns_dbnode_t *node, dns_name_t *name) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence isc_result_t result;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_t rdataset;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdatasetiter_t *rdsiter;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence isc_boolean_t isdelegation = ISC_FALSE;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_diff_t del, add;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence char namestr[DNS_NAME_FORMATSIZE];
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_init(&rdataset);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_name_format(name, namestr, sizeof(namestr));
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews /*
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Determine if this is a delegation point.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence if (delegation(name, node, NULL))
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence isdelegation = ISC_TRUE;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /*
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence * Now iterate through the rdatasets.
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence */
16ee4fe11bad616a76c79e9f626a7e04a88ef4abMark Andrews dns_diff_init(mctx, &del);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_diff_init(mctx, &add);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence rdsiter = NULL;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
8af4e7aa4e2a6fe84bf4ebe09ca1d4ef1d8ab593Mark Andrews check_result(result, "dns_db_allrdatasets()");
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence result = dns_rdatasetiter_first(rdsiter);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence while (result == ISC_R_SUCCESS) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /* If this is a RRSIG set, skip it. */
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence if (rdataset.type == dns_rdatatype_rrsig)
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence goto skip;
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence /*
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.
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence */
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence if (isdelegation) {
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence if (rdataset.type != nsec_datatype &&
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence rdataset.type != dns_rdatatype_ds)
3fafd7c0c42134ff2964b74a31500465a96dee90Andreas Gustafsson goto skip;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews } else if (rdataset.type == dns_rdatatype_ds) {
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews char namebuf[DNS_NAME_FORMATSIZE];
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews dns_name_format(name, namebuf, sizeof(namebuf));
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence fatal("'%s': found DS RRset without NS RRset\n",
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence namebuf);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence }
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence signset(&del, &add, node, name, &rdataset);
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence skip:
9a2574531e3d2ced31072200b416467fdee0c29cDavid Lawrence dns_rdataset_disassociate(&rdataset);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence result = dns_rdatasetiter_next(rdsiter);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence }
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence if (result != ISC_R_NOMORE)
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley fatal("rdataset iteration for name '%s' failed: %s",
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley namestr, isc_result_totext(result));
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_rdatasetiter_destroy(&rdsiter);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence result = dns_diff_applysilently(&del, gdb, gversion);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence if (result != ISC_R_SUCCESS)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence fatal("failed to delete SIGs at node '%s': %s",
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence namestr, isc_result_totext(result));
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence result = dns_diff_applysilently(&add, gdb, gversion);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence if (result != ISC_R_SUCCESS)
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff fatal("failed to add SIGs at node '%s': %s",
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff namestr, isc_result_totext(result));
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff dns_diff_clear(&del);
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff dns_diff_clear(&add);
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff}
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graff
882350d11c90de9de6fc1cead25690c8114b0b95Michael Graffstatic inline isc_boolean_t
64ba6e4cc3a0ccf8c8c6349fa75b937ca9bad9a6Michael Graffactive_node(dns_dbnode_t *node) {
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdatasetiter_t *rdsiter = NULL;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdatasetiter_t *rdsiter2 = NULL;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob isc_boolean_t active = ISC_FALSE;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob isc_result_t result;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdataset_t rdataset;
547f79ea44f0a91442fd942b04c11c1958f75136Andreas Gustafsson dns_rdatatype_t type;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdatatype_t covers;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob isc_boolean_t found;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdataset_init(&rdataset);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob check_result(result, "dns_db_allrdatasets()");
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_rdatasetiter_first(rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob while (result == ISC_R_SUCCESS) {
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdatasetiter_current(rdsiter, &rdataset);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob if (rdataset.type != dns_rdatatype_nsec &&
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob rdataset.type != dns_rdatatype_nsec3 &&
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob rdataset.type != dns_rdatatype_rrsig)
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob active = ISC_TRUE;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdataset_disassociate(&rdataset);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob if (!active)
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_rdatasetiter_next(rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob else
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = ISC_R_NOMORE;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob }
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob if (result != ISC_R_NOMORE)
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob fatal("rdataset iteration failed: %s",
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob isc_result_totext(result));
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob if (!active && nsec_datatype == dns_rdatatype_nsec) {
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob /*%
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob * The node is empty of everything but NSEC / RRSIG records.
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob */
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob for (result = dns_rdatasetiter_first(rdsiter);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result == ISC_R_SUCCESS;
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_rdatasetiter_next(rdsiter)) {
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdatasetiter_current(rdsiter, &rdataset);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob result = dns_db_deleterdataset(gdb, node, gversion,
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob rdataset.type,
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob rdataset.covers);
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob check_result(result, "dns_db_deleterdataset()");
d901b2252d664a5b96bae117416f8ee822dc6691Stephen Jacob dns_rdataset_disassociate(&rdataset);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence }
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence if (result != ISC_R_NOMORE)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence fatal("rdataset iteration failed: %s",
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley isc_result_totext(result));
a5cf3cf61e96e0db9ffe433402783e1ddbb2fbc3Michael Graff } else {
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley /*
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Delete RRSIGs for types that no longer exist.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley */
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley check_result(result, "dns_db_allrdatasets()");
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley for (result = dns_rdatasetiter_first(rdsiter);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result == ISC_R_SUCCESS;
c64aeaf419a7ef156b4aabfa2a913831e773157eBob Halley result = dns_rdatasetiter_next(rdsiter)) {
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews dns_rdatasetiter_current(rdsiter, &rdataset);
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews type = rdataset.type;
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews covers = rdataset.covers;
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews dns_rdataset_disassociate(&rdataset);
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews /*
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews * Delete the NSEC chain if we are signing with
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews * NSEC3.
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews */
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews if (nsec_datatype == dns_rdatatype_nsec3 &&
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews (type == dns_rdatatype_nsec ||
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley covers == dns_rdatatype_nsec)) {
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_db_deleterdataset(gdb, node,
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley gversion, type,
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley covers);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley check_result(result,
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley "dns_db_deleterdataset(nsec/rrsig)");
c64aeaf419a7ef156b4aabfa2a913831e773157eBob Halley continue;
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews }
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews if (type != dns_rdatatype_rrsig)
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews continue;
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews found = ISC_FALSE;
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews for (result = dns_rdatasetiter_first(rdsiter2);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley !found && result == ISC_R_SUCCESS;
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_rdatasetiter_next(rdsiter2)) {
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson dns_rdatasetiter_current(rdsiter2, &rdataset);
ce8c568e0d6106bb87069453505e09bc66754b40Andreas Gustafsson if (rdataset.type == covers)
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson found = ISC_TRUE;
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson dns_rdataset_disassociate(&rdataset);
ce8c568e0d6106bb87069453505e09bc66754b40Andreas Gustafsson }
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson if (!found) {
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson if (result != ISC_R_NOMORE)
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley fatal("rdataset iteration failed: %s",
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley isc_result_totext(result));
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson result = dns_db_deleterdataset(gdb, node,
c64aeaf419a7ef156b4aabfa2a913831e773157eBob Halley gversion, type,
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews covers);
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews check_result(result,
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews "dns_db_deleterdataset(rrsig)");
aceae69c7f3e76e8842de178851928619c65b61cMark Andrews } else if (result != ISC_R_NOMORE &&
6e1141e6e83b3907b8b187d97932f30fa82470efMark Andrews result != ISC_R_SUCCESS)
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley fatal("rdataset iteration failed: %s",
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews isc_result_totext(result));
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews }
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews if (result != ISC_R_NOMORE)
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews fatal("rdataset iteration failed: %s",
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews isc_result_totext(result));
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews dns_rdatasetiter_destroy(&rdsiter2);
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews }
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews dns_rdatasetiter_destroy(&rdsiter);
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews return (active);
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews}
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews/*%
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
9ed37e8b9ccd53bc37b546fffe487b9547dda3a0Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrenceget_soa_ttls(void) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_t soaset;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_fixedname_t fname;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_name_t *name;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_result_t result;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_rdata_t rdata = DNS_RDATA_INIT;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_fixedname_init(&fname);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence name = dns_fixedname_name(&fname);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence dns_rdataset_init(&soaset);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa,
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington 0, 0, NULL, name, &soaset, NULL);
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington if (result != ISC_R_SUCCESS)
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington fatal("failed to find an SOA at the zone apex: %s",
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington isc_result_totext(result));
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington result = dns_rdataset_first(&soaset);
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington check_result(result, "dns_rdataset_first");
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington dns_rdataset_current(&soaset, &rdata);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence zone_soa_min_ttl = dns_soa_getminimum(&rdata);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence soa_ttl = soaset.ttl;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_rdataset_disassociate(&soaset);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence}
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington/*%
c0ef1acf49b383d8b6d3742cb963f7d08f5762e3Andreas Gustafsson * Increment (or set if nonzero) the SOA serial
c0ef1acf49b383d8b6d3742cb963f7d08f5762e3Andreas Gustafsson */
c0ef1acf49b383d8b6d3742cb963f7d08f5762e3Andreas Gustafssonstatic isc_result_t
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellingtonsetsoaserial(isc_uint32_t serial) {
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington isc_result_t result;
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington dns_dbnode_t *node = NULL;
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington dns_rdataset_t rdataset;
4108eed5092156cf0407a97a9bd8ab7775164694Brian Wellington dns_rdata_t rdata = DNS_RDATA_INIT;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence isc_uint32_t old_serial, new_serial;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_getoriginnode(gdb, &node);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (result != ISC_R_SUCCESS)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence return result;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdataset_init(&rdataset);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_findrdataset(gdb, node, gversion,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdatatype_soa, 0,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence 0, &rdataset, NULL);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (result != ISC_R_SUCCESS)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence goto cleanup;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_rdataset_first(&rdataset);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence RUNTIME_CHECK(result == ISC_R_SUCCESS);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdataset_current(&rdataset, &rdata);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence old_serial = dns_soa_getserial(&rdata);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (serial) {
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence /* Set SOA serial to the value provided. */
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence new_serial = serial;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence } else {
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence /* Increment SOA serial using RFC 1982 arithmetics */
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence new_serial = (old_serial + 1) & 0xFFFFFFFF;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (new_serial == 0)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence new_serial = 1;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence }
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
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 *
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 */
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (new_serial == old_serial ||
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence (new_serial - old_serial) > 0x7fffffffU)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence fprintf(stderr, "%s: warning: Serial number not advanced, "
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence "zone may not transfer\n", program);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_soa_setserial(new_serial, &rdata);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdatatype_soa, 0);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence check_result(result, "dns_db_deleterdataset");
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (result != ISC_R_SUCCESS)
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence goto cleanup;
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence result = dns_db_addrdataset(gdb, node, gversion,
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence 0, &rdataset, 0, NULL);
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence check_result(result, "dns_db_addrdataset");
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (result != ISC_R_SUCCESS)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence goto cleanup;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrencecleanup:
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence dns_rdataset_disassociate(&rdataset);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (node != NULL)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_db_detachnode(gdb, &node);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdata_reset(&rdata);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence return (result);
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence}
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence/*%
3fafd7c0c42134ff2964b74a31500465a96dee90Andreas Gustafsson * Delete any RRSIG records at a node.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrewsstatic void
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrewscleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdatasetiter_t *rdsiter = NULL;
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews dns_rdataset_t set;
aa30ee42c4b6da9bab4fb84d6cbbda6036a4d426Mark Andrews isc_result_t result, dresult;
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence if (outputformat != dns_masterformat_text || !disable_zone_check)
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence return;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence dns_rdataset_init(&set);
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence check_result(result, "dns_db_allrdatasets");
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence result = dns_rdatasetiter_first(rdsiter);
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence while (result == ISC_R_SUCCESS) {
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence isc_boolean_t destroy = ISC_FALSE;
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence dns_rdatatype_t covers = 0;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence dns_rdatasetiter_current(rdsiter, &set);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence if (set.type == dns_rdatatype_rrsig) {
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley covers = set.covers;
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley destroy = ISC_TRUE;
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff }
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews dns_rdataset_disassociate(&set);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews result = dns_rdatasetiter_next(rdsiter);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews if (destroy) {
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews dresult = dns_db_deleterdataset(db, node, version,
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews dns_rdatatype_rrsig,
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews covers);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews check_result(dresult, "dns_db_deleterdataset");
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews }
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews }
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews if (result != ISC_R_NOMORE)
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews fatal("rdataset iteration failed: %s",
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews isc_result_totext(result));
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews dns_rdatasetiter_destroy(&rdsiter);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews}
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews/*%
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews * Set up the iterator and global state before starting the tasks.
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews */
435532822dc571a904207d8176e063cc8731eef5Bob Halleystatic void
9ac79ef3f89b23d80f9649abf71fdc65bb7a8b62David Lawrencepresign(void) {
435532822dc571a904207d8176e063cc8731eef5Bob Halley isc_result_t result;
435532822dc571a904207d8176e063cc8731eef5Bob Halley
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence gdbiter = NULL;
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews result = dns_db_createiterator(gdb, 0, &gdbiter);
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews check_result(result, "dns_db_createiterator()");
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews}
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews
7c014c5bf41dc38802e8889c0a9110204eb1a552Andreas Gustafsson/*%
435532822dc571a904207d8176e063cc8731eef5Bob Halley * Clean up the iterator and global state after the tasks complete.
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence */
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrencestatic void
435532822dc571a904207d8176e063cc8731eef5Bob Halleypostsign(void) {
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_dbiterator_destroy(&gdbiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence}
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafssonstatic isc_boolean_t
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafssongoodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdataset_t *rdataset)
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson{
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdata_dnskey_t key;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdata_rrsig_t sig;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dst_key_t *dstkey = NULL;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson isc_result_t result;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson
7c014c5bf41dc38802e8889c0a9110204eb1a552Andreas Gustafsson dns_rdata_tostruct(sigrdata, &sig, NULL);
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson for (result = dns_rdataset_first(keyrdataset);
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson result == ISC_R_SUCCESS;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson result = dns_rdataset_next(keyrdataset)) {
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdata_t rdata = DNS_RDATA_INIT;
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdataset_current(keyrdataset, &rdata);
9f6c66e1b3902b61256267d124f1b9cd61402e76Andreas Gustafsson dns_rdata_tostruct(&rdata, &key, NULL);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff &dstkey);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff if (result != ISC_R_SUCCESS)
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff return (ISC_FALSE);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff if (sig.algorithm != key.algorithm ||
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff sig.keyid != dst_key_id(dstkey) ||
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff !dns_name_equal(&sig.signer, gorigin)) {
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff dst_key_free(&dstkey);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff continue;
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff }
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff mctx, sigrdata);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff dst_key_free(&dstkey);
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews if (result == ISC_R_SUCCESS)
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff return(ISC_TRUE);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff }
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff return (ISC_FALSE);
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff}
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graffstatic void
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)
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence{
163bf7444f140c9201cc093c31431a56d4665af7Michael Graff unsigned char set_algorithms[256];
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff char namebuf[DNS_NAME_FORMATSIZE];
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff char algbuf[80];
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff char typebuf[80];
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff dns_rdataset_t sigrdataset;
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff dns_rdatasetiter_t *rdsiter = NULL;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence isc_result_t result;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence int i;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley dns_rdataset_init(&sigrdataset);
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);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff result == ISC_R_SUCCESS;
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews result = dns_rdatasetiter_next(rdsiter)) {
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence dns_rdatasetiter_current(rdsiter, &sigrdataset);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence if (sigrdataset.type == dns_rdatatype_rrsig &&
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence sigrdataset.covers == rdataset->type)
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence break;
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence dns_rdataset_disassociate(&sigrdataset);
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence }
7bb707a34778fc4bd9624d6c5de95675424ea59fDavid Lawrence if (result != ISC_R_SUCCESS) {
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley dns_name_format(name, namebuf, sizeof(namebuf));
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++)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence if (ksk_algorithms[i] != 0)
0adde9f4f9369b23c67b9a29e824dda09b19022fDavid Lawrence bad_algorithms[i] = 1;
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews return;
19cfe6a53b6b932a375299ff8d82dbd66e54b5fdMark Andrews }
435532822dc571a904207d8176e063cc8731eef5Bob Halley
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence memset(set_algorithms, 0, sizeof(set_algorithms));
2f330bed30b752451b8a5258c7551b22ba602337Andreas Gustafsson for (result = dns_rdataset_first(&sigrdataset);
2f330bed30b752451b8a5258c7551b22ba602337Andreas Gustafsson result == ISC_R_SUCCESS;
ece3d6c35693f9e2145434b0bf14e8b752cdeee8Michael Graff result = dns_rdataset_next(&sigrdataset)) {
e544b507b8019a62c5d2716281f6832519a8791dDavid Lawrence dns_rdata_t rdata = DNS_RDATA_INIT;
0fde58a7673f28fcc08eb8f597581247a4c2db20Bob Halley dns_rdata_rrsig_t sig;
0fde58a7673f28fcc08eb8f597581247a4c2db20Bob Halley
0fde58a7673f28fcc08eb8f597581247a4c2db20Bob Halley dns_rdataset_current(&sigrdataset, &rdata);
0fde58a7673f28fcc08eb8f597581247a4c2db20Bob Halley dns_rdata_tostruct(&rdata, &sig, NULL);
8313838954d67250d0ed7edf67fba5da0790d1a7Michael Graff if ((set_algorithms[sig.algorithm] != 0) ||
6526fd032fc418411da3af4201214e95c113d3e2Mark Andrews (ksk_algorithms[sig.algorithm] == 0))
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence continue;
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews if (goodsig(&rdata, name, keyrdataset, rdataset))
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews set_algorithms[sig.algorithm] = 1;
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews }
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews dns_rdatasetiter_destroy(&rdsiter);
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 Andrews (set_algorithms[i] == 0)) {
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews dns_secalg_format(i, algbuf, sizeof(algbuf));
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews fprintf(stderr, "Missing %s signature for "
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews "%s %s\n", algbuf, namebuf, typebuf);
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews bad_algorithms[i] = 1;
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews }
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews }
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews dns_rdataset_disassociate(&sigrdataset);
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews}
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrews
31d3464c0c0a35236c7924f698c5a8a66a9ed534Mark Andrewsstatic void
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)
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence{
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_rdataset_t rdataset;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdatasetiter_t *rdsiter = NULL;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_result_t result;
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews check_result(result, "dns_db_allrdatasets()");
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews result = dns_rdatasetiter_first(rdsiter);
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence dns_rdataset_init(&rdataset);
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews while (result == ISC_R_SUCCESS) {
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews if (rdataset.type != dns_rdatatype_rrsig &&
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews rdataset.type != dns_rdatatype_dnskey &&
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews (!delegation || rdataset.type == dns_rdatatype_ds ||
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews rdataset.type == dns_rdatatype_nsec)) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews verifyset(&rdataset, name, node, keyrdataset,
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence ksk_algorithms, bad_algorithms);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_disassociate(&rdataset);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_rdatasetiter_next(rdsiter);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result != ISC_R_NOMORE)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("rdataset iteration failed: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_result_totext(result));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdatasetiter_destroy(&rdsiter);
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson}
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson/*%
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews * Verify that certain things are sane:
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews *
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.
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson *
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence * The DNSKEY record was signed with at least one of the KSKs in this
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson * set.
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence *
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson * The rest of the zone was signed with at least one of the ZSKs
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews * present in the DNSKEY RRSET.
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrews */
5f4098e478ae913cdc1bb8851599b8f2431050d3Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsverifyzone(void) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews char algbuf[80];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbiterator_t *dbiter = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbnode_t *node = NULL, *nextnode = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_t fname, fnextname, fzonecut;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_t *name, *nextname, *zonecut;
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson dns_rdata_dnskey_t dnskey;
9de05727e334336ceb0abcca404d770abd23b876Mark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_t rdataset;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_t sigrdataset;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews int i;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t done = ISC_FALSE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t first = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t goodksk = ISC_FALSE;
41149b919e439a0551be66eabe76398ab493e436Andreas Gustafsson isc_boolean_t goodzsk = ISC_FALSE;
495c00c1c995c96587b38d2d5fa41f127869d5b8David Lawrence isc_result_t result;
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence unsigned char revoked_ksk[256];
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence unsigned char revoked_zsk[256];
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence unsigned char standby_ksk[256];
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence unsigned char standby_zsk[256];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char ksk_algorithms[256];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char zsk_algorithms[256];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char bad_algorithms[256];
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence#ifdef ALLOW_KSKLESS_ZONES
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t allzsksigned = ISC_TRUE;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char self_algorithms[256];
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#endif
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence if (disable_zone_check)
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence return;
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence if (result != ISC_R_SUCCESS)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("failed to find the zone's origin: %s",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_result_totext(result));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_init(&rdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_init(&sigrdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_db_findrdataset(gdb, node, gversion,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdatatype_dnskey,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence 0, 0, &rdataset, &sigrdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_db_detachnode(gdb, &node);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (result != ISC_R_SUCCESS)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("cannot find DNSKEY rrset\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!dns_rdataset_isassociated(&sigrdataset))
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("cannot find DNSKEY RRSIGs\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(revoked_ksk, 0, sizeof(revoked_ksk));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(revoked_zsk, 0, sizeof(revoked_zsk));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(standby_ksk, 0, sizeof(standby_ksk));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(standby_zsk, 0, sizeof(standby_zsk));
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#ifdef ALLOW_KSKLESS_ZONES
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence memset(self_algorithms, 0, sizeof(self_algorithms));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#endif
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence /*
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 */
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (result = dns_rdataset_first(&rdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result == ISC_R_SUCCESS;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_rdataset_next(&rdataset)) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_current(&rdataset, &rdata);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_rdata_tostruct");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence ;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence !dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence &sigrdataset, ISC_FALSE,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence mctx)) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence char namebuf[DNS_NAME_FORMATSIZE];
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence char buffer[1024];
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_buffer_t buf;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_name_format(gorigin, namebuf,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence sizeof(namebuf));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_buffer_init(&buf, buffer, sizeof(buffer));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_rdata_totext(&rdata, NULL, &buf);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_rdata_totext");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("revoked KSK is not self signed:\n"
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence "%s DNSKEY %.*s", namebuf,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence (int)isc_buffer_usedlength(&buf), buffer);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence revoked_ksk[dnskey.algorithm] != 255)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence revoked_ksk[dnskey.algorithm]++;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence revoked_zsk[dnskey.algorithm] != 255)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence revoked_zsk[dnskey.algorithm]++;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews &sigrdataset, ISC_FALSE, mctx)) {
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews if (ksk_algorithms[dnskey.algorithm] != 255)
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews ksk_algorithms[dnskey.algorithm]++;
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews goodksk = ISC_TRUE;
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews } else {
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews if (standby_ksk[dnskey.algorithm] != 255)
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews standby_ksk[dnskey.algorithm]++;
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews }
c4157085cd215999883eb3de41bf16ce798379ceAndreas Gustafsson } else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews &sigrdataset, ISC_FALSE,
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews mctx)) {
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews#ifdef ALLOW_KSKLESS_ZONES
2449f41e75d3b3f1c0ec3f05b1603fd8f80d8ae0Mark Andrews if (self_algorithms[dnskey.algorithm] != 255)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence self_algorithms[dnskey.algorithm]++;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#endif
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (zsk_algorithms[dnskey.algorithm] != 255)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence zsk_algorithms[dnskey.algorithm]++;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence goodzsk = ISC_TRUE;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence } else {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (standby_zsk[dnskey.algorithm] != 255)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence standby_zsk[dnskey.algorithm]++;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#ifdef ALLOW_KSKLESS_ZONES
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence allzsksigned = ISC_FALSE;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#endif
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdata_freestruct(&dnskey);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdata_reset(&rdata);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_disassociate(&sigrdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#ifdef ALLOW_KSKLESS_ZONES
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!goodksk) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!ignore_kskflag)
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 if (!allzsksigned)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "warning: not all ZSK's are self "
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence "signed.\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#else
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!goodksk) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fatal("no self signed KSK's found");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#endif
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "Verifying the zone using the following algorithms:");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#ifdef ALLOW_KSKLESS_ZONES
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#else
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (ksk_algorithms[i] != 0)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence#endif
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_secalg_format(i, algbuf, sizeof(algbuf));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, " %s", algbuf);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, ".\n");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (!ignore_kskflag && !keyset_kskonly) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence /*
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 */
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if ((ksk_algorithms[i] != 0) ==
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence (zsk_algorithms[i] != 0))
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence continue;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_secalg_format(i, algbuf, sizeof(algbuf));
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence fprintf(stderr, "Missing %s for algorithm %s\n",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence (ksk_algorithms[i] != 0)
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence ? "ZSK"
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence : "self signing KSK",
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence algbuf);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence bad_algorithms[i] = 1;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence /*
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * Check that all the other records were signed by keys that are
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * present in the DNSKEY RRSET.
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence */
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_fixedname_init(&fname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews name = dns_fixedname_name(&fname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_init(&fnextname);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence nextname = dns_fixedname_name(&fnextname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_init(&fzonecut);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews zonecut = NULL;
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_db_createiterator()");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
703e1c0bb66f3cd3d300358ca0c1fdf3cb5fb1c5Brian Wellington result = dns_dbiterator_first(dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_dbiterator_first()");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence while (!done) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence isc_boolean_t isdelegation = ISC_FALSE;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_dns_dbiterator_current(result);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews if (delegation(name, node, NULL)) {
8ca42f6318be756354b70260050132545aa680d3Mark Andrews zonecut = dns_fixedname_name(&fzonecut);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_name_copy(name, zonecut, NULL);
6408533a88411b624477895d4e39ea7c58cebfc3Mark Andrews isdelegation = ISC_TRUE;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews }
8ca42f6318be756354b70260050132545aa680d3Mark Andrews verifynode(name, node, isdelegation, &rdataset,
8ca42f6318be756354b70260050132545aa680d3Mark Andrews ksk_algorithms, bad_algorithms);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_next(dbiter);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews nextnode = NULL;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews while (result == ISC_R_SUCCESS) {
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
8ca42f6318be756354b70260050132545aa680d3Mark Andrews nextname);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews check_dns_dbiterator_current(result);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
fed3d5c2fc3fa8e1547e8b5c28c01f1095e17e5fMark Andrews (zonecut != NULL &&
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_name_issubdomain(nextname, zonecut)))
8ca42f6318be756354b70260050132545aa680d3Mark Andrews {
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_db_detachnode(gdb, &nextnode);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_dbiterator_next(dbiter);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews continue;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews }
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_db_detachnode(gdb, &nextnode);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews break;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews }
8ca42f6318be756354b70260050132545aa680d3Mark Andrews if (result == ISC_R_NOMORE) {
8ca42f6318be756354b70260050132545aa680d3Mark Andrews done = ISC_TRUE;
8ca42f6318be756354b70260050132545aa680d3Mark Andrews } else if (result != ISC_R_SUCCESS)
8ca42f6318be756354b70260050132545aa680d3Mark Andrews fatal("iterating through the database failed: %s",
8ca42f6318be756354b70260050132545aa680d3Mark Andrews isc_result_totext(result));
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_db_detachnode(gdb, &node);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews }
8ca42f6318be756354b70260050132545aa680d3Mark Andrews
8ca42f6318be756354b70260050132545aa680d3Mark Andrews dns_dbiterator_destroy(&dbiter);
8ca42f6318be756354b70260050132545aa680d3Mark Andrews
8ca42f6318be756354b70260050132545aa680d3Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_result(result, "dns_db_createiterator()");
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (result = dns_dbiterator_first(dbiter);
be0e075ac2c10ade3e80edef7fa14ac0fda92690Mark Andrews result == ISC_R_SUCCESS;
be0e075ac2c10ade3e80edef7fa14ac0fda92690Mark Andrews result = dns_dbiterator_next(dbiter) ) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence result = dns_dbiterator_current(dbiter, &node, name);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence check_dns_dbiterator_current(result);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence verifynode(name, node, ISC_FALSE, &rdataset,
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence ksk_algorithms, bad_algorithms);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_db_detachnode(gdb, &node);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence }
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_dbiterator_destroy(&dbiter);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence dns_rdataset_disassociate(&rdataset);
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence /*
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence * If we made it this far, we have what we consider a properly signed
be0e075ac2c10ade3e80edef7fa14ac0fda92690Mark Andrews * zone. Set the good flag.
be0e075ac2c10ade3e80edef7fa14ac0fda92690Mark Andrews */
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence for (i = 0; i < 256; i++) {
905e0c15332d3209dd73ff8b2334f6b80f7fe3a6David Lawrence if (bad_algorithms[i] != 0) {
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence if (first)
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 fprintf(stderr, " %s", algbuf);
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson first = ISC_FALSE;
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson }
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson }
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson if (!first) {
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson fprintf(stderr, ".\n");
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson fatal("DNSSEC completeness test failed.");
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson }
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews if (goodksk || ignore_kskflag) {
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews /*
21f1794606dce19928cf455029e173321f166380Mark Andrews * Print the success summary.
21f1794606dce19928cf455029e173321f166380Mark Andrews */
21f1794606dce19928cf455029e173321f166380Mark Andrews fprintf(stderr, "Zone signing complete:\n");
21f1794606dce19928cf455029e173321f166380Mark Andrews for (i = 0; i < 256; i++) {
21f1794606dce19928cf455029e173321f166380Mark Andrews if ((ksk_algorithms[i] != 0) ||
21f1794606dce19928cf455029e173321f166380Mark Andrews (standby_ksk[i] != 0) ||
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews (revoked_zsk[i] != 0) ||
ac124a78a097a0840992c5726cbbdaf1448b6ab3Mark Andrews (zsk_algorithms[i] != 0) ||
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews (standby_zsk[i] != 0) ||
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews (revoked_zsk[i] != 0)) {
ac124a78a097a0840992c5726cbbdaf1448b6ab3Mark Andrews dns_secalg_format(i, algbuf, sizeof(algbuf));
a34d19803a206febe10866394393ec1c09b28984Mark Andrews fprintf(stderr, "Algorithm: %s: KSKs: "
21f1794606dce19928cf455029e173321f166380Mark Andrews "%u active, %u stand-by, %u revoked\n",
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews algbuf, ksk_algorithms[i],
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews standby_ksk[i], revoked_ksk[i]);
21f1794606dce19928cf455029e173321f166380Mark Andrews fprintf(stderr, "%*sZSKs: "
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews "%u active, %u %s, %u revoked\n",
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews (int) strlen(algbuf) + 13, "",
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews zsk_algorithms[i],
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews standby_zsk[i],
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews keyset_kskonly ? "present" : "stand-by",
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews revoked_zsk[i]);
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews }
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews }
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews }
ba1549060f6bc5750adc20ed9d695f8b2cc556d7Andreas Gustafsson}
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews/*%
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 * records.
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews */
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrewsstatic void
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrewssignapex(void) {
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews dns_dbnode_t *node = NULL;
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews dns_fixedname_t fixed;
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews dns_name_t *name;
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews isc_result_t result;
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews dns_fixedname_init(&fixed);
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews name = dns_fixedname_name(&fixed);
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews result = dns_dbiterator_seek(gdbiter, gorigin);
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews check_result(result, "dns_dbiterator_seek()");
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews result = dns_dbiterator_current(gdbiter, &node, name);
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews check_dns_dbiterator_current(result);
affd6c025b39ec89a91056efb084fff7239ad6e3Mark Andrews signname(node, name);
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews dumpnode(name, node);
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews cleannode(gdb, gversion, node);
734b3777705434fedc7eb4b4c5f51e9a606d86b7Mark Andrews dns_db_detachnode(gdb, &node);
734b3777705434fedc7eb4b4c5f51e9a606d86b7Mark Andrews result = dns_dbiterator_first(gdbiter);
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews if (result == ISC_R_NOMORE)
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews finished = ISC_TRUE;
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley else if (result != ISC_R_SUCCESS)
16a68807e13caea3183a41a5292f1b3f48b81a26Mark Andrews fatal("failure iterating database: %s",
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews isc_result_totext(result));
f95231835fdcd8d5f58486c9f9993602f27fe157Mark Andrews}
935000aa6e2b9d08f363b2e698a258a458a5a7cfMark Andrews
c654449ccf403ccd2b81be2038b1013d6fbb06ccMark Andrews/*%
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrence * Assigns a node to a worker thread. This is protected by the master task's
694c897b20f06f8a5349fd9ac5df93947f6f5a2aBob Halley * lock.
694c897b20f06f8a5349fd9ac5df93947f6f5a2aBob Halley */
a59b51eb1d9a80d682efc669414e16dc8da47e95David Lawrencestatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsassignwork(isc_task_t *task, isc_task_t *worker) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_t *fname;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_t *name;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbnode_t *node;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews sevent_t *sevent;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_t nsec;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_boolean_t found;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_result_t result;
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
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (shuttingdown)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews return;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews LOCK(&namelock);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (finished) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews ended++;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (ended == ntasks) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_task_detach(&task);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_app_shutdown();
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews goto unlock;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fname = isc_mem_get(mctx, sizeof(dns_fixedname_t));
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson if (fname == NULL)
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews fatal("out of memory");
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews dns_fixedname_init(fname);
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews name = dns_fixedname_name(fname);
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews node = NULL;
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews found = ISC_FALSE;
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews while (!found) {
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews result = dns_dbiterator_current(gdbiter, &node, name);
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews check_dns_dbiterator_current(result);
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews /*
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews * The origin was handled by signapex().
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews */
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson if (dns_name_equal(name, gorigin)) {
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson dns_db_detachnode(gdb, &node);
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews goto next;
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews }
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews /*
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.
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews */
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews dns_rdataset_init(&nsec);
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson result = dns_db_findrdataset(gdb, node, gversion,
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews nsec_datatype, 0, 0,
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews &nsec, NULL);
9105a6a730bfb8472c48230629c5a0aebb88c422Mark Andrews if (dns_rdataset_isassociated(&nsec))
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews dns_rdataset_disassociate(&nsec);
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews if (result == ISC_R_SUCCESS) {
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson found = ISC_TRUE;
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews } else if (nsec_datatype == dns_rdatatype_nsec3) {
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews if (dns_name_issubdomain(name, gorigin) &&
28a3d529046ec5536e1ea619454624b683509675Andreas Gustafsson (zonecut == NULL ||
b4028939fdffc92cf659764deb9c6e3c805cc948Mark Andrews !dns_name_issubdomain(name, zonecut))) {
5c00d1c90030a311d2700970fa7cffc8f828a48cBob Halley if (delegation(name, node, NULL)) {
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_fixedname_init(&fzonecut);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence zonecut = dns_fixedname_name(&fzonecut);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_name_copy(name, zonecut, NULL);
5c00d1c90030a311d2700970fa7cffc8f828a48cBob Halley if (!OPTOUT(nsec3flags) ||
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington secure(name, node))
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington found = ISC_TRUE;
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington } else
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington found = ISC_TRUE;
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington }
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington }
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington if (!found) {
e980502db40155234b4e8d320b748b34dbaba3a2Brian Wellington dumpnode(name, node);
f8727bd90366af835f551da1b5e1fdfcd2d3d01fBrian Wellington dns_db_detachnode(gdb, &node);
5c00d1c90030a311d2700970fa7cffc8f828a48cBob Halley }
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews next:
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews result = dns_dbiterator_next(gdbiter);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (result == ISC_R_NOMORE) {
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews finished = ISC_TRUE;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews break;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews } else if (result != ISC_R_SUCCESS)
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews fatal("failure iterating database: %s",
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_result_totext(result));
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews }
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (!found) {
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews ended++;
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews if (ended == ntasks) {
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_task_detach(&task);
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_app_shutdown();
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews }
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews isc_mem_put(mctx, fname, sizeof(dns_fixedname_t));
4423c99613db1399dbb5c51e86ef0d351a1418c2Mark Andrews goto unlock;
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews }
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews sevent = (sevent_t *)
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews isc_event_allocate(mctx, task, SIGNER_EVENT_WORK,
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews sign, NULL, sizeof(sevent_t));
6286983c506433d642b23e64845c50be30f2a7f6Mark Andrews if (sevent == NULL)
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews fatal("failed to allocate event\n");
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews sevent->node = node;
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews sevent->fname = fname;
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews isc_task_send(worker, ISC_EVENT_PTR(&sevent));
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews unlock:
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews UNLOCK(&namelock);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews}
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews/*%
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence * Start a worker task
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence */
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrencestatic void
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrencestartworker(isc_task_t *task, isc_event_t *event) {
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence isc_task_t *worker;
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence worker = (isc_task_t *)event->ev_arg;
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence assignwork(task, worker);
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence isc_event_free(&event);
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson}
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson/*%
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson * Write a node to the output file, and restart the worker task.
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson */
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrewsstatic void
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrewswritenode(isc_task_t *task, isc_event_t *event) {
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_task_t *worker;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews sevent_t *sevent = (sevent_t *)event;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews worker = (isc_task_t *)event->ev_sender;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews dumpnode(dns_fixedname_name(sevent->fname), sevent->node);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews cleannode(gdb, gversion, sevent->node);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews dns_db_detachnode(gdb, &sevent->node);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t));
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews assignwork(task, worker);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_event_free(&event);
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews}
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews/*%
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews * Sign a database node.
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews */
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrewsstatic void
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrewssign(isc_task_t *task, isc_event_t *event) {
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews dns_fixedname_t *fname;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews dns_dbnode_t *node;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews sevent_t *sevent, *wevent;
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews sevent = (sevent_t *)event;
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson node = sevent->node;
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson fname = sevent->fname;
9de05727e334336ceb0abcca404d770abd23b876Mark Andrews isc_event_free(&event);
9de05727e334336ceb0abcca404d770abd23b876Mark Andrews
9de05727e334336ceb0abcca404d770abd23b876Mark Andrews signname(node, dns_fixedname_name(fname));
caa736a754e90f44bbc249e22f96bcbf4e04b849Andreas Gustafsson wevent = (sevent_t *)
6ab3d08c1257efa6287d8ad7bb41d8fb99d5d6dfMark Andrews isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE,
52d6c41cfcf21ddd240ddba15f3cdccea2e1ef47Andreas Gustafsson writenode, NULL, sizeof(sevent_t));
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews if (wevent == NULL)
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews fatal("failed to allocate event\n");
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews wevent->node = node;
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews wevent->fname = fname;
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews isc_task_send(master, ISC_EVENT_PTR(&wevent));
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews}
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews/*%
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews * Update / remove the DS RRset. Preserve RRSIG(DS) if possible.
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews */
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrewsstatic void
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrewsadd_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews dns_rdataset_t dsset;
e2cf63c5df79eb7c8b86b6278289883fa760cda5Mark Andrews dns_rdataset_t sigdsset;
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews isc_result_t result;
95b484c9580d06eb2f9735a22e9841389c2859baMark Andrews
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews dns_rdataset_init(&dsset);
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews dns_rdataset_init(&sigdsset);
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews result = dns_db_findrdataset(gdb, node, gversion,
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews dns_rdatatype_ds,
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews 0, 0, &dsset, &sigdsset);
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews if (result == ISC_R_SUCCESS) {
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews dns_rdataset_disassociate(&dsset);
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
43501e6570e9081d459fb5c1a81b73c2c53c5df0Mark Andrews dns_rdatatype_ds, 0);
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence check_result(result, "dns_db_deleterdataset");
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence }
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence result = loadds(name, nsttl, &dsset);
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence if (result == ISC_R_SUCCESS) {
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence result = dns_db_addrdataset(gdb, node, gversion, 0,
073719ac7155ba72a353590190da58837bd590eaMark Andrews &dsset, 0, NULL);
073719ac7155ba72a353590190da58837bd590eaMark Andrews check_result(result, "dns_db_addrdataset");
37aa91031830d2fc428331378f089169eb3e6dc2David Lawrence dns_rdataset_disassociate(&dsset);
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence if (dns_rdataset_isassociated(&sigdsset))
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence dns_rdataset_disassociate(&sigdsset);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence } else if (dns_rdataset_isassociated(&sigdsset)) {
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatatype_rrsig,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatatype_ds);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_deleterdataset");
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence dns_rdataset_disassociate(&sigdsset);
1ad94515ee37580a2298b1484ddf44b52dc03a6aMark Andrews }
09ba9eacebdffc689da9851ce3bd932aedd1deddMark Andrews}
09ba9eacebdffc689da9851ce3bd932aedd1deddMark Andrews
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence/*%
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records.
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence */
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrencestatic void
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrencensecify(void) {
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_dbiterator_t *dbiter = NULL;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_dbnode_t *node = NULL, *nextnode = NULL;
9c9cf3a8d063b0255dbc8679dab588708e9b6f1cAndreas Gustafsson dns_fixedname_t fname, fnextname, fzonecut;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_name_t *name, *nextname, *zonecut;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdataset_t rdataset;
b1070fe55c8864ef24a479a6c40d1776f35c2593Mark Andrews dns_rdatasetiter_t *rdsiter = NULL;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatatype_t type, covers;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence isc_boolean_t done = ISC_FALSE;
1672cc63c190e073706a742ebaabc20ac4d2c916Mark Andrews isc_result_t result;
1672cc63c190e073706a742ebaabc20ac4d2c916Mark Andrews isc_uint32_t nsttl = 0;
1672cc63c190e073706a742ebaabc20ac4d2c916Mark Andrews
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdataset_init(&rdataset);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_fixedname_init(&fname);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence name = dns_fixedname_name(&fname);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_fixedname_init(&fnextname);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence nextname = dns_fixedname_name(&fnextname);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_fixedname_init(&fzonecut);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence zonecut = NULL;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence /*
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence * Remove any NSEC3 chains.
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence */
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result, "dns_db_createiterator()");
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence for (result = dns_dbiterator_first(dbiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result == ISC_R_SUCCESS;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence result = dns_dbiterator_next(dbiter)) {
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_dbiterator_current(dbiter, &node, name);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_dns_dbiterator_current(result);
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 result == ISC_R_SUCCESS;
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_rdatasetiter_next(rdsiter)) {
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatasetiter_current(rdsiter, &rdataset);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence type = rdataset.type;
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence covers = rdataset.covers;
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence dns_rdataset_disassociate(&rdataset);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence result = dns_db_deleterdataset(gdb, node, gversion,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence type, covers);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence check_result(result,
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence "dns_db_deleterdataset(nsec3param/rrsig)");
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence }
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_rdatasetiter_destroy(&rdsiter);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_db_detachnode(gdb, &node);
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence }
ed71ea51c6ecb5d7d659b6e6a20f6b3f5c2678c6David Lawrence dns_dbiterator_destroy(&dbiter);
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence
8b11f3debd9a9494d5aec60ea228ab393fbdc26eDavid Lawrence result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_result(result, "dns_db_createiterator()");
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_dbiterator_first(dbiter);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_result(result, "dns_dbiterator_first()");
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_dns_dbiterator_current(result);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews /*
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Delete any NSEC3PARAM records at the apex.
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews */
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_db_allrdatasets()");
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews for (result = dns_rdatasetiter_first(rdsiter);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result == ISC_R_SUCCESS;
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_rdatasetiter_next(rdsiter)) {
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews dns_rdatasetiter_current(rdsiter, &rdataset);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews type = rdataset.type;
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews covers = rdataset.covers;
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews dns_rdataset_disassociate(&rdataset);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews if (type == dns_rdatatype_nsec3param ||
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews covers == dns_rdatatype_nsec3param) {
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews type, covers);
41f5cf4ac1728a1584b71085868962d977b6c4e5Mark Andrews check_result(result,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 "dns_db_deleterdataset(nsec3param/rrsig)");
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 continue;
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_rdatasetiter_destroy(&rdsiter);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_db_detachnode(gdb, &node);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 while (!done) {
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_dbiterator_current(dbiter, &node, name);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 check_dns_dbiterator_current(result);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 if (delegation(name, node, &nsttl)) {
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 zonecut = dns_fixedname_name(&fzonecut);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_name_copy(name, zonecut, NULL);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 if (generateds)
2dea622a0c24e7fbeee9e574fc617704efb12432Tatuya JINMEI 神明達哉 add_ds(name, node, nsttl);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_dbiterator_next(dbiter);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 nextnode = NULL;
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 while (result == ISC_R_SUCCESS) {
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 isc_boolean_t active = ISC_FALSE;
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_dbiterator_current(dbiter, &nextnode,
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews nextname);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 check_dns_dbiterator_current(result);
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews active = active_node(nextnode);
161835380928f2ff8abff8930078152a71340b65Tatuya JINMEI 神明達哉 if (!active) {
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_db_detachnode(gdb, &nextnode);
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews result = dns_dbiterator_next(dbiter);
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews continue;
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews }
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews (zonecut != NULL &&
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews dns_name_issubdomain(nextname, zonecut)))
9de05727e334336ceb0abcca404d770abd23b876Mark Andrews {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_db_detachnode(gdb, &nextnode);
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews result = dns_dbiterator_next(dbiter);
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews continue;
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_db_detachnode(gdb, &nextnode);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 break;
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 if (result == ISC_R_NOMORE) {
2dea622a0c24e7fbeee9e574fc617704efb12432Tatuya JINMEI 神明達哉 dns_name_clone(gorigin, nextname);
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews done = ISC_TRUE;
2dea622a0c24e7fbeee9e574fc617704efb12432Tatuya JINMEI 神明達哉 } else if (result != ISC_R_SUCCESS)
161835380928f2ff8abff8930078152a71340b65Tatuya JINMEI 神明達哉 fatal("iterating through the database failed: %s",
161835380928f2ff8abff8930078152a71340b65Tatuya JINMEI 神明達哉 isc_result_totext(result));
161835380928f2ff8abff8930078152a71340b65Tatuya JINMEI 神明達哉 dns_dbiterator_pause(dbiter);
78ff0e94eae96f2cf8bf94454d8ff01ba280d30dMark Andrews result = dns_nsec_build(gdb, gversion, node, nextname,
78ff0e94eae96f2cf8bf94454d8ff01ba280d30dMark Andrews zone_soa_min_ttl);
78ff0e94eae96f2cf8bf94454d8ff01ba280d30dMark Andrews check_result(result, "dns_nsec_build()");
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_db_detachnode(gdb, &node);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 }
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_dbiterator_destroy(&dbiter);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉}
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉static void
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉addnsec3param(const unsigned char *salt, size_t salt_length,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned int iterations)
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉{
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_dbnode_t *node = NULL;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdata_nsec3param_t nsec3param;
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews unsigned char nsec3parambuf[5 + 255];
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdatalist_t rdatalist;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdataset_t rdataset;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdata_t rdata = DNS_RDATA_INIT;
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews isc_buffer_t b;
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews isc_result_t result;
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews
01b8bc018d83e757b0578723977b0a71e1e626f8Mark Andrews dns_rdataset_init(&rdataset);
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.common.rdclass = gclass;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.common.rdtype = dns_rdatatype_nsec3param;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews ISC_LINK_INIT(&nsec3param.common, link);
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.mctx = NULL;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.flags = 0;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.iterations = iterations;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews nsec3param.salt_length = salt_length;
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews DE_CONST(salt, nsec3param.salt);
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf));
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews result = dns_rdata_fromstruct(&rdata, gclass,
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews dns_rdatatype_nsec3param,
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews &nsec3param, &b);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 rdatalist.rdclass = rdata.rdclass;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 rdatalist.type = rdata.type;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 rdatalist.covers = 0;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 rdatalist.ttl = 0;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 ISC_LIST_INIT(rdatalist.rdata);
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 神明達哉
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 check_result(result, "dns_db_find(gorigin)");
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews /*
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews * Delete any current NSEC3PARAM records.
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews */
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_deleterdataset(gdb, node, gversion,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdatatype_nsec3param, 0);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 if (result == DNS_R_UNCHANGED)
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = ISC_R_SUCCESS;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 check_result(result, "dddnsec3param: dns_db_deleterdataset()");
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 DNS_DBADD_MERGE, NULL);
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 if (result == DNS_R_UNCHANGED)
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews result = ISC_R_SUCCESS;
6672b3524c2305d8c66d8189c774f549be352ac0Mark Andrews check_result(result, "addnsec3param: dns_db_addrdataset()");
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews dns_db_detachnode(gdb, &node);
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews}
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉static void
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 神明達哉 dns_ttl_t ttl)
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉{
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned char hash[NSEC3_MAX_HASH_LENGTH];
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 const unsigned char *nexthash;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE];
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_fixedname_t hashname;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdatalist_t rdatalist;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdataset_t rdataset;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_rdata_t rdata = DNS_RDATA_INIT;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 isc_result_t result;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 dns_dbnode_t *nsec3node = NULL;
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 char namebuf[DNS_NAME_FORMATSIZE];
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 size_t hash_length;
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_name_format(name, namebuf, sizeof(namebuf));
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_fixedname_init(&hashname);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_rdataset_init(&rdataset);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 dns_name_downcase(name, name, NULL);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 result = dns_nsec3_hashname(&hashname, hash, &hash_length,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 name, gorigin, dns_hash_sha1, iterations,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 salt, salt_length);
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,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 unknownalg ?
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 DNS_NSEC3_UNKNOWNALG : dns_hash_sha1,
c528bd698637d84a0081d26a58813607c7f52bb7Tatuya JINMEI 神明達哉 nsec3flags, iterations,
f31446e6b5925395fce4f62adf71f7ad70cea6ceMark Andrews salt, salt_length,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 nexthash, ISC_SHA1_DIGESTLENGTH,
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 nsec3buffer, &rdata);
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 check_result(result, "addnsec3: dns_nsec3_buildrdata()");
5597be9bb88de138dfec9fa9176708443813925eTatuya JINMEI 神明達哉 rdatalist.rdclass = rdata.rdclass;
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews rdatalist.type = rdata.type;
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews rdatalist.covers = 0;
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews rdatalist.ttl = ttl;
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews ISC_LIST_INIT(rdatalist.rdata);
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 ISC_TRUE, &nsec3node);
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews check_result(result, "addnsec3: dns_db_findnode()");
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset,
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews 0, NULL);
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews if (result == DNS_R_UNCHANGED)
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews result = ISC_R_SUCCESS;
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews check_result(result, "addnsec3: dns_db_addrdataset()");
b2f160f266005ceaed77a3f575109f74cd13d548Mark Andrews dns_db_detachnode(gdb, &nsec3node);
f252f91e2725f2b505d12da6c049896e1de74112Andreas Gustafsson}
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews/*%
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list.
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews *
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 *
2b66a51a7d72e9cc07917fb583ad528b0539d2a3Mark Andrews * XXXMPA Should we also check that it of the form <hash>.<origin>?
f252f91e2725f2b505d12da6c049896e1de74112Andreas Gustafsson */
f252f91e2725f2b505d12da6c049896e1de74112Andreas Gustafssonstatic void
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{
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_label_t label;
26bc09bc89c2a96f36147be4e664c552efe78fa2Andreas Gustafsson dns_rdata_nsec3_t nsec3;
26bc09bc89c2a96f36147be4e664c552efe78fa2Andreas Gustafsson dns_rdata_t rdata, delrdata;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdatalist_t rdatalist;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdataset_t rdataset, delrdataset;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_boolean_t delete_rrsigs = ISC_FALSE;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_buffer_t target;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_result_t result;
26bc09bc89c2a96f36147be4e664c552efe78fa2Andreas Gustafsson unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein isc_boolean_t exists;
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein /*
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein * Get the first label.
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein */
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein dns_name_getlabel(name, 0, &label);
94a8c22d559fe1f977ed41d6fe0b2513ecee7ff9Rob Austein
2bd433da8785d3da8e8dd140248762c5d3220b0fEric Luce /*
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * We want just the label contents.
2bd433da8785d3da8e8dd140248762c5d3220b0fEric Luce */
2bd433da8785d3da8e8dd140248762c5d3220b0fEric Luce isc_region_consume(&label, 1);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /*
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Decode base32hex string.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_buffer_init(&target, hash, sizeof(hash) - 1);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = isc_base32hex_decoderegion(&label, &target);
2bd433da8785d3da8e8dd140248762c5d3220b0fEric Luce if (result != ISC_R_SUCCESS)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein return;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
2bd433da8785d3da8e8dd140248762c5d3220b0fEric Luce hash[isc_buffer_usedlength(&target)] = 0;
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews exists = hashlist_exists(hashlist, hash);
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews /*
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews * Verify that the NSEC3 parameters match the current ones
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews * otherwise we are dealing with a different NSEC3 chain.
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews */
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdataset_init(&rdataset);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdataset_init(&delrdataset);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3,
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson 0, 0, &rdataset, NULL);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson if (result != ISC_R_SUCCESS)
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson return;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson /*
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson * Delete any NSEC3 records which are not part of the current
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson * NSEC3 chain.
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson */
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson for (result = dns_rdataset_first(&rdataset);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result == ISC_R_SUCCESS;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_rdataset_next(&rdataset)) {
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdata_init(&rdata);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdataset_current(&rdataset, &rdata);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson check_result(result, "dns_rdata_tostruct");
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson if (exists && nsec3.hash == hashalg &&
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson nsec3.iterations == iterations &&
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson nsec3.salt_length == salt_length &&
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson !memcmp(nsec3.salt, salt, salt_length))
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson continue;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson rdatalist.rdclass = rdata.rdclass;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson rdatalist.type = rdata.type;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson rdatalist.covers = 0;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson rdatalist.ttl = rdataset.ttl;
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson ISC_LIST_INIT(rdatalist.rdata);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdata_init(&delrdata);
68f72235f8f41fa949823551d8e6476057ec5bd6Andreas Gustafsson dns_rdata_clone(&rdata, &delrdata);
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 &delrdataset, 0, NULL);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdataset_disassociate(&delrdataset);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein check_result(result, "dns_db_subtractrdataset(NSEC3)");
35ae209f35b5df8515ad4ef1578c8f8b1922a3d5Brian Wellington delete_rrsigs = ISC_TRUE;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein }
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdataset_disassociate(&rdataset);
60084a1a5a9e570842b8147ff4c34b68ce4de7f8Andreas Gustafsson if (result != ISC_R_NOMORE)
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson check_result(result, "dns_rdataset_first/next");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (!delete_rrsigs)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein return;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /*
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Delete the NSEC3 RRSIGs
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_deleterdataset(gdb, node, gversion,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdatatype_rrsig,
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews dns_rdatatype_nsec3);
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews}
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
a737f45fbacf209ec75595c85447b2bfd264138bAndreas Gustafsson/*
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Generate NSEC3 records for the zone.
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austeinstatic void
45fca822d565a2c600b04330a1dd25a9db7e2974Andreas Gustafssonnsec3ify(unsigned int hashalg, unsigned int iterations,
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein{
f9f9c47053364ba915d3ef0dbb4f55bd202487daAndreas Gustafsson dns_dbiterator_t *dbiter = NULL;
60084a1a5a9e570842b8147ff4c34b68ce4de7f8Andreas Gustafsson dns_dbnode_t *node = NULL, *nextnode = NULL;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_fixedname_t fname, fnextname, fzonecut;
60084a1a5a9e570842b8147ff4c34b68ce4de7f8Andreas Gustafsson dns_name_t *name, *nextname, *zonecut;
45fca822d565a2c600b04330a1dd25a9db7e2974Andreas Gustafsson dns_rdataset_t rdataset;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdatasetiter_t *rdsiter = NULL;
b796a9c6f99410b08f4ecdfca5d9ddf7bd6d1ad5Andreas Gustafsson dns_rdatatype_t type, covers;
23dd0aa5d54bd459dbb5e73f1213fb103114945cAndreas Gustafsson int order;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_boolean_t active;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein isc_boolean_t done = ISC_FALSE;
23dd0aa5d54bd459dbb5e73f1213fb103114945cAndreas Gustafsson isc_result_t result;
23dd0aa5d54bd459dbb5e73f1213fb103114945cAndreas Gustafsson isc_uint32_t nsttl = 0;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein unsigned int count, nlabels;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdataset_init(&rdataset);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_fixedname_init(&fname);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein name = dns_fixedname_name(&fname);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_fixedname_init(&fnextname);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein nextname = dns_fixedname_name(&fnextname);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_fixedname_init(&fzonecut);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein zonecut = NULL;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /*
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein * Walk the zone generating the hash names.
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein check_result(result, "dns_db_createiterator()");
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_dbiterator_first(dbiter);
23dd0aa5d54bd459dbb5e73f1213fb103114945cAndreas Gustafsson check_result(result, "dns_dbiterator_first()");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews check_dns_dbiterator_current(result);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews /*
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews * Delete any NSEC records at the apex.
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews */
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews check_result(result, "dns_db_allrdatasets()");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews for (result = dns_rdatasetiter_first(rdsiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result == ISC_R_SUCCESS;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_rdatasetiter_next(rdsiter)) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_rdatasetiter_current(rdsiter, &rdataset);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews type = rdataset.type;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews covers = rdataset.covers;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_rdataset_disassociate(&rdataset);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (type == dns_rdatatype_nsec ||
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews covers == dns_rdatatype_nsec) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (!update_chain)
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews fatal("Zone contains NSEC records. Use -u "
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews "to update to NSEC3.");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_db_deleterdataset(gdb, node, gversion,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews type, covers);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews check_result(result,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews "dns_db_deleterdataset(nsec3param/rrsig)");
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews continue;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_rdatasetiter_destroy(&rdsiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_db_detachnode(gdb, &node);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews while (!done) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews check_dns_dbiterator_current(result);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_next(dbiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews nextnode = NULL;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews while (result == ISC_R_SUCCESS) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews nextname);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews check_dns_dbiterator_current(result);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews active = active_node(nextnode);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (!active) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_db_detachnode(gdb, &nextnode);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_next(dbiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews continue;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews (zonecut != NULL &&
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_name_issubdomain(nextname, zonecut))) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_db_detachnode(gdb, &nextnode);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_next(dbiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews continue;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (delegation(nextname, nextnode, &nsttl)) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews zonecut = dns_fixedname_name(&fzonecut);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_name_copy(nextname, zonecut, NULL);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (generateds)
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews add_ds(nextname, nextnode, nsttl);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (OPTOUT(nsec3flags) &&
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews !secure(nextname, nextnode)) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_db_detachnode(gdb, &nextnode);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews result = dns_dbiterator_next(dbiter);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews continue;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_db_detachnode(gdb, &nextnode);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews break;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews }
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews if (result == ISC_R_NOMORE) {
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_name_copy(gorigin, nextname, NULL);
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews done = ISC_TRUE;
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews } else if (result != ISC_R_SUCCESS)
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews fatal("iterating through the database failed: %s",
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews isc_result_totext(result));
6cf369f528c4acd8182eada41ad83b8d97623db8Mark Andrews dns_name_downcase(name, name, NULL);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence hashlist_add_dns_name(hashlist, name, hashalg, iterations,
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence salt, salt_length, ISC_FALSE);
df3c4c7988b9bae7d121a8ac9ed17a23366a948dDavid Lawrence dns_db_detachnode(gdb, &node);
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley /*
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.
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson */
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley dns_name_downcase(nextname, nextname, NULL);
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff dns_name_fullcompare(name, nextname, &order, &nlabels);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews addnowildcardhash(hashlist, name, hashalg, iterations,
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley salt, salt_length);
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley count = dns_name_countlabels(nextname);
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington while (count > nlabels + 1) {
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson count--;
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley dns_name_split(nextname, count, NULL, nextname);
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff hashlist_add_dns_name(hashlist, nextname, hashalg,
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews iterations, salt, salt_length,
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley ISC_FALSE);
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley addnowildcardhash(hashlist, nextname, hashalg,
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington iterations, salt, salt_length);
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson }
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley }
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff dns_dbiterator_destroy(&dbiter);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley /*
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley * We have all the hashes now so we can sort them.
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews */
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews hashlist_sort(hashlist);
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley /*
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley * Check for duplicate hashes. If found the salt needs to
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * be changed.
2180f41c907e013715cbc54c64545b26fc3c0dbaMichael Graff */
2180f41c907e013715cbc54c64545b26fc3c0dbaMichael Graff if (hashlist_hasdup(hashlist))
2180f41c907e013715cbc54c64545b26fc3c0dbaMichael Graff fatal("Duplicate hash detected. Pick a different salt.");
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley /*
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Generate the nsec3 records.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley */
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington zonecut = NULL;
b1e8b7fd92f6b23954c8077d6f5de93fab23fc12Andreas Gustafsson done = ISC_FALSE;
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson addnsec3param(salt, salt_length, iterations);
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson /*
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley * Clean out NSEC3 records which don't match this chain.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley */
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews check_result(result, "dns_db_createiterator()");
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews for (result = dns_dbiterator_first(dbiter);
b2f85baf7905bad89781f8ef73003d4cfa955257Michael Graff result == ISC_R_SUCCESS;
b2f85baf7905bad89781f8ef73003d4cfa955257Michael Graff result = dns_dbiterator_next(dbiter)) {
b2f85baf7905bad89781f8ef73003d4cfa955257Michael Graff result = dns_dbiterator_current(dbiter, &node, name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_dns_dbiterator_current(result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews nsec3clean(name, node, hashalg, iterations, salt, salt_length,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews hashlist);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_db_detachnode(gdb, &node);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_dbiterator_destroy(&dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Generate / complete the new chain.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_result(result, "dns_db_createiterator()");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_first(dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_result(result, "dns_dbiterator_first()");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (!done) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_current(dbiter, &node, name);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_dns_dbiterator_current(result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_next(dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews nextnode = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (result == ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_current(dbiter, &nextnode,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews nextname);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews check_dns_dbiterator_current(result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews active = active_node(nextnode);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (!active) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_db_detachnode(gdb, &nextnode);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_next(dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews continue;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (!dns_name_issubdomain(nextname, gorigin) ||
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews (zonecut != NULL &&
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_name_issubdomain(nextname, zonecut))) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_db_detachnode(gdb, &nextnode);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_dbiterator_next(dbiter);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews continue;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (delegation(nextname, nextnode, NULL)) {
e560f615b2592deea69c49bfc74acbb56f4fd913Mark Andrews zonecut = dns_fixedname_name(&fzonecut);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_name_copy(nextname, zonecut, NULL);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews if (OPTOUT(nsec3flags) &&
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews !secure(nextname, nextnode)) {
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_db_detachnode(gdb, &nextnode);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews result = dns_dbiterator_next(dbiter);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews continue;
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews }
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews }
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_db_detachnode(gdb, &nextnode);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews break;
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews }
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews if (result == ISC_R_NOMORE) {
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_name_copy(gorigin, nextname, NULL);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews done = ISC_TRUE;
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews } else if (result != ISC_R_SUCCESS)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("iterating through the database failed: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_result_totext(result));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews /*
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * We need to pause here to release the lock on the database.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbiterator_pause(dbiter);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews addnsec3(name, node, salt, salt_length, iterations,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews hashlist, zone_soa_min_ttl);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_db_detachnode(gdb, &node);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews /*
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Add NSEC3's for empty nodes. Use closest encloser logic.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_fullcompare(name, nextname, &order, &nlabels);
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews count = dns_name_countlabels(nextname);
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews while (count > nlabels + 1) {
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews count--;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_split(nextname, count, NULL, nextname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews addnsec3(nextname, NULL, salt, salt_length,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews iterations, hashlist, zone_soa_min_ttl);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbiterator_destroy(&dbiter);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews/*%
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Load the zone file from disk
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsloadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_buffer_t b;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews int len;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_fixedname_t fname;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_name_t *name;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_result_t result;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews len = strlen(origin);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_buffer_init(&b, origin, len);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_buffer_add(&b, len);
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews dns_fixedname_init(&fname);
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews name = dns_fixedname_name(&fname);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result != ISC_R_SUCCESS)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("failed converting name '%s' to dns format: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews origin, isc_result_totext(result));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews rdclass, 0, NULL, db);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews check_result(result, "dns_db_create()");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_load2(*db, file, inputformat);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("failed loading zone from '%s': %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews file, isc_result_totext(result));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews/*%
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Finds all public zone keys in the zone, and attempts to load the
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * private keys from disk.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsloadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_dbnode_t *node;
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews dns_dbversion_t *currentversion = NULL;
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews isc_result_t result;
7794a776e0c12bb5be0b813dfd7fa797358ff451Mark Andrews dns_rdataset_t rdataset, keysigs, soasigs;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews node = NULL;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (result != ISC_R_SUCCESS)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews fatal("failed to find the zone's origin: %s",
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews isc_result_totext(result));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_db_currentversion(gdb, &currentversion);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_rdataset_init(&rdataset);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_rdataset_init(&soasigs);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews dns_rdataset_init(&keysigs);
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews /* Make note of the keys which signed the SOA, if any */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_db_findrdataset(gdb, node, currentversion,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdatatype_soa, 0, 0,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein &rdataset, &soasigs);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (result != ISC_R_SUCCESS)
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein goto cleanup;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein /* Preserve the TTL of the DNSKEY RRset, if any */
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein dns_rdataset_disassociate(&rdataset);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein result = dns_db_findrdataset(gdb, node, currentversion,
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews dns_rdatatype_dnskey, 0, 0,
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein &rdataset, &keysigs);
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (set_keyttl && keyttl != rdataset.ttl) {
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein fprintf(stderr, "User-specified TTL (%d) conflicts "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "with existing DNSKEY RRset TTL.\n",
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley keyttl);
9fbc1afb8b08432e3a1adda1f41d5575620e9785Bob Halley fprintf(stderr, "Imported keys will use the RRSet "
694c897b20f06f8a5349fd9ac5df93947f6f5a2aBob Halley "TTL (%d) instead.\n",
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley rdataset.ttl);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley }
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley keyttl = rdataset.ttl;
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley /* Load keys corresponding to the existing DNSKEY RRset */
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley &rdataset, &keysigs, &soasigs,
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley preserve_keys, load_public,
d8dcd6ad4617cc8d7df979bd62101fa9c4bac1bcBob Halley &keylist);
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington if (result != ISC_R_SUCCESS)
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington fatal("failed to load the zone keys: %s",
fafb62400d2f1b1da4f3908447e1f3935fc5155bBrian Wellington isc_result_totext(result));
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington cleanup:
1d92d8a2456b23842a649b6104c60a9d6ea25333Brian Wellington if (dns_rdataset_isassociated(&rdataset))
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson dns_rdataset_disassociate(&rdataset);
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson if (dns_rdataset_isassociated(&keysigs))
be7f27304337afbf078e8bd8db0f951a33abe33bAndreas Gustafsson dns_rdataset_disassociate(&keysigs);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley if (dns_rdataset_isassociated(&soasigs))
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley dns_rdataset_disassociate(&soasigs);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley dns_db_detachnode(gdb, &node);
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews dns_db_closeversion(gdb, &currentversion, ISC_FALSE);
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews}
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrewsstatic void
c68fa795a1c87fd5d0386e0503dc5666490ac77fMichael Graffloadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
c68fa795a1c87fd5d0386e0503dc5666490ac77fMichael Graff isc_result_t result;
c68fa795a1c87fd5d0386e0503dc5666490ac77fMichael Graff int i;
c7620c99f1139b77f14678e21a44f7c8c4236a7bMark Andrews
35c842e05dc6382ce1d9161a658d3ff4b2c3d4c9Bob Halley for (i = 0; i < n; i++) {
bf6d4f9cad79d182eea7487e2ee2fb2bc4b0824eBrian Wellington dns_dnsseckey_t *key = NULL;
34729dbcb3526974cf98ee03ec20a107d9458417Andreas Gustafsson dst_key_t *newkey = NULL;
34729dbcb3526974cf98ee03ec20a107d9458417Andreas Gustafsson
34729dbcb3526974cf98ee03ec20a107d9458417Andreas Gustafsson result = dst_key_fromnamedfile(keyfiles[i], directory,
44aae046c38e796e581110b7ecdf4478167d684dBob Halley DST_TYPE_PUBLIC |
44aae046c38e796e581110b7ecdf4478167d684dBob Halley DST_TYPE_PRIVATE,
44aae046c38e796e581110b7ecdf4478167d684dBob Halley mctx, &newkey);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley if (result != ISC_R_SUCCESS)
fa67ca21f6d5033221d9893b3c38a7bf8fecdb18Mark Andrews fatal("cannot load dnskey %s: %s", keyfiles[i],
690a68b8112039e633e26f9216c0d463751e011aMichael Graff isc_result_totext(result));
1cafbcfa6f7560597e577f78795143b4964464d9Bob Halley
12ccbb032ec1b5f6b93aac923f2645a19fc90c75David Lawrence if (!dns_name_equal(gorigin, dst_key_name(newkey)))
326bcfa0e2a6b924cb829a0bcc3bf9590ce21ad6Mark Andrews fatal("key %s not at origin\n", keyfiles[i]);
cc5ea458fe9f12f247e2549b6dc24fe475a824c2Michael Sawyer
d11097cf86e789c8dbb7df86753491b30add2f5aMichael Sawyer if (!dst_key_isprivate(newkey))
44aae046c38e796e581110b7ecdf4478167d684dBob Halley fatal("cannot sign zone with non-private dnskey %s",
44aae046c38e796e581110b7ecdf4478167d684dBob Halley keyfiles[i]);
44aae046c38e796e581110b7ecdf4478167d684dBob Halley
44aae046c38e796e581110b7ecdf4478167d684dBob Halley /* Skip any duplicates */
297a9ce042b977f2e4eb3b3e4bf9e7b72f96d640William King for (key = ISC_LIST_HEAD(keylist);
297a9ce042b977f2e4eb3b3e4bf9e7b72f96d640William King key != NULL;
297a9ce042b977f2e4eb3b3e4bf9e7b72f96d640William King key = ISC_LIST_NEXT(key, link)) {
65c4736d9c0ebc6d9b1d991593b55566909da9cdBrian Wellington if (dst_key_id(key->key) == dst_key_id(newkey) &&
a9f861e65b6544e16c23a44b239d80436b3e0414William King dst_key_alg(key->key) == dst_key_alg(newkey))
0111b7c5e12837bca4b97d2dd0e3989348a6a85dMichael Graff break;
683da0cd900532fc45fa4dfb687b5041156ec8abAndreas Gustafsson }
244b9e154bde055d9b7798111dbaadab5dee73eaMichael Sawyer
3ecf3394e37dc2848a09ffc643565d454e9e6974Andreas Gustafsson if (key == NULL) {
39469093ea30f42ee3fcc6c457688cf8577432c6Brian Wellington /* We haven't seen this key before */
0b1f1952f4a1c8ddb90dc2dfcab30669903c6e8eBrian Wellington dns_dnsseckey_create(mctx, &newkey, &key);
e855fd594d04413c29504bdc6b8792be9fa79bd2Andreas Gustafsson ISC_LIST_APPEND(keylist, key, link);
95be83b467e2384d414693982318a5c06cccf1d7Andreas Gustafsson key->source = dns_keysource_user;
4bd173d7ae482d5cc297295aca6db1d609ab7b91Andreas Gustafsson } else {
59563a18b7d83c3de5bb4b57f41fb4c0f9162cd0Andreas Gustafsson dst_key_free(&key->key);
22f0b13f28a7df3b348b18848d0ccd745ea88c3cAndreas Gustafsson key->key = newkey;
c7dd0420a25bcc4adcdd8d8f9d6b01c3e90ae816Brian Wellington }
b5ad6dfea4cc3e7d1d322ac99f1e5a31096837c4Mark Andrews
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein key->force_publish = ISC_TRUE;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein key->force_sign = ISC_TRUE;
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein
268a4475065fe6a8cd7cc707820982cf5e98f430Rob Austein if (setksk)
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews key->ksk = ISC_TRUE;
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews }
29747dfe5e073a299b3681e01f5c55540f8bfed7Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsreport(const char *format, ...) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews va_list args;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews va_start(args, format);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews vfprintf(stderr, format, args);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews va_end(args);
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence}
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrewsstatic void
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrewsbuild_final_keylist() {
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews isc_result_t result;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews dns_dbversion_t *ver = NULL;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews dns_diff_t del, add;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews dns_dnsseckeylist_t matchkeys;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews char name[DNS_NAME_FORMATSIZE];
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews /*
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews * Find keys that match this zone in the key repository.
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews */
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews ISC_LIST_INIT(matchkeys);
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews result = dns_dnssec_findmatchingkeys(gorigin, directory,
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews mctx, &matchkeys);
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews if (result == ISC_R_NOTFOUND)
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews result = ISC_R_SUCCESS;
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews check_result(result, "dns_dnssec_findmatchingkeys");
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews result = dns_db_newversion(gdb, &ver);
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews check_result(result, "dns_db_newversion");
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews dns_diff_init(mctx, &del);
3ca0e71a863fe3fbb4f439e5d0bebfd7bd38fb16Mark Andrews dns_diff_init(mctx, &add);
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence /*
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence * Update keylist with information from from the key repository.
afbf0f0d778da7958bbd8d7d71614f32cdc9a9b0David Lawrence */
dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
&add, &del, ignore_kskflag, mctx, report);
dns_name_format(gorigin, name, sizeof(name));
result = dns_diff_applysilently(&del, gdb, ver);
if (result != ISC_R_SUCCESS)
fatal("failed to delete DNSKEYs at node '%s': %s",
name, isc_result_totext(result));
result = dns_diff_applysilently(&add, gdb, ver);
if (result != ISC_R_SUCCESS)
fatal("failed to add DNSKEYs at node '%s': %s",
name, isc_result_totext(result));
dns_db_closeversion(gdb, &ver, ISC_TRUE);
dns_diff_clear(&del);
dns_diff_clear(&add);
}
static void
warnifallksk(dns_db_t *db) {
dns_dbversion_t *currentversion = NULL;
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
dns_rdata_dnskey_t dnskey;
isc_boolean_t have_non_ksk = ISC_FALSE;
dns_db_currentversion(db, &currentversion);
result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s",
isc_result_totext(result));
dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, currentversion,
dns_rdatatype_dnskey, 0, 0, &rdataset,
NULL);
if (result != ISC_R_SUCCESS)
fatal("failed to find keys at the zone apex: %s",
isc_result_totext(result));
result = dns_rdataset_first(&rdataset);
check_result(result, "dns_rdataset_first");
while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
check_result(result, "dns_rdata_tostruct");
if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
have_non_ksk = ISC_TRUE;
result = ISC_R_NOMORE;
} else
result = dns_rdataset_next(&rdataset);
dns_rdata_freestruct(&dnskey);
}
dns_rdataset_disassociate(&rdataset);
dns_db_detachnode(db, &node);
dns_db_closeversion(db, &currentversion, ISC_FALSE);
if (!have_non_ksk && !ignore_kskflag) {
if (disable_zone_check)
fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; "
"supply a ZSK or use '-z'.\n",
program);
else
fatal("No non-KSK DNSKEY found; "
"supply a ZSK or use '-z'.");
}
}
static void
set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
isc_boolean_t set_optout, isc_boolean_t set_iter)
{
isc_result_t result;
dns_dbversion_t *ver = NULL;
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3_t nsec3;
dns_fixedname_t fname;
dns_name_t *hashname;
unsigned char orig_salt[256];
size_t orig_saltlen;
dns_hash_t orig_hash;
isc_uint16_t orig_iter;
dns_db_currentversion(gdb, &ver);
dns_rdataset_init(&rdataset);
orig_saltlen = sizeof(orig_salt);
result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
&orig_iter, orig_salt,
&orig_saltlen);
if (result != ISC_R_SUCCESS)
goto cleanup;
nsec_datatype = dns_rdatatype_nsec3;
if (!update_chain && set_salt) {
if (salt_length != orig_saltlen ||
memcmp(saltbuf, orig_salt, salt_length) != 0)
fatal("An NSEC3 chain exists with a different salt. "
"Use -u to update it.");
} else if (!set_salt) {
salt_length = orig_saltlen;
memcpy(saltbuf, orig_salt, orig_saltlen);
salt = saltbuf;
}
if (!update_chain && set_iter) {
if (nsec3iter != orig_iter)
fatal("An NSEC3 chain exists with different "
"iterations. Use -u to update it.");
} else if (!set_iter)
nsec3iter = orig_iter;
/*
* Find an NSEC3 record to get the current OPTOUT value.
* (This assumes all NSEC3 records agree.)
*/
dns_fixedname_init(&fname);
hashname = dns_fixedname_name(&fname);
result = dns_nsec3_hashname(&fname, NULL, NULL,
gorigin, gorigin, dns_hash_sha1,
orig_iter, orig_salt, orig_saltlen);
check_result(result, "dns_nsec3_hashname");
result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
0, 0, &rdataset, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_rdataset_first(&rdataset);
check_result(result, "dns_rdataset_first");
dns_rdataset_current(&rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
check_result(result, "dns_rdata_tostruct");
if (!update_chain && set_optout) {
if (nsec3flags != nsec3.flags)
fatal("An NSEC3 chain exists with%s OPTOUT. "
"Use -u -%s to %s it.",
OPTOUT(nsec3.flags) ? "" : "out",
OPTOUT(nsec3.flags) ? "AA" : "A",
OPTOUT(nsec3.flags) ? "clear" : "set");
} else if (!set_optout)
nsec3flags = nsec3.flags;
dns_rdata_freestruct(&nsec3);
cleanup:
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
if (node != NULL)
dns_db_detachnode(gdb, &node);
dns_db_closeversion(gdb, &ver, ISC_FALSE);
}
static void
writeset(const char *prefix, dns_rdatatype_t type) {
char *filename;
char namestr[DNS_NAME_FORMATSIZE];
dns_db_t *db = NULL;
dns_dbversion_t *version = NULL;
dns_diff_t diff;
dns_difftuple_t *tuple = NULL;
dns_fixedname_t fixed;
dns_name_t *name;
dns_rdata_t rdata, ds;
isc_boolean_t have_ksk = ISC_FALSE;
isc_boolean_t have_non_ksk = ISC_FALSE;
isc_buffer_t b;
isc_buffer_t namebuf;
isc_region_t r;
isc_result_t result;
dns_dnsseckey_t *key, *tmpkey;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
unsigned char keybuf[DST_KEY_MAXSIZE];
unsigned int filenamelen;
const dns_master_style_t *style =
(type == dns_rdatatype_dnskey) ? masterstyle : dsstyle;
isc_buffer_init(&namebuf, namestr, sizeof(namestr));
result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf);
check_result(result, "dns_name_tofilenametext");
isc_buffer_putuint8(&namebuf, 0);
filenamelen = strlen(prefix) + strlen(namestr);
if (dsdir != NULL)
filenamelen += strlen(dsdir) + 1;
filename = isc_mem_get(mctx, filenamelen + 1);
if (filename == NULL)
fatal("out of memory");
if (dsdir != NULL)
sprintf(filename, "%s/", dsdir);
else
filename[0] = 0;
strcat(filename, prefix);
strcat(filename, namestr);
dns_diff_init(mctx, &diff);
if (type == dns_rdatatype_dlv) {
dns_name_t tname;
unsigned int labels;
dns_name_init(&tname, NULL);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
labels = dns_name_countlabels(gorigin);
dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname);
result = dns_name_concatenate(&tname, dlv, name, NULL);
check_result(result, "dns_name_concatenate");
} else
name = gorigin;
for (key = ISC_LIST_HEAD(keylist);
key != NULL;
key = ISC_LIST_NEXT(key, link))
{
if (REVOKE(key->key))
continue;
if (isksk(key)) {
have_ksk = ISC_TRUE;
have_non_ksk = ISC_FALSE;
} else {
have_ksk = ISC_FALSE;
have_non_ksk = ISC_TRUE;
}
for (tmpkey = ISC_LIST_HEAD(keylist);
tmpkey != NULL;
tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key))
continue;
if (REVOKE(tmpkey->key))
continue;
if (isksk(tmpkey))
have_ksk = ISC_TRUE;
else
have_non_ksk = ISC_TRUE;
}
if (have_ksk && have_non_ksk && !isksk(key))
continue;
dns_rdata_init(&rdata);
dns_rdata_init(&ds);
isc_buffer_init(&b, keybuf, sizeof(keybuf));
result = dst_key_todns(key->key, &b);
check_result(result, "dst_key_todns");
isc_buffer_usedregion(&b, &r);
dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r);
if (type != dns_rdatatype_dnskey) {
result = dns_ds_buildrdata(gorigin, &rdata,
DNS_DSDIGEST_SHA1,
dsbuf, &ds);
check_result(result, "dns_ds_buildrdata");
if (type == dns_rdatatype_dlv)
ds.type = dns_rdatatype_dlv;
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
name, 0, &ds, &tuple);
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
dns_rdata_reset(&ds);
result = dns_ds_buildrdata(gorigin, &rdata,
DNS_DSDIGEST_SHA256,
dsbuf, &ds);
check_result(result, "dns_ds_buildrdata");
if (type == dns_rdatatype_dlv)
ds.type = dns_rdatatype_dlv;
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
name, 0, &ds, &tuple);
} else
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
gorigin, zone_soa_min_ttl,
&rdata, &tuple);
check_result(result, "dns_difftuple_create");
dns_diff_append(&diff, &tuple);
}
result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
gclass, 0, NULL, &db);
check_result(result, "dns_db_create");
result = dns_db_newversion(db, &version);
check_result(result, "dns_db_newversion");
result = dns_diff_apply(&diff, db, version);
check_result(result, "dns_diff_apply");
dns_diff_clear(&diff);
result = dns_master_dump(mctx, db, version, style, filename);
check_result(result, "dns_master_dump");
isc_mem_put(mctx, filename, filenamelen + 1);
dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
}
static void
print_time(FILE *fp) {
time_t currenttime;
if (outputformat != dns_masterformat_text)
return;
currenttime = time(NULL);
fprintf(fp, "; File written on %s", ctime(&currenttime));
}
static void
print_version(FILE *fp) {
if (outputformat != dns_masterformat_text)
return;
fprintf(fp, "; dnssec_signzone version " VERSION "\n");
}
ISC_PLATFORM_NORETURN_PRE static void
usage(void) ISC_PLATFORM_NORETURN_POST;
static void
usage(void) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\t%s [options] zonefile [keys]\n", program);
fprintf(stderr, "\n");
fprintf(stderr, "Version: %s\n", VERSION);
fprintf(stderr, "Options: (default value in parenthesis) \n");
fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
"\t\tfor the zone and determines how they are to "
"be used\n");
fprintf(stderr, "\t-K directory:\n");
fprintf(stderr, "\t\tdirectory to find key files (.)\n");
fprintf(stderr, "\t-d directory:\n");
fprintf(stderr, "\t\tdirectory to find dsset files (.)\n");
fprintf(stderr, "\t-g:\t");
fprintf(stderr, "generate dsset file, and/or include DS records\n"
"\t\tfrom child zones' dsset files\n");
fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
"(now + 30 days)\n");
fprintf(stderr, "\t-i interval:\n");
fprintf(stderr, "\t\tcycle interval - resign "
"if < interval from end ( (end-start)/4 )\n");
fprintf(stderr, "\t-j jitter:\n");
fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
fprintf(stderr, "\t-v debuglevel (0)\n");
fprintf(stderr, "\t-o origin:\n");
fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
fprintf(stderr, "\t-f outfile:\n");
fprintf(stderr, "\t\tfile the signed zone is written in "
"(zonefile + .signed)\n");
fprintf(stderr, "\t-I format:\n");
fprintf(stderr, "\t\tfile format of input zonefile (text)\n");
fprintf(stderr, "\t-O format:\n");
fprintf(stderr, "\t\tfile format of signed zone file (text)\n");
fprintf(stderr, "\t-N format:\n");
fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n");
fprintf(stderr, "\t-r randomdev:\n");
fprintf(stderr, "\t\ta file containing random data\n");
fprintf(stderr, "\t-a:\t");
fprintf(stderr, "verify generated signatures\n");
fprintf(stderr, "\t-c class (IN)\n");
fprintf(stderr, "\t-E engine:\n");
#ifdef USE_PKCS11
fprintf(stderr, "\t\tname of an OpenSSL engine to use "
"(default is \"pkcs11\")\n");
#else
fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
#endif
fprintf(stderr, "\t-p:\t");
fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
fprintf(stderr, "\t-P:\t");
fprintf(stderr, "disable post-sign verification\n");
fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs");
fprintf(stderr, "\t-t:\t");
fprintf(stderr, "print statistics\n");
fprintf(stderr, "\t-u:\t");
fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n");
fprintf(stderr, "\t-z:\tsign all records with KSKs\n");
fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
"\t\twith older versions of dnssec-signzone -g\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
fprintf(stderr, "\t-k key_signing_key\n");
fprintf(stderr, "\t-l lookasidezone\n");
fprintf(stderr, "\t-3 NSEC3 salt\n");
fprintf(stderr, "\t-H NSEC3 iterations (10)\n");
fprintf(stderr, "\t-A NSEC3 optout\n");
fprintf(stderr, "\n");
fprintf(stderr, "Signing Keys: ");
fprintf(stderr, "(default: all zone keys that have private keys)\n");
fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n");
exit(0);
}
static void
removetempfile(void) {
if (removefile)
isc_file_remove(tempfile);
}
static void
print_stats(isc_time_t *timer_start, isc_time_t *timer_finish) {
isc_uint64_t runtime_us; /* Runtime in microseconds */
isc_uint64_t runtime_ms; /* Runtime in milliseconds */
isc_uint64_t sig_ms; /* Signatures per millisecond */
runtime_us = isc_time_microdiff(timer_finish, timer_start);
printf("Signatures generated: %10d\n", nsigned);
printf("Signatures retained: %10d\n", nretained);
printf("Signatures dropped: %10d\n", ndropped);
printf("Signatures successfully verified: %10d\n", nverified);
printf("Signatures unsuccessfully verified: %10d\n", nverifyfailed);
runtime_ms = runtime_us / 1000;
printf("Runtime in seconds: %7u.%03u\n",
(unsigned int) (runtime_ms / 1000),
(unsigned int) (runtime_ms % 1000));
if (runtime_us > 0) {
sig_ms = ((isc_uint64_t)nsigned * 1000000000) / runtime_us;
printf("Signatures per second: %7u.%03u\n",
(unsigned int) sig_ms / 1000,
(unsigned int) sig_ms % 1000);
}
}
int
main(int argc, char *argv[]) {
int i, ch;
char *startstr = NULL, *endstr = NULL, *classname = NULL;
char *origin = NULL, *file = NULL, *output = NULL;
char *inputformatstr = NULL, *outputformatstr = NULL;
char *serialformatstr = NULL;
char *dskeyfile[MAXDSKEYS];
int ndskeys = 0;
char *endp;
isc_time_t timer_start, timer_finish;
dns_dnsseckey_t *key;
isc_result_t result;
isc_log_t *log = NULL;
isc_boolean_t pseudorandom = ISC_FALSE;
#ifdef USE_PKCS11
const char *engine = "pkcs11";
#else
const char *engine = NULL;
#endif
unsigned int eflags;
isc_boolean_t free_output = ISC_FALSE;
int tempfilelen;
dns_rdataclass_t rdclass;
isc_task_t **tasks = NULL;
isc_buffer_t b;
int len;
hashlist_t hashlist;
isc_boolean_t smartsign = ISC_FALSE;
isc_boolean_t make_keyset = ISC_FALSE;
isc_boolean_t set_salt = ISC_FALSE;
isc_boolean_t set_optout = ISC_FALSE;
isc_boolean_t set_iter = ISC_FALSE;
#define CMDLINE_FLAGS \
"3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
/*
* Process memory debugging argument first.
*/
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
case 'm':
if (strcasecmp(isc_commandline_argument, "record") == 0)
isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
if (strcasecmp(isc_commandline_argument, "trace") == 0)
isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
if (strcasecmp(isc_commandline_argument, "usage") == 0)
isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
if (strcasecmp(isc_commandline_argument, "size") == 0)
isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
if (strcasecmp(isc_commandline_argument, "mctx") == 0)
isc_mem_debugging |= ISC_MEM_DEBUGCTX;
break;
default:
break;
}
}
isc_commandline_reset = ISC_TRUE;
masterstyle = &dns_master_style_explicitttl;
check_result(isc_app_start(), "isc_app_start");
result = isc_mem_create(0, 0, &mctx);
if (result != ISC_R_SUCCESS)
fatal("out of memory");
dns_result_register();
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
switch (ch) {
case '3':
set_salt = ISC_TRUE;
nsec_datatype = dns_rdatatype_nsec3;
if (strcmp(isc_commandline_argument, "-") != 0) {
isc_buffer_t target;
char *sarg;
sarg = isc_commandline_argument;
isc_buffer_init(&target, saltbuf,
sizeof(saltbuf));
result = isc_hex_decodestring(sarg, &target);
check_result(result,
"isc_hex_decodestring(salt)");
salt_length = isc_buffer_usedlength(&target);
}
break;
case 'A':
set_optout = ISC_TRUE;
if (OPTOUT(nsec3flags))
nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
else
nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
break;
case 'a':
tryverify = ISC_TRUE;
break;
case 'C':
make_keyset = ISC_TRUE;
break;
case 'c':
classname = isc_commandline_argument;
break;
case 'd':
dsdir = isc_commandline_argument;
if (strlen(dsdir) == 0U)
fatal("DS directory must be non-empty string");
result = try_dir(dsdir);
if (result != ISC_R_SUCCESS)
fatal("cannot open directory %s: %s",
dsdir, isc_result_totext(result));
break;
case 'E':
engine = isc_commandline_argument;
break;
case 'e':
endstr = isc_commandline_argument;
break;
case 'f':
output = isc_commandline_argument;
break;
case 'g':
generateds = ISC_TRUE;
break;
case 'H':
set_iter = ISC_TRUE;
nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("iterations must be numeric");
if (nsec3iter > 0xffffU)
fatal("iterations too big");
break;
case 'h':
usage();
break;
case 'I':
inputformatstr = isc_commandline_argument;
break;
case 'i':
endp = NULL;
cycle = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0' || cycle < 0)
fatal("cycle period must be numeric and "
"positive");
break;
case 'j':
endp = NULL;
jitter = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0' || jitter < 0)
fatal("jitter must be numeric and positive");
break;
case 'K':
directory = isc_commandline_argument;
break;
case 'k':
if (ndskeys == MAXDSKEYS)
fatal("too many key-signing keys specified");
dskeyfile[ndskeys++] = isc_commandline_argument;
break;
case 'l':
len = strlen(isc_commandline_argument);
isc_buffer_init(&b, isc_commandline_argument, len);
isc_buffer_add(&b, len);
dns_fixedname_init(&dlv_fixed);
dlv = dns_fixedname_name(&dlv_fixed);
result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
NULL);
check_result(result, "dns_name_fromtext(dlv)");
break;
case 'm':
break;
case 'N':
serialformatstr = isc_commandline_argument;
break;
case 'n':
endp = NULL;
ntasks = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0' || ntasks > ISC_INT32_MAX)
fatal("number of cpus must be numeric");
break;
case 'O':
outputformatstr = isc_commandline_argument;
break;
case 'o':
origin = isc_commandline_argument;
break;
case 'P':
disable_zone_check = ISC_TRUE;
break;
case 'p':
pseudorandom = ISC_TRUE;
break;
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
case 'S':
smartsign = ISC_TRUE;
generateds = ISC_TRUE;
break;
case 's':
startstr = isc_commandline_argument;
break;
case 'T':
endp = NULL;
set_keyttl = ISC_TRUE;
keyttl = strtottl(isc_commandline_argument);
break;
case 't':
printstats = ISC_TRUE;
break;
case 'U': /* Undocumented for testing only. */
unknownalg = ISC_TRUE;
break;
case 'u':
update_chain = ISC_TRUE;
break;
case 'v':
endp = NULL;
verbose = strtol(isc_commandline_argument, &endp, 0);
if (*endp != '\0')
fatal("verbose level must be numeric");
break;
case 'x':
keyset_kskonly = ISC_TRUE;
break;
case 'z':
ignore_kskflag = ISC_TRUE;
break;
case 'F':
/* Reserved for FIPS mode */
/* FALLTHROUGH */
case '?':
if (isc_commandline_option != '?')
fprintf(stderr, "%s: invalid argument -%c\n",
program, isc_commandline_option);
usage();
break;
default:
fprintf(stderr, "%s: unhandled option -%c\n",
program, isc_commandline_option);
exit(1);
}
}
if (ectx == NULL)
setup_entropy(mctx, NULL, &ectx);
eflags = ISC_ENTROPY_BLOCKING;
if (!pseudorandom)
eflags |= ISC_ENTROPY_GOODONLY;
result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
if (result != ISC_R_SUCCESS)
fatal("could not create hash context");
result = dst_lib_init2(mctx, ectx, engine, eflags);
if (result != ISC_R_SUCCESS)
fatal("could not initialize dst: %s",
isc_result_totext(result));
isc_stdtime_get(&now);
if (startstr != NULL) {
starttime = strtotime(startstr, now, now);
} else
starttime = now - 3600; /* Allow for some clock skew. */
if (endstr != NULL) {
endtime = strtotime(endstr, now, starttime);
} else
endtime = starttime + (30 * 24 * 60 * 60);
if (cycle == -1)
cycle = (endtime - starttime) / 4;
if (ntasks == 0)
ntasks = isc_os_ncpus() * 2;
vbprintf(4, "using %d cpus\n", ntasks);
rdclass = strtoclass(classname);
if (directory == NULL)
directory = ".";
setup_logging(verbose, mctx, &log);
argc -= isc_commandline_index;
argv += isc_commandline_index;
if (argc < 1)
usage();
file = argv[0];
argc -= 1;
argv += 1;
if (origin == NULL)
origin = file;
if (output == NULL) {
free_output = ISC_TRUE;
output = isc_mem_allocate(mctx,
strlen(file) + strlen(".signed") + 1);
if (output == NULL)
fatal("out of memory");
sprintf(output, "%s.signed", file);
}
if (inputformatstr != NULL) {
if (strcasecmp(inputformatstr, "text") == 0)
inputformat = dns_masterformat_text;
else if (strcasecmp(inputformatstr, "raw") == 0)
inputformat = dns_masterformat_raw;
else
fatal("unknown file format: %s\n", inputformatstr);
}
if (outputformatstr != NULL) {
if (strcasecmp(outputformatstr, "text") == 0)
outputformat = dns_masterformat_text;
else if (strcasecmp(outputformatstr, "raw") == 0)
outputformat = dns_masterformat_raw;
else
fatal("unknown file format: %s\n", outputformatstr);
}
if (serialformatstr != NULL) {
if (strcasecmp(serialformatstr, "keep") == 0)
serialformat = SOA_SERIAL_KEEP;
else if (strcasecmp(serialformatstr, "increment") == 0 ||
strcasecmp(serialformatstr, "incr") == 0)
serialformat = SOA_SERIAL_INCREMENT;
else if (strcasecmp(serialformatstr, "unixtime") == 0)
serialformat = SOA_SERIAL_UNIXTIME;
else
fatal("unknown soa serial format: %s\n",
serialformatstr);
}
result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
0, 24, 0, 0, 0, 8, mctx);
check_result(result, "dns_master_stylecreate");
gdb = NULL;
TIME_NOW(&timer_start);
loadzone(file, origin, rdclass, &gdb);
gorigin = dns_db_origin(gdb);
gclass = dns_db_class(gdb);
get_soa_ttls();
if (!set_keyttl)
keyttl = soa_ttl;
/*
* Check for any existing NSEC3 parameters in the zone,
* and use them as defaults if -u was not specified.
*/
if (update_chain && !set_optout && !set_iter && !set_salt)
nsec_datatype = dns_rdatatype_nsec;
else
set_nsec3params(update_chain, set_salt, set_optout, set_iter);
if (IS_NSEC3) {
isc_boolean_t answer;
hash_length = dns_nsec3_hashlength(dns_hash_sha1);
hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
hash_length);
result = dns_nsec_nseconly(gdb, gversion, &answer);
check_result(result, "dns_nsec_nseconly");
if (answer)
fatal("NSEC3 generation requested with "
"NSEC only DNSKEY");
}
/*
* We need to do this early on, as we start messing with the list
* of keys rather early.
*/
ISC_LIST_INIT(keylist);
isc_rwlock_init(&keylist_lock, 0, 0);
/*
* Fill keylist with:
* 1) Keys listed in the DNSKEY set that have
* private keys associated
* 2) KSKs set on the command line
* 3) ZSKs set on the command line
* 4) Any keys remaining in the DNSKEY set which
* do not have private keys associated and were
* not specified on the command line.
*/
loadzonekeys(!smartsign, ISC_FALSE);
loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
loadexplicitkeys(argv, argc, ISC_FALSE);
loadzonekeys(!smartsign, ISC_TRUE);
/*
* If we're doing smart signing, look in the key repository for
* key files with metadata, and merge them with the keylist
* we have now.
*/
if (smartsign)
build_final_keylist();
/* Now enumerate the key list */
for (key = ISC_LIST_HEAD(keylist);
key != NULL;
key = ISC_LIST_NEXT(key, link)) {
key->index = keycount++;
}
if (keycount == 0) {
if (disable_zone_check)
fprintf(stderr, "%s: warning: No keys specified "
"or found\n", program);
else
fatal("No signing keys specified or found.");
nokeys = ISC_TRUE;
}
if (IS_NSEC3) {
unsigned int max;
result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
check_result(result, "dns_nsec3_maxiterations()");
if (nsec3iter > max)
fatal("NSEC3 iterations too big for weakest DNSKEY "
"strength. Maximum iterations allowed %u.", max);
}
warnifallksk(gdb);
gversion = NULL;
result = dns_db_newversion(gdb, &gversion);
check_result(result, "dns_db_newversion()");
switch (serialformat) {
case SOA_SERIAL_INCREMENT:
setsoaserial(0);
break;
case SOA_SERIAL_UNIXTIME:
setsoaserial(now);
break;
case SOA_SERIAL_KEEP:
default:
/* do nothing */
break;
}
if (IS_NSEC3)
nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
&hashlist);
else
nsecify();
if (!nokeys) {
writeset("dsset-", dns_rdatatype_ds);
if (make_keyset)
writeset("keyset-", dns_rdatatype_dnskey);
if (dlv != NULL) {
writeset("dlvset-", dns_rdatatype_dlv);
}
}
tempfilelen = strlen(output) + 20;
tempfile = isc_mem_get(mctx, tempfilelen);
if (tempfile == NULL)
fatal("out of memory");
result = isc_file_mktemplate(output, tempfile, tempfilelen);
check_result(result, "isc_file_mktemplate");
fp = NULL;
result = isc_file_openunique(tempfile, &fp);
if (result != ISC_R_SUCCESS)
fatal("failed to open temporary output file: %s",
isc_result_totext(result));
removefile = ISC_TRUE;
setfatalcallback(&removetempfile);
print_time(fp);
print_version(fp);
result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr);
if (result != ISC_R_SUCCESS)
fatal("failed to create task manager: %s",
isc_result_totext(result));
master = NULL;
result = isc_task_create(taskmgr, 0, &master);
if (result != ISC_R_SUCCESS)
fatal("failed to create task: %s", isc_result_totext(result));
tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
if (tasks == NULL)
fatal("out of memory");
for (i = 0; i < (int)ntasks; i++) {
tasks[i] = NULL;
result = isc_task_create(taskmgr, 0, &tasks[i]);
if (result != ISC_R_SUCCESS)
fatal("failed to create task: %s",
isc_result_totext(result));
}
RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS);
if (printstats)
RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS);
presign();
signapex();
if (!finished) {
/*
* There is more work to do. Spread it out over multiple
* processors if possible.
*/
for (i = 0; i < (int)ntasks; i++) {
result = isc_app_onrun(mctx, master, startworker,
tasks[i]);
if (result != ISC_R_SUCCESS)
fatal("failed to start task: %s",
isc_result_totext(result));
}
(void)isc_app_run();
if (!finished)
fatal("process aborted by user");
} else
isc_task_detach(&master);
shuttingdown = ISC_TRUE;
for (i = 0; i < (int)ntasks; i++)
isc_task_detach(&tasks[i]);
isc_taskmgr_destroy(&taskmgr);
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
postsign();
verifyzone();
if (outputformat != dns_masterformat_text) {
result = dns_master_dumptostream2(mctx, gdb, gversion,
masterstyle, outputformat,
fp);
check_result(result, "dns_master_dumptostream2");
}
result = isc_stdio_close(fp);
check_result(result, "isc_stdio_close");
removefile = ISC_FALSE;
result = isc_file_rename(tempfile, output);
if (result != ISC_R_SUCCESS)
fatal("failed to rename temp file to %s: %s\n",
output, isc_result_totext(result));
DESTROYLOCK(&namelock);
if (printstats)
DESTROYLOCK(&statslock);
printf("%s\n", output);
dns_db_closeversion(gdb, &gversion, ISC_FALSE);
dns_db_detach(&gdb);
while (!ISC_LIST_EMPTY(keylist)) {
key = ISC_LIST_HEAD(keylist);
ISC_LIST_UNLINK(keylist, key, link);
dns_dnsseckey_destroy(mctx, &key);
}
isc_mem_put(mctx, tempfile, tempfilelen);
if (free_output)
isc_mem_free(mctx, output);
dns_master_styledestroy(&dsstyle, mctx);
cleanup_logging(&log);
dst_lib_destroy();
isc_hash_destroy();
cleanup_entropy(&ectx);
dns_name_destroy();
if (verbose > 10)
isc_mem_stats(mctx, stdout);
isc_mem_destroy(&mctx);
(void) isc_app_finish();
if (printstats) {
TIME_NOW(&timer_finish);
print_stats(&timer_start, &timer_finish);
}
return (0);
}