Match DS with DNSKEY and return validation status

This commit is contained in:
Willem Toorop 2014-02-07 23:02:10 +01:00
parent 649814f0e3
commit e6da267b21
2 changed files with 58 additions and 28 deletions

View File

@ -137,6 +137,7 @@ this_callbackfn(struct getdns_context *context, uint16_t callback_type,
size_t replies_tree_length, i; size_t replies_tree_length, i;
struct getdns_dict *reply; struct getdns_dict *reply;
struct getdns_list *answer; struct getdns_list *answer;
size_t answer_length;
getdns_return_t r; getdns_return_t r;
do { do {
@ -195,13 +196,23 @@ this_callbackfn(struct getdns_context *context, uint16_t callback_type,
" %d\n", r); " %d\n", r);
break; break;
} }
r = getdns_list_get_length(answer, &answer_length);
if (r != GETDNS_RETURN_GOOD) {
fprintf(stderr,
"Could not get length of answer list:"
" %d\n", r);
break;
}
if (answer_length == 0)
continue;
r = getdns_validate_dnssec(answer, r = getdns_validate_dnssec(answer,
validation_chain, trust_anchors); validation_chain, trust_anchors);
printf("getdns_validate_dnssec returned: %d\n", r); printf("getdns_validate_dnssec returned: %d\n", r);
} }
//printf("%s\n", getdns_pretty_print_dict(response));
getdns_list_destroy(trust_anchors); getdns_list_destroy(trust_anchors);
} while (0); } while (0);
//printf("%s\n", getdns_pretty_print_dict(response));
getdns_dict_destroy(response); getdns_dict_destroy(response);
(void) event_base_loopexit((struct event_base *)userarg, NULL); (void) event_base_loopexit((struct event_base *)userarg, NULL);
} }

View File

