]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
key prime, DS test.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Aug 2007 09:33:35 +0000 (09:33 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 16 Aug 2007 09:33:35 +0000 (09:33 +0000)
git-svn-id: file:///svn/unbound/trunk@525 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
doc/README
testcode/unitverify.c
testdata/test_ds_sig.1 [new file with mode: 0644]
util/log.c
validator/val_kentry.c
validator/val_sigcrypt.c
validator/val_utils.c
validator/validator.c

index 7cec25ed28e68c77cc7540545515db1b39ff4fde..aec453a2b2983c44c31e400c1ad75ef883ace9b4 100644 (file)
@@ -1,3 +1,10 @@
+16 August 2007: Wouter
+       - DS sig unit test.
+       - latest release libevent 1.3c and 1.3d have threading fixed.
+       - key entry fixup data pointer and ttl absolute.
+       - This makes a key-prime succeed in validator, with DS or DNSKEY as
+         trust-anchor.
+       
 15 August 2007: Wouter
        - crypto calls to verify signatures.
        - unit test for rrsig verification.
index 54a844e6c26598b481602e68f7f84c6b3a9f82d5..9b216b24dd017fb0030ce1cba243cc289ec99eaf 100644 (file)
@@ -34,7 +34,7 @@ This software is under BSD license, see LICENSE for details.
 
 Known issues
 ------------
-o If libevent is older (1.3 and before), unbound will exit instead of reload
+o If libevent is older (before 1.3c), unbound will exit instead of reload
   on sighup. On a restart 'did not exit gracefully last time' warning is 
   printed. Perform ./configure --with-libevent=no or update libevent, rerun 
   configure and recompile unbound to make sighup work correctly.
index 8087112b3013f0b5dc42d371dc40e2c81e714530..51cca401dff04739ade7d274dea9cd734ac97ac8 100644 (file)
@@ -182,6 +182,59 @@ verifytest_entry(struct entry* e, struct alloc_cache* alloc, struct region*
        query_info_clear(&qinfo);
 }
 
+/** find RRset in reply by type */
+static struct ub_packed_rrset_key*
+find_rrset_type(struct reply_info* rep, uint16_t type)
+{
+       size_t i;
+       for(i=0; i<rep->rrset_count; i++) {
+               if(ntohs(rep->rrsets[i]->rk.type) == type)
+                       return rep->rrsets[i];
+       }
+       return NULL;
+}
+
+/** DS sig test an entry - get DNSKEY and DS in entry and verify */
+static void
+dstest_entry(struct entry* e, struct alloc_cache* alloc, struct region*
+        region, ldns_buffer* pkt, struct module_env* env)
+{
+       struct query_info qinfo;
+       struct reply_info* rep = NULL;
+       struct ub_packed_rrset_key* ds, *dnskey;
+       int ret;
+
+       region_free_all(region);
+       if(vsig) {
+               printf("verifying DS-DNSKEY match:\n");
+               ldns_pkt_print(stdout, e->reply_list->reply);
+               printf("\n");
+       }
+       entry_to_repinfo(e, alloc, region, pkt, &qinfo, &rep);
+       ds = find_rrset_type(rep, LDNS_RR_TYPE_DS);
+       dnskey = find_rrset_type(rep, LDNS_RR_TYPE_DNSKEY);
+       /* check test is OK */
+       unit_assert(ds && dnskey);
+
+       ret = ds_digest_match_dnskey(env, dnskey, 0, ds, 0);
+       if(strncmp((char*)qinfo.qname, "\003yes", 4) == 0) {
+               if(vsig) {
+                       printf("result(yes)= %s\n", ret?"yes":"no");
+               }
+               unit_assert(ret);
+       } else if (strncmp((char*)qinfo.qname, "\002no", 3) == 0) {
+               if(vsig) {
+                       printf("result(no)= %s\n", ret?"yes":"no");
+               }
+               unit_assert(!ret);
+       } else {
+               fatal_exit("Bad qname in DS unit test, yes or no");
+       }
+
+       reply_info_parsedelete(rep, alloc);
+       query_info_clear(&qinfo);
+}
+
 /** verify from a file */
 static void
 verifytest_file(const char* fname, const char* at_date)
@@ -224,9 +277,45 @@ verifytest_file(const char* fname, const char* at_date)
        ldns_buffer_free(buf);
 }
 
