dnssec_return_full_validation_chain extension

That also returns all records that had to be proofed secure in canonical form in the "validation_chain".
This commit is contained in:
Willem Toorop 2016-04-18 22:06:12 +02:00
parent e1126c9cf8
commit 4849329818
6 changed files with 86 additions and 59 deletions

View File

@ -848,7 +848,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
head->rrset.pkt = rrset->pkt;
head->rrset.pkt_len = rrset->pkt_len;
head->netreq = netreq;
head->signer = 0;
head->signer = -1;
head->node_count = node_count;
if (!node_count) {
@ -877,8 +877,8 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
node->ds_req = NULL;
node->dnskey_req = NULL;
node->soa_req = NULL;
node->ds_signer = 0;
node->dnskey_signer = 0;
node->ds_signer = -1;
node->dnskey_signer = -1;
node->chains = *chain_p;
}
@ -3016,8 +3016,8 @@ static int rrset_in_list(getdns_rrset *rrset, getdns_list *list)
return 0;
}
static void append_canonical_rrset2val_chain_list(
getdns_list *val_chain_list, getdns_rrset *rrset, rrsig_iter *rrsig)
static void append_rrset2val_chain_list(
getdns_list *val_chain_list, getdns_rrset *rrset, int signer)
{
_getdns_rr_iter val_rrset_spc[VAL_RRSET_SPC_SZ];
_getdns_rr_iter *val_rrset = val_rrset_spc;
@ -3025,8 +3025,23 @@ static void append_canonical_rrset2val_chain_list(
size_t n_rrs, i;
uint32_t orig_ttl;
getdns_dict *rr_dict;
rrsig_iter *rrsig, rrsig_spc;
assert(val_chain_list && rrset && rrsig);
assert(val_chain_list && rrset);
if (signer < 0)
return;
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
; rrsig &&
( rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28
|| gldns_read_uint16(rrsig->rr_i.rr_type + 26)
!= (signer & 0xFFFF))
; rrsig = rrsig_iter_next(rrsig))
; /* pass */
if (!rrsig)
return;
/* keytag was already read, so orig_ttl should cause no problem */
assert(rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 18);
@ -3097,25 +3112,13 @@ static void append_rrs2val_chain_list(getdns_context *ctxt,
rrset->rr_type != GETDNS_RRTYPE_DS)
continue;
if ((signer & 0xFFFF)) {
if (signer > 0) {
/* We have a signer! Return RRset in canonical
* form and order with only the RRSIG that signed
* the RRset.
*/
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
; rrsig &&
( rrsig->rr_i.nxt < rrsig->rr_i.rr_type + 28
|| gldns_read_uint16(rrsig->rr_i.rr_type + 26)
!= (signer & 0xFFFF))
; rrsig = rrsig_iter_next(rrsig))
; /* pass */
if (!rrsig) {
/* Signer not found, try next RR set */
continue;
}
append_canonical_rrset2val_chain_list(
val_chain_list, rrset, rrsig);
append_rrset2val_chain_list(
val_chain_list, rrset, signer);
continue;
}
for ( rr = rrtype_iter_init(&rr_spc, rrset)
@ -3176,7 +3179,7 @@ static void check_chain_complete(chain_head *chain)
getdns_dns_req *dnsreq;
getdns_context *context;
size_t o, node_count;
chain_head *head, *next;
chain_head *head, *next, *same_chain;
chain_node *node;
getdns_list *val_chain_list;
getdns_dict *response_dict;
@ -3240,22 +3243,39 @@ static void check_chain_complete(chain_head *chain)
/* Walk chain to add values to val_chain_list and to cleanup */
for ( head = chain; head ; head = next ) {
next = head->next;
if (dnsreq->dnssec_return_full_validation_chain &&
head->node_count && head->signer > 0) {
append_rrset2val_chain_list(
val_chain_list, &head->rrset, head->signer);
for ( same_chain = next
; same_chain && same_chain->signer == head->signer
; same_chain = same_chain->next) {
append_rrset2val_chain_list(val_chain_list,
&same_chain->rrset, same_chain->signer);
same_chain->signer = -1;
}
}
for ( node_count = head->node_count, node = head->parent
; node_count
; node_count--, node = node->parent ) {
if (node->dnskey_req) {
append_rrs2val_chain_list(
context, val_chain_list,
node->dnskey_req, node->dnskey_signer);
if (val_chain_list)
append_rrs2val_chain_list(
context, val_chain_list,
node->dnskey_req,
node->dnskey_signer);
_getdns_dns_req_free(node->dnskey_req->owner);
}
if (node->ds_req) {
append_rrs2val_chain_list(
context, val_chain_list,
node->ds_req, node->ds_signer);
if (val_chain_list)
append_rrs2val_chain_list(
context, val_chain_list,
node->ds_req, node->ds_signer);
if (!node->ds_signer &&
if (val_chain_list && node->ds_signer == -1 &&
!rrset_has_rrs(&node->ds)) {
/* Add empty DS, to prevent less
* specific to be able to authenticate

View File

@ -403,6 +403,7 @@ validate_extensions(struct getdns_dict * extensions)
{"add_opt_parameters" , t_dict, 1},
{"add_warning_for_bad_dns" , t_int , 1},
{"dnssec_return_all_statuses" , t_int , 1},
{"dnssec_return_full_validation_chain", t_int , 1},
{"dnssec_return_only_secure" , t_int , 1},
{"dnssec_return_status" , t_int , 1},
{"dnssec_return_validation_chain", t_int , 1},

View File

@ -658,6 +658,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
= is_extension_set(extensions, "dnssec_return_only_secure");
int dnssec_return_all_statuses
= is_extension_set(extensions, "dnssec_return_all_statuses");
int dnssec_return_full_validation_chain
= is_extension_set(extensions, "dnssec_return_full_validation_chain");
int dnssec_return_validation_chain
= is_extension_set(extensions, "dnssec_return_validation_chain");
int edns_cookies
@ -674,6 +676,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
int dnssec_extension_set = dnssec_return_status
|| dnssec_return_only_secure || dnssec_return_all_statuses
|| dnssec_return_validation_chain
|| dnssec_return_full_validation_chain
|| (extensions == dnssec_ok_checking_disabled)
|| (extensions == dnssec_ok_checking_disabled_roadblock_avoidance)
|| (extensions == dnssec_ok_checking_disabled_avoid_roadblocks)
@ -874,7 +877,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->dnssec_return_status = dnssec_return_status;
result->dnssec_return_only_secure = dnssec_return_only_secure;
result->dnssec_return_all_statuses = dnssec_return_all_statuses;
result->dnssec_return_validation_chain = dnssec_return_validation_chain;
result->dnssec_return_full_validation_chain =
dnssec_return_full_validation_chain;
result->dnssec_return_validation_chain = dnssec_return_validation_chain
|| dnssec_return_full_validation_chain;
result->edns_cookies = edns_cookies;
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;

View File

@ -474,6 +474,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t+dnssec_return_only_secure\n");
fprintf(out, "\t+dnssec_return_all_statuses\n");
fprintf(out, "\t+dnssec_return_validation_chain\n");
fprintf(out, "\t+dnssec_return_full_validation_chain\n");
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
fprintf(out, "\t+dnssec_roadblock_avoidance\n");
#endif

View File

@ -272,37 +272,39 @@ typedef struct getdns_dns_req {
uint8_t name[256];
size_t name_len;
getdns_append_name_t append_name;
const uint8_t *suffix;
size_t suffix_len;
int suffix_appended;
uint16_t request_class;
/* canceled flag */
int canceled;
/* context that owns the request */
struct getdns_context *context;
getdns_append_name_t append_name;
const uint8_t *suffix;
size_t suffix_len;
int suffix_appended : 1;
/* canceled flag */
int canceled : 1;
/* request extensions */
int dnssec_return_status;
int dnssec_return_only_secure;
int dnssec_return_all_statuses;
int dnssec_return_validation_chain;
int dnssec_return_status : 1;
int dnssec_return_only_secure : 1;
int dnssec_return_all_statuses : 1;
int dnssec_return_validation_chain : 1;
int dnssec_return_full_validation_chain : 1;
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
int dnssec_roadblock_avoidance;
int avoid_dnssec_roadblocks;
int dnssec_roadblock_avoidance : 1;
int avoid_dnssec_roadblocks : 1;
#endif
int edns_cookies;
int edns_client_subnet_private;
uint16_t tls_query_padding_blocksize;
int return_call_reporting;
int add_warning_for_bad_dns;
int edns_cookies : 1;
int edns_client_subnet_private : 1;
int return_call_reporting : 1;
int add_warning_for_bad_dns : 1;
/* Internally used by return_validation_chain */
int dnssec_ok_checking_disabled;
int is_sync_request;
int dnssec_ok_checking_disabled : 1;
int is_sync_request : 1;
uint16_t tls_query_padding_blocksize;
/* internally scheduled request */
internal_cb_t internal_cb;

View File

@ -160,6 +160,9 @@ _getdns_rr_iter2rr_dict_canonical(
uint8_t ff_bytes[256];
uint16_t rr_type;
int canonicalize;
gldns_buffer gbuf;
getdns_bindata *bindata;
uint8_t *data;
assert(i);
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
@ -402,14 +405,8 @@ _getdns_rr_iter2rr_dict_canonical(
goto rdata_error;
if (canonicalize && rdata_sz) {
fprintf(stderr, "XXXXXXXXXX: owner_len: %zu, rdata_len: %zu\n", owner_len, rdata_sz);
gldns_buffer gbuf;
getdns_bindata *bindata;
uint8_t *data = GETDNS_XMALLOC(
*mf, uint8_t, owner_len + 10 + rdata_sz);
if (!data)
if (!(data = GETDNS_XMALLOC(
*mf, uint8_t, owner_len + 10 + rdata_sz)))
return rr_dict;
gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz);