* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.209.12.3 2009/01/18 23:25:15 marka Exp $ */
+/* $Id: dnssec-signzone.c,v 1.209.12.4 2009/06/04 02:41:54 marka Exp $ */
/*! \file */
#include <isc/os.h>
#include <isc/print.h>
#include <isc/random.h>
+#include <isc/rwlock.h>
#include <isc/serial.h>
#include <isc/stdio.h>
#include <isc/stdlib.h>
isc_boolean_t issigningkey;
isc_boolean_t isdsk;
isc_boolean_t isksk;
+ isc_boolean_t wasused;
+ isc_boolean_t commandline;
unsigned int position;
ISC_LINK(signer_key_t) link;
};
static ISC_LIST(signer_key_t) keylist;
static unsigned int keycount = 0;
+isc_rwlock_t keylist_lock;
static isc_stdtime_t starttime = 0, endtime = 0, now;
static int cycle = -1;
static int jitter = 0;
static unsigned int serialformat = SOA_SERIAL_KEEP;
static unsigned int hash_length = 0;
static isc_boolean_t unknownalg = ISC_FALSE;
+static isc_boolean_t disable_zone_check = ISC_FALSE;
#define INCSTAT(counter) \
if (printstats) { \
key->isksk = ISC_FALSE;
key->isdsk = ISC_TRUE;
}
+ key->wasused = ISC_FALSE;
+ key->commandline = ISC_FALSE;
key->position = keycount++;
ISC_LINK_INIT(key, link);
return (key);
}
/*%
- * Finds the key that generated a RRSIG, if possible. First look at the keys
- * that we've loaded already, and then see if there's a key on disk.
+ * Find the key if it is in our list. If it is, return it, otherwise null.
+ * No locking is performed here, this must be done by the caller.
*/
static signer_key_t *
-keythatsigned(dns_rdata_rrsig_t *rrsig) {
- isc_result_t result;
- dst_key_t *pubkey = NULL, *privkey = NULL;
+keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
signer_key_t *key;
key = ISC_LIST_HEAD(keylist);
if (rrsig->keyid == dst_key_id(key->key) &&
rrsig->algorithm == dst_key_alg(key->key) &&
dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
- return key;
+ return (key);
key = ISC_LIST_NEXT(key, link);
}
+ return (NULL);
+}
+
+/*%
+ * Finds the key that generated a RRSIG, if possible. First look at the keys
+ * that we've loaded already, and then see if there's a key on disk.
+ */
+static signer_key_t *
+keythatsigned(dns_rdata_rrsig_t *rrsig) {
+ isc_result_t result;
+ dst_key_t *pubkey = NULL, *privkey = NULL;
+ signer_key_t *key;
+
+ isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
+ key = keythatsigned_unlocked(rrsig);
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read);
+ if (key != NULL)
+ return (key);
+
+ /*
+ * We did not find the key in our list. Get a write lock now, since
+ * we may be modifying the bits. We could do the tryupgrade() dance,
+ * but instead just get a write lock and check once again to see if
+ * it is on our list. It's possible someone else may have added it
+ * after all.
+ */
+ isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
+
+ key = keythatsigned_unlocked(rrsig);
+ if (key != NULL) {
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
+ return (key);
+ }
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm, DST_TYPE_PUBLIC,
NULL, mctx, &pubkey);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (NULL);
+ }
result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
rrsig->algorithm,
} else
key = newkeystruct(pubkey, ISC_FALSE);
ISC_LIST_APPEND(keylist, key, link);
+
+ isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
return (key);
}
keep = ISC_TRUE;
wassignedby[key->position] = ISC_TRUE;
nowsignedby[key->position] = ISC_TRUE;
+ key->wasused = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
keep = ISC_TRUE;
wassignedby[key->position] = ISC_TRUE;
nowsignedby[key->position] = ISC_TRUE;
+ key->wasused = ISC_TRUE;
} else {
vbprintf(2, "\trrsig by %s dropped - %s\n",
sigstr,
isc_buffer_init(&b, array, sizeof(array));
signwithkey(name, set, &trdata, key->key, &b);
nowsignedby[key->position] = ISC_TRUE;
+ key->wasused = ISC_TRUE;
tuple = NULL;
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
name, ttl, &trdata,
dns_rdata_init(&trdata);
isc_buffer_init(&b, array, sizeof(array));
signwithkey(name, set, &trdata, key->key, &b);
+ key->wasused = ISC_TRUE;
tuple = NULL;
result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
ttl, &trdata, &tuple);
dns_rdataset_t set;
isc_result_t result, dresult;
- if (outputformat != dns_masterformat_text)
+ if (outputformat != dns_masterformat_text || !disable_zone_check)
return;
dns_rdataset_init(&set);
dns_dbiterator_destroy(&gdbiter);
}
+static isc_boolean_t
+goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
+ dns_rdataset_t *rdataset)
+{
+ dns_rdata_dnskey_t key;
+ dns_rdata_rrsig_t sig;
+ dst_key_t *dstkey = NULL;
+ isc_result_t result;
+
+ dns_rdata_tostruct(sigrdata, &sig, NULL);
+
+ for (result = dns_rdataset_first(keyrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(keyrdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(keyrdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &key, NULL);
+ result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
+ &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ if (sig.algorithm != key.algorithm ||
+ sig.keyid != dst_key_id(dstkey) ||
+ !dns_name_equal(&sig.signer, gorigin)) {
+ dst_key_free(&dstkey);
+ continue;
+ }
+ result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
+ mctx, sigrdata);
+ dst_key_free(&dstkey);
+ if (result == ISC_R_SUCCESS)
+ return(ISC_TRUE);
+ }
+ return (ISC_FALSE);
+}
+
+static void
+verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
+ dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
+ char *bad_algorithms)
+{
+ unsigned char set_algorithms[256];
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char algbuf[80];
+ char typebuf[80];
+ dns_rdataset_t sigrdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ isc_result_t result;
+ int i;
+
+ dns_rdataset_init(&sigrdataset);
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ for (result = dns_rdatasetiter_first(rdsiter);
+ result == ISC_R_SUCCESS;
+ result = dns_rdatasetiter_next(rdsiter)) {
+ dns_rdatasetiter_current(rdsiter, &sigrdataset);
+ if (sigrdataset.type == dns_rdatatype_rrsig &&
+ sigrdataset.covers == rdataset->type)
+ break;
+ dns_rdataset_disassociate(&sigrdataset);
+ }
+ if (result != ISC_R_SUCCESS) {
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ type_format(rdataset->type, typebuf, sizeof(typebuf));
+ fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
+ for (i = 0; i < 256; i++)
+ if (ksk_algorithms[i])
+ bad_algorithms[i] = 1;
+ return;
+ }
+
+ memset(set_algorithms, 0, sizeof(set_algorithms));
+ for (result = dns_rdataset_first(&sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&sigrdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_rrsig_t sig;
+
+ dns_rdataset_current(&sigrdataset, &rdata);
+ dns_rdata_tostruct(&rdata, &sig, NULL);
+ if (set_algorithms[sig.algorithm] ||
+ !ksk_algorithms[sig.algorithm])
+ continue;
+ if (goodsig(&rdata, name, keyrdataset, rdataset))
+ set_algorithms[sig.algorithm] = 1;
+ }
+ dns_rdatasetiter_destroy(&rdsiter);
+ if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ type_format(rdataset->type, typebuf, sizeof(typebuf));
+ for (i = 0; i < 256; i++)
+ if (ksk_algorithms[i] && !set_algorithms[i]) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s signature for "
+ "%s %s\n", algbuf, namebuf, typebuf);
+ bad_algorithms[i] = 1;
+ }
+ }
+ dns_rdataset_disassociate(&sigrdataset);
+}
+
+static void
+verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
+ dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
+ char *bad_algorithms)
+{
+ dns_rdataset_t rdataset;
+ dns_rdatasetiter_t *rdsiter = NULL;
+ isc_result_t result;
+
+ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
+ check_result(result, "dns_db_allrdatasets()");
+ result = dns_rdatasetiter_first(rdsiter);
+ dns_rdataset_init(&rdataset);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdatasetiter_current(rdsiter, &rdataset);
+ if (rdataset.type != dns_rdatatype_rrsig &&
+ rdataset.type != dns_rdatatype_dnskey &&
+ (!delegation || rdataset.type == dns_rdatatype_ds ||
+ rdataset.type == dns_rdatatype_nsec)) {
+ verifyset(&rdataset, name, node, keyrdataset,
+ ksk_algorithms, bad_algorithms);
+ }
+ dns_rdataset_disassociate(&rdataset);
+ result = dns_rdatasetiter_next(rdsiter);
+ }
+ if (result != ISC_R_NOMORE)
+ fatal("rdataset iteration failed: %s",
+ isc_result_totext(result));
+ dns_rdatasetiter_destroy(&rdsiter);
+}
+
+/*%
+ * Verify that certain things are sane:
+ *
+ * The apex has a DNSKEY record with at least one KSK and at least
+ * one ZSK.
+ *
+ * The DNSKEY record was signed with at least one of the KSKs in this
+ * set.
+ *
+ * The rest of the zone was signed with at least one of the ZSKs
+ * present in the DNSKEY RRSET.
+ */
+static void
+verifyzone(void) {
+ char algbuf[80];
+ dns_dbiterator_t *dbiter = NULL;
+ dns_dbnode_t *node = NULL, *nextnode = NULL;
+ dns_fixedname_t fname, fnextname, fzonecut;
+ dns_name_t *name, *nextname, *zonecut;
+ dns_rdata_dnskey_t dnskey;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ dns_rdataset_t sigrdataset;
+ int i;
+ isc_boolean_t done = ISC_FALSE;
+ isc_boolean_t first = ISC_TRUE;
+ isc_boolean_t goodksk = ISC_FALSE;
+ isc_boolean_t goodzsk = ISC_FALSE;
+ isc_result_t result;
+ unsigned char revoked[256];
+ unsigned char standby[256];
+ unsigned char ksk_algorithms[256];
+ unsigned char zsk_algorithms[256];
+ unsigned char bad_algorithms[256];
+#ifdef ALLOW_KSKLESS_ZONES
+ isc_boolean_t allzsksigned = ISC_TRUE;
+ unsigned char self_algorithms[256];
+#endif
+
+ if (disable_zone_check)
+ return;
+
+ result = dns_db_findnode(gdb, 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);
+ dns_rdataset_init(&sigrdataset);
+ result = dns_db_findrdataset(gdb, node, gversion,
+ dns_rdatatype_dnskey,
+ 0, 0, &rdataset, &sigrdataset);
+ dns_db_detachnode(gdb, &node);
+ if (result != ISC_R_SUCCESS)
+ fatal("cannot find DNSKEY rrset\n");
+
+ if (!dns_rdataset_isassociated(&sigrdataset))
+ fatal("cannot find DNSKEY RRSIGs\n");
+
+ memset(revoked, 0, sizeof(revoked));
+ memset(standby, 0, sizeof(revoked));
+ memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
+ memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
+ memset(bad_algorithms, 0, sizeof(bad_algorithms));
+#ifdef ALLOW_KSKLESS_ZONES
+ memset(self_algorithms, 0, sizeof(self_algorithms));
+#endif
+
+ /*
+ * Check that the DNSKEY RR has at least one self signing KSK and
+ * one ZSK per algorithm in it.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
+ check_result(result, "dns_rdata_tostruct");
+
+ if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
+ ;
+ else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
+ !dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE,
+ mctx)) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char buffer[1024];
+ isc_buffer_t buf;
+
+ dns_name_format(gorigin, namebuf,
+ sizeof(namebuf));
+ isc_buffer_init(&buf, buffer, sizeof(buffer));
+ result = dns_rdata_totext(&rdata, NULL, &buf);
+ check_result(result, "dns_rdata_totext");
+ fatal("revoked KSK is not self signed:\n"
+ "%s DNSKEY %.*s", namebuf,
+ (int)isc_buffer_usedlength(&buf), buffer);
+ }
+ if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
+ revoked[dnskey.algorithm] != 255)
+ revoked[dnskey.algorithm]++;
+ } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
+ if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE, mctx)) {
+ if (ksk_algorithms[dnskey.algorithm] != 255)
+ ksk_algorithms[dnskey.algorithm]++;
+ goodksk = ISC_TRUE;
+ } else {
+ if (standby[dnskey.algorithm] != 255)
+ standby[dnskey.algorithm]++;
+ }
+ } else if (dns_dnssec_selfsigns(&rdata, gorigin, &rdataset,
+ &sigrdataset, ISC_FALSE,
+ mctx)) {
+#ifdef ALLOW_KSKLESS_ZONES
+ if (self_algorithms[dnskey.algorithm] != 255)
+ self_algorithms[dnskey.algorithm]++;
+#endif
+ if (zsk_algorithms[dnskey.algorithm] != 255)
+ zsk_algorithms[dnskey.algorithm]++;
+ goodzsk = ISC_TRUE;
+ } else {
+ if (zsk_algorithms[dnskey.algorithm] != 255)
+ zsk_algorithms[dnskey.algorithm]++;
+#ifdef ALLOW_KSKLESS_ZONES
+ allzsksigned = ISC_FALSE;
+#endif
+ }
+ dns_rdata_freestruct(&dnskey);
+ dns_rdata_reset(&rdata);
+ }
+ dns_rdataset_disassociate(&sigrdataset);
+
+ if (!goodksk) {
+#ifdef ALLOW_KSKLESS_ZONES
+ if (!goodzsk)
+ fatal("no self signing keys found");
+ fprintf(stderr, "No self signing KSK found. Using self signed "
+ "ZSK's for active algorithm list.\n");
+ memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
+ if (!allzsksigned)
+ fprintf(stderr, "warning: not all ZSK's are self "
+ "signed.\n");
+#else
+ fatal("no self signed KSK's found");
+#endif
+ }
+
+ fprintf(stderr, "Verifying the zone using the following algorithms:");
+ for (i = 0; i < 256; i++) {
+ if (ksk_algorithms[i]) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, " %s", algbuf);
+ }
+ }
+ fprintf(stderr, ".\n");
+
+ if (memcmp(ksk_algorithms, zsk_algorithms, sizeof(ksk_algorithms))) {
+ for (i = 0; i < 256; i++) {
+ if (ksk_algorithms[i] == zsk_algorithms[i])
+ continue;
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Missing %s for algorithm %s\n",
+ ksk_algorithms[i] ? "ZSK" : "self signing KSK",
+ algbuf);
+ bad_algorithms[i] = 1;
+ }
+ }
+
+ /*
+ * Check that all the other records were signed by keys that are
+ * present in the DNSKEY RRSET.
+ */
+
+ dns_fixedname_init(&fname);
+ name = dns_fixedname_name(&fname);
+ dns_fixedname_init(&fnextname);
+ nextname = dns_fixedname_name(&fnextname);
+ dns_fixedname_init(&fzonecut);
+ zonecut = NULL;
+
+ result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ result = dns_dbiterator_first(dbiter);
+ check_result(result, "dns_dbiterator_first()");
+
+ while (!done) {
+ isc_boolean_t isdelegation = ISC_FALSE;
+
+ dns_dbiterator_current(dbiter, &node, name);
+ if (delegation(name, node, NULL)) {
+ zonecut = dns_fixedname_name(&fzonecut);
+ dns_name_copy(name, zonecut, NULL);
+ isdelegation = ISC_TRUE;
+ }
+ verifynode(name, node, isdelegation, &rdataset,
+ ksk_algorithms, bad_algorithms);
+ result = dns_dbiterator_next(dbiter);
+ nextnode = NULL;
+ while (result == ISC_R_SUCCESS) {
+ result = dns_dbiterator_current(dbiter, &nextnode,
+ nextname);
+ if (result != ISC_R_SUCCESS)
+ break;
+ if (!dns_name_issubdomain(nextname, gorigin) ||
+ (zonecut != NULL &&
+ dns_name_issubdomain(nextname, zonecut)))
+ {
+ dns_db_detachnode(gdb, &nextnode);
+ result = dns_dbiterator_next(dbiter);
+ continue;
+ }
+ dns_db_detachnode(gdb, &nextnode);
+ break;
+ }
+ if (result == ISC_R_NOMORE) {
+ done = ISC_TRUE;
+ } else if (result != ISC_R_SUCCESS)
+ fatal("iterating through the database failed: %s",
+ isc_result_totext(result));
+ dns_db_detachnode(gdb, &node);
+ }
+
+ dns_dbiterator_destroy(&dbiter);
+
+ result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
+ check_result(result, "dns_db_createiterator()");
+
+ for (result = dns_dbiterator_first(dbiter);
+ result == ISC_R_SUCCESS;
+ result = dns_dbiterator_next(dbiter) ) {
+ dns_dbiterator_current(dbiter, &node, name);
+ verifynode(name, node, ISC_FALSE, &rdataset,
+ ksk_algorithms, bad_algorithms);
+ dns_db_detachnode(gdb, &node);
+ }
+ dns_dbiterator_destroy(&dbiter);
+
+ dns_rdataset_disassociate(&rdataset);
+
+ /*
+ * If we made it this far, we have what we consider a properly signed
+ * zone. Set the good flag.
+ */
+ for (i = 0; i < 256; i++) {
+ if (bad_algorithms[i]) {
+ if (first)
+ fprintf(stderr, "The zone is not fully signed "
+ "for the following algorithms:");
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, " %s", algbuf);
+ first = ISC_FALSE;
+ }
+ }
+ if (!first) {
+ fprintf(stderr, ".\n");
+ fatal("DNSSEC completeness test failed.");
+ }
+
+ if (goodksk) {
+ /*
+ * Print the success summary.
+ */
+ fprintf(stderr, "Zone signing complete:\n");
+ for (i = 0; i < 256; i++) {
+ if (zsk_algorithms[i] || ksk_algorithms[i] ||
+ revoked[i] || standby[i]) {
+ alg_format(i, algbuf, sizeof(algbuf));
+ fprintf(stderr, "Algorithm: %s: ZSKs: %u, "
+ "KSKs: %u active, %u revoked, %u "
+ "stand-by\n", algbuf,
+ zsk_algorithms[i], ksk_algorithms[i],
+ revoked[i], standby[i]);
+ }
+ }
+ }
+}
+
/*%
* Sign the apex of the zone.
* Note the origin may not be the first node if there are out of zone
result = dns_rdataset_next(&rdataset)) {
dns_rdata_init(&rdata);
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ check_result(result, "dns_rdata_tostruct");
if (nsec3.hash == hashalg &&
nsec3.iterations == iterations &&
nsec3.salt_length == salt_length &&
dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
- dns_rdata_key_t key;
+ dns_rdata_dnskey_t dnskey;
isc_boolean_t have_non_ksk = ISC_FALSE;
dns_db_currentversion(db, ¤tversion);
while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &key, NULL);
+ result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
check_result(result, "dns_rdata_tostruct");
- if ((key.flags & DNS_KEYFLAG_KSK) == 0) {
+ 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, ¤tversion, ISC_FALSE);
- if (!have_non_ksk && !ignoreksk)
- fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
- "Supply non-KSK dnskey or use '-z'.\n",
- program);
+ if (!have_non_ksk && !ignoreksk) {
+ if (disable_zone_check)
+ fprintf(stderr, "%s: warning: No non-KSK dnskey found. "
+ "Supply non-KSK dnskey or use '-z'.\n",
+ program);
+ else
+ fatal("No non-KSK dnskey found. "
+ "Supply non-KSK dnskey or use '-z'.");
+ }
}
static void
fprintf(stderr, "verify generated signatures\n");
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:\t");
fprintf(stderr, "print statistics\n");
fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
fatal("jitter must be numeric and positive");
break;
+ case 'k':
+ if (ndskeys == MAXDSKEYS)
+ fatal("too many key-signing keys specified");
+ dskeyfile[ndskeys++] = isc_commandline_argument;
+ break;
+
case 'l':
- dns_fixedname_init(&dlv_fixed);
len = strlen(isc_commandline_argument);
isc_buffer_init(&b, isc_commandline_argument, len);
isc_buffer_add(&b, len);
check_result(result, "dns_name_fromtext(dlv)");
break;
- case 'k':
- if (ndskeys == MAXDSKEYS)
- fatal("too many key-signing keys specified");
- dskeyfile[ndskeys++] = isc_commandline_argument;
- break;
-
case 'm':
break;
serialformatstr = isc_commandline_argument;
break;
- case 'H':
- iterations = strtoul(isc_commandline_argument,
- &endp, 0);
- if (*endp != '\0')
- fatal("iterations must be numeric");
- if (iterations > 0xffffU)
- fatal("iterations too big");
- break;
-
case 'o':
origin = isc_commandline_argument;
break;
pseudorandom = ISC_TRUE;
break;
+ case 'P':
+ disable_zone_check = ISC_TRUE;
+ break;
+
case 'r':
setup_entropy(mctx, isc_commandline_argument, &ectx);
break;
case 'z':
ignoreksk = ISC_TRUE;
break;
+
+ 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);
}
}
"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);
if (argc == 0) {
loadzonekeys(gdb);
}
if (key == NULL) {
key = newkeystruct(newkey, ISC_TRUE);
+ key->commandline = ISC_TRUE;
ISC_LIST_APPEND(keylist, key, link);
} else
dst_key_free(&newkey);
}
if (ISC_LIST_EMPTY(keylist)) {
- fprintf(stderr, "%s: warning: No keys specified or found\n",
- program);
+ 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;
}
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,