- Implemented trust anchor signaling using key tag query.

git-svn-id: file:///svn/unbound/trunk@4134 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2017-04-26 12:58:13 +00:00
parent 619b808b31
commit a511d5d95e
10 changed files with 2156 additions and 2051 deletions

View file

@ -1,3 +1,6 @@
26 April 2017: Ralph
- Implemented trust anchor signaling using key tag query.
26 April 2017: Wouter 26 April 2017: Wouter
- Based on #1257: check parse limit before t increment in sldns RR - Based on #1257: check parse limit before t increment in sldns RR
string parse routine. string parse routine.

View file

@ -804,6 +804,9 @@ the trusted\-keys { name flag proto algo "key"; }; clauses are read.
It is possible to use wildcards with this statement, the wildcard is It is possible to use wildcards with this statement, the wildcard is
expanded on start and on reload. expanded on start and on reload.
.TP .TP
.B trust\-anchor\-signaling: \fI<yes or no>
Send RFC8145 key tag query after trust anchor priming. Default is off.
.TP
.B dlv\-anchor\-file: \fI<filename> .B dlv\-anchor\-file: \fI<filename>
This option was used during early days DNSSEC deployment when no parent-side This option was used during early days DNSSEC deployment when no parent-side
DS record registrations were easily available. Nowadays, it is best to have DS record registrations were easily available. Nowadays, it is best to have

View file

@ -206,6 +206,7 @@ config_create(void)
cfg->trust_anchor_file_list = NULL; cfg->trust_anchor_file_list = NULL;
cfg->trust_anchor_list = NULL; cfg->trust_anchor_list = NULL;
cfg->trusted_keys_file_list = NULL; cfg->trusted_keys_file_list = NULL;
cfg->trust_anchor_signaling = 0;
cfg->dlv_anchor_file = NULL; cfg->dlv_anchor_file = NULL;
cfg->dlv_anchor_list = NULL; cfg->dlv_anchor_list = NULL;
cfg->domain_insecure = NULL; cfg->domain_insecure = NULL;
@ -480,6 +481,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STRLIST("trust-anchor-file:", trust_anchor_file_list) else S_STRLIST("trust-anchor-file:", trust_anchor_file_list)
else S_STRLIST("trust-anchor:", trust_anchor_list) else S_STRLIST("trust-anchor:", trust_anchor_list)
else S_STRLIST("trusted-keys-file:", trusted_keys_file_list) else S_STRLIST("trusted-keys-file:", trusted_keys_file_list)
else S_YNO("trust-anchor-signaling:", trust_anchor_signaling)
else S_STR("dlv-anchor-file:", dlv_anchor_file) else S_STR("dlv-anchor-file:", dlv_anchor_file)
else S_STRLIST("dlv-anchor:", dlv_anchor_list) else S_STRLIST("dlv-anchor:", dlv_anchor_list)
else S_STRLIST("domain-insecure:", domain_insecure) else S_STRLIST("domain-insecure:", domain_insecure)
@ -861,6 +863,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LST(opt, "trust-anchor-file", trust_anchor_file_list) else O_LST(opt, "trust-anchor-file", trust_anchor_file_list)
else O_LST(opt, "trust-anchor", trust_anchor_list) else O_LST(opt, "trust-anchor", trust_anchor_list)
else O_LST(opt, "trusted-keys-file", trusted_keys_file_list) else O_LST(opt, "trusted-keys-file", trusted_keys_file_list)
else O_YNO(opt, "trust-anchor-signaling", trust_anchor_signaling)
else O_LST(opt, "dlv-anchor", dlv_anchor_list) else O_LST(opt, "dlv-anchor", dlv_anchor_list)
else O_LST(opt, "control-interface", control_ifs) else O_LST(opt, "control-interface", control_ifs)
else O_LST(opt, "domain-insecure", domain_insecure) else O_LST(opt, "domain-insecure", domain_insecure)

View file

