From: Wouter Wijngaards Date: Thu, 16 Aug 2007 09:33:35 +0000 (+0000) Subject: key prime, DS test. X-Git-Tag: release-0.5~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4aa70b4c539efb3db42fcbf9654aa79345c6314;p=thirdparty%2Funbound.git key prime, DS test. git-svn-id: file:///svn/unbound/trunk@525 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 7cec25ed2..aec453a2b 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/doc/README b/doc/README index 54a844e6c..9b216b24d 100644 --- a/doc/README +++ b/doc/README @@ -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. diff --git a/testcode/unitverify.c b/testcode/unitverify.c index 8087112b3..51cca401d 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -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; irrset_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 index 000000000..b3c6da5f3 --- /dev/null +++ b/testdata/test_ds_sig.1 @@ -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 + diff --git a/util/log.c b/util/log.c index 8968c705a..a77e57ad1 100644 --- a/util/log.c +++ b/util/log.c @@ -190,7 +190,7 @@ log_hex(const char* msg, void* data, size_t length) else { for(i=0; ientry.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, diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 26f67cc35..a5e12d902 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -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; iquery_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,