+/** verify DS matches DNSKEY from a file */
+static void
+dstest_file(const char* fname)
+{
+       /* 
+        * The file contains a list of ldns-testpkts entries.
+        * The first entry must be a query for DNSKEY.
+        * The answer rrset is the keyset that will be used for verification
+        */
+       struct region* region = region_create(malloc, free);
+       struct alloc_cache alloc;
+       ldns_buffer* buf = ldns_buffer_new(65535);
+       struct entry* e;
+       struct entry* list = read_datafile(fname);
+       struct module_env env;
+
+       if(!list)
+               fatal_exit("could not read %s: %s", fname, strerror(errno));
+       alloc_init(&alloc, NULL, 1);
+       memset(&env, 0, sizeof(env));
+       env.scratch = region;
+       env.scratch_buffer = buf;
+       unit_assert(region && buf);
+
+       /* ready to go! */
+       for(e = list; e; e = e->next) {
+               dstest_entry(e, &alloc, region, buf, &env);
+       }
+
+       delete_entry(list);
+       region_destroy(region);
+       alloc_clear(&alloc);
+       ldns_buffer_free(buf);
+}
+
 void 
 verify_test()
 {
        printf("verify test\n");
        verifytest_file("testdata/test_signatures.1", "20070818005004");
+       dstest_file("testdata/test_ds_sig.1");
 }
diff --git a/testdata/test_ds_sig.1 b/testdata/test_ds_sig.1
new file mode 100644 (file)
index 0000000..b3c6da5
--- /dev/null
@@ -0,0 +1,33 @@
+;
+; DS match test file.
+; test matching of DS hash against DNSKEYs.
+;
+; enter ENTRYs with a DS and a DNSKEY.
+; These are matched against another.
+; If the query name starts with 'yes' then it must match.
+; If the query name starts with 'no' then it must not match.
+
+ENTRY_BEGIN
+SECTION QUESTION
+yes. IN A
+SECTION ANSWER
+nlnetlabs.nl.   3600    IN      DS      43791 RSASHA1 1 81ee88356df3c3077549445ed2fb1c92adc80641
+nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+yes. IN A
+SECTION ANSWER
+jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A
+jelte.nlnetlabs.nl.     3600    IN      DNSKEY  256 3 5 AQOraLfzarHAlFskVGwAGnX0LRjlcOiO6y5WM4Kz+QvZ9vX28h4lOvnf d5tkxnZm7ERLTAJoFq+1w/wl7VXs2Isz75BSZ7LQh3OT2xXnS6VT5ZxX ko/UCOdoGiKZZ63jHZ0jNSTCYy8+5rfvwRD8s3gGuErp5KcHg3V8VLUK SDNNEQ==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+no. IN A
+SECTION ANSWER
+nlnetlabs.nl.   3600    IN      DS      43791 RSASHA1 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A
+nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ==
+ENTRY_END
+
index 8968c705aeff0cfeaaba4dc5af5fd7e851bc6c55..a77e57ad109561bec621cc2cc4839316c52e60e7 100644 (file)
@@ -190,7 +190,7 @@ log_hex(const char* msg, void* data, size_t length)
        else {
                for(i=0; i<length*2; i+=blocksize) {
                        log_info("%s[%u:%u] %.*s", msg, (unsigned)length, 
-                               (unsigned)i, blocksize, buf+i);
+                               (unsigned)i/2, blocksize, buf+i);
                }
        }
        free(buf);