@ -119,7 +119,8 @@ rrset_iter_init_zone(zone_iter *i, ldns_dnssec_zone *zone)
assert(i); assert(i);
i->zone = zone; i->zone = zone;
i->cur_node = ldns_rbtree_first(zone->names); i->cur_node = zone->names ? ldns_rbtree_first(zone->names)
: LDNS_RBTREE_NULL;
i->cur_rrset = i->cur_node != LDNS_RBTREE_NULL i->cur_rrset = i->cur_node != LDNS_RBTREE_NULL
? ((ldns_dnssec_name *)i->cur_node->data)->rrsets ? ((ldns_dnssec_name *)i->cur_node->data)->rrsets
: NULL; : NULL;
@ -180,56 +181,76 @@ chase(ldns_dnssec_rrsets *rrset, ldns_dnssec_zone *support,
{ {
ldns_status s; ldns_status s;
ldns_rr_list *verifying_keys; ldns_rr_list *verifying_keys;
size_t i; size_t i, j;
ldns_rr *rr; ldns_rr *rr;
ldns_dnssec_rrsets *key_rrset; ldns_dnssec_rrsets *key_rrset;
ldns_dnssec_rrs *rrs;
printf(";; RRSET to validate:\n"); /* Secure by trusted keys? */
ldns_dnssec_rrsets_print(stdout, rrset, 0);
printf(";;\n;; Validating with trust anchors:\n");
verifying_keys = ldns_rr_list_new(); verifying_keys = ldns_rr_list_new();
s = verify_rrset(rrset, trusted, verifying_keys); s = verify_rrset(rrset, trusted, verifying_keys);
printf(";; status: %s\n", ldns_get_errorstr_by_id(s));
if (ldns_rr_list_rr_count(verifying_keys)) { ldns_rr_list_print(stdout, verifying_keys); printf(";;\n"); }
ldns_rr_list_free(verifying_keys);
if (s == 0) if (s == 0)
return s; goto done_free_verifying_keys;
printf(";; Validating with support keys:\n"); /* No, chase with support records..
* Is there a verifying key in the support records?
*/
verifying_keys = ldns_rr_list_new(); verifying_keys = ldns_rr_list_new();
s = verify_rrset(rrset, support_keys, verifying_keys); s = verify_rrset(rrset, support_keys, verifying_keys);
printf(";; status: %s\n", ldns_get_errorstr_by_id(s));
if (ldns_rr_list_rr_count(verifying_keys)) { ldns_rr_list_print(stdout, verifying_keys); printf(";;\n"); }
if (s != 0) if (s != 0)
goto done_free_verifying_keys; goto done_free_verifying_keys;
printf(";; Looking up the verifying keys:\n"); /* Ok, we have verifying keys from the support records.
* Compare them with the *trusted* keys or DSes,
* or chase them further down the validation chain.
*/
for (i = 0; i < ldns_rr_list_rr_count(verifying_keys); i++) { for (i = 0; i < ldns_rr_list_rr_count(verifying_keys); i++) {
/* Lookup the rrset for key rr from the support records */
rr = ldns_rr_list_rr(verifying_keys, i); rr = ldns_rr_list_rr(verifying_keys, i);
key_rrset = ldns_dnssec_zone_find_rrset( key_rrset = ldns_dnssec_zone_find_rrset(
support, ldns_rr_owner(rr), ldns_rr_get_type(rr)); support, ldns_rr_owner(rr), ldns_rr_get_type(rr));
if (! key_rrset) { if (! key_rrset) {
printf(";; Key not found:\n;;\n");
s = LDNS_STATUS_CRYPTO_NO_DNSKEY; s = LDNS_STATUS_CRYPTO_NO_DNSKEY;
break; break;
} }
/* When we signed ourselves, we have to cross domain border
* and look for a matching DS signed by a parents key
*/
if (rrset == key_rrset) { if (rrset == key_rrset) {
printf(";; Key verifies itself, lookup DS:\n"); /* Is the verifying key trusted?
* (i.e. DS in trusted)
*/
for (j = 0; j < ldns_rr_list_rr_count(trusted); j++)
if (ldns_rr_compare_ds(ldns_rr_list_rr(
trusted, j), rr))
break;
/* If so, check for the next verifying key
* (or exit SECURE)
*/
if (j < ldns_rr_list_rr_count(trusted))
continue;
/* Search for a matching DS in the support records */
key_rrset = ldns_dnssec_zone_find_rrset( key_rrset = ldns_dnssec_zone_find_rrset(
support, ldns_rr_owner(rr), LDNS_RR_TYPE_DS); support, ldns_rr_owner(rr), LDNS_RR_TYPE_DS);
if (! key_rrset) { if (! key_rrset) {
printf(";; DS not found:\n;;\n");
s = LDNS_STATUS_CRYPTO_NO_DNSKEY; s = LDNS_STATUS_CRYPTO_NO_DNSKEY;
break; break;
} }
/* Now check if DS matches the DNSKEY! */ /* Now check if DS matches the DNSKEY! */
for (rrs = key_rrset->rrs; rrs; rrs = rrs->next)
if (ldns_rr_compare_ds(rr, rrs->rr))
break;
if (! rrs) {
s = LDNS_STATUS_CRYPTO_NO_DNSKEY;
break;
}
} }
/* Pursue the chase with the verifying key (or its DS) */
s = chase(key_rrset, support, support_keys, trusted); s = chase(key_rrset, support, support_keys, trusted);
if (s != 0) if (s != 0)
break; break;
} }
done_free_verifying_keys: done_free_verifying_keys:
ldns_rr_list_free(verifying_keys); ldns_rr_list_free(verifying_keys);
return s; return s;
@ -252,7 +273,7 @@ getdns_validate_dnssec(struct getdns_list *records_to_validate,
zone_iter i; zone_iter i;
ldns_dnssec_rrsets *rrset; ldns_dnssec_rrsets *rrset;
ldns_dnssec_rrs *rrs; ldns_dnssec_rrs *rrs;
ldns_status s; ldns_status s = LDNS_STATUS_OK;
if ((r = priv_getdns_rr_list_from_list(trust_anchors, &trusted))) if ((r = priv_getdns_rr_list_from_list(trust_anchors, &trusted)))
return r; return r;
@ -288,14 +309,12 @@ getdns_validate_dnssec(struct getdns_list *records_to_validate,
if (s != 0) if (s != 0)
break; break;
} }
if (s == LDNS_STATUS_CRYPTO_BOGUS)
/* r = GETDNS_DNSSEC_BOGUS;
for(zone_iter_init(&i, to_validate); else if (s != LDNS_STATUS_OK)
(rrset = zone_iter_rrset(&i)); zone_iter_next(&i)) { r = GETDNS_DNSSEC_INSECURE;
else
ldns_dnssec_rrsets_print(stdout, rrset, 0); r = GETDNS_DNSSEC_SECURE;
}
*/
ldns_rr_list_free(support_keys); ldns_rr_list_free(support_keys);
done_free_to_validate: done_free_to_validate: