]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2608. [func] Perform post signing verification checks in
authorMark Andrews <marka@isc.org>
Thu, 4 Jun 2009 02:41:54 +0000 (02:41 +0000)
committerMark Andrews <marka@isc.org>
Thu, 4 Jun 2009 02:41:54 +0000 (02:41 +0000)
                        dnssec-signzone.  These can be disabled with -P.

                        The post sign verification test ensures that for each
                        algorithm in use there is at least one non revoked
                        self signed KSK key.  That all revoked KSK keys are
                        self signed.  That all records in the zone are signed
                        by the algorithm.  [RT #19653]

CHANGES
bin/dnssec/dnssec-signzone.c
bin/dnssec/dnssec-signzone.docbook
bin/dnssec/dnssectool.c
bin/tests/system/dnssec/ns1/sign.sh
bin/tests/system/dnssec/ns2/sign.sh
bin/tests/system/dnssec/ns3/sign.sh
lib/dns/dnssec.c
lib/dns/include/dns/dnssec.h
lib/dns/include/dns/keyvalues.h

diff --git a/CHANGES b/CHANGES
index 126e037c4ff5547cae348493869015ed22c2ab0f..8724c3b9a5601860bf2ab3c9b0413540dbc2f4a6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+2608.  [func]          Perform post signing verification checks in
+                       dnssec-signzone.  These can be disabled with -P.
+
+                       The post sign verification test ensures that for each
+                       algorithm in use there is at least one non revoked
+                       self signed KSK key.  That all revoked KSK keys are
+                       self signed.  That all records in the zone are signed
+                       by the algorithm.  [RT #19653]
+
 2607.  [bug]           named could incorrectly delete NSEC3 records for
                        empty nodes when processing a update request.  
                        [RT #19749]
index 1da280f711f657a8a98103850abadbe71fd81ed5..3cf84f7624333b11d973de211deb2641c2c3e8d4 100644 (file)
@@ -29,7 +29,7 @@
  * 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 */
 
@@ -51,6 +51,7 @@
 #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>
@@ -106,6 +107,8 @@ struct signer_key_struct {
        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;
 };
@@ -127,6 +130,7 @@ struct signer_event {
 
 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;
@@ -164,6 +168,7 @@ static dns_master_style_t *dsstyle = NULL;
 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) {               \
@@ -206,6 +211,8 @@ newkeystruct(dst_key_t *dstkey, isc_boolean_t signwithkey) {
                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);
@@ -255,13 +262,11 @@ iszonekey(signer_key_t *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);
@@ -269,15 +274,50 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
                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,
@@ -289,6 +329,8 @@ keythatsigned(dns_rdata_rrsig_t *rrsig) {
        } else
                key = newkeystruct(pubkey, ISC_FALSE);
        ISC_LIST_APPEND(keylist, key, link);
+
+       isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
        return (key);
 }
 
@@ -438,6 +480,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                                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,
@@ -453,6 +496,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                                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,
@@ -511,6 +555,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                        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,
@@ -555,6 +600,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
                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);
@@ -1198,7 +1244,7 @@ cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
        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);
@@ -1248,6 +1294,419 @@ postsign(void) {
        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
@@ -1764,7 +2223,8 @@ nsec3clean(dns_name_t *name, dns_dbnode_t *node,
             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 &&
@@ -2134,7 +2594,7 @@ warnifallksk(dns_db_t *db) {
        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, &currentversion);
@@ -2155,21 +2615,27 @@ warnifallksk(dns_db_t *db) {
        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, &currentversion, 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
@@ -2370,6 +2836,8 @@ usage(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");
@@ -2567,8 +3035,13 @@ main(int argc, char *argv[]) {
                                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);
@@ -2580,12 +3053,6 @@ main(int argc, char *argv[]) {
                        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;
 
@@ -2600,15 +3067,6 @@ main(int argc, char *argv[]) {
                        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;
@@ -2621,6 +3079,10 @@ main(int argc, char *argv[]) {
                        pseudorandom = ISC_TRUE;
                        break;
 
+               case 'P':
+                       disable_zone_check = ISC_TRUE;
+                       break;
+
                case 'r':
                        setup_entropy(mctx, isc_commandline_argument, &ectx);
                        break;
@@ -2653,6 +3115,18 @@ main(int argc, char *argv[]) {
                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);
                }
        }
 
@@ -2769,7 +3243,12 @@ main(int argc, char *argv[]) {
                              "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);
@@ -2806,6 +3285,7 @@ main(int argc, char *argv[]) {
                        }
                        if (key == NULL) {
                                key = newkeystruct(newkey, ISC_TRUE);
+                               key->commandline = ISC_TRUE;
                                ISC_LIST_APPEND(keylist, key, link);
                        } else
                                dst_key_free(&newkey);
@@ -2856,8 +3336,11 @@ main(int argc, char *argv[]) {
        }
 
        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;
        }
 
@@ -2972,6 +3455,7 @@ main(int argc, char *argv[]) {
        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,
index 2f26ba4e15502dee92fdfd7938b72bac538a6059..70f53fdf540cbd3564c5b682e20bd69ccd61e1b3 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: dnssec-signzone.docbook,v 1.31 2008/10/14 14:28:25 jreed Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.31.44.1 2009/06/04 02:41:54 marka Exp $ -->
 <refentry id="man.dnssec-signzone">
   <refentryinfo>
     <date>June 30, 2000</date>
@@ -72,6 +72,7 @@
       <arg><option>-o <replaceable class="parameter">origin</replaceable></option></arg>
       <arg><option>-O <replaceable class="parameter">output-format</replaceable></option></arg>
       <arg><option>-p</option></arg>
+      <arg><option>-P</option></arg>
       <arg><option>-r <replaceable class="parameter">randomdev</replaceable></option></arg>
       <arg><option>-s <replaceable class="parameter">start-time</replaceable></option></arg>
       <arg><option>-t</option></arg>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>-P</term>
+        <listitem>
+          <para>
+           Disable post sign verification tests.
+          </para>
+          <para>
+           The post sign verification test ensures that for each algorithm
+           in use there is at least one non revoked self signed KSK key.
+           That all revoked KSK keys are self signed.  That all records
+           in the zone are signed by the algorithm.
+          </para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>-r <replaceable class="parameter">randomdev</replaceable></term>
         <listitem>
index e933a06d6023fdb47a36bef56bc1fd3976700beb..7018827d556040398b17470149de5f5b127bb525 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssectool.c,v 1.45 2007/06/19 23:46:59 tbox Exp $ */
+/* $Id: dnssectool.c,v 1.45.334.1 2009/06/04 02:41:54 marka Exp $ */
 
 /*! \file */
 
@@ -65,7 +65,7 @@ void
 fatal(const char *format, ...) {
        va_list args;
 
-       fprintf(stderr, "%s: ", program);
+       fprintf(stderr, "%s: fatal: ", program);
        va_start(args, format);
        vfprintf(stderr, format, args);
        va_end(args);
index 9bc0dddaf1c391b9231379738c93f1032c4b3b2e..3356dc45a23a7deb626d07c37e9543c71a917c63 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.25 2008/09/25 04:02:38 tbox Exp $
+# $Id: sign.sh,v 1.25.48.1 2009/06/04 02:41:54 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -35,8 +35,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
 cat $infile $keyname.key > $zonefile
 
-echo $SIGNER -g -r $RANDFILE -o $zone $zonefile
-$SIGNER -g -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null
 
 # Configure the resolving server with a trusted key.
 
index 4389678cd45b1331ccd61ba9bf7c1ad20a99fabe..1bb4007c8106d14c055eb78f7561031aee1bac73 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.30 2008/09/25 04:02:38 tbox Exp $
+# $Id: sign.sh,v 1.30.48.1 2009/06/04 02:41:54 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -40,7 +40,7 @@ keyname2=`$KEYGEN -r $RANDFILE -a DSA -b 768 -n zone $zone`
 
 cat $infile $keyname1.key $keyname2.key >$zonefile
 
-$SIGNER -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
+$SIGNER -P -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
 
 # Sign the privately secure file
 
@@ -52,7 +52,7 @@ privkeyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $privzone`
 
 cat $privinfile $privkeyname.key >$privzonefile
 
-$SIGNER -g -r $RANDFILE -o $privzone -l dlv $privzonefile > /dev/null
+$SIGNER -P -g -r $RANDFILE -o $privzone -l dlv $privzonefile > /dev/null
 
 # Sign the DLV secure zone.
 
@@ -65,4 +65,4 @@ dlvkeyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $dlvzone`
 
 cat $dlvinfile $dlvkeyname.key dlvset-$privzone > $dlvzonefile
 
-$SIGNER -g -r $RANDFILE -o $dlvzone $dlvzonefile > /dev/null
+$SIGNER -P -g -r $RANDFILE -o $dlvzone $dlvzonefile > /dev/null
index eb362aa9a561c7890a36530996c79d90fd886e83..346daf02199e9edfb82e729d941386b061e1e330 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.25 2008/09/25 04:02:38 tbox Exp $
+# $Id: sign.sh,v 1.25.48.1 2009/06/04 02:41:54 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -30,7 +30,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 zone=bogus.example.
 infile=bogus.example.db.in
@@ -40,7 +40,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 zone=dynamic.example.
 infile=dynamic.example.db.in
@@ -51,7 +51,7 @@ keyname2=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 1024 -n zone -f KSK $zone`
 
 cat $infile $keyname1.key $keyname2.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 zone=keyless.example.
 infile=keyless.example.db.in
@@ -61,7 +61,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 # Change the signer field of the a.b.keyless.example SIG A
 # to point to a provably nonexistent KEY record.
@@ -81,7 +81,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 #  NSEC3/NSEC3 test zone
@@ -94,7 +94,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 #  OPTOUT/NSEC3 test zone
@@ -107,7 +107,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 # A nsec3 zone (non-optout).
@@ -120,7 +120,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -g -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -g -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 #  OPTOUT/NSEC test zone
@@ -133,7 +133,7 @@ keyname=`$KEYGEN -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 #  OPTOUT/NSEC3 test zone
@@ -146,7 +146,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 #  OPTOUT/OPTOUT test zone
@@ -159,7 +159,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 # A optout nsec3 zone.
@@ -172,7 +172,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -g -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -g -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 # A nsec3 zone (non-optout) with unknown hash algorithm.
@@ -185,7 +185,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -U -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -U -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 # A optout nsec3 zone.
@@ -198,7 +198,7 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -3 - -U -A -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -U -A -r $RANDFILE -o $zone $zonefile > /dev/null
 
 #
 # A multiple parameter nsec3 zone.
@@ -211,14 +211,14 @@ keyname=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 768 -n zone $zone`
 
 cat $infile $keyname.key >$zonefile
 
-$SIGNER -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null
 mv $zonefile.signed $zonefile
-$SIGNER -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 - -r $RANDFILE -o $zone $zonefile > /dev/null
 mv $zonefile.signed $zonefile
-$SIGNER -3 AAAA -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 AAAA -r $RANDFILE -o $zone $zonefile > /dev/null
 mv $zonefile.signed $zonefile
-$SIGNER -3 BBBB -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 BBBB -r $RANDFILE -o $zone $zonefile > /dev/null
 mv $zonefile.signed $zonefile
-$SIGNER -3 CCCC -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 CCCC -r $RANDFILE -o $zone $zonefile > /dev/null
 mv $zonefile.signed $zonefile
-$SIGNER -3 DDDD -r $RANDFILE -o $zone $zonefile > /dev/null
+$SIGNER -P -3 DDDD -r $RANDFILE -o $zone $zonefile > /dev/null
index f06d715c4d32f15879e02446ca1187549b9dfb05..8afeadfff057d592b2f0324e2872a799f51e949d 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 /*
- * $Id: dnssec.c,v 1.93 2008/11/14 23:47:33 tbox Exp $
+ * $Id: dnssec.c,v 1.93.12.1 2009/06/04 02:41:54 marka Exp $
  */
 
 /*! \file */
@@ -93,6 +93,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
        isc_result_t ret;
        int i = 0, n;
        dns_rdata_t *data;
+       dns_rdataset_t rdataset;
 
        n = dns_rdataset_count(set);
 
@@ -100,8 +101,11 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
        if (data == NULL)
                return (ISC_R_NOMEMORY);
 
-       ret = dns_rdataset_first(set);
+       dns_rdataset_init(&rdataset);
+       dns_rdataset_clone(set, &rdataset);
+       ret = dns_rdataset_first(&rdataset);
        if (ret != ISC_R_SUCCESS) {
+               dns_rdataset_disassociate(&rdataset);
                isc_mem_put(mctx, data, n * sizeof(dns_rdata_t));
                return (ret);
        }
@@ -111,8 +115,8 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
         */
        do {
                dns_rdata_init(&data[i]);
-               dns_rdataset_current(set, &data[i++]);
-       } while (dns_rdataset_next(set) == ISC_R_SUCCESS);
+               dns_rdataset_current(&rdataset, &data[i++]);
+       } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
 
        /*
         * Sort the array.
@@ -120,6 +124,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
        qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
        *rdata = data;
        *nrdata = n;
+       dns_rdataset_disassociate(&rdataset);
        return (ISC_R_SUCCESS);
 }
 
@@ -890,3 +895,59 @@ failure:
 
        return (result);
 }
+
+/*%
+ * Does this key ('rdata') self sign the rrset ('rdataset')?
+ */
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+                    dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+                    isc_boolean_t ignoretime, isc_mem_t *mctx)
+{
+       dst_key_t *dstkey = NULL;
+        dns_keytag_t keytag;
+        dns_rdata_dnskey_t key;
+        dns_rdata_rrsig_t sig;
+        dns_rdata_t sigrdata = DNS_RDATA_INIT;
+        isc_result_t result;
+
+        INSIST(rdataset->type == dns_rdatatype_key ||
+               rdataset->type == dns_rdatatype_dnskey);
+       if (rdataset->type == dns_rdatatype_key) {
+               INSIST(sigrdataset->type == dns_rdatatype_sig);
+               INSIST(sigrdataset->covers == dns_rdatatype_key);
+       } else {
+               INSIST(sigrdataset->type == dns_rdatatype_rrsig);
+               INSIST(sigrdataset->covers == dns_rdatatype_dnskey);
+       }
+
+       result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey);
+       if (result != ISC_R_SUCCESS)
+               return (ISC_FALSE);
+       result = dns_rdata_tostruct(rdata, &key, NULL);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+       keytag = dst_key_id(dstkey);
+       for (result = dns_rdataset_first(sigrdataset);
+            result == ISC_R_SUCCESS;
+            result = dns_rdataset_next(sigrdataset))
+       {
+               dns_rdata_reset(&sigrdata);
+               dns_rdataset_current(sigrdataset, &sigrdata);
+               result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+               if (sig.algorithm == key.algorithm &&
+                   sig.keyid == keytag) {
+                       result = dns_dnssec_verify2(name, rdataset, dstkey,
+                                                   ignoretime, mctx,
+                                                   &sigrdata, NULL);
+                       if (result == ISC_R_SUCCESS) {
+                               dst_key_free(&dstkey);
+                               return (ISC_TRUE);
+                       }
+               }
+        }
+       dst_key_free(&dstkey);
+        return (ISC_FALSE);
+}
index f8a59d05f87fe981dc5d5c3ebec80ba9de126f97..5addf867ed08b7426e8a8beab80b9e66c79f5cfb 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: dnssec.h,v 1.32 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: dnssec.h,v 1.32.332.1 2009/06/04 02:41:54 marka Exp $ */
 
 #ifndef DNS_DNSSEC_H
 #define DNS_DNSSEC_H 1
@@ -178,6 +178,12 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
  *\li          DST_R_*
  */
 
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+                     dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+                     isc_boolean_t ignoretime, isc_mem_t *mctx);
+
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_DNSSEC_H */
index 7040389403668f9a967eedca490ac73b3427aecc..a89cc74e63bdc6ecb298eb18bbf1368ead12c8c6 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: keyvalues.h,v 1.23 2008/09/25 04:02:39 tbox Exp $ */
+/* $Id: keyvalues.h,v 1.23.48.1 2009/06/04 02:41:54 marka Exp $ */
 
 #ifndef DNS_KEYVALUES_H
 #define DNS_KEYVALUES_H 1
@@ -42,7 +42,7 @@
 #define DNS_KEYOWNER_ENTITY    0x0200  /*%< key is assoc. with entity eg host */
 #define DNS_KEYOWNER_ZONE      0x0100  /*%< key is zone key */
 #define DNS_KEYOWNER_RESERVED  0x0300  /*%< reserved meaning */
-#define DNS_KEYFLAG_RESERVED8  0x0080  /*%< reserved - must be zero */
+#define DNS_KEYFLAG_REVOKE     0x0080  /*%< key revoked (per rfc5001) */
 #define DNS_KEYFLAG_RESERVED9  0x0040  /*%< reserved - must be zero */
 #define DNS_KEYFLAG_RESERVED10 0x0020  /*%< reserved - must be zero */
 #define DNS_KEYFLAG_RESERVED11 0x0010  /*%< reserved - must be zero */