@ -274,6 +274,8 @@ struct config_file {
struct config_strlist* dlv_anchor_list; struct config_strlist* dlv_anchor_list;
/** insecure domain list */ /** insecure domain list */
struct config_strlist* domain_insecure; struct config_strlist* domain_insecure;
/** send key tag query */
int trust_anchor_signaling;
/** if not 0, this value is the validation date for RRSIGs */ /** if not 0, this value is the validation date for RRSIGs */
int32_t val_date_override; int32_t val_date_override;

File diff suppressed because it is too large Load diff

View file

@ -317,6 +317,7 @@ trust-anchor-file{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_FILE) }
auto-trust-anchor-file{COLON} { YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) } auto-trust-anchor-file{COLON} { YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) }
trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) } trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) }
trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) } trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) }
trust-anchor-signaling{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_SIGNALING) }
val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) } val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) } val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) } val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }

File diff suppressed because it is too large Load diff

View file

@ -241,15 +241,16 @@ extern int yydebug;
VAR_FAKE_SHA1 = 451, VAR_FAKE_SHA1 = 451,
VAR_LOG_IDENTITY = 452, VAR_LOG_IDENTITY = 452,
VAR_HIDE_TRUSTANCHOR = 453, VAR_HIDE_TRUSTANCHOR = 453,
VAR_USE_SYSTEMD = 454, VAR_TRUST_ANCHOR_SIGNALING = 454,
VAR_SHM_ENABLE = 455, VAR_USE_SYSTEMD = 455,
VAR_SHM_KEY = 456, VAR_SHM_ENABLE = 456,
VAR_DNSCRYPT = 457, VAR_SHM_KEY = 457,
VAR_DNSCRYPT_ENABLE = 458, VAR_DNSCRYPT = 458,
VAR_DNSCRYPT_PORT = 459, VAR_DNSCRYPT_ENABLE = 459,
VAR_DNSCRYPT_PROVIDER = 460, VAR_DNSCRYPT_PORT = 460,
VAR_DNSCRYPT_SECRET_KEY = 461, VAR_DNSCRYPT_PROVIDER = 461,
VAR_DNSCRYPT_PROVIDER_CERT = 462 VAR_DNSCRYPT_SECRET_KEY = 462,
VAR_DNSCRYPT_PROVIDER_CERT = 463
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@ -449,15 +450,16 @@ extern int yydebug;
#define VAR_FAKE_SHA1 451 #define VAR_FAKE_SHA1 451
#define VAR_LOG_IDENTITY 452 #define VAR_LOG_IDENTITY 452
#define VAR_HIDE_TRUSTANCHOR 453 #define VAR_HIDE_TRUSTANCHOR 453
#define VAR_USE_SYSTEMD 454 #define VAR_TRUST_ANCHOR_SIGNALING 454
#define VAR_SHM_ENABLE 455 #define VAR_USE_SYSTEMD 455
#define VAR_SHM_KEY 456 #define VAR_SHM_ENABLE 456
#define VAR_DNSCRYPT 457 #define VAR_SHM_KEY 457
#define VAR_DNSCRYPT_ENABLE 458 #define VAR_DNSCRYPT 458
#define VAR_DNSCRYPT_PORT 459 #define VAR_DNSCRYPT_ENABLE 459
#define VAR_DNSCRYPT_PROVIDER 460 #define VAR_DNSCRYPT_PORT 460
#define VAR_DNSCRYPT_SECRET_KEY 461 #define VAR_DNSCRYPT_PROVIDER 461
#define VAR_DNSCRYPT_PROVIDER_CERT 462 #define VAR_DNSCRYPT_SECRET_KEY 462
#define VAR_DNSCRYPT_PROVIDER_CERT 463
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -468,7 +470,7 @@ union YYSTYPE
char* str; char* str;
#line 472 "util/configparser.h" /* yacc.c:1909 */ #line 474 "util/configparser.h" /* yacc.c:1909 */
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View file

@ -140,7 +140,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION %token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW %token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1 %token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR %token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY %token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER %token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT %token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
@ -228,7 +228,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_fake_dsa | server_log_identity | server_use_systemd | server_fake_dsa | server_log_identity | server_use_systemd |
server_response_ip_tag | server_response_ip | server_response_ip_data | server_response_ip_tag | server_response_ip | server_response_ip_data |
server_shm_enable | server_shm_key | server_fake_sha1 | server_shm_enable | server_shm_key | server_fake_sha1 |
server_hide_trustanchor server_hide_trustanchor | server_trust_anchor_signaling
; ;
stubstart: VAR_STUB_ZONE stubstart: VAR_STUB_ZONE
{ {
@ -783,6 +783,17 @@ server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG
yyerror("out of memory"); yyerror("out of memory");
} }
; ;
server_trust_anchor_signaling: VAR_TRUST_ANCHOR_SIGNALING STRING_ARG
{
OUTYY(("P(server_trust_anchor_signaling:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else
cfg_parser->cfg->trust_anchor_signaling =
(strcmp($2, "yes")==0);
free($2);
}
;
server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
{ {
OUTYY(("P(server_domain_insecure:%s)\n", $2)); OUTYY(("P(server_domain_insecure:%s)\n", $2));

View file

@ -60,6 +60,7 @@
#include "util/fptr_wlist.h" #include "util/fptr_wlist.h"
#include "sldns/rrdef.h" #include "sldns/rrdef.h"
#include "sldns/wire2str.h" #include "sldns/wire2str.h"
#include "sldns/str2wire.h"
/* forward decl for cache response and normal super inform calls of a DS */ /* forward decl for cache response and normal super inform calls of a DS */
static void process_ds_response(struct module_qstate* qstate, static void process_ds_response(struct module_qstate* qstate,
@ -439,6 +440,65 @@ prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq,
return 1; return 1;
} }
/**
* Generate, send and detach key tag signaling query.
*
* @param qstate: query state.
* @param id: module id.
* @param ta: trust anchor, locked.
* @return false on a processing error.
*/
static int
generate_keytag_query(struct module_qstate* qstate, int id,
struct trust_anchor* ta)
{
/* 3 bytes for "_ta", 5 bytes per tag (4 bytes + "-") */
#define MAX_LABEL_TAGS (LDNS_MAX_LABELLEN-3)/5
size_t i, numtag;
uint16_t tags[MAX_LABEL_TAGS];
char tagstr[LDNS_MAX_LABELLEN+1] = "_ta"; /* +1 for NULL byte */
char* tagstr_pos = tagstr + strlen(tagstr);
uint8_t dnamebuf[LDNS_MAX_DOMAINLEN+1]; /* +1 for label length byte */
size_t dnamebuf_len = sizeof(dnamebuf);
uint8_t* keytagdname;
numtag = anchor_list_keytags(ta, tags, MAX_LABEL_TAGS);
if(numtag == 0)
return 0;
for(i=0; i<numtag; i++) {
/* Buffer can't overflow; numtag is limited to tags that fit in
* the buffer. */
sprintf(tagstr_pos, "-%04x", (unsigned)tags[i]);
tagstr_pos += strlen(tagstr_pos);
}
*tagstr_pos = '\0';
sldns_str2wire_dname_buf_origin(tagstr, dnamebuf, &dnamebuf_len,
ta->name, ta->namelen);
if(!(keytagdname = (uint8_t*)regional_alloc(qstate->region,
dnamebuf_len))) {
log_err("could not generate key tag query: out of memory");
return 0;
}
memcpy(keytagdname, dnamebuf, dnamebuf_len);
log_nametypeclass(VERB_ALGO, "keytag query", keytagdname,
LDNS_RR_TYPE_NULL, ta->dclass);
if(!generate_request(qstate, id, keytagdname, dnamebuf_len,
LDNS_RR_TYPE_NULL, ta->dclass, 0)) {
log_err("failed to generate key tag signaling request");
return 0;
}
/* We are not interrested in the response, detach this (and all other!)
* subqueries. */
fptr_ok(fptr_whitelist_modenv_detach_subs(qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
return 1;
}
/** /**
* Validate if the ANSWER and AUTHORITY sections contain valid rrsets. * Validate if the ANSWER and AUTHORITY sections contain valid rrsets.
* They must be validly signed with the given key. * They must be validly signed with the given key.
@ -2857,6 +2917,13 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
ta->name, ta->namelen, LDNS_RR_TYPE_DNSKEY, ta->name, ta->namelen, LDNS_RR_TYPE_DNSKEY,
ta->dclass); ta->dclass);
} }
if(qstate->env->cfg->trust_anchor_signaling &&
!generate_keytag_query(qstate, id, ta)) {
log_err("keytag signaling query failed");
return;
}
if(ta->autr) { if(ta->autr) {
if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset)) { if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset)) {
/* trust anchor revoked, restart with less anchors */ /* trust anchor revoked, restart with less anchors */