mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 14:53:15 -05:00
key prime, DS test.
git-svn-id: file:///svn/unbound/trunk@525 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
f6371f11a4
commit
e4aa70b4c5
9 changed files with 149 additions and 8 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
33
testdata/test_ds_sig.1
vendored
Normal file
33
testdata/test_ds_sig.1
vendored
Normal 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
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue