key prime, DS test.

git-svn-id: file:///svn/unbound/trunk@525 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-08-16 09:33:35 +00:00
parent f6371f11a4
commit e4aa70b4c5
9 changed files with 149 additions and 8 deletions

View 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 15 August 2007: Wouter
- crypto calls to verify signatures. - crypto calls to verify signatures.
- unit test for rrsig verification. - unit test for rrsig verification.

View file

@ -34,7 +34,7 @@ This software is under BSD license, see LICENSE for details.
Known issues 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 on sighup. On a restart 'did not exit gracefully last time' warning is
printed. Perform ./configure --with-libevent=no or update libevent, rerun printed. Perform ./configure --with-libevent=no or update libevent, rerun
configure and recompile unbound to make sighup work correctly. configure and recompile unbound to make sighup work correctly.

View file

@ -182,6 +182,59 @@ verifytest_entry(struct entry* e, struct alloc_cache* alloc, struct region*
query_info_clear(&qinfo); 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 */ /** verify from a file */
static void static void
verifytest_file(const char* fname, const char* at_date) 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); 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 void
verify_test() verify_test()
{ {
printf("verify test\n"); printf("verify test\n");
verifytest_file("testdata/test_signatures.1", "20070818005004"); verifytest_file("testdata/test_signatures.1", "20070818005004");
dstest_file("testdata/test_ds_sig.1");
} }

33
testdata/test_ds_sig.1 vendored Normal file
View file

@ -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

View file

@ -190,7 +190,7 @@ log_hex(const char* msg, void* data, size_t length)
else { else {
for(i=0; i<length*2; i+=blocksize) { for(i=0; i<length*2; i+=blocksize) {
log_info("%s[%u:%u] %.*s", msg, (unsigned)length, log_info("%s[%u:%u] %.*s", msg, (unsigned)length,
(unsigned)i, blocksize, buf+i); (unsigned)i/2, blocksize, buf+i);
} }
} }
free(buf); free(buf);

View file

@ -218,7 +218,7 @@ key_entry_setup(struct region* region,
*d = region_alloc(region, sizeof(**d)); *d = region_alloc(region, sizeof(**d));
if(!*d) if(!*d)
return 0; return 0;
(*k)->entry.data = d; (*k)->entry.data = *d;
return 1; return 1;
} }
@ -248,8 +248,8 @@ key_entry_create_rrset(struct region* region,
rrset->entry.data; rrset->entry.data;
if(!key_entry_setup(region, name, namelen, dclass, &k, &d)) if(!key_entry_setup(region, name, namelen, dclass, &k, &d))
return NULL; return NULL;
d->ttl = rd->ttl; log_info("New key entry TTL is now+%d", (int)rd->ttl);
log_info("New key entry TTL is %d", (int)d->ttl); d->ttl = rd->ttl + time(NULL);
d->isbad = 0; d->isbad = 0;
d->rrset_type = ntohs(rrset->rk.type); d->rrset_type = ntohs(rrset->rk.type);
d->rrset_data = (struct packed_rrset_data*)region_alloc_init(region, d->rrset_data = (struct packed_rrset_data*)region_alloc_init(region,

View file

@ -200,7 +200,7 @@ ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx)
if(len < 2+2) if(len < 2+2)
return 0; return 0;
memmove(&t, rdata+2, 2); 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); int algo = rrset_get_sig_algo(rrset, sig_idx);
size_t i, num = rrset_get_count(dnskey); size_t i, num = rrset_get_count(dnskey);
size_t numchecked = 0; size_t numchecked = 0;
verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
for(i=0; i<num; i++) { for(i=0; i<num; i++) {
/* see if key matches keytag and algo */ /* see if key matches keytag and algo */

View 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)) { != ds_get_keytag(ds_rrset, ds_idx)) {
continue; 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 /* Convert the candidate DNSKEY into a hash using the
* same DS hash algorithm. */ * same DS hash algorithm. */

View 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 /* If the CD bit is on in the original request, then we don't bother to
* validate anything.*/ * validate anything.*/
if(qstate->query_flags | BIT_CD) { if(qstate->query_flags & BIT_CD) {
verbose(VERB_ALGO, "not validating response due to CD bit"); verbose(VERB_ALGO, "not validating response due to CD bit");
return 0; 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", log_query_info(VERB_DETAIL, "validator operate: chased to",
&vq->qchase); &vq->qchase);
(void)outbound; (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 */ /* pass request to next module, to get it */
verbose(VERB_ALGO, "validator: pass to next module"); verbose(VERB_ALGO, "validator: pass to next module");
qstate->ext_state[id] = module_wait_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); val_handle(qstate, vq, ve, id);
return; 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)); log_err("validator: bad event %s", strmodulevent(event));
qstate->ext_state[id] = module_error; qstate->ext_state[id] = module_error;
return; return;
@ -448,6 +455,7 @@ primeResponseToKE(int rcode, struct dns_msg* msg, struct trust_anchor* ta,
sec = sec_status_secure; sec = sec_status_secure;
else else
sec = sec_status_bogus; sec = sec_status_bogus;
log_info("priming DS result %s", sec_status_to_string(sec));
} }
if(sec != sec_status_secure && ta->dnskey_rrset) { if(sec != sec_status_secure && ta->dnskey_rrset) {
sec = val_verify_rrset(qstate->env, ve, dnskey_rrset, sec = val_verify_rrset(qstate->env, ve, dnskey_rrset,