index 5ef050b7c78c8d4598054d8fb5bb194199b486c9..e491fc5fb3180fbd5cc923771a516c81618980f5 100644 (file)
@@ -218,7 +218,7 @@ key_entry_setup(struct region* region,
        *d = region_alloc(region, sizeof(**d));
        if(!*d)
                return 0;
-       (*k)->entry.data = d;
+       (*k)->entry.data = *d;
        return 1;
 }
 
@@ -248,8 +248,8 @@ key_entry_create_rrset(struct region* region,
                rrset->entry.data;
        if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
                return NULL;
-       d->ttl = rd->ttl;
-       log_info("New key entry TTL is %d", (int)d->ttl);
+       log_info("New key entry TTL is now+%d", (int)rd->ttl);
+       d->ttl = rd->ttl + time(NULL);
        d->isbad = 0;
        d->rrset_type = ntohs(rrset->rk.type);
        d->rrset_data = (struct packed_rrset_data*)region_alloc_init(region,
index 26f67cc3504b3a8386b41c83b0b6efd9afcaec92..a5e12d90245e222faa1049a6bf46b8bf6221b14b 100644 (file)
@@ -200,7 +200,7 @@ ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx)
        if(len < 2+2)
                return 0;
        memmove(&t, rdata+2, 2);
-       return t;
+       return ntohs(t);
 }
 
 /**
@@ -430,6 +430,7 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
        int algo = rrset_get_sig_algo(rrset, sig_idx);
        size_t i, num = rrset_get_count(dnskey);
        size_t numchecked = 0;
+       verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
        
        for(i=0; i<num; i++) {
                /* see if key matches keytag and algo */
index d2f9052d8c13c5c2d48ddf6ab1ef48bb1573b4fb..45a70f073ad822a1d43846bb58b3831346eadb08 100644 (file)
@@ -227,6 +227,9 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
                   != ds_get_keytag(ds_rrset, ds_idx)) {
                        continue;
                }
+               verbose(VERB_ALGO, "attempt DS match algo %d keytag %d",
+                       ds_get_key_algo(ds_rrset, ds_idx),
+                       ds_get_keytag(ds_rrset, ds_idx));
 
                /* Convert the candidate DNSKEY into a hash using the 
                 * same DS hash algorithm. */
index 5f28ca0122b2e2fa06503c33111e9ce306eaf84c..158be88c6adcc0c9b9b6a87588e0c1852e4000f7 100644 (file)
@@ -178,7 +178,7 @@ needs_validation(struct module_qstate* qstate, struct val_qstate* vq)
 
        /* If the CD bit is on in the original request, then we don't bother to
         * validate anything.*/
-       if(qstate->query_flags | BIT_CD) {
+       if(qstate->query_flags & BIT_CD) {
                verbose(VERB_ALGO, "not validating response due to CD bit");
                return 0;
        }
@@ -357,7 +357,8 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
                log_query_info(VERB_DETAIL, "validator operate: chased to",
                &vq->qchase);
        (void)outbound;
-       if(event == module_event_new || event == module_event_pass) {
+       if(event == module_event_new || 
+               (event == module_event_pass && vq == NULL)) {
                /* pass request to next module, to get it */
                verbose(VERB_ALGO, "validator: pass to next module");
                qstate->ext_state[id] = module_wait_module;
@@ -392,6 +393,12 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
                val_handle(qstate, vq, ve, id);
                return;
        }
+       if(event == module_event_pass) {
+               qstate->ext_state[id] = module_error; /* override this */
+               /* continue processing, since val_env exists */
+               val_handle(qstate, vq, ve, id);
+               return;
+       }
        log_err("validator: bad event %s", strmodulevent(event));
        qstate->ext_state[id] = module_error;
        return;
@@ -448,6 +455,7 @@ primeResponseToKE(int rcode, struct dns_msg* msg, struct trust_anchor* ta,
                        sec = sec_status_secure;
                else
                        sec = sec_status_bogus;
+               log_info("priming DS result %s", sec_status_to_string(sec));
        }
        if(sec != sec_status_secure && ta->dnskey_rrset) {
                sec = val_verify_rrset(qstate->env, ve, dnskey_rrset,