mirror of https://github.com/getdnsapi/getdns.git
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:
parent
e1126c9cf8
commit
4849329818
78
src/dnssec.c
78
src/dnssec.c
|
@ -848,7 +848,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
|
||||||
head->rrset.pkt = rrset->pkt;
|
head->rrset.pkt = rrset->pkt;
|
||||||
head->rrset.pkt_len = rrset->pkt_len;
|
head->rrset.pkt_len = rrset->pkt_len;
|
||||||
head->netreq = netreq;
|
head->netreq = netreq;
|
||||||
head->signer = 0;
|
head->signer = -1;
|
||||||
head->node_count = node_count;
|
head->node_count = node_count;
|
||||||
|
|
||||||
if (!node_count) {
|
if (!node_count) {
|
||||||
|
@ -877,8 +877,8 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
|
||||||
node->ds_req = NULL;
|
node->ds_req = NULL;
|
||||||
node->dnskey_req = NULL;
|
node->dnskey_req = NULL;
|
||||||
node->soa_req = NULL;
|
node->soa_req = NULL;
|
||||||
node->ds_signer = 0;
|
node->ds_signer = -1;
|
||||||
node->dnskey_signer = 0;
|
node->dnskey_signer = -1;
|
||||||
|
|
||||||
node->chains = *chain_p;
|
node->chains = *chain_p;
|
||||||
}
|
}
|
||||||
|
@ -3016,8 +3016,8 @@ static int rrset_in_list(getdns_rrset *rrset, getdns_list *list)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_canonical_rrset2val_chain_list(
|
static void append_rrset2val_chain_list(
|
||||||
getdns_list *val_chain_list, getdns_rrset *rrset, rrsig_iter *rrsig)
|
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_spc[VAL_RRSET_SPC_SZ];
|
||||||
_getdns_rr_iter *val_rrset = val_rrset_spc;
|
_getdns_rr_iter *val_rrset = val_rrset_spc;
|
||||||
|
@ -3025,8 +3025,23 @@ static void append_canonical_rrset2val_chain_list(
|
||||||
size_t n_rrs, i;
|
size_t n_rrs, i;
|
||||||
uint32_t orig_ttl;
|
uint32_t orig_ttl;
|
||||||
getdns_dict *rr_dict;
|
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 */
|
/* keytag was already read, so orig_ttl should cause no problem */
|
||||||
assert(rrsig->rr_i.nxt >= rrsig->rr_i.rr_type + 18);
|
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)
|
rrset->rr_type != GETDNS_RRTYPE_DS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((signer & 0xFFFF)) {
|
if (signer > 0) {
|
||||||
/* We have a signer! Return RRset in canonical
|
/* We have a signer! Return RRset in canonical
|
||||||
* form and order with only the RRSIG that signed
|
* form and order with only the RRSIG that signed
|
||||||
* the RRset.
|
* the RRset.
|
||||||
*/
|
*/
|
||||||
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
|
append_rrset2val_chain_list(
|
||||||
; rrsig &&
|
val_chain_list, rrset, signer);
|
||||||
( 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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for ( rr = rrtype_iter_init(&rr_spc, rrset)
|
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_dns_req *dnsreq;
|
||||||
getdns_context *context;
|
getdns_context *context;
|
||||||
size_t o, node_count;
|
size_t o, node_count;
|
||||||
chain_head *head, *next;
|
chain_head *head, *next, *same_chain;
|
||||||
chain_node *node;
|
chain_node *node;
|
||||||
getdns_list *val_chain_list;
|
getdns_list *val_chain_list;
|
||||||
getdns_dict *response_dict;
|
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 */
|
/* Walk chain to add values to val_chain_list and to cleanup */
|
||||||
for ( head = chain; head ; head = next ) {
|
for ( head = chain; head ; head = next ) {
|
||||||
next = 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
|
for ( node_count = head->node_count, node = head->parent
|
||||||
; node_count
|
; node_count
|
||||||
; node_count--, node = node->parent ) {
|
; node_count--, node = node->parent ) {
|
||||||
|
|
||||||
if (node->dnskey_req) {
|
if (node->dnskey_req) {
|
||||||
append_rrs2val_chain_list(
|
if (val_chain_list)
|
||||||
context, val_chain_list,
|
append_rrs2val_chain_list(
|
||||||
node->dnskey_req, node->dnskey_signer);
|
context, val_chain_list,
|
||||||
|
node->dnskey_req,
|
||||||
|
node->dnskey_signer);
|
||||||
_getdns_dns_req_free(node->dnskey_req->owner);
|
_getdns_dns_req_free(node->dnskey_req->owner);
|
||||||
}
|
}
|
||||||
if (node->ds_req) {
|
if (node->ds_req) {
|
||||||
append_rrs2val_chain_list(
|
if (val_chain_list)
|
||||||
context, val_chain_list,
|
append_rrs2val_chain_list(
|
||||||
node->ds_req, node->ds_signer);
|
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)) {
|
!rrset_has_rrs(&node->ds)) {
|
||||||
/* Add empty DS, to prevent less
|
/* Add empty DS, to prevent less
|
||||||
* specific to be able to authenticate
|
* specific to be able to authenticate
|
||||||
|
|
|
@ -403,6 +403,7 @@ validate_extensions(struct getdns_dict * extensions)
|
||||||
{"add_opt_parameters" , t_dict, 1},
|
{"add_opt_parameters" , t_dict, 1},
|
||||||
{"add_warning_for_bad_dns" , t_int , 1},
|
{"add_warning_for_bad_dns" , t_int , 1},
|
||||||
{"dnssec_return_all_statuses" , 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_only_secure" , t_int , 1},
|
||||||
{"dnssec_return_status" , t_int , 1},
|
{"dnssec_return_status" , t_int , 1},
|
||||||
{"dnssec_return_validation_chain", t_int , 1},
|
{"dnssec_return_validation_chain", t_int , 1},
|
||||||
|
|
|
@ -658,6 +658,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
= is_extension_set(extensions, "dnssec_return_only_secure");
|
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||||
int dnssec_return_all_statuses
|
int dnssec_return_all_statuses
|
||||||
= is_extension_set(extensions, "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
|
int dnssec_return_validation_chain
|
||||||
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
||||||
int edns_cookies
|
int edns_cookies
|
||||||
|
@ -674,6 +676,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
int dnssec_extension_set = dnssec_return_status
|
int dnssec_extension_set = dnssec_return_status
|
||||||
|| dnssec_return_only_secure || dnssec_return_all_statuses
|
|| dnssec_return_only_secure || dnssec_return_all_statuses
|
||||||
|| dnssec_return_validation_chain
|
|| dnssec_return_validation_chain
|
||||||
|
|| dnssec_return_full_validation_chain
|
||||||
|| (extensions == dnssec_ok_checking_disabled)
|
|| (extensions == dnssec_ok_checking_disabled)
|
||||||
|| (extensions == dnssec_ok_checking_disabled_roadblock_avoidance)
|
|| (extensions == dnssec_ok_checking_disabled_roadblock_avoidance)
|
||||||
|| (extensions == dnssec_ok_checking_disabled_avoid_roadblocks)
|
|| (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_status = dnssec_return_status;
|
||||||
result->dnssec_return_only_secure = dnssec_return_only_secure;
|
result->dnssec_return_only_secure = dnssec_return_only_secure;
|
||||||
result->dnssec_return_all_statuses = dnssec_return_all_statuses;
|
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;
|
result->edns_cookies = edns_cookies;
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
|
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
|
||||||
|
|
|
@ -474,6 +474,7 @@ print_usage(FILE *out, const char *progname)
|
||||||
fprintf(out, "\t+dnssec_return_only_secure\n");
|
fprintf(out, "\t+dnssec_return_only_secure\n");
|
||||||
fprintf(out, "\t+dnssec_return_all_statuses\n");
|
fprintf(out, "\t+dnssec_return_all_statuses\n");
|
||||||
fprintf(out, "\t+dnssec_return_validation_chain\n");
|
fprintf(out, "\t+dnssec_return_validation_chain\n");
|
||||||
|
fprintf(out, "\t+dnssec_return_full_validation_chain\n");
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
fprintf(out, "\t+dnssec_roadblock_avoidance\n");
|
fprintf(out, "\t+dnssec_roadblock_avoidance\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -272,37 +272,39 @@ typedef struct getdns_dns_req {
|
||||||
uint8_t name[256];
|
uint8_t name[256];
|
||||||
size_t name_len;
|
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;
|
uint16_t request_class;
|
||||||
|
|
||||||
/* canceled flag */
|
|
||||||
int canceled;
|
|
||||||
|
|
||||||
/* context that owns the request */
|
/* context that owns the request */
|
||||||
struct getdns_context *context;
|
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 */
|
/* request extensions */
|
||||||
int dnssec_return_status;
|
int dnssec_return_status : 1;
|
||||||
int dnssec_return_only_secure;
|
int dnssec_return_only_secure : 1;
|
||||||
int dnssec_return_all_statuses;
|
int dnssec_return_all_statuses : 1;
|
||||||
int dnssec_return_validation_chain;
|
int dnssec_return_validation_chain : 1;
|
||||||
|
int dnssec_return_full_validation_chain : 1;
|
||||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
int dnssec_roadblock_avoidance;
|
int dnssec_roadblock_avoidance : 1;
|
||||||
int avoid_dnssec_roadblocks;
|
int avoid_dnssec_roadblocks : 1;
|
||||||
#endif
|
#endif
|
||||||
int edns_cookies;
|
int edns_cookies : 1;
|
||||||
int edns_client_subnet_private;
|
int edns_client_subnet_private : 1;
|
||||||
uint16_t tls_query_padding_blocksize;
|
int return_call_reporting : 1;
|
||||||
int return_call_reporting;
|
int add_warning_for_bad_dns : 1;
|
||||||
int add_warning_for_bad_dns;
|
|
||||||
|
|
||||||
/* Internally used by return_validation_chain */
|
/* Internally used by return_validation_chain */
|
||||||
int dnssec_ok_checking_disabled;
|
int dnssec_ok_checking_disabled : 1;
|
||||||
int is_sync_request;
|
int is_sync_request : 1;
|
||||||
|
|
||||||
|
uint16_t tls_query_padding_blocksize;
|
||||||
|
|
||||||
/* internally scheduled request */
|
/* internally scheduled request */
|
||||||
internal_cb_t internal_cb;
|
internal_cb_t internal_cb;
|
||||||
|
|
|
@ -160,6 +160,9 @@ _getdns_rr_iter2rr_dict_canonical(
|
||||||
uint8_t ff_bytes[256];
|
uint8_t ff_bytes[256];
|
||||||
uint16_t rr_type;
|
uint16_t rr_type;
|
||||||
int canonicalize;
|
int canonicalize;
|
||||||
|
gldns_buffer gbuf;
|
||||||
|
getdns_bindata *bindata;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
assert(i);
|
assert(i);
|
||||||
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
|
if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
|
||||||
|
@ -402,14 +405,8 @@ _getdns_rr_iter2rr_dict_canonical(
|
||||||
goto rdata_error;
|
goto rdata_error;
|
||||||
|
|
||||||
if (canonicalize && rdata_sz) {
|
if (canonicalize && rdata_sz) {
|
||||||
fprintf(stderr, "XXXXXXXXXX: owner_len: %zu, rdata_len: %zu\n", owner_len, rdata_sz);
|
if (!(data = GETDNS_XMALLOC(
|
||||||
|
*mf, uint8_t, owner_len + 10 + rdata_sz)))
|
||||||
gldns_buffer gbuf;
|
|
||||||
getdns_bindata *bindata;
|
|
||||||
uint8_t *data = GETDNS_XMALLOC(
|
|
||||||
*mf, uint8_t, owner_len + 10 + rdata_sz);
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return rr_dict;
|
return rr_dict;
|
||||||
|
|
||||||
gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz);
|
gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz);
|
||||||
|
|
Loading…
Reference in New Issue