]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
* Add ldns-verify-zone -s option. It checks all signature results,
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Feb 2025 14:08:35 +0000 (15:08 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Feb 2025 14:08:35 +0000 (15:08 +0100)
  instead of passing by when one RRSIG validates. That prints output
  for spurious RRSIGs, the failures for them.

Changelog
examples/ldns-verify-zone.1.in
examples/ldns-verify-zone.c

index d4a294bd8b9e1748969f09a3630e2e317cd8486b..19cfc4f114aec276534c0a4caa402932133c1bb3 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -13,6 +13,9 @@
          window and the type modulo 256 is equal to zero.
        * Fix #271: Intermittent build failure with multi-job
          builds (make -j).
+       * Add ldns-verify-zone -s option. It checks all signature results,
+         instead of passing by when one RRSIG validates. That prints output
+         for spurious RRSIGs, the failures for them.
 
 1.8.4  2024-07-19
        * Fix building documentation in build directory.
index 6bea57f0c1535d45bd84b2bec6ca8ee0f676b860..ea232d7130bd2ab7678fd3ebe72db169c2d761f6 100644 (file)
@@ -48,6 +48,13 @@ Only check this percentage of the zone.
 Which names to check is determined randomly.
 Defaults to 100.
 
+.TP
+\fB-s\fR
+Check all signature results, instead of one. Without the option one signature
+that validates stops error output for the RRset. With the option, all
+results from signature validations are printed. For spurious RRSIGs that
+prints output for the spurious RRSIGs if they are wrong.
+
 .TP
 \fB-S\fR
 Chase signature(s) to a known key.
index ac076cd1afe7b3d95f05985bd2a94ae85507e963..8bf00d51e4956f0aadb957b5040a34e7acd71920 100644 (file)
@@ -26,6 +26,7 @@ static int32_t inception_offset = 0;
 static int32_t expiration_offset = 0;
 static bool do_sigchase = false;
 static bool no_nomatch_msg = false;
+static int check_all_sigs = 0;
 
 static FILE* myout;
 static FILE* myerr;
@@ -171,23 +172,32 @@ verify_rrs(ldns_rr_list* rrset_rrs, ldns_dnssec_rrs* cur_sig,
                ldns_rr_list* keys)
 {
        ldns_status status, result = LDNS_STATUS_OK;
+       int one_signature_verified = 0;
        ldns_dnssec_rrs *cur_sig_bak = cur_sig;
+       int is_dnskey_rrset = ldns_rr_list_rr_count(rrset_rrs) > 0 &&
+           ldns_rr_get_type(ldns_rr_list_rr(rrset_rrs, 0)) == LDNS_RR_TYPE_DNSKEY;
 
        /* A single valid signature validates the RRset */
-       while (cur_sig) {
+       /* With check all sigs, it skips this, except for the DNSKEY RRset. */
+       if(!check_all_sigs || is_dnskey_rrset) {
+           while (cur_sig) {
                if (ldns_verify_rrsig_keylist_time( rrset_rrs, cur_sig->rr
                                                  , keys, check_time, NULL)
                ||  rrsig_check_time_margins(cur_sig->rr))
                        cur_sig = cur_sig->next;
                else
                        return LDNS_STATUS_OK;
+           }
        }
        /* Without any valid signature, do print all errors.  */
+       /* When checking all sigs, keep track if one is valid. */
        for (cur_sig = cur_sig_bak; cur_sig; cur_sig = cur_sig->next) {
                status = ldns_verify_rrsig_keylist_time(rrset_rrs,
                    cur_sig->rr, keys, check_time, NULL);
                status = status ? status 
                       : rrsig_check_time_margins(cur_sig->rr);
+               if(check_all_sigs && status == LDNS_STATUS_OK)
+                       one_signature_verified += 1;
                if (!status)
                        ; /* pass */
                else if (!no_nomatch_msg || status !=
@@ -196,6 +206,8 @@ verify_rrs(ldns_rr_list* rrset_rrs, ldns_dnssec_rrs* cur_sig,
                            myerr, rrset_rrs, status, cur_sig);
                update_error(&result, status);
        }
+       if(check_all_sigs && one_signature_verified)
+               return LDNS_STATUS_OK;
        return result;
 }
 
@@ -712,6 +724,7 @@ static void print_usage(FILE *out, const char *progname)
               "\t\t\tDefault is %s\n", LDNS_TRUST_ANCHOR_FILE);
        fprintf(out, "\t-p [0-100]\tonly checks this percentage of "
               "the zone.\n\t\t\tDefaults to 100\n");
+       fprintf(out, "\t-s\t\tcheck all signature results, instead of one.\n");
        fprintf(out, "\t-S\t\tchase signature(s) to a known key. "
               "The network may be\n\t\t\taccessed to "
               "validate the zone's DNSKEYs. (implies -k)\n");
@@ -759,7 +772,7 @@ main(int argc, char **argv)
        myout = stdout;
        myerr = stderr;
 
-       while ((c = getopt(argc, argv, "ae:hi:k:vV:p:St:Z")) != -1) {
+       while ((c = getopt(argc, argv, "ae:hi:k:vV:p:sSt:Z")) != -1) {
                switch(c) {
                 case 'a':
                         apexonly = true;
@@ -828,6 +841,9 @@ main(int argc, char **argv)
                         }
                         srandom(time(NULL) ^ getpid());
                         break;
+               case 's':
+                       check_all_sigs = 1;
+                       break;
                case 'S':
                        do_sigchase = true;
                        /* may chase */