1 /* 2 * validator/validator.c - secure validator DNS query response module 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains a module that performs validation of DNS queries. 40 * According to RFC 4034. 41 */ 42 #include "config.h" 43 #include <ctype.h> 44 #include "validator/validator.h" 45 #include "validator/val_anchor.h" 46 #include "validator/val_kcache.h" 47 #include "validator/val_kentry.h" 48 #include "validator/val_utils.h" 49 #include "validator/val_nsec.h" 50 #include "validator/val_nsec3.h" 51 #include "validator/val_neg.h" 52 #include "validator/val_sigcrypt.h" 53 #include "validator/autotrust.h" 54 #include "services/cache/dns.h" 55 #include "services/cache/rrset.h" 56 #include "util/data/dname.h" 57 #include "util/module.h" 58 #include "util/log.h" 59 #include "util/net_help.h" 60 #include "util/regional.h" 61 #include "util/config_file.h" 62 #include "util/fptr_wlist.h" 63 #include "sldns/rrdef.h" 64 #include "sldns/wire2str.h" 65 #include "sldns/str2wire.h" 66 67 /* forward decl for cache response and normal super inform calls of a DS */ 68 static void process_ds_response(struct module_qstate* qstate, 69 struct val_qstate* vq, int id, int rcode, struct dns_msg* msg, 70 struct query_info* qinfo, struct sock_list* origin); 71 72 73 /* Updates the suplied EDE (RFC8914) code selectively so we don't loose 74 * a more specific code 75 */ 76 static void 77 update_reason_bogus(struct reply_info* rep, sldns_ede_code reason_bogus) 78 { 79 if (rep->reason_bogus == LDNS_EDE_DNSSEC_BOGUS || 80 rep->reason_bogus == LDNS_EDE_NONE) { 81 rep->reason_bogus = reason_bogus; 82 } 83 } 84 85 86 /** fill up nsec3 key iterations config entry */ 87 static int 88 fill_nsec3_iter(struct val_env* ve, char* s, int c) 89 { 90 char* e; 91 int i; 92 free(ve->nsec3_keysize); 93 free(ve->nsec3_maxiter); 94 ve->nsec3_keysize = (size_t*)calloc(sizeof(size_t), (size_t)c); 95 ve->nsec3_maxiter = (size_t*)calloc(sizeof(size_t), (size_t)c); 96 if(!ve->nsec3_keysize || !ve->nsec3_maxiter) { 97 log_err("out of memory"); 98 return 0; 99 } 100 for(i=0; i<c; i++) { 101 ve->nsec3_keysize[i] = (size_t)strtol(s, &e, 10); 102 if(s == e) { 103 log_err("cannot parse: %s", s); 104 return 0; 105 } 106 s = e; 107 ve->nsec3_maxiter[i] = (size_t)strtol(s, &e, 10); 108 if(s == e) { 109 log_err("cannot parse: %s", s); 110 return 0; 111 } 112 s = e; 113 if(i>0 && ve->nsec3_keysize[i-1] >= ve->nsec3_keysize[i]) { 114 log_err("nsec3 key iterations not ascending: %d %d", 115 (int)ve->nsec3_keysize[i-1], 116 (int)ve->nsec3_keysize[i]); 117 return 0; 118 } 119 verbose(VERB_ALGO, "validator nsec3cfg keysz %d mxiter %d", 120 (int)ve->nsec3_keysize[i], (int)ve->nsec3_maxiter[i]); 121 } 122 return 1; 123 } 124 125 /** apply config settings to validator */ 126 static int 127 val_apply_cfg(struct module_env* env, struct val_env* val_env, 128 struct config_file* cfg) 129 { 130 int c; 131 val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl; 132 if(!env->anchors) 133 env->anchors = anchors_create(); 134 if(!env->anchors) { 135 log_err("out of memory"); 136 return 0; 137 } 138 if (env->key_cache) 139 val_env->kcache = env->key_cache; 140 if(!val_env->kcache) 141 val_env->kcache = key_cache_create(cfg); 142 if(!val_env->kcache) { 143 log_err("out of memory"); 144 return 0; 145 } 146 env->key_cache = val_env->kcache; 147 if(!anchors_apply_cfg(env->anchors, cfg)) { 148 log_err("validator: error in trustanchors config"); 149 return 0; 150 } 151 val_env->date_override = cfg->val_date_override; 152 val_env->skew_min = cfg->val_sig_skew_min; 153 val_env->skew_max = cfg->val_sig_skew_max; 154 val_env->max_restart = cfg->val_max_restart; 155 c = cfg_count_numbers(cfg->val_nsec3_key_iterations); 156 if(c < 1 || (c&1)) { 157 log_err("validator: unparsable or odd nsec3 key " 158 "iterations: %s", cfg->val_nsec3_key_iterations); 159 return 0; 160 } 161 val_env->nsec3_keyiter_count = c/2; 162 if(!fill_nsec3_iter(val_env, cfg->val_nsec3_key_iterations, c/2)) { 163 log_err("validator: cannot apply nsec3 key iterations"); 164 return 0; 165 } 166 if (env->neg_cache) 167 val_env->neg_cache = env->neg_cache; 168 if(!val_env->neg_cache) 169 val_env->neg_cache = val_neg_create(cfg, 170 val_env->nsec3_maxiter[val_env->nsec3_keyiter_count-1]); 171 if(!val_env->neg_cache) { 172 log_err("out of memory"); 173 return 0; 174 } 175 env->neg_cache = val_env->neg_cache; 176 return 1; 177 } 178 179 #ifdef USE_ECDSA_EVP_WORKAROUND 180 void ecdsa_evp_workaround_init(void); 181 #endif 182 int 183 val_init(struct module_env* env, int id) 184 { 185 struct val_env* val_env = (struct val_env*)calloc(1, 186 sizeof(struct val_env)); 187 if(!val_env) { 188 log_err("malloc failure"); 189 return 0; 190 } 191 env->modinfo[id] = (void*)val_env; 192 env->need_to_validate = 1; 193 lock_basic_init(&val_env->bogus_lock); 194 lock_protect(&val_env->bogus_lock, &val_env->num_rrset_bogus, 195 sizeof(val_env->num_rrset_bogus)); 196 #ifdef USE_ECDSA_EVP_WORKAROUND 197 ecdsa_evp_workaround_init(); 198 #endif 199 if(!val_apply_cfg(env, val_env, env->cfg)) { 200 log_err("validator: could not apply configuration settings."); 201 return 0; 202 } 203 204 return 1; 205 } 206 207 void 208 val_deinit(struct module_env* env, int id) 209 { 210 struct val_env* val_env; 211 if(!env || !env->modinfo[id]) 212 return; 213 val_env = (struct val_env*)env->modinfo[id]; 214 lock_basic_destroy(&val_env->bogus_lock); 215 anchors_delete(env->anchors); 216 env->anchors = NULL; 217 key_cache_delete(val_env->kcache); 218 env->key_cache = NULL; 219 neg_cache_delete(val_env->neg_cache); 220 env->neg_cache = NULL; 221 free(val_env->nsec3_keysize); 222 free(val_env->nsec3_maxiter); 223 free(val_env); 224 env->modinfo[id] = NULL; 225 } 226 227 /** fill in message structure */ 228 static struct val_qstate* 229 val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq) 230 { 231 if(!qstate->return_msg || qstate->return_rcode != LDNS_RCODE_NOERROR) { 232 /* create a message to verify */ 233 verbose(VERB_ALGO, "constructing reply for validation"); 234 vq->orig_msg = (struct dns_msg*)regional_alloc(qstate->region, 235 sizeof(struct dns_msg)); 236 if(!vq->orig_msg) 237 return NULL; 238 vq->orig_msg->qinfo = qstate->qinfo; 239 vq->orig_msg->rep = (struct reply_info*)regional_alloc( 240 qstate->region, sizeof(struct reply_info)); 241 if(!vq->orig_msg->rep) 242 return NULL; 243 memset(vq->orig_msg->rep, 0, sizeof(struct reply_info)); 244 vq->orig_msg->rep->flags = (uint16_t)(qstate->return_rcode&0xf) 245 |BIT_QR|BIT_RA|(qstate->query_flags|(BIT_CD|BIT_RD)); 246 vq->orig_msg->rep->qdcount = 1; 247 vq->orig_msg->rep->reason_bogus = LDNS_EDE_NONE; 248 } else { 249 vq->orig_msg = qstate->return_msg; 250 } 251 vq->qchase = qstate->qinfo; 252 /* chase reply will be an edited (sub)set of the orig msg rrset ptrs */ 253 vq->chase_reply = regional_alloc_init(qstate->region, 254 vq->orig_msg->rep, 255 sizeof(struct reply_info) - sizeof(struct rrset_ref)); 256 if(!vq->chase_reply) 257 return NULL; 258 if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX) 259 return NULL; /* protect against integer overflow */ 260 vq->chase_reply->rrsets = regional_alloc_init(qstate->region, 261 vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*) 262 * vq->orig_msg->rep->rrset_count); 263 if(!vq->chase_reply->rrsets) 264 return NULL; 265 vq->rrset_skip = 0; 266 return vq; 267 } 268 269 /** allocate new validator query state */ 270 static struct val_qstate* 271 val_new(struct module_qstate* qstate, int id) 272 { 273 struct val_qstate* vq = (struct val_qstate*)regional_alloc( 274 qstate->region, sizeof(*vq)); 275 log_assert(!qstate->minfo[id]); 276 if(!vq) 277 return NULL; 278 memset(vq, 0, sizeof(*vq)); 279 qstate->minfo[id] = vq; 280 vq->state = VAL_INIT_STATE; 281 return val_new_getmsg(qstate, vq); 282 } 283 284 /** 285 * Exit validation with an error status 286 * 287 * @param qstate: query state 288 * @param id: validator id. 289 * @return false, for use by caller to return to stop processing. 290 */ 291 static int 292 val_error(struct module_qstate* qstate, int id) 293 { 294 qstate->ext_state[id] = module_error; 295 qstate->return_rcode = LDNS_RCODE_SERVFAIL; 296 return 0; 297 } 298 299 /** 300 * Check to see if a given response needs to go through the validation 301 * process. Typical reasons for this routine to return false are: CD bit was 302 * on in the original request, or the response is a kind of message that 303 * is unvalidatable (i.e., SERVFAIL, REFUSED, etc.) 304 * 305 * @param qstate: query state. 306 * @param ret_rc: rcode for this message (if noerror - examine ret_msg). 307 * @param ret_msg: return msg, can be NULL; look at rcode instead. 308 * @return true if the response could use validation (although this does not 309 * mean we can actually validate this response). 310 */ 311 static int 312 needs_validation(struct module_qstate* qstate, int ret_rc, 313 struct dns_msg* ret_msg) 314 { 315 int rcode; 316 317 /* If the CD bit is on in the original request, then you could think 318 * that we don't bother to validate anything. 319 * But this is signalled internally with the valrec flag. 320 * User queries are validated with BIT_CD to make our cache clean 321 * so that bogus messages get retried by the upstream also for 322 * downstream validators that set BIT_CD. 323 * For DNS64 bit_cd signals no dns64 processing, but we want to 324 * provide validation there too */ 325 /* 326 if(qstate->query_flags & BIT_CD) { 327 verbose(VERB_ALGO, "not validating response due to CD bit"); 328 return 0; 329 } 330 */ 331 if(qstate->is_valrec) { 332 verbose(VERB_ALGO, "not validating response, is valrec" 333 "(validation recursion lookup)"); 334 return 0; 335 } 336 337 if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg) 338 rcode = ret_rc; 339 else rcode = (int)FLAGS_GET_RCODE(ret_msg->rep->flags); 340 341 if(rcode != LDNS_RCODE_NOERROR && rcode != LDNS_RCODE_NXDOMAIN) { 342 if(verbosity >= VERB_ALGO) { 343 char rc[16]; 344 rc[0]=0; 345 (void)sldns_wire2str_rcode_buf(rcode, rc, sizeof(rc)); 346 verbose(VERB_ALGO, "cannot validate non-answer, rcode %s", rc); 347 } 348 return 0; 349 } 350 351 /* cannot validate positive RRSIG response. (negatives can) */ 352 if(qstate->qinfo.qtype == LDNS_RR_TYPE_RRSIG && 353 rcode == LDNS_RCODE_NOERROR && ret_msg && 354 ret_msg->rep->an_numrrsets > 0) { 355 verbose(VERB_ALGO, "cannot validate RRSIG, no sigs on sigs."); 356 return 0; 357 } 358 return 1; 359 } 360 361 /** 362 * Check to see if the response has already been validated. 363 * @param ret_msg: return msg, can be NULL 364 * @return true if the response has already been validated 365 */ 366 static int 367 already_validated(struct dns_msg* ret_msg) 368 { 369 /* validate unchecked, and re-validate bogus messages */ 370 if (ret_msg && ret_msg->rep->security > sec_status_bogus) 371 { 372 verbose(VERB_ALGO, "response has already been validated: %s", 373 sec_status_to_string(ret_msg->rep->security)); 374 return 1; 375 } 376 return 0; 377 } 378 379 /** 380 * Generate a request for DNS data. 381 * 382 * @param qstate: query state that is the parent. 383 * @param id: module id. 384 * @param name: what name to query for. 385 * @param namelen: length of name. 386 * @param qtype: query type. 387 * @param qclass: query class. 388 * @param flags: additional flags, such as the CD bit (BIT_CD), or 0. 389 * @param newq: If the subquery is newly created, it is returned, 390 * otherwise NULL is returned 391 * @param detached: true if this qstate should not attach to the subquery 392 * @return false on alloc failure. 393 */ 394 static int 395 generate_request(struct module_qstate* qstate, int id, uint8_t* name, 396 size_t namelen, uint16_t qtype, uint16_t qclass, uint16_t flags, 397 struct module_qstate** newq, int detached) 398 { 399 struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id]; 400 struct query_info ask; 401 int valrec; 402 ask.qname = name; 403 ask.qname_len = namelen; 404 ask.qtype = qtype; 405 ask.qclass = qclass; 406 ask.local_alias = NULL; 407 log_query_info(VERB_ALGO, "generate request", &ask); 408 /* enable valrec flag to avoid recursion to the same validation 409 * routine, this lookup is simply a lookup. */ 410 valrec = 1; 411 412 fptr_ok(fptr_whitelist_modenv_detect_cycle(qstate->env->detect_cycle)); 413 if((*qstate->env->detect_cycle)(qstate, &ask, 414 (uint16_t)(BIT_RD|flags), 0, valrec)) { 415 verbose(VERB_ALGO, "Could not generate request: cycle detected"); 416 return 0; 417 } 418 419 if(detached) { 420 struct mesh_state* sub = NULL; 421 fptr_ok(fptr_whitelist_modenv_add_sub( 422 qstate->env->add_sub)); 423 if(!(*qstate->env->add_sub)(qstate, &ask, 424 (uint16_t)(BIT_RD|flags), 0, valrec, newq, &sub)){ 425 log_err("Could not generate request: out of memory"); 426 return 0; 427 } 428 } 429 else { 430 fptr_ok(fptr_whitelist_modenv_attach_sub( 431 qstate->env->attach_sub)); 432 if(!(*qstate->env->attach_sub)(qstate, &ask, 433 (uint16_t)(BIT_RD|flags), 0, valrec, newq)){ 434 log_err("Could not generate request: out of memory"); 435 return 0; 436 } 437 } 438 /* newq; validator does not need state created for that 439 * query, and its a 'normal' for iterator as well */ 440 if(*newq) { 441 /* add our blacklist to the query blacklist */ 442 sock_list_merge(&(*newq)->blacklist, (*newq)->region, 443 vq->chain_blacklist); 444 } 445 qstate->ext_state[id] = module_wait_subquery; 446 return 1; 447 } 448 449 /** 450 * Generate, send and detach key tag signaling query. 451 * 452 * @param qstate: query state. 453 * @param id: module id. 454 * @param ta: trust anchor, locked. 455 * @return false on a processing error. 456 */ 457 static int 458 generate_keytag_query(struct module_qstate* qstate, int id, 459 struct trust_anchor* ta) 460 { 461 /* 3 bytes for "_ta", 5 bytes per tag (4 bytes + "-") */ 462 #define MAX_LABEL_TAGS (LDNS_MAX_LABELLEN-3)/5 463 size_t i, numtag; 464 uint16_t tags[MAX_LABEL_TAGS]; 465 char tagstr[LDNS_MAX_LABELLEN+1] = "_ta"; /* +1 for NULL byte */ 466 size_t tagstr_left = sizeof(tagstr) - strlen(tagstr); 467 char* tagstr_pos = tagstr + strlen(tagstr); 468 uint8_t dnamebuf[LDNS_MAX_DOMAINLEN+1]; /* +1 for label length byte */ 469 size_t dnamebuf_len = sizeof(dnamebuf); 470 uint8_t* keytagdname; 471 struct module_qstate* newq = NULL; 472 enum module_ext_state ext_state = qstate->ext_state[id]; 473 474 numtag = anchor_list_keytags(ta, tags, MAX_LABEL_TAGS); 475 if(numtag == 0) 476 return 0; 477 478 for(i=0; i<numtag; i++) { 479 /* Buffer can't overflow; numtag is limited to tags that fit in 480 * the buffer. */ 481 snprintf(tagstr_pos, tagstr_left, "-%04x", (unsigned)tags[i]); 482 tagstr_left -= strlen(tagstr_pos); 483 tagstr_pos += strlen(tagstr_pos); 484 } 485 486 sldns_str2wire_dname_buf_origin(tagstr, dnamebuf, &dnamebuf_len, 487 ta->name, ta->namelen); 488 if(!(keytagdname = (uint8_t*)regional_alloc_init(qstate->region, 489 dnamebuf, dnamebuf_len))) { 490 log_err("could not generate key tag query: out of memory"); 491 return 0; 492 } 493 494 log_nametypeclass(VERB_OPS, "generate keytag query", keytagdname, 495 LDNS_RR_TYPE_NULL, ta->dclass); 496 if(!generate_request(qstate, id, keytagdname, dnamebuf_len, 497 LDNS_RR_TYPE_NULL, ta->dclass, 0, &newq, 1)) { 498 verbose(VERB_ALGO, "failed to generate key tag signaling request"); 499 return 0; 500 } 501 502 /* Not interested in subquery response. Restore the ext_state, 503 * that might be changed by generate_request() */ 504 qstate->ext_state[id] = ext_state; 505 506 return 1; 507 } 508 509 /** 510 * Get keytag as uint16_t from string 511 * 512 * @param start: start of string containing keytag 513 * @param keytag: pointer where to store the extracted keytag 514 * @return: 1 if keytag was extracted, else 0. 515 */ 516 static int 517 sentinel_get_keytag(char* start, uint16_t* keytag) { 518 char* keytag_str; 519 char* e = NULL; 520 keytag_str = calloc(1, SENTINEL_KEYTAG_LEN + 1 /* null byte */); 521 if(!keytag_str) 522 return 0; 523 memmove(keytag_str, start, SENTINEL_KEYTAG_LEN); 524 keytag_str[SENTINEL_KEYTAG_LEN] = '\0'; 525 *keytag = (uint16_t)strtol(keytag_str, &e, 10); 526 if(!e || *e != '\0') { 527 free(keytag_str); 528 return 0; 529 } 530 free(keytag_str); 531 return 1; 532 } 533 534 /** 535 * Prime trust anchor for use. 536 * Generate and dispatch a priming query for the given trust anchor. 537 * The trust anchor can be DNSKEY or DS and does not have to be signed. 538 * 539 * @param qstate: query state. 540 * @param vq: validator query state. 541 * @param id: module id. 542 * @param toprime: what to prime. 543 * @return false on a processing error. 544 */ 545 static int 546 prime_trust_anchor(struct module_qstate* qstate, struct val_qstate* vq, 547 int id, struct trust_anchor* toprime) 548 { 549 struct module_qstate* newq = NULL; 550 int ret = generate_request(qstate, id, toprime->name, toprime->namelen, 551 LDNS_RR_TYPE_DNSKEY, toprime->dclass, BIT_CD, &newq, 0); 552 553 if(newq && qstate->env->cfg->trust_anchor_signaling && 554 !generate_keytag_query(qstate, id, toprime)) { 555 verbose(VERB_ALGO, "keytag signaling query failed"); 556 return 0; 557 } 558 559 if(!ret) { 560 verbose(VERB_ALGO, "Could not prime trust anchor"); 561 return 0; 562 } 563 /* ignore newq; validator does not need state created for that 564 * query, and its a 'normal' for iterator as well */ 565 vq->wait_prime_ta = 1; /* to elicit PRIME_RESP_STATE processing 566 from the validator inform_super() routine */ 567 /* store trust anchor name for later lookup when prime returns */ 568 vq->trust_anchor_name = regional_alloc_init(qstate->region, 569 toprime->name, toprime->namelen); 570 vq->trust_anchor_len = toprime->namelen; 571 vq->trust_anchor_labs = toprime->namelabs; 572 if(!vq->trust_anchor_name) { 573 log_err("Could not prime trust anchor: out of memory"); 574 return 0; 575 } 576 return 1; 577 } 578 579 /** 580 * Validate if the ANSWER and AUTHORITY sections contain valid rrsets. 581 * They must be validly signed with the given key. 582 * Tries to validate ADDITIONAL rrsets as well, but only to check them. 583 * Allows unsigned CNAME after a DNAME that expands the DNAME. 584 * 585 * Note that by the time this method is called, the process of finding the 586 * trusted DNSKEY rrset that signs this response must already have been 587 * completed. 588 * 589 * @param qstate: query state. 590 * @param env: module env for verify. 591 * @param ve: validator env for verify. 592 * @param qchase: query that was made. 593 * @param chase_reply: answer to validate. 594 * @param key_entry: the key entry, which is trusted, and which matches 595 * the signer of the answer. The key entry isgood(). 596 * @return false if any of the rrsets in the an or ns sections of the message 597 * fail to verify. The message is then set to bogus. 598 */ 599 static int 600 validate_msg_signatures(struct module_qstate* qstate, struct module_env* env, 601 struct val_env* ve, struct query_info* qchase, 602 struct reply_info* chase_reply, struct key_entry_key* key_entry) 603 { 604 uint8_t* sname; 605 size_t i, slen; 606 struct ub_packed_rrset_key* s; 607 enum sec_status sec; 608 int dname_seen = 0; 609 char* reason = NULL; 610 sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS; 611 612 /* validate the ANSWER section */ 613 for(i=0; i<chase_reply->an_numrrsets; i++) { 614 s = chase_reply->rrsets[i]; 615 /* Skip the CNAME following a (validated) DNAME. 616 * Because of the normalization routines in the iterator, 617 * there will always be an unsigned CNAME following a DNAME 618 * (unless qtype=DNAME). */ 619 if(dname_seen && ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) { 620 dname_seen = 0; 621 /* CNAME was synthesized by our own iterator */ 622 /* since the DNAME verified, mark the CNAME as secure */ 623 ((struct packed_rrset_data*)s->entry.data)->security = 624 sec_status_secure; 625 ((struct packed_rrset_data*)s->entry.data)->trust = 626 rrset_trust_validated; 627 continue; 628 } 629 630 /* Verify the answer rrset */ 631 sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, 632 &reason_bogus, LDNS_SECTION_ANSWER, qstate); 633 /* If the (answer) rrset failed to validate, then this 634 * message is BAD. */ 635 if(sec != sec_status_secure) { 636 log_nametypeclass(VERB_QUERY, "validator: response " 637 "has failed ANSWER rrset:", s->rk.dname, 638 ntohs(s->rk.type), ntohs(s->rk.rrset_class)); 639 errinf_ede(qstate, reason, reason_bogus); 640 if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) 641 errinf(qstate, "for CNAME"); 642 else if(ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME) 643 errinf(qstate, "for DNAME"); 644 errinf_origin(qstate, qstate->reply_origin); 645 chase_reply->security = sec_status_bogus; 646 update_reason_bogus(chase_reply, reason_bogus); 647 648 return 0; 649 } 650 651 /* Notice a DNAME that should be followed by an unsigned 652 * CNAME. */ 653 if(qchase->qtype != LDNS_RR_TYPE_DNAME && 654 ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME) { 655 dname_seen = 1; 656 } 657 } 658 659 /* validate the AUTHORITY section */ 660 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 661 chase_reply->ns_numrrsets; i++) { 662 s = chase_reply->rrsets[i]; 663 sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, 664 &reason_bogus, LDNS_SECTION_AUTHORITY, qstate); 665 /* If anything in the authority section fails to be secure, 666 * we have a bad message. */ 667 if(sec != sec_status_secure) { 668 log_nametypeclass(VERB_QUERY, "validator: response " 669 "has failed AUTHORITY rrset:", s->rk.dname, 670 ntohs(s->rk.type), ntohs(s->rk.rrset_class)); 671 errinf_ede(qstate, reason, reason_bogus); 672 errinf_origin(qstate, qstate->reply_origin); 673 errinf_rrset(qstate, s); 674 chase_reply->security = sec_status_bogus; 675 update_reason_bogus(chase_reply, reason_bogus); 676 return 0; 677 } 678 } 679 680 /* If set, the validator should clean the additional section of 681 * secure messages. */ 682 if(!env->cfg->val_clean_additional) 683 return 1; 684 /* attempt to validate the ADDITIONAL section rrsets */ 685 for(i=chase_reply->an_numrrsets+chase_reply->ns_numrrsets; 686 i<chase_reply->rrset_count; i++) { 687 s = chase_reply->rrsets[i]; 688 /* only validate rrs that have signatures with the key */ 689 /* leave others unchecked, those get removed later on too */ 690 val_find_rrset_signer(s, &sname, &slen); 691 692 if(sname && query_dname_compare(sname, key_entry->name)==0) 693 (void)val_verify_rrset_entry(env, ve, s, key_entry, 694 &reason, NULL, LDNS_SECTION_ADDITIONAL, qstate); 695 /* the additional section can fail to be secure, 696 * it is optional, check signature in case we need 697 * to clean the additional section later. */ 698 } 699 700 return 1; 701 } 702 703 /** 704 * Detect wrong truncated response (say from BIND 9.6.1 that is forwarding 705 * and saw the NS record without signatures from a referral). 706 * The positive response has a mangled authority section. 707 * Remove that authority section and the additional section. 708 * @param rep: reply 709 * @return true if a wrongly truncated response. 710 */ 711 static int 712 detect_wrongly_truncated(struct reply_info* rep) 713 { 714 size_t i; 715 /* only NS in authority, and it is bogus */ 716 if(rep->ns_numrrsets != 1 || rep->an_numrrsets == 0) 717 return 0; 718 if(ntohs(rep->rrsets[ rep->an_numrrsets ]->rk.type) != LDNS_RR_TYPE_NS) 719 return 0; 720 if(((struct packed_rrset_data*)rep->rrsets[ rep->an_numrrsets ] 721 ->entry.data)->security == sec_status_secure) 722 return 0; 723 /* answer section is present and secure */ 724 for(i=0; i<rep->an_numrrsets; i++) { 725 if(((struct packed_rrset_data*)rep->rrsets[ i ] 726 ->entry.data)->security != sec_status_secure) 727 return 0; 728 } 729 verbose(VERB_ALGO, "truncating to minimal response"); 730 return 1; 731 } 732 733 /** 734 * For messages that are not referrals, if the chase reply contains an 735 * unsigned NS record in the authority section it could have been 736 * inserted by a (BIND) forwarder that thinks the zone is insecure, and 737 * that has an NS record without signatures in cache. Remove the NS 738 * record since the reply does not hinge on that record (in the authority 739 * section), but do not remove it if it removes the last record from the 740 * answer+authority sections. 741 * @param chase_reply: the chased reply, we have a key for this contents, 742 * so we should have signatures for these rrsets and not having 743 * signatures means it will be bogus. 744 * @param orig_reply: original reply, remove NS from there as well because 745 * we cannot mark the NS record as DNSSEC valid because it is not 746 * validated by signatures. 747 */ 748 static void 749 remove_spurious_authority(struct reply_info* chase_reply, 750 struct reply_info* orig_reply) 751 { 752 size_t i, found = 0; 753 int remove = 0; 754 /* if no answer and only 1 auth RRset, do not remove that one */ 755 if(chase_reply->an_numrrsets == 0 && chase_reply->ns_numrrsets == 1) 756 return; 757 /* search authority section for unsigned NS records */ 758 for(i = chase_reply->an_numrrsets; 759 i < chase_reply->an_numrrsets+chase_reply->ns_numrrsets; i++) { 760 struct packed_rrset_data* d = (struct packed_rrset_data*) 761 chase_reply->rrsets[i]->entry.data; 762 if(ntohs(chase_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS 763 && d->rrsig_count == 0) { 764 found = i; 765 remove = 1; 766 break; 767 } 768 } 769 /* see if we found the entry */ 770 if(!remove) return; 771 log_rrset_key(VERB_ALGO, "Removing spurious unsigned NS record " 772 "(likely inserted by forwarder)", chase_reply->rrsets[found]); 773 774 /* find rrset in orig_reply */ 775 for(i = orig_reply->an_numrrsets; 776 i < orig_reply->an_numrrsets+orig_reply->ns_numrrsets; i++) { 777 if(ntohs(orig_reply->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS 778 && query_dname_compare(orig_reply->rrsets[i]->rk.dname, 779 chase_reply->rrsets[found]->rk.dname) == 0) { 780 /* remove from orig_msg */ 781 val_reply_remove_auth(orig_reply, i); 782 break; 783 } 784 } 785 /* remove rrset from chase_reply */ 786 val_reply_remove_auth(chase_reply, found); 787 } 788 789 /** 790 * Given a "positive" response -- a response that contains an answer to the 791 * question, and no CNAME chain, validate this response. 792 * 793 * The answer and authority RRsets must already be verified as secure. 794 * 795 * @param env: module env for verify. 796 * @param ve: validator env for verify. 797 * @param qchase: query that was made. 798 * @param chase_reply: answer to that query to validate. 799 * @param kkey: the key entry, which is trusted, and which matches 800 * the signer of the answer. The key entry isgood(). 801 */ 802 static void 803 validate_positive_response(struct module_env* env, struct val_env* ve, 804 struct query_info* qchase, struct reply_info* chase_reply, 805 struct key_entry_key* kkey) 806 { 807 uint8_t* wc = NULL; 808 size_t wl; 809 int wc_cached = 0; 810 int wc_NSEC_ok = 0; 811 int nsec3s_seen = 0; 812 size_t i; 813 struct ub_packed_rrset_key* s; 814 815 /* validate the ANSWER section - this will be the answer itself */ 816 for(i=0; i<chase_reply->an_numrrsets; i++) { 817 s = chase_reply->rrsets[i]; 818 819 /* Check to see if the rrset is the result of a wildcard 820 * expansion. If so, an additional check will need to be 821 * made in the authority section. */ 822 if(!val_rrset_wildcard(s, &wc, &wl)) { 823 log_nametypeclass(VERB_QUERY, "Positive response has " 824 "inconsistent wildcard sigs:", s->rk.dname, 825 ntohs(s->rk.type), ntohs(s->rk.rrset_class)); 826 chase_reply->security = sec_status_bogus; 827 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 828 return; 829 } 830 if(wc && !wc_cached && env->cfg->aggressive_nsec) { 831 rrset_cache_update_wildcard(env->rrset_cache, s, wc, wl, 832 env->alloc, *env->now); 833 wc_cached = 1; 834 } 835 836 } 837 838 /* validate the AUTHORITY section as well - this will generally be 839 * the NS rrset (which could be missing, no problem) */ 840 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 841 chase_reply->ns_numrrsets; i++) { 842 s = chase_reply->rrsets[i]; 843 844 /* If this is a positive wildcard response, and we have a 845 * (just verified) NSEC record, try to use it to 1) prove 846 * that qname doesn't exist and 2) that the correct wildcard 847 * was used. */ 848 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 849 if(val_nsec_proves_positive_wildcard(s, qchase, wc)) { 850 wc_NSEC_ok = 1; 851 } 852 /* if not, continue looking for proof */ 853 } 854 855 /* Otherwise, if this is a positive wildcard response and 856 * we have NSEC3 records */ 857 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 858 nsec3s_seen = 1; 859 } 860 } 861 862 /* If this was a positive wildcard response that we haven't already 863 * proven, and we have NSEC3 records, try to prove it using the NSEC3 864 * records. */ 865 if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) { 866 enum sec_status sec = nsec3_prove_wildcard(env, ve, 867 chase_reply->rrsets+chase_reply->an_numrrsets, 868 chase_reply->ns_numrrsets, qchase, kkey, wc); 869 if(sec == sec_status_insecure) { 870 verbose(VERB_ALGO, "Positive wildcard response is " 871 "insecure"); 872 chase_reply->security = sec_status_insecure; 873 return; 874 } else if(sec == sec_status_secure) 875 wc_NSEC_ok = 1; 876 } 877 878 /* If after all this, we still haven't proven the positive wildcard 879 * response, fail. */ 880 if(wc != NULL && !wc_NSEC_ok) { 881 verbose(VERB_QUERY, "positive response was wildcard " 882 "expansion and did not prove original data " 883 "did not exist"); 884 chase_reply->security = sec_status_bogus; 885 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 886 return; 887 } 888 889 verbose(VERB_ALGO, "Successfully validated positive response"); 890 chase_reply->security = sec_status_secure; 891 } 892 893 /** 894 * Validate a NOERROR/NODATA signed response -- a response that has a 895 * NOERROR Rcode but no ANSWER section RRsets. This consists of making 896 * certain that the authority section NSEC/NSEC3s proves that the qname 897 * does exist and the qtype doesn't. 898 * 899 * The answer and authority RRsets must already be verified as secure. 900 * 901 * @param env: module env for verify. 902 * @param ve: validator env for verify. 903 * @param qchase: query that was made. 904 * @param chase_reply: answer to that query to validate. 905 * @param kkey: the key entry, which is trusted, and which matches 906 * the signer of the answer. The key entry isgood(). 907 */ 908 static void 909 validate_nodata_response(struct module_env* env, struct val_env* ve, 910 struct query_info* qchase, struct reply_info* chase_reply, 911 struct key_entry_key* kkey) 912 { 913 /* Since we are here, there must be nothing in the ANSWER section to 914 * validate. */ 915 /* (Note: CNAME/DNAME responses will not directly get here -- 916 * instead, they are chased down into individual CNAME validations, 917 * and at the end of the cname chain a POSITIVE, or CNAME_NOANSWER 918 * validation.) */ 919 920 /* validate the AUTHORITY section */ 921 int has_valid_nsec = 0; /* If true, then the NODATA has been proven.*/ 922 uint8_t* ce = NULL; /* for wildcard nodata responses. This is the 923 proven closest encloser. */ 924 uint8_t* wc = NULL; /* for wildcard nodata responses. wildcard nsec */ 925 int nsec3s_seen = 0; /* nsec3s seen */ 926 struct ub_packed_rrset_key* s; 927 size_t i; 928 929 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 930 chase_reply->ns_numrrsets; i++) { 931 s = chase_reply->rrsets[i]; 932 /* If we encounter an NSEC record, try to use it to prove 933 * NODATA. 934 * This needs to handle the ENT NODATA case. */ 935 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 936 if(nsec_proves_nodata(s, qchase, &wc)) { 937 has_valid_nsec = 1; 938 /* sets wc-encloser if wildcard applicable */ 939 } 940 if(val_nsec_proves_name_error(s, qchase->qname)) { 941 ce = nsec_closest_encloser(qchase->qname, s); 942 } 943 if(val_nsec_proves_insecuredelegation(s, qchase)) { 944 verbose(VERB_ALGO, "delegation is insecure"); 945 chase_reply->security = sec_status_insecure; 946 return; 947 } 948 } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 949 nsec3s_seen = 1; 950 } 951 } 952 953 /* check to see if we have a wildcard NODATA proof. */ 954 955 /* The wildcard NODATA is 1 NSEC proving that qname does not exist 956 * (and also proving what the closest encloser is), and 1 NSEC 957 * showing the matching wildcard, which must be *.closest_encloser. */ 958 if(wc && !ce) 959 has_valid_nsec = 0; 960 else if(wc && ce) { 961 if(query_dname_compare(wc, ce) != 0) { 962 has_valid_nsec = 0; 963 } 964 } 965 966 if(!has_valid_nsec && nsec3s_seen) { 967 enum sec_status sec = nsec3_prove_nodata(env, ve, 968 chase_reply->rrsets+chase_reply->an_numrrsets, 969 chase_reply->ns_numrrsets, qchase, kkey); 970 if(sec == sec_status_insecure) { 971 verbose(VERB_ALGO, "NODATA response is insecure"); 972 chase_reply->security = sec_status_insecure; 973 return; 974 } else if(sec == sec_status_secure) 975 has_valid_nsec = 1; 976 } 977 978 if(!has_valid_nsec) { 979 verbose(VERB_QUERY, "NODATA response failed to prove NODATA " 980 "status with NSEC/NSEC3"); 981 if(verbosity >= VERB_ALGO) 982 log_dns_msg("Failed NODATA", qchase, chase_reply); 983 chase_reply->security = sec_status_bogus; 984 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 985 return; 986 } 987 988 verbose(VERB_ALGO, "successfully validated NODATA response."); 989 chase_reply->security = sec_status_secure; 990 } 991 992 /** 993 * Validate a NAMEERROR signed response -- a response that has a NXDOMAIN 994 * Rcode. 995 * This consists of making certain that the authority section NSEC proves 996 * that the qname doesn't exist and the covering wildcard also doesn't exist.. 997 * 998 * The answer and authority RRsets must have already been verified as secure. 999 * 1000 * @param env: module env for verify. 1001 * @param ve: validator env for verify. 1002 * @param qchase: query that was made. 1003 * @param chase_reply: answer to that query to validate. 1004 * @param kkey: the key entry, which is trusted, and which matches 1005 * the signer of the answer. The key entry isgood(). 1006 * @param rcode: adjusted RCODE, in case of RCODE/proof mismatch leniency. 1007 */ 1008 static void 1009 validate_nameerror_response(struct module_env* env, struct val_env* ve, 1010 struct query_info* qchase, struct reply_info* chase_reply, 1011 struct key_entry_key* kkey, int* rcode) 1012 { 1013 int has_valid_nsec = 0; 1014 int has_valid_wnsec = 0; 1015 int nsec3s_seen = 0; 1016 struct ub_packed_rrset_key* s; 1017 size_t i; 1018 uint8_t* ce; 1019 int ce_labs = 0; 1020 int prev_ce_labs = 0; 1021 1022 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 1023 chase_reply->ns_numrrsets; i++) { 1024 s = chase_reply->rrsets[i]; 1025 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1026 if(val_nsec_proves_name_error(s, qchase->qname)) 1027 has_valid_nsec = 1; 1028 ce = nsec_closest_encloser(qchase->qname, s); 1029 ce_labs = dname_count_labels(ce); 1030 /* Use longest closest encloser to prove wildcard. */ 1031 if(ce_labs > prev_ce_labs || 1032 (ce_labs == prev_ce_labs && 1033 has_valid_wnsec == 0)) { 1034 if(val_nsec_proves_no_wc(s, qchase->qname, 1035 qchase->qname_len)) 1036 has_valid_wnsec = 1; 1037 else 1038 has_valid_wnsec = 0; 1039 } 1040 prev_ce_labs = ce_labs; 1041 if(val_nsec_proves_insecuredelegation(s, qchase)) { 1042 verbose(VERB_ALGO, "delegation is insecure"); 1043 chase_reply->security = sec_status_insecure; 1044 return; 1045 } 1046 } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) 1047 nsec3s_seen = 1; 1048 } 1049 1050 if((!has_valid_nsec || !has_valid_wnsec) && nsec3s_seen) { 1051 /* use NSEC3 proof, both answer and auth rrsets, in case 1052 * NSEC3s end up in the answer (due to qtype=NSEC3 or so) */ 1053 chase_reply->security = nsec3_prove_nameerror(env, ve, 1054 chase_reply->rrsets, chase_reply->an_numrrsets+ 1055 chase_reply->ns_numrrsets, qchase, kkey); 1056 if(chase_reply->security != sec_status_secure) { 1057 verbose(VERB_QUERY, "NameError response failed nsec, " 1058 "nsec3 proof was %s", sec_status_to_string( 1059 chase_reply->security)); 1060 return; 1061 } 1062 has_valid_nsec = 1; 1063 has_valid_wnsec = 1; 1064 } 1065 1066 /* If the message fails to prove either condition, it is bogus. */ 1067 if(!has_valid_nsec) { 1068 verbose(VERB_QUERY, "NameError response has failed to prove: " 1069 "qname does not exist"); 1070 chase_reply->security = sec_status_bogus; 1071 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1072 /* Be lenient with RCODE in NSEC NameError responses */ 1073 validate_nodata_response(env, ve, qchase, chase_reply, kkey); 1074 if (chase_reply->security == sec_status_secure) 1075 *rcode = LDNS_RCODE_NOERROR; 1076 return; 1077 } 1078 1079 if(!has_valid_wnsec) { 1080 verbose(VERB_QUERY, "NameError response has failed to prove: " 1081 "covering wildcard does not exist"); 1082 chase_reply->security = sec_status_bogus; 1083 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1084 /* Be lenient with RCODE in NSEC NameError responses */ 1085 validate_nodata_response(env, ve, qchase, chase_reply, kkey); 1086 if (chase_reply->security == sec_status_secure) 1087 *rcode = LDNS_RCODE_NOERROR; 1088 return; 1089 } 1090 1091 /* Otherwise, we consider the message secure. */ 1092 verbose(VERB_ALGO, "successfully validated NAME ERROR response."); 1093 chase_reply->security = sec_status_secure; 1094 } 1095 1096 /** 1097 * Given a referral response, validate rrsets and take least trusted rrset 1098 * as the current validation status. 1099 * 1100 * Note that by the time this method is called, the process of finding the 1101 * trusted DNSKEY rrset that signs this response must already have been 1102 * completed. 1103 * 1104 * @param chase_reply: answer to validate. 1105 */ 1106 static void 1107 validate_referral_response(struct reply_info* chase_reply) 1108 { 1109 size_t i; 1110 enum sec_status s; 1111 /* message security equals lowest rrset security */ 1112 chase_reply->security = sec_status_secure; 1113 for(i=0; i<chase_reply->rrset_count; i++) { 1114 s = ((struct packed_rrset_data*)chase_reply->rrsets[i] 1115 ->entry.data)->security; 1116 if(s < chase_reply->security) 1117 chase_reply->security = s; 1118 } 1119 verbose(VERB_ALGO, "validated part of referral response as %s", 1120 sec_status_to_string(chase_reply->security)); 1121 } 1122 1123 /** 1124 * Given an "ANY" response -- a response that contains an answer to a 1125 * qtype==ANY question, with answers. This does no checking that all 1126 * types are present. 1127 * 1128 * NOTE: it may be possible to get parent-side delegation point records 1129 * here, which won't all be signed. Right now, this routine relies on the 1130 * upstream iterative resolver to not return these responses -- instead 1131 * treating them as referrals. 1132 * 1133 * NOTE: RFC 4035 is silent on this issue, so this may change upon 1134 * clarification. Clarification draft -05 says to not check all types are 1135 * present. 1136 * 1137 * Note that by the time this method is called, the process of finding the 1138 * trusted DNSKEY rrset that signs this response must already have been 1139 * completed. 1140 * 1141 * @param env: module env for verify. 1142 * @param ve: validator env for verify. 1143 * @param qchase: query that was made. 1144 * @param chase_reply: answer to that query to validate. 1145 * @param kkey: the key entry, which is trusted, and which matches 1146 * the signer of the answer. The key entry isgood(). 1147 */ 1148 static void 1149 validate_any_response(struct module_env* env, struct val_env* ve, 1150 struct query_info* qchase, struct reply_info* chase_reply, 1151 struct key_entry_key* kkey) 1152 { 1153 /* all answer and auth rrsets already verified */ 1154 /* but check if a wildcard response is given, then check NSEC/NSEC3 1155 * for qname denial to see if wildcard is applicable */ 1156 uint8_t* wc = NULL; 1157 size_t wl; 1158 int wc_NSEC_ok = 0; 1159 int nsec3s_seen = 0; 1160 size_t i; 1161 struct ub_packed_rrset_key* s; 1162 1163 if(qchase->qtype != LDNS_RR_TYPE_ANY) { 1164 log_err("internal error: ANY validation called for non-ANY"); 1165 chase_reply->security = sec_status_bogus; 1166 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1167 return; 1168 } 1169 1170 /* validate the ANSWER section - this will be the answer itself */ 1171 for(i=0; i<chase_reply->an_numrrsets; i++) { 1172 s = chase_reply->rrsets[i]; 1173 1174 /* Check to see if the rrset is the result of a wildcard 1175 * expansion. If so, an additional check will need to be 1176 * made in the authority section. */ 1177 if(!val_rrset_wildcard(s, &wc, &wl)) { 1178 log_nametypeclass(VERB_QUERY, "Positive ANY response" 1179 " has inconsistent wildcard sigs:", 1180 s->rk.dname, ntohs(s->rk.type), 1181 ntohs(s->rk.rrset_class)); 1182 chase_reply->security = sec_status_bogus; 1183 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1184 return; 1185 } 1186 } 1187 1188 /* if it was a wildcard, check for NSEC/NSEC3s in both answer 1189 * and authority sections (NSEC may be moved to the ANSWER section) */ 1190 if(wc != NULL) 1191 for(i=0; i<chase_reply->an_numrrsets+chase_reply->ns_numrrsets; 1192 i++) { 1193 s = chase_reply->rrsets[i]; 1194 1195 /* If this is a positive wildcard response, and we have a 1196 * (just verified) NSEC record, try to use it to 1) prove 1197 * that qname doesn't exist and 2) that the correct wildcard 1198 * was used. */ 1199 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1200 if(val_nsec_proves_positive_wildcard(s, qchase, wc)) { 1201 wc_NSEC_ok = 1; 1202 } 1203 /* if not, continue looking for proof */ 1204 } 1205 1206 /* Otherwise, if this is a positive wildcard response and 1207 * we have NSEC3 records */ 1208 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 1209 nsec3s_seen = 1; 1210 } 1211 } 1212 1213 /* If this was a positive wildcard response that we haven't already 1214 * proven, and we have NSEC3 records, try to prove it using the NSEC3 1215 * records. */ 1216 if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) { 1217 /* look both in answer and auth section for NSEC3s */ 1218 enum sec_status sec = nsec3_prove_wildcard(env, ve, 1219 chase_reply->rrsets, 1220 chase_reply->an_numrrsets+chase_reply->ns_numrrsets, 1221 qchase, kkey, wc); 1222 if(sec == sec_status_insecure) { 1223 verbose(VERB_ALGO, "Positive ANY wildcard response is " 1224 "insecure"); 1225 chase_reply->security = sec_status_insecure; 1226 return; 1227 } else if(sec == sec_status_secure) 1228 wc_NSEC_ok = 1; 1229 } 1230 1231 /* If after all this, we still haven't proven the positive wildcard 1232 * response, fail. */ 1233 if(wc != NULL && !wc_NSEC_ok) { 1234 verbose(VERB_QUERY, "positive ANY response was wildcard " 1235 "expansion and did not prove original data " 1236 "did not exist"); 1237 chase_reply->security = sec_status_bogus; 1238 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1239 return; 1240 } 1241 1242 verbose(VERB_ALGO, "Successfully validated positive ANY response"); 1243 chase_reply->security = sec_status_secure; 1244 } 1245 1246 /** 1247 * Validate CNAME response, or DNAME+CNAME. 1248 * This is just like a positive proof, except that this is about a 1249 * DNAME+CNAME. Possible wildcard proof. 1250 * Difference with positive proof is that this routine refuses 1251 * wildcarded DNAMEs. 1252 * 1253 * The answer and authority rrsets must already be verified as secure. 1254 * 1255 * @param env: module env for verify. 1256 * @param ve: validator env for verify. 1257 * @param qchase: query that was made. 1258 * @param chase_reply: answer to that query to validate. 1259 * @param kkey: the key entry, which is trusted, and which matches 1260 * the signer of the answer. The key entry isgood(). 1261 */ 1262 static void 1263 validate_cname_response(struct module_env* env, struct val_env* ve, 1264 struct query_info* qchase, struct reply_info* chase_reply, 1265 struct key_entry_key* kkey) 1266 { 1267 uint8_t* wc = NULL; 1268 size_t wl; 1269 int wc_NSEC_ok = 0; 1270 int nsec3s_seen = 0; 1271 size_t i; 1272 struct ub_packed_rrset_key* s; 1273 1274 /* validate the ANSWER section - this will be the CNAME (+DNAME) */ 1275 for(i=0; i<chase_reply->an_numrrsets; i++) { 1276 s = chase_reply->rrsets[i]; 1277 1278 /* Check to see if the rrset is the result of a wildcard 1279 * expansion. If so, an additional check will need to be 1280 * made in the authority section. */ 1281 if(!val_rrset_wildcard(s, &wc, &wl)) { 1282 log_nametypeclass(VERB_QUERY, "Cname response has " 1283 "inconsistent wildcard sigs:", s->rk.dname, 1284 ntohs(s->rk.type), ntohs(s->rk.rrset_class)); 1285 chase_reply->security = sec_status_bogus; 1286 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1287 return; 1288 } 1289 1290 /* Refuse wildcarded DNAMEs rfc 4597. 1291 * Do not follow a wildcarded DNAME because 1292 * its synthesized CNAME expansion is underdefined */ 1293 if(qchase->qtype != LDNS_RR_TYPE_DNAME && 1294 ntohs(s->rk.type) == LDNS_RR_TYPE_DNAME && wc) { 1295 log_nametypeclass(VERB_QUERY, "cannot validate a " 1296 "wildcarded DNAME:", s->rk.dname, 1297 ntohs(s->rk.type), ntohs(s->rk.rrset_class)); 1298 chase_reply->security = sec_status_bogus; 1299 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1300 return; 1301 } 1302 1303 /* If we have found a CNAME, stop looking for one. 1304 * The iterator has placed the CNAME chain in correct 1305 * order. */ 1306 if (ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) { 1307 break; 1308 } 1309 } 1310 1311 /* AUTHORITY section */ 1312 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 1313 chase_reply->ns_numrrsets; i++) { 1314 s = chase_reply->rrsets[i]; 1315 1316 /* If this is a positive wildcard response, and we have a 1317 * (just verified) NSEC record, try to use it to 1) prove 1318 * that qname doesn't exist and 2) that the correct wildcard 1319 * was used. */ 1320 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1321 if(val_nsec_proves_positive_wildcard(s, qchase, wc)) { 1322 wc_NSEC_ok = 1; 1323 } 1324 /* if not, continue looking for proof */ 1325 } 1326 1327 /* Otherwise, if this is a positive wildcard response and 1328 * we have NSEC3 records */ 1329 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 1330 nsec3s_seen = 1; 1331 } 1332 } 1333 1334 /* If this was a positive wildcard response that we haven't already 1335 * proven, and we have NSEC3 records, try to prove it using the NSEC3 1336 * records. */ 1337 if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) { 1338 enum sec_status sec = nsec3_prove_wildcard(env, ve, 1339 chase_reply->rrsets+chase_reply->an_numrrsets, 1340 chase_reply->ns_numrrsets, qchase, kkey, wc); 1341 if(sec == sec_status_insecure) { 1342 verbose(VERB_ALGO, "wildcard CNAME response is " 1343 "insecure"); 1344 chase_reply->security = sec_status_insecure; 1345 return; 1346 } else if(sec == sec_status_secure) 1347 wc_NSEC_ok = 1; 1348 } 1349 1350 /* If after all this, we still haven't proven the positive wildcard 1351 * response, fail. */ 1352 if(wc != NULL && !wc_NSEC_ok) { 1353 verbose(VERB_QUERY, "CNAME response was wildcard " 1354 "expansion and did not prove original data " 1355 "did not exist"); 1356 chase_reply->security = sec_status_bogus; 1357 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1358 return; 1359 } 1360 1361 verbose(VERB_ALGO, "Successfully validated CNAME response"); 1362 chase_reply->security = sec_status_secure; 1363 } 1364 1365 /** 1366 * Validate CNAME NOANSWER response, no more data after a CNAME chain. 1367 * This can be a NODATA or a NAME ERROR case, but not both at the same time. 1368 * We don't know because the rcode has been set to NOERROR by the CNAME. 1369 * 1370 * The answer and authority rrsets must already be verified as secure. 1371 * 1372 * @param env: module env for verify. 1373 * @param ve: validator env for verify. 1374 * @param qchase: query that was made. 1375 * @param chase_reply: answer to that query to validate. 1376 * @param kkey: the key entry, which is trusted, and which matches 1377 * the signer of the answer. The key entry isgood(). 1378 */ 1379 static void 1380 validate_cname_noanswer_response(struct module_env* env, struct val_env* ve, 1381 struct query_info* qchase, struct reply_info* chase_reply, 1382 struct key_entry_key* kkey) 1383 { 1384 int nodata_valid_nsec = 0; /* If true, then NODATA has been proven.*/ 1385 uint8_t* ce = NULL; /* for wildcard nodata responses. This is the 1386 proven closest encloser. */ 1387 uint8_t* wc = NULL; /* for wildcard nodata responses. wildcard nsec */ 1388 int nxdomain_valid_nsec = 0; /* if true, nameerror has been proven */ 1389 int nxdomain_valid_wnsec = 0; 1390 int nsec3s_seen = 0; /* nsec3s seen */ 1391 struct ub_packed_rrset_key* s; 1392 size_t i; 1393 uint8_t* nsec_ce; /* Used to find the NSEC with the longest ce */ 1394 int ce_labs = 0; 1395 int prev_ce_labs = 0; 1396 1397 /* the AUTHORITY section */ 1398 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 1399 chase_reply->ns_numrrsets; i++) { 1400 s = chase_reply->rrsets[i]; 1401 1402 /* If we encounter an NSEC record, try to use it to prove 1403 * NODATA. This needs to handle the ENT NODATA case. 1404 * Also try to prove NAMEERROR, and absence of a wildcard */ 1405 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1406 if(nsec_proves_nodata(s, qchase, &wc)) { 1407 nodata_valid_nsec = 1; 1408 /* set wc encloser if wildcard applicable */ 1409 } 1410 if(val_nsec_proves_name_error(s, qchase->qname)) { 1411 ce = nsec_closest_encloser(qchase->qname, s); 1412 nxdomain_valid_nsec = 1; 1413 } 1414 nsec_ce = nsec_closest_encloser(qchase->qname, s); 1415 ce_labs = dname_count_labels(nsec_ce); 1416 /* Use longest closest encloser to prove wildcard. */ 1417 if(ce_labs > prev_ce_labs || 1418 (ce_labs == prev_ce_labs && 1419 nxdomain_valid_wnsec == 0)) { 1420 if(val_nsec_proves_no_wc(s, qchase->qname, 1421 qchase->qname_len)) 1422 nxdomain_valid_wnsec = 1; 1423 else 1424 nxdomain_valid_wnsec = 0; 1425 } 1426 prev_ce_labs = ce_labs; 1427 if(val_nsec_proves_insecuredelegation(s, qchase)) { 1428 verbose(VERB_ALGO, "delegation is insecure"); 1429 chase_reply->security = sec_status_insecure; 1430 return; 1431 } 1432 } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 1433 nsec3s_seen = 1; 1434 } 1435 } 1436 1437 /* check to see if we have a wildcard NODATA proof. */ 1438 1439 /* The wildcard NODATA is 1 NSEC proving that qname does not exists 1440 * (and also proving what the closest encloser is), and 1 NSEC 1441 * showing the matching wildcard, which must be *.closest_encloser. */ 1442 if(wc && !ce) 1443 nodata_valid_nsec = 0; 1444 else if(wc && ce) { 1445 if(query_dname_compare(wc, ce) != 0) { 1446 nodata_valid_nsec = 0; 1447 } 1448 } 1449 if(nxdomain_valid_nsec && !nxdomain_valid_wnsec) { 1450 /* name error is missing wildcard denial proof */ 1451 nxdomain_valid_nsec = 0; 1452 } 1453 1454 if(nodata_valid_nsec && nxdomain_valid_nsec) { 1455 verbose(VERB_QUERY, "CNAMEchain to noanswer proves that name " 1456 "exists and not exists, bogus"); 1457 chase_reply->security = sec_status_bogus; 1458 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1459 return; 1460 } 1461 if(!nodata_valid_nsec && !nxdomain_valid_nsec && nsec3s_seen) { 1462 int nodata; 1463 enum sec_status sec = nsec3_prove_nxornodata(env, ve, 1464 chase_reply->rrsets+chase_reply->an_numrrsets, 1465 chase_reply->ns_numrrsets, qchase, kkey, &nodata); 1466 if(sec == sec_status_insecure) { 1467 verbose(VERB_ALGO, "CNAMEchain to noanswer response " 1468 "is insecure"); 1469 chase_reply->security = sec_status_insecure; 1470 return; 1471 } else if(sec == sec_status_secure) { 1472 if(nodata) 1473 nodata_valid_nsec = 1; 1474 else nxdomain_valid_nsec = 1; 1475 } 1476 } 1477 1478 if(!nodata_valid_nsec && !nxdomain_valid_nsec) { 1479 verbose(VERB_QUERY, "CNAMEchain to noanswer response failed " 1480 "to prove status with NSEC/NSEC3"); 1481 if(verbosity >= VERB_ALGO) 1482 log_dns_msg("Failed CNAMEnoanswer", qchase, chase_reply); 1483 chase_reply->security = sec_status_bogus; 1484 update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1485 return; 1486 } 1487 1488 if(nodata_valid_nsec) 1489 verbose(VERB_ALGO, "successfully validated CNAME chain to a " 1490 "NODATA response."); 1491 else verbose(VERB_ALGO, "successfully validated CNAME chain to a " 1492 "NAMEERROR response."); 1493 chase_reply->security = sec_status_secure; 1494 } 1495 1496 /** 1497 * Process init state for validator. 1498 * Process the INIT state. First tier responses start in the INIT state. 1499 * This is where they are vetted for validation suitability, and the initial 1500 * key search is done. 1501 * 1502 * Currently, events the come through this routine will be either promoted 1503 * to FINISHED/CNAME_RESP (no validation needed), FINDKEY (next step to 1504 * validation), or will be (temporarily) retired and a new priming request 1505 * event will be generated. 1506 * 1507 * @param qstate: query state. 1508 * @param vq: validator query state. 1509 * @param ve: validator shared global environment. 1510 * @param id: module id. 1511 * @return true if the event should be processed further on return, false if 1512 * not. 1513 */ 1514 static int 1515 processInit(struct module_qstate* qstate, struct val_qstate* vq, 1516 struct val_env* ve, int id) 1517 { 1518 uint8_t* lookup_name; 1519 size_t lookup_len; 1520 struct trust_anchor* anchor; 1521 enum val_classification subtype = val_classify_response( 1522 qstate->query_flags, &qstate->qinfo, &vq->qchase, 1523 vq->orig_msg->rep, vq->rrset_skip); 1524 if(vq->restart_count > ve->max_restart) { 1525 verbose(VERB_ALGO, "restart count exceeded"); 1526 return val_error(qstate, id); 1527 } 1528 1529 /* correctly initialize reason_bogus */ 1530 update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_BOGUS); 1531 1532 verbose(VERB_ALGO, "validator classification %s", 1533 val_classification_to_string(subtype)); 1534 if(subtype == VAL_CLASS_REFERRAL && 1535 vq->rrset_skip < vq->orig_msg->rep->rrset_count) { 1536 /* referral uses the rrset name as qchase, to find keys for 1537 * that rrset */ 1538 vq->qchase.qname = vq->orig_msg->rep-> 1539 rrsets[vq->rrset_skip]->rk.dname; 1540 vq->qchase.qname_len = vq->orig_msg->rep-> 1541 rrsets[vq->rrset_skip]->rk.dname_len; 1542 vq->qchase.qtype = ntohs(vq->orig_msg->rep-> 1543 rrsets[vq->rrset_skip]->rk.type); 1544 vq->qchase.qclass = ntohs(vq->orig_msg->rep-> 1545 rrsets[vq->rrset_skip]->rk.rrset_class); 1546 } 1547 lookup_name = vq->qchase.qname; 1548 lookup_len = vq->qchase.qname_len; 1549 /* for type DS look at the parent side for keys/trustanchor */ 1550 /* also for NSEC not at apex */ 1551 if(vq->qchase.qtype == LDNS_RR_TYPE_DS || 1552 (vq->qchase.qtype == LDNS_RR_TYPE_NSEC && 1553 vq->orig_msg->rep->rrset_count > vq->rrset_skip && 1554 ntohs(vq->orig_msg->rep->rrsets[vq->rrset_skip]->rk.type) == 1555 LDNS_RR_TYPE_NSEC && 1556 !(vq->orig_msg->rep->rrsets[vq->rrset_skip]-> 1557 rk.flags&PACKED_RRSET_NSEC_AT_APEX))) { 1558 dname_remove_label(&lookup_name, &lookup_len); 1559 } 1560 1561 val_mark_indeterminate(vq->chase_reply, qstate->env->anchors, 1562 qstate->env->rrset_cache, qstate->env); 1563 vq->key_entry = NULL; 1564 vq->empty_DS_name = NULL; 1565 vq->ds_rrset = 0; 1566 anchor = anchors_lookup(qstate->env->anchors, 1567 lookup_name, lookup_len, vq->qchase.qclass); 1568 1569 /* Determine the signer/lookup name */ 1570 val_find_signer(subtype, &vq->qchase, vq->orig_msg->rep, 1571 vq->rrset_skip, &vq->signer_name, &vq->signer_len); 1572 if(vq->signer_name != NULL && 1573 !dname_subdomain_c(lookup_name, vq->signer_name)) { 1574 log_nametypeclass(VERB_ALGO, "this signer name is not a parent " 1575 "of lookupname, omitted", vq->signer_name, 0, 0); 1576 vq->signer_name = NULL; 1577 } 1578 if(vq->signer_name == NULL) { 1579 log_nametypeclass(VERB_ALGO, "no signer, using", lookup_name, 1580 0, 0); 1581 } else { 1582 lookup_name = vq->signer_name; 1583 lookup_len = vq->signer_len; 1584 log_nametypeclass(VERB_ALGO, "signer is", lookup_name, 0, 0); 1585 } 1586 1587 /* for NXDOMAIN it could be signed by a parent of the trust anchor */ 1588 if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name && 1589 anchor && dname_strict_subdomain_c(anchor->name, lookup_name)){ 1590 lock_basic_unlock(&anchor->lock); 1591 anchor = anchors_lookup(qstate->env->anchors, 1592 lookup_name, lookup_len, vq->qchase.qclass); 1593 if(!anchor) { /* unsigned parent denies anchor*/ 1594 verbose(VERB_QUERY, "unsigned parent zone denies" 1595 " trust anchor, indeterminate"); 1596 vq->chase_reply->security = sec_status_indeterminate; 1597 update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_INDETERMINATE); 1598 vq->state = VAL_FINISHED_STATE; 1599 return 1; 1600 } 1601 verbose(VERB_ALGO, "trust anchor NXDOMAIN by signed parent"); 1602 } else if(subtype == VAL_CLASS_POSITIVE && 1603 qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY && 1604 query_dname_compare(lookup_name, qstate->qinfo.qname) == 0) { 1605 /* is a DNSKEY so lookup a bit higher since we want to 1606 * get it from a parent or from trustanchor */ 1607 dname_remove_label(&lookup_name, &lookup_len); 1608 } 1609 1610 if(vq->rrset_skip > 0 || subtype == VAL_CLASS_CNAME || 1611 subtype == VAL_CLASS_REFERRAL) { 1612 /* extract this part of orig_msg into chase_reply for 1613 * the eventual VALIDATE stage */ 1614 val_fill_reply(vq->chase_reply, vq->orig_msg->rep, 1615 vq->rrset_skip, lookup_name, lookup_len, 1616 vq->signer_name); 1617 if(verbosity >= VERB_ALGO) 1618 log_dns_msg("chased extract", &vq->qchase, 1619 vq->chase_reply); 1620 } 1621 1622 vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len, 1623 vq->qchase.qclass, qstate->region, *qstate->env->now); 1624 1625 /* there is no key and no trust anchor */ 1626 if(vq->key_entry == NULL && anchor == NULL) { 1627 /*response isn't under a trust anchor, so we cannot validate.*/ 1628 vq->chase_reply->security = sec_status_indeterminate; 1629 update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSSEC_INDETERMINATE); 1630 /* go to finished state to cache this result */ 1631 vq->state = VAL_FINISHED_STATE; 1632 return 1; 1633 } 1634 /* if not key, or if keyentry is *above* the trustanchor, i.e. 1635 * the keyentry is based on another (higher) trustanchor */ 1636 else if(vq->key_entry == NULL || (anchor && 1637 dname_strict_subdomain_c(anchor->name, vq->key_entry->name))) { 1638 /* trust anchor is an 'unsigned' trust anchor */ 1639 if(anchor && anchor->numDS == 0 && anchor->numDNSKEY == 0) { 1640 vq->chase_reply->security = sec_status_insecure; 1641 val_mark_insecure(vq->chase_reply, anchor->name, 1642 qstate->env->rrset_cache, qstate->env); 1643 lock_basic_unlock(&anchor->lock); 1644 /* go to finished state to cache this result */ 1645 vq->state = VAL_FINISHED_STATE; 1646 return 1; 1647 } 1648 /* fire off a trust anchor priming query. */ 1649 verbose(VERB_DETAIL, "prime trust anchor"); 1650 if(!prime_trust_anchor(qstate, vq, id, anchor)) { 1651 lock_basic_unlock(&anchor->lock); 1652 return val_error(qstate, id); 1653 } 1654 lock_basic_unlock(&anchor->lock); 1655 /* and otherwise, don't continue processing this event. 1656 * (it will be reactivated when the priming query returns). */ 1657 vq->state = VAL_FINDKEY_STATE; 1658 return 0; 1659 } 1660 if(anchor) { 1661 lock_basic_unlock(&anchor->lock); 1662 } 1663 1664 if(key_entry_isnull(vq->key_entry)) { 1665 /* response is under a null key, so we cannot validate 1666 * However, we do set the status to INSECURE, since it is 1667 * essentially proven insecure. */ 1668 vq->chase_reply->security = sec_status_insecure; 1669 val_mark_insecure(vq->chase_reply, vq->key_entry->name, 1670 qstate->env->rrset_cache, qstate->env); 1671 /* go to finished state to cache this result */ 1672 vq->state = VAL_FINISHED_STATE; 1673 return 1; 1674 } else if(key_entry_isbad(vq->key_entry)) { 1675 sldns_ede_code ede = LDNS_EDE_DNSSEC_BOGUS; 1676 1677 /* the key could have a more spefic EDE than just bogus */ 1678 if(key_entry_get_reason_bogus(vq->key_entry) != LDNS_EDE_NONE) { 1679 ede = key_entry_get_reason_bogus(vq->key_entry); 1680 } 1681 1682 /* key is bad, chain is bad, reply is bogus */ 1683 errinf_dname(qstate, "key for validation", vq->key_entry->name); 1684 errinf_ede(qstate, "is marked as invalid", ede); 1685 if(key_entry_get_reason(vq->key_entry)) { 1686 errinf(qstate, "because of a previous"); 1687 errinf(qstate, key_entry_get_reason(vq->key_entry)); 1688 } 1689 1690 /* no retries, stop bothering the authority until timeout */ 1691 vq->restart_count = ve->max_restart; 1692 vq->chase_reply->security = sec_status_bogus; 1693 update_reason_bogus(vq->chase_reply, ede); 1694 vq->state = VAL_FINISHED_STATE; 1695 return 1; 1696 } 1697 1698 /* otherwise, we have our "closest" cached key -- continue 1699 * processing in the next state. */ 1700 vq->state = VAL_FINDKEY_STATE; 1701 return 1; 1702 } 1703 1704 /** 1705 * Process the FINDKEY state. Generally this just calculates the next name 1706 * to query and either issues a DS or a DNSKEY query. It will check to see 1707 * if the correct key has already been reached, in which case it will 1708 * advance the event to the next state. 1709 * 1710 * @param qstate: query state. 1711 * @param vq: validator query state. 1712 * @param id: module id. 1713 * @return true if the event should be processed further on return, false if 1714 * not. 1715 */ 1716 static int 1717 processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id) 1718 { 1719 uint8_t* target_key_name, *current_key_name; 1720 size_t target_key_len; 1721 int strip_lab; 1722 struct module_qstate* newq = NULL; 1723 1724 log_query_info(VERB_ALGO, "validator: FindKey", &vq->qchase); 1725 /* We know that state.key_entry is not 0 or bad key -- if it were, 1726 * then previous processing should have directed this event to 1727 * a different state. 1728 * It could be an isnull key, which signals the DNSKEY failed 1729 * with retry and has to be looked up again. */ 1730 log_assert(vq->key_entry && !key_entry_isbad(vq->key_entry)); 1731 if(key_entry_isnull(vq->key_entry)) { 1732 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1733 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1734 vq->qchase.qclass, BIT_CD, &newq, 0)) { 1735 verbose(VERB_ALGO, "error generating DNSKEY request"); 1736 return val_error(qstate, id); 1737 } 1738 return 0; 1739 } 1740 1741 target_key_name = vq->signer_name; 1742 target_key_len = vq->signer_len; 1743 if(!target_key_name) { 1744 target_key_name = vq->qchase.qname; 1745 target_key_len = vq->qchase.qname_len; 1746 } 1747 1748 current_key_name = vq->key_entry->name; 1749 1750 /* If our current key entry matches our target, then we are done. */ 1751 if(query_dname_compare(target_key_name, current_key_name) == 0) { 1752 vq->state = VAL_VALIDATE_STATE; 1753 return 1; 1754 } 1755 1756 if(vq->empty_DS_name) { 1757 /* if the last empty nonterminal/emptyDS name we detected is 1758 * below the current key, use that name to make progress 1759 * along the chain of trust */ 1760 if(query_dname_compare(target_key_name, 1761 vq->empty_DS_name) == 0) { 1762 /* do not query for empty_DS_name again */ 1763 verbose(VERB_ALGO, "Cannot retrieve DS for signature"); 1764 errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING); 1765 errinf_origin(qstate, qstate->reply_origin); 1766 vq->chase_reply->security = sec_status_bogus; 1767 update_reason_bogus(vq->chase_reply, LDNS_EDE_RRSIGS_MISSING); 1768 vq->state = VAL_FINISHED_STATE; 1769 return 1; 1770 } 1771 current_key_name = vq->empty_DS_name; 1772 } 1773 1774 log_nametypeclass(VERB_ALGO, "current keyname", current_key_name, 1775 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1776 log_nametypeclass(VERB_ALGO, "target keyname", target_key_name, 1777 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1778 /* assert we are walking down the DNS tree */ 1779 if(!dname_subdomain_c(target_key_name, current_key_name)) { 1780 verbose(VERB_ALGO, "bad signer name"); 1781 vq->chase_reply->security = sec_status_bogus; 1782 vq->state = VAL_FINISHED_STATE; 1783 return 1; 1784 } 1785 /* so this value is >= -1 */ 1786 strip_lab = dname_count_labels(target_key_name) - 1787 dname_count_labels(current_key_name) - 1; 1788 log_assert(strip_lab >= -1); 1789 verbose(VERB_ALGO, "striplab %d", strip_lab); 1790 if(strip_lab > 0) { 1791 dname_remove_labels(&target_key_name, &target_key_len, 1792 strip_lab); 1793 } 1794 log_nametypeclass(VERB_ALGO, "next keyname", target_key_name, 1795 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1796 1797 /* The next step is either to query for the next DS, or to query 1798 * for the next DNSKEY. */ 1799 if(vq->ds_rrset) 1800 log_nametypeclass(VERB_ALGO, "DS RRset", vq->ds_rrset->rk.dname, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN); 1801 else verbose(VERB_ALGO, "No DS RRset"); 1802 1803 if(vq->ds_rrset && query_dname_compare(vq->ds_rrset->rk.dname, 1804 vq->key_entry->name) != 0) { 1805 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1806 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1807 vq->qchase.qclass, BIT_CD, &newq, 0)) { 1808 verbose(VERB_ALGO, "error generating DNSKEY request"); 1809 return val_error(qstate, id); 1810 } 1811 return 0; 1812 } 1813 1814 if(!vq->ds_rrset || query_dname_compare(vq->ds_rrset->rk.dname, 1815 target_key_name) != 0) { 1816 /* check if there is a cache entry : pick up an NSEC if 1817 * there is no DS, check if that NSEC has DS-bit unset, and 1818 * thus can disprove the secure delegation we seek. 1819 * We can then use that NSEC even in the absence of a SOA 1820 * record that would be required by the iterator to supply 1821 * a completely protocol-correct response. 1822 * Uses negative cache for NSEC3 lookup of DS responses. */ 1823 /* only if cache not blacklisted, of course */ 1824 struct dns_msg* msg; 1825 if(!qstate->blacklist && !vq->chain_blacklist && 1826 (msg=val_find_DS(qstate->env, target_key_name, 1827 target_key_len, vq->qchase.qclass, qstate->region, 1828 vq->key_entry->name)) ) { 1829 verbose(VERB_ALGO, "Process cached DS response"); 1830 process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR, 1831 msg, &msg->qinfo, NULL); 1832 return 1; /* continue processing ds-response results */ 1833 } 1834 if(!generate_request(qstate, id, target_key_name, 1835 target_key_len, LDNS_RR_TYPE_DS, vq->qchase.qclass, 1836 BIT_CD, &newq, 0)) { 1837 verbose(VERB_ALGO, "error generating DS request"); 1838 return val_error(qstate, id); 1839 } 1840 return 0; 1841 } 1842 1843 /* Otherwise, it is time to query for the DNSKEY */ 1844 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1845 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1846 vq->qchase.qclass, BIT_CD, &newq, 0)) { 1847 verbose(VERB_ALGO, "error generating DNSKEY request"); 1848 return val_error(qstate, id); 1849 } 1850 1851 return 0; 1852 } 1853 1854 /** 1855 * Process the VALIDATE stage, the init and findkey stages are finished, 1856 * and the right keys are available to validate the response. 1857 * Or, there are no keys available, in order to invalidate the response. 1858 * 1859 * After validation, the status is recorded in the message and rrsets, 1860 * and finished state is started. 1861 * 1862 * @param qstate: query state. 1863 * @param vq: validator query state. 1864 * @param ve: validator shared global environment. 1865 * @param id: module id. 1866 * @return true if the event should be processed further on return, false if 1867 * not. 1868 */ 1869 static int 1870 processValidate(struct module_qstate* qstate, struct val_qstate* vq, 1871 struct val_env* ve, int id) 1872 { 1873 enum val_classification subtype; 1874 int rcode; 1875 1876 if(!vq->key_entry) { 1877 verbose(VERB_ALGO, "validate: no key entry, failed"); 1878 return val_error(qstate, id); 1879 } 1880 1881 /* This is the default next state. */ 1882 vq->state = VAL_FINISHED_STATE; 1883 1884 /* Unsigned responses must be underneath a "null" key entry.*/ 1885 if(key_entry_isnull(vq->key_entry)) { 1886 verbose(VERB_DETAIL, "Verified that %sresponse is INSECURE", 1887 vq->signer_name?"":"unsigned "); 1888 vq->chase_reply->security = sec_status_insecure; 1889 val_mark_insecure(vq->chase_reply, vq->key_entry->name, 1890 qstate->env->rrset_cache, qstate->env); 1891 key_cache_insert(ve->kcache, vq->key_entry, qstate); 1892 return 1; 1893 } 1894 1895 if(key_entry_isbad(vq->key_entry)) { 1896 log_nametypeclass(VERB_DETAIL, "Could not establish a chain " 1897 "of trust to keys for", vq->key_entry->name, 1898 LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class); 1899 vq->chase_reply->security = sec_status_bogus; 1900 1901 update_reason_bogus(vq->chase_reply, LDNS_EDE_DNSKEY_MISSING); 1902 errinf_ede(qstate, "while building chain of trust", 1903 LDNS_EDE_DNSKEY_MISSING); 1904 if(vq->restart_count >= ve->max_restart) 1905 key_cache_insert(ve->kcache, vq->key_entry, qstate); 1906 return 1; 1907 } 1908 1909 /* signerName being null is the indicator that this response was 1910 * unsigned */ 1911 if(vq->signer_name == NULL) { 1912 log_query_info(VERB_ALGO, "processValidate: state has no " 1913 "signer name", &vq->qchase); 1914 verbose(VERB_DETAIL, "Could not establish validation of " 1915 "INSECURE status of unsigned response."); 1916 errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING); 1917 errinf_origin(qstate, qstate->reply_origin); 1918 vq->chase_reply->security = sec_status_bogus; 1919 update_reason_bogus(vq->chase_reply, LDNS_EDE_RRSIGS_MISSING); 1920 return 1; 1921 } 1922 subtype = val_classify_response(qstate->query_flags, &qstate->qinfo, 1923 &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); 1924 if(subtype != VAL_CLASS_REFERRAL) 1925 remove_spurious_authority(vq->chase_reply, vq->orig_msg->rep); 1926 1927 /* check signatures in the message; 1928 * answer and authority must be valid, additional is only checked. */ 1929 if(!validate_msg_signatures(qstate, qstate->env, ve, &vq->qchase, 1930 vq->chase_reply, vq->key_entry)) { 1931 /* workaround bad recursor out there that truncates (even 1932 * with EDNS4k) to 512 by removing RRSIG from auth section 1933 * for positive replies*/ 1934 if((subtype == VAL_CLASS_POSITIVE || subtype == VAL_CLASS_ANY 1935 || subtype == VAL_CLASS_CNAME) && 1936 detect_wrongly_truncated(vq->orig_msg->rep)) { 1937 /* truncate the message some more */ 1938 vq->orig_msg->rep->ns_numrrsets = 0; 1939 vq->orig_msg->rep->ar_numrrsets = 0; 1940 vq->orig_msg->rep->rrset_count = 1941 vq->orig_msg->rep->an_numrrsets; 1942 vq->chase_reply->ns_numrrsets = 0; 1943 vq->chase_reply->ar_numrrsets = 0; 1944 vq->chase_reply->rrset_count = 1945 vq->chase_reply->an_numrrsets; 1946 qstate->errinf = NULL; 1947 } 1948 else { 1949 verbose(VERB_DETAIL, "Validate: message contains " 1950 "bad rrsets"); 1951 return 1; 1952 } 1953 } 1954 1955 switch(subtype) { 1956 case VAL_CLASS_POSITIVE: 1957 verbose(VERB_ALGO, "Validating a positive response"); 1958 validate_positive_response(qstate->env, ve, 1959 &vq->qchase, vq->chase_reply, vq->key_entry); 1960 verbose(VERB_DETAIL, "validate(positive): %s", 1961 sec_status_to_string( 1962 vq->chase_reply->security)); 1963 break; 1964 1965 case VAL_CLASS_NODATA: 1966 verbose(VERB_ALGO, "Validating a nodata response"); 1967 validate_nodata_response(qstate->env, ve, 1968 &vq->qchase, vq->chase_reply, vq->key_entry); 1969 verbose(VERB_DETAIL, "validate(nodata): %s", 1970 sec_status_to_string( 1971 vq->chase_reply->security)); 1972 break; 1973 1974 case VAL_CLASS_NAMEERROR: 1975 rcode = (int)FLAGS_GET_RCODE(vq->orig_msg->rep->flags); 1976 verbose(VERB_ALGO, "Validating a nxdomain response"); 1977 validate_nameerror_response(qstate->env, ve, 1978 &vq->qchase, vq->chase_reply, vq->key_entry, &rcode); 1979 verbose(VERB_DETAIL, "validate(nxdomain): %s", 1980 sec_status_to_string( 1981 vq->chase_reply->security)); 1982 FLAGS_SET_RCODE(vq->orig_msg->rep->flags, rcode); 1983 FLAGS_SET_RCODE(vq->chase_reply->flags, rcode); 1984 break; 1985 1986 case VAL_CLASS_CNAME: 1987 verbose(VERB_ALGO, "Validating a cname response"); 1988 validate_cname_response(qstate->env, ve, 1989 &vq->qchase, vq->chase_reply, vq->key_entry); 1990 verbose(VERB_DETAIL, "validate(cname): %s", 1991 sec_status_to_string( 1992 vq->chase_reply->security)); 1993 break; 1994 1995 case VAL_CLASS_CNAMENOANSWER: 1996 verbose(VERB_ALGO, "Validating a cname noanswer " 1997 "response"); 1998 validate_cname_noanswer_response(qstate->env, ve, 1999 &vq->qchase, vq->chase_reply, vq->key_entry); 2000 verbose(VERB_DETAIL, "validate(cname_noanswer): %s", 2001 sec_status_to_string( 2002 vq->chase_reply->security)); 2003 break; 2004 2005 case VAL_CLASS_REFERRAL: 2006 verbose(VERB_ALGO, "Validating a referral response"); 2007 validate_referral_response(vq->chase_reply); 2008 verbose(VERB_DETAIL, "validate(referral): %s", 2009 sec_status_to_string( 2010 vq->chase_reply->security)); 2011 break; 2012 2013 case VAL_CLASS_ANY: 2014 verbose(VERB_ALGO, "Validating a positive ANY " 2015 "response"); 2016 validate_any_response(qstate->env, ve, &vq->qchase, 2017 vq->chase_reply, vq->key_entry); 2018 verbose(VERB_DETAIL, "validate(positive_any): %s", 2019 sec_status_to_string( 2020 vq->chase_reply->security)); 2021 break; 2022 2023 default: 2024 log_err("validate: unhandled response subtype: %d", 2025 subtype); 2026 } 2027 if(vq->chase_reply->security == sec_status_bogus) { 2028 if(subtype == VAL_CLASS_POSITIVE) 2029 errinf(qstate, "wildcard"); 2030 else errinf(qstate, val_classification_to_string(subtype)); 2031 errinf(qstate, "proof failed"); 2032 errinf_origin(qstate, qstate->reply_origin); 2033 } 2034 2035 return 1; 2036 } 2037 2038 /** 2039 * The Finished state. The validation status (good or bad) has been determined. 2040 * 2041 * @param qstate: query state. 2042 * @param vq: validator query state. 2043 * @param ve: validator shared global environment. 2044 * @param id: module id. 2045 * @return true if the event should be processed further on return, false if 2046 * not. 2047 */ 2048 static int 2049 processFinished(struct module_qstate* qstate, struct val_qstate* vq, 2050 struct val_env* ve, int id) 2051 { 2052 enum val_classification subtype = val_classify_response( 2053 qstate->query_flags, &qstate->qinfo, &vq->qchase, 2054 vq->orig_msg->rep, vq->rrset_skip); 2055 2056 /* store overall validation result in orig_msg */ 2057 if(vq->rrset_skip == 0) { 2058 vq->orig_msg->rep->security = vq->chase_reply->security; 2059 update_reason_bogus(vq->orig_msg->rep, vq->chase_reply->reason_bogus); 2060 } else if(subtype != VAL_CLASS_REFERRAL || 2061 vq->rrset_skip < vq->orig_msg->rep->an_numrrsets + 2062 vq->orig_msg->rep->ns_numrrsets) { 2063 /* ignore sec status of additional section if a referral 2064 * type message skips there and 2065 * use the lowest security status as end result. */ 2066 if(vq->chase_reply->security < vq->orig_msg->rep->security) { 2067 vq->orig_msg->rep->security = 2068 vq->chase_reply->security; 2069 update_reason_bogus(vq->orig_msg->rep, vq->chase_reply->reason_bogus); 2070 } 2071 } 2072 2073 if(subtype == VAL_CLASS_REFERRAL) { 2074 /* for a referral, move to next unchecked rrset and check it*/ 2075 vq->rrset_skip = val_next_unchecked(vq->orig_msg->rep, 2076 vq->rrset_skip); 2077 if(vq->rrset_skip < vq->orig_msg->rep->rrset_count) { 2078 /* and restart for this rrset */ 2079 verbose(VERB_ALGO, "validator: go to next rrset"); 2080 vq->chase_reply->security = sec_status_unchecked; 2081 vq->state = VAL_INIT_STATE; 2082 return 1; 2083 } 2084 /* referral chase is done */ 2085 } 2086 if(vq->chase_reply->security != sec_status_bogus && 2087 subtype == VAL_CLASS_CNAME) { 2088 /* chase the CNAME; process next part of the message */ 2089 if(!val_chase_cname(&vq->qchase, vq->orig_msg->rep, 2090 &vq->rrset_skip)) { 2091 verbose(VERB_ALGO, "validator: failed to chase CNAME"); 2092 vq->orig_msg->rep->security = sec_status_bogus; 2093 update_reason_bogus(vq->orig_msg->rep, LDNS_EDE_DNSSEC_BOGUS); 2094 } else { 2095 /* restart process for new qchase at rrset_skip */ 2096 log_query_info(VERB_ALGO, "validator: chased to", 2097 &vq->qchase); 2098 vq->chase_reply->security = sec_status_unchecked; 2099 vq->state = VAL_INIT_STATE; 2100 return 1; 2101 } 2102 } 2103 2104 if(vq->orig_msg->rep->security == sec_status_secure) { 2105 /* If the message is secure, check that all rrsets are 2106 * secure (i.e. some inserted RRset for CNAME chain with 2107 * a different signer name). And drop additional rrsets 2108 * that are not secure (if clean-additional option is set) */ 2109 /* this may cause the msg to be marked bogus */ 2110 val_check_nonsecure(qstate->env, vq->orig_msg->rep); 2111 if(vq->orig_msg->rep->security == sec_status_secure) { 2112 log_query_info(VERB_DETAIL, "validation success", 2113 &qstate->qinfo); 2114 if(!qstate->no_cache_store) { 2115 val_neg_addreply(qstate->env->neg_cache, 2116 vq->orig_msg->rep); 2117 } 2118 } 2119 } 2120 2121 /* if the result is bogus - set message ttl to bogus ttl to avoid 2122 * endless bogus revalidation */ 2123 if(vq->orig_msg->rep->security == sec_status_bogus) { 2124 /* see if we can try again to fetch data */ 2125 if(vq->restart_count < ve->max_restart) { 2126 int restart_count = vq->restart_count+1; 2127 verbose(VERB_ALGO, "validation failed, " 2128 "blacklist and retry to fetch data"); 2129 val_blacklist(&qstate->blacklist, qstate->region, 2130 qstate->reply_origin, 0); 2131 qstate->reply_origin = NULL; 2132 qstate->errinf = NULL; 2133 memset(vq, 0, sizeof(*vq)); 2134 vq->restart_count = restart_count; 2135 vq->state = VAL_INIT_STATE; 2136 verbose(VERB_ALGO, "pass back to next module"); 2137 qstate->ext_state[id] = module_restart_next; 2138 return 0; 2139 } 2140 2141 vq->orig_msg->rep->ttl = ve->bogus_ttl; 2142 vq->orig_msg->rep->prefetch_ttl = 2143 PREFETCH_TTL_CALC(vq->orig_msg->rep->ttl); 2144 vq->orig_msg->rep->serve_expired_ttl = 2145 vq->orig_msg->rep->ttl + qstate->env->cfg->serve_expired_ttl; 2146 if((qstate->env->cfg->val_log_level >= 1 || 2147 qstate->env->cfg->log_servfail) && 2148 !qstate->env->cfg->val_log_squelch) { 2149 if(qstate->env->cfg->val_log_level < 2 && 2150 !qstate->env->cfg->log_servfail) 2151 log_query_info(NO_VERBOSE, "validation failure", 2152 &qstate->qinfo); 2153 else { 2154 char* err = errinf_to_str_bogus(qstate); 2155 if(err) log_info("%s", err); 2156 free(err); 2157 } 2158 } 2159 /* 2160 * If set, the validator will not make messages bogus, instead 2161 * indeterminate is issued, so that no clients receive SERVFAIL. 2162 * This allows an operator to run validation 'shadow' without 2163 * hurting responses to clients. 2164 */ 2165 /* If we are in permissive mode, bogus gets indeterminate */ 2166 if(qstate->env->cfg->val_permissive_mode) 2167 vq->orig_msg->rep->security = sec_status_indeterminate; 2168 } 2169 2170 if(vq->orig_msg->rep->security == sec_status_secure && 2171 qstate->env->cfg->root_key_sentinel && 2172 (qstate->qinfo.qtype == LDNS_RR_TYPE_A || 2173 qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)) { 2174 char* keytag_start; 2175 uint16_t keytag; 2176 if(*qstate->qinfo.qname == strlen(SENTINEL_IS) + 2177 SENTINEL_KEYTAG_LEN && 2178 dname_lab_startswith(qstate->qinfo.qname, SENTINEL_IS, 2179 &keytag_start)) { 2180 if(sentinel_get_keytag(keytag_start, &keytag) && 2181 !anchor_has_keytag(qstate->env->anchors, 2182 (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) { 2183 vq->orig_msg->rep->security = 2184 sec_status_secure_sentinel_fail; 2185 } 2186 } else if(*qstate->qinfo.qname == strlen(SENTINEL_NOT) + 2187 SENTINEL_KEYTAG_LEN && 2188 dname_lab_startswith(qstate->qinfo.qname, SENTINEL_NOT, 2189 &keytag_start)) { 2190 if(sentinel_get_keytag(keytag_start, &keytag) && 2191 anchor_has_keytag(qstate->env->anchors, 2192 (uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) { 2193 vq->orig_msg->rep->security = 2194 sec_status_secure_sentinel_fail; 2195 } 2196 } 2197 } 2198 /* store results in cache */ 2199 if(qstate->query_flags&BIT_RD) { 2200 /* if secure, this will override cache anyway, no need 2201 * to check if from parentNS */ 2202 if(!qstate->no_cache_store) { 2203 if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 2204 vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, 2205 qstate->query_flags)) { 2206 log_err("out of memory caching validator results"); 2207 } 2208 } 2209 } else { 2210 /* for a referral, store the verified RRsets */ 2211 /* and this does not get prefetched, so no leeway */ 2212 if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 2213 vq->orig_msg->rep, 1, 0, 0, NULL, 2214 qstate->query_flags)) { 2215 log_err("out of memory caching validator results"); 2216 } 2217 } 2218 qstate->return_rcode = LDNS_RCODE_NOERROR; 2219 qstate->return_msg = vq->orig_msg; 2220 qstate->ext_state[id] = module_finished; 2221 return 0; 2222 } 2223 2224 /** 2225 * Handle validator state. 2226 * If a method returns true, the next state is started. If false, then 2227 * processing will stop. 2228 * @param qstate: query state. 2229 * @param vq: validator query state. 2230 * @param ve: validator shared global environment. 2231 * @param id: module id. 2232 */ 2233 static void 2234 val_handle(struct module_qstate* qstate, struct val_qstate* vq, 2235 struct val_env* ve, int id) 2236 { 2237 int cont = 1; 2238 while(cont) { 2239 verbose(VERB_ALGO, "val handle processing q with state %s", 2240 val_state_to_string(vq->state)); 2241 switch(vq->state) { 2242 case VAL_INIT_STATE: 2243 cont = processInit(qstate, vq, ve, id); 2244 break; 2245 case VAL_FINDKEY_STATE: 2246 cont = processFindKey(qstate, vq, id); 2247 break; 2248 case VAL_VALIDATE_STATE: 2249 cont = processValidate(qstate, vq, ve, id); 2250 break; 2251 case VAL_FINISHED_STATE: 2252 cont = processFinished(qstate, vq, ve, id); 2253 break; 2254 default: 2255 log_warn("validator: invalid state %d", 2256 vq->state); 2257 cont = 0; 2258 break; 2259 } 2260 } 2261 } 2262 2263 void 2264 val_operate(struct module_qstate* qstate, enum module_ev event, int id, 2265 struct outbound_entry* outbound) 2266 { 2267 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2268 struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id]; 2269 verbose(VERB_QUERY, "validator[module %d] operate: extstate:%s " 2270 "event:%s", id, strextstate(qstate->ext_state[id]), 2271 strmodulevent(event)); 2272 log_query_info(VERB_QUERY, "validator operate: query", 2273 &qstate->qinfo); 2274 if(vq && qstate->qinfo.qname != vq->qchase.qname) 2275 log_query_info(VERB_QUERY, "validator operate: chased to", 2276 &vq->qchase); 2277 (void)outbound; 2278 if(event == module_event_new || 2279 (event == module_event_pass && vq == NULL)) { 2280 2281 /* pass request to next module, to get it */ 2282 verbose(VERB_ALGO, "validator: pass to next module"); 2283 qstate->ext_state[id] = module_wait_module; 2284 return; 2285 } 2286 if(event == module_event_moddone) { 2287 /* check if validation is needed */ 2288 verbose(VERB_ALGO, "validator: nextmodule returned"); 2289 2290 if(!needs_validation(qstate, qstate->return_rcode, 2291 qstate->return_msg)) { 2292 /* no need to validate this */ 2293 if(qstate->return_msg) 2294 qstate->return_msg->rep->security = 2295 sec_status_indeterminate; 2296 qstate->ext_state[id] = module_finished; 2297 return; 2298 } 2299 if(already_validated(qstate->return_msg)) { 2300 qstate->ext_state[id] = module_finished; 2301 return; 2302 } 2303 /* qclass ANY should have validation result from spawned 2304 * queries. If we get here, it is bogus or an internal error */ 2305 if(qstate->qinfo.qclass == LDNS_RR_CLASS_ANY) { 2306 verbose(VERB_ALGO, "cannot validate classANY: bogus"); 2307 if(qstate->return_msg) { 2308 qstate->return_msg->rep->security = 2309 sec_status_bogus; 2310 update_reason_bogus(qstate->return_msg->rep, LDNS_EDE_DNSSEC_BOGUS); 2311 } 2312 qstate->ext_state[id] = module_finished; 2313 return; 2314 } 2315 /* create state to start validation */ 2316 qstate->ext_state[id] = module_error; /* override this */ 2317 if(!vq) { 2318 vq = val_new(qstate, id); 2319 if(!vq) { 2320 log_err("validator: malloc failure"); 2321 qstate->ext_state[id] = module_error; 2322 return; 2323 } 2324 } else if(!vq->orig_msg) { 2325 if(!val_new_getmsg(qstate, vq)) { 2326 log_err("validator: malloc failure"); 2327 qstate->ext_state[id] = module_error; 2328 return; 2329 } 2330 } 2331 val_handle(qstate, vq, ve, id); 2332 return; 2333 } 2334 if(event == module_event_pass) { 2335 qstate->ext_state[id] = module_error; /* override this */ 2336 /* continue processing, since val_env exists */ 2337 val_handle(qstate, vq, ve, id); 2338 return; 2339 } 2340 log_err("validator: bad event %s", strmodulevent(event)); 2341 qstate->ext_state[id] = module_error; 2342 return; 2343 } 2344 2345 /** 2346 * Evaluate the response to a priming request. 2347 * 2348 * @param dnskey_rrset: DNSKEY rrset (can be NULL if none) in prime reply. 2349 * (this rrset is allocated in the wrong region, not the qstate). 2350 * @param ta: trust anchor. 2351 * @param qstate: qstate that needs key. 2352 * @param id: module id. 2353 * @return new key entry or NULL on allocation failure. 2354 * The key entry will either contain a validated DNSKEY rrset, or 2355 * represent a Null key (query failed, but validation did not), or a 2356 * Bad key (validation failed). 2357 */ 2358 static struct key_entry_key* 2359 primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, 2360 struct trust_anchor* ta, struct module_qstate* qstate, int id) 2361 { 2362 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2363 struct key_entry_key* kkey = NULL; 2364 enum sec_status sec = sec_status_unchecked; 2365 char* reason = NULL; 2366 sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS; 2367 int downprot = qstate->env->cfg->harden_algo_downgrade; 2368 2369 if(!dnskey_rrset) { 2370 log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- " 2371 "could not fetch DNSKEY rrset", 2372 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2373 if(qstate->env->cfg->harden_dnssec_stripped) { 2374 errinf_ede(qstate, "no DNSKEY rrset", LDNS_EDE_DNSKEY_MISSING); 2375 kkey = key_entry_create_bad(qstate->region, ta->name, 2376 ta->namelen, ta->dclass, BOGUS_KEY_TTL, 2377 *qstate->env->now); 2378 } else kkey = key_entry_create_null(qstate->region, ta->name, 2379 ta->namelen, ta->dclass, NULL_KEY_TTL, 2380 *qstate->env->now); 2381 if(!kkey) { 2382 log_err("out of memory: allocate fail prime key"); 2383 return NULL; 2384 } 2385 return kkey; 2386 } 2387 /* attempt to verify with trust anchor DS and DNSKEY */ 2388 kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve, 2389 dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot, 2390 &reason, &reason_bogus, qstate); 2391 if(!kkey) { 2392 log_err("out of memory: verifying prime TA"); 2393 return NULL; 2394 } 2395 if(key_entry_isgood(kkey)) 2396 sec = sec_status_secure; 2397 else 2398 sec = sec_status_bogus; 2399 verbose(VERB_DETAIL, "validate keys with anchor(DS): %s", 2400 sec_status_to_string(sec)); 2401 2402 if(sec != sec_status_secure) { 2403 log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- " 2404 "DNSKEY rrset is not secure", 2405 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2406 /* NOTE: in this case, we should probably reject the trust 2407 * anchor for longer, perhaps forever. */ 2408 if(qstate->env->cfg->harden_dnssec_stripped) { 2409 errinf_ede(qstate, reason, reason_bogus); 2410 kkey = key_entry_create_bad(qstate->region, ta->name, 2411 ta->namelen, ta->dclass, BOGUS_KEY_TTL, 2412 *qstate->env->now); 2413 } else kkey = key_entry_create_null(qstate->region, ta->name, 2414 ta->namelen, ta->dclass, NULL_KEY_TTL, 2415 *qstate->env->now); 2416 if(!kkey) { 2417 log_err("out of memory: allocate null prime key"); 2418 return NULL; 2419 } 2420 return kkey; 2421 } 2422 2423 log_nametypeclass(VERB_DETAIL, "Successfully primed trust anchor", 2424 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2425 return kkey; 2426 } 2427 2428 /** 2429 * In inform supers, with the resulting message and rcode and the current 2430 * keyset in the super state, validate the DS response, returning a KeyEntry. 2431 * 2432 * @param qstate: query state that is validating and asked for a DS. 2433 * @param vq: validator query state 2434 * @param id: module id. 2435 * @param rcode: rcode result value. 2436 * @param msg: result message (if rcode is OK). 2437 * @param qinfo: from the sub query state, query info. 2438 * @param ke: the key entry to return. It returns 2439 * is_bad if the DS response fails to validate, is_null if the 2440 * DS response indicated an end to secure space, is_good if the DS 2441 * validated. It returns ke=NULL if the DS response indicated that the 2442 * request wasn't a delegation point. 2443 * @return 0 on servfail error (malloc failure). 2444 */ 2445 static int 2446 ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, 2447 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2448 struct key_entry_key** ke) 2449 { 2450 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2451 char* reason = NULL; 2452 sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS; 2453 enum val_classification subtype; 2454 if(rcode != LDNS_RCODE_NOERROR) { 2455 char rc[16]; 2456 rc[0]=0; 2457 (void)sldns_wire2str_rcode_buf(rcode, rc, sizeof(rc)); 2458 /* errors here pretty much break validation */ 2459 verbose(VERB_DETAIL, "DS response was error, thus bogus"); 2460 errinf(qstate, rc); 2461 errinf_ede(qstate, "no DS", LDNS_EDE_NETWORK_ERROR); 2462 2463 goto return_bogus; 2464 } 2465 2466 subtype = val_classify_response(BIT_RD, qinfo, qinfo, msg->rep, 0); 2467 if(subtype == VAL_CLASS_POSITIVE) { 2468 struct ub_packed_rrset_key* ds; 2469 enum sec_status sec; 2470 ds = reply_find_answer_rrset(qinfo, msg->rep); 2471 /* If there was no DS rrset, then we have mis-classified 2472 * this message. */ 2473 if(!ds) { 2474 log_warn("internal error: POSITIVE DS response was " 2475 "missing DS."); 2476 errinf_ede(qstate, "no DS record", LDNS_EDE_DNSSEC_BOGUS); 2477 goto return_bogus; 2478 } 2479 /* Verify only returns BOGUS or SECURE. If the rrset is 2480 * bogus, then we are done. */ 2481 sec = val_verify_rrset_entry(qstate->env, ve, ds, 2482 vq->key_entry, &reason, &reason_bogus, LDNS_SECTION_ANSWER, qstate); 2483 if(sec != sec_status_secure) { 2484 verbose(VERB_DETAIL, "DS rrset in DS response did " 2485 "not verify"); 2486 errinf_ede(qstate, reason, reason_bogus); 2487 goto return_bogus; 2488 } 2489 2490 /* If the DS rrset validates, we still have to make sure 2491 * that they are usable. */ 2492 if(!val_dsset_isusable(ds)) { 2493 /* If they aren't usable, then we treat it like 2494 * there was no DS. */ 2495 2496 // @TODO add EDE Unsupported DS Digest Type 2497 2498 *ke = key_entry_create_null(qstate->region, 2499 qinfo->qname, qinfo->qname_len, qinfo->qclass, 2500 ub_packed_rrset_ttl(ds), *qstate->env->now); 2501 return (*ke) != NULL; 2502 } 2503 2504 /* Otherwise, we return the positive response. */ 2505 log_query_info(VERB_DETAIL, "validated DS", qinfo); 2506 *ke = key_entry_create_rrset(qstate->region, 2507 qinfo->qname, qinfo->qname_len, qinfo->qclass, ds, 2508 NULL, *qstate->env->now); 2509 return (*ke) != NULL; 2510 } else if(subtype == VAL_CLASS_NODATA || 2511 subtype == VAL_CLASS_NAMEERROR) { 2512 /* NODATA means that the qname exists, but that there was 2513 * no DS. This is a pretty normal case. */ 2514 time_t proof_ttl = 0; 2515 enum sec_status sec; 2516 2517 /* make sure there are NSECs or NSEC3s with signatures */ 2518 if(!val_has_signed_nsecs(msg->rep, &reason)) { 2519 verbose(VERB_ALGO, "no NSECs: %s", reason); 2520 errinf_ede(qstate, reason, LDNS_EDE_NSEC_MISSING); 2521 goto return_bogus; 2522 } 2523 2524 /* For subtype Name Error. 2525 * attempt ANS 2.8.1.0 compatibility where it sets rcode 2526 * to nxdomain, but really this is an Nodata/Noerror response. 2527 * Find and prove the empty nonterminal in that case */ 2528 2529 /* Try to prove absence of the DS with NSEC */ 2530 sec = val_nsec_prove_nodata_dsreply( 2531 qstate->env, ve, qinfo, msg->rep, vq->key_entry, 2532 &proof_ttl, &reason, qstate); 2533 switch(sec) { 2534 case sec_status_secure: 2535 verbose(VERB_DETAIL, "NSEC RRset for the " 2536 "referral proved no DS."); 2537 *ke = key_entry_create_null(qstate->region, 2538 qinfo->qname, qinfo->qname_len, 2539 qinfo->qclass, proof_ttl, 2540 *qstate->env->now); 2541 return (*ke) != NULL; 2542 case sec_status_insecure: 2543 verbose(VERB_DETAIL, "NSEC RRset for the " 2544 "referral proved not a delegation point"); 2545 *ke = NULL; 2546 return 1; 2547 case sec_status_bogus: 2548 verbose(VERB_DETAIL, "NSEC RRset for the " 2549 "referral did not prove no DS."); 2550 errinf(qstate, reason); 2551 goto return_bogus; 2552 case sec_status_unchecked: 2553 default: 2554 /* NSEC proof did not work, try next */ 2555 break; 2556 } 2557 2558 sec = nsec3_prove_nods(qstate->env, ve, 2559 msg->rep->rrsets + msg->rep->an_numrrsets, 2560 msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason, 2561 &reason_bogus, qstate); 2562 switch(sec) { 2563 case sec_status_insecure: 2564 /* case insecure also continues to unsigned 2565 * space. If nsec3-iter-count too high or 2566 * optout, then treat below as unsigned */ 2567 case sec_status_secure: 2568 verbose(VERB_DETAIL, "NSEC3s for the " 2569 "referral proved no DS."); 2570 *ke = key_entry_create_null(qstate->region, 2571 qinfo->qname, qinfo->qname_len, 2572 qinfo->qclass, proof_ttl, 2573 *qstate->env->now); 2574 return (*ke) != NULL; 2575 case sec_status_indeterminate: 2576 verbose(VERB_DETAIL, "NSEC3s for the " 2577 "referral proved no delegation"); 2578 *ke = NULL; 2579 return 1; 2580 case sec_status_bogus: 2581 verbose(VERB_DETAIL, "NSEC3s for the " 2582 "referral did not prove no DS."); 2583 errinf_ede(qstate, reason, reason_bogus); 2584 goto return_bogus; 2585 case sec_status_unchecked: 2586 default: 2587 /* NSEC3 proof did not work */ 2588 break; 2589 } 2590 2591 /* Apparently, no available NSEC/NSEC3 proved NODATA, so 2592 * this is BOGUS. */ 2593 verbose(VERB_DETAIL, "DS %s ran out of options, so return " 2594 "bogus", val_classification_to_string(subtype)); 2595 errinf(qstate, "no DS but also no proof of that"); 2596 goto return_bogus; 2597 } else if(subtype == VAL_CLASS_CNAME || 2598 subtype == VAL_CLASS_CNAMENOANSWER) { 2599 /* if the CNAME matches the exact name we want and is signed 2600 * properly, then also, we are sure that no DS exists there, 2601 * much like a NODATA proof */ 2602 enum sec_status sec; 2603 struct ub_packed_rrset_key* cname; 2604 cname = reply_find_rrset_section_an(msg->rep, qinfo->qname, 2605 qinfo->qname_len, LDNS_RR_TYPE_CNAME, qinfo->qclass); 2606 if(!cname) { 2607 errinf(qstate, "validator classified CNAME but no " 2608 "CNAME of the queried name for DS"); 2609 goto return_bogus; 2610 } 2611 if(((struct packed_rrset_data*)cname->entry.data)->rrsig_count 2612 == 0) { 2613 if(msg->rep->an_numrrsets != 0 && ntohs(msg->rep-> 2614 rrsets[0]->rk.type)==LDNS_RR_TYPE_DNAME) { 2615 errinf(qstate, "DS got DNAME answer"); 2616 } else { 2617 errinf(qstate, "DS got unsigned CNAME answer"); 2618 } 2619 goto return_bogus; 2620 } 2621 sec = val_verify_rrset_entry(qstate->env, ve, cname, 2622 vq->key_entry, &reason, NULL, LDNS_SECTION_ANSWER, qstate); 2623 if(sec == sec_status_secure) { 2624 verbose(VERB_ALGO, "CNAME validated, " 2625 "proof that DS does not exist"); 2626 /* and that it is not a referral point */ 2627 *ke = NULL; 2628 return 1; 2629 } 2630 errinf(qstate, "CNAME in DS response was not secure."); 2631 errinf(qstate, reason); 2632 goto return_bogus; 2633 } else { 2634 verbose(VERB_QUERY, "Encountered an unhandled type of " 2635 "DS response, thus bogus."); 2636 errinf(qstate, "no DS and"); 2637 if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) { 2638 char rc[16]; 2639 rc[0]=0; 2640 (void)sldns_wire2str_rcode_buf((int)FLAGS_GET_RCODE( 2641 msg->rep->flags), rc, sizeof(rc)); 2642 errinf(qstate, rc); 2643 } else errinf(qstate, val_classification_to_string(subtype)); 2644 errinf(qstate, "message fails to prove that"); 2645 goto return_bogus; 2646 } 2647 return_bogus: 2648 *ke = key_entry_create_bad(qstate->region, qinfo->qname, 2649 qinfo->qname_len, qinfo->qclass, 2650 BOGUS_KEY_TTL, *qstate->env->now); 2651 return (*ke) != NULL; 2652 } 2653 2654 /** 2655 * Process DS response. Called from inform_supers. 2656 * Because it is in inform_supers, the mesh itself is busy doing callbacks 2657 * for a state that is to be deleted soon; don't touch the mesh; instead 2658 * set a state in the super, as the super will be reactivated soon. 2659 * Perform processing to determine what state to set in the super. 2660 * 2661 * @param qstate: query state that is validating and asked for a DS. 2662 * @param vq: validator query state 2663 * @param id: module id. 2664 * @param rcode: rcode result value. 2665 * @param msg: result message (if rcode is OK). 2666 * @param qinfo: from the sub query state, query info. 2667 * @param origin: the origin of msg. 2668 */ 2669 static void 2670 process_ds_response(struct module_qstate* qstate, struct val_qstate* vq, 2671 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2672 struct sock_list* origin) 2673 { 2674 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2675 struct key_entry_key* dske = NULL; 2676 uint8_t* olds = vq->empty_DS_name; 2677 vq->empty_DS_name = NULL; 2678 if(!ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske)) { 2679 log_err("malloc failure in process_ds_response"); 2680 vq->key_entry = NULL; /* make it error */ 2681 vq->state = VAL_VALIDATE_STATE; 2682 return; 2683 } 2684 if(dske == NULL) { 2685 vq->empty_DS_name = regional_alloc_init(qstate->region, 2686 qinfo->qname, qinfo->qname_len); 2687 if(!vq->empty_DS_name) { 2688 log_err("malloc failure in empty_DS_name"); 2689 vq->key_entry = NULL; /* make it error */ 2690 vq->state = VAL_VALIDATE_STATE; 2691 return; 2692 } 2693 vq->empty_DS_len = qinfo->qname_len; 2694 vq->chain_blacklist = NULL; 2695 /* ds response indicated that we aren't on a delegation point. 2696 * Keep the forState.state on FINDKEY. */ 2697 } else if(key_entry_isgood(dske)) { 2698 vq->ds_rrset = key_entry_get_rrset(dske, qstate->region); 2699 if(!vq->ds_rrset) { 2700 log_err("malloc failure in process DS"); 2701 vq->key_entry = NULL; /* make it error */ 2702 vq->state = VAL_VALIDATE_STATE; 2703 return; 2704 } 2705 vq->chain_blacklist = NULL; /* fresh blacklist for next part*/ 2706 /* Keep the forState.state on FINDKEY. */ 2707 } else if(key_entry_isbad(dske) 2708 && vq->restart_count < ve->max_restart) { 2709 vq->empty_DS_name = olds; 2710 val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); 2711 qstate->errinf = NULL; 2712 vq->restart_count++; 2713 } else { 2714 if(key_entry_isbad(dske)) { 2715 errinf_origin(qstate, origin); 2716 errinf_dname(qstate, "for DS", qinfo->qname); 2717 } 2718 /* NOTE: the reason for the DS to be not good (that is, 2719 * either bad or null) should have been logged by 2720 * dsResponseToKE. */ 2721 vq->key_entry = dske; 2722 /* The FINDKEY phase has ended, so move on. */ 2723 vq->state = VAL_VALIDATE_STATE; 2724 } 2725 } 2726 2727 /** 2728 * Process DNSKEY response. Called from inform_supers. 2729 * Sets the key entry in the state. 2730 * Because it is in inform_supers, the mesh itself is busy doing callbacks 2731 * for a state that is to be deleted soon; don't touch the mesh; instead 2732 * set a state in the super, as the super will be reactivated soon. 2733 * Perform processing to determine what state to set in the super. 2734 * 2735 * @param qstate: query state that is validating and asked for a DNSKEY. 2736 * @param vq: validator query state 2737 * @param id: module id. 2738 * @param rcode: rcode result value. 2739 * @param msg: result message (if rcode is OK). 2740 * @param qinfo: from the sub query state, query info. 2741 * @param origin: the origin of msg. 2742 */ 2743 static void 2744 process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, 2745 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2746 struct sock_list* origin) 2747 { 2748 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2749 struct key_entry_key* old = vq->key_entry; 2750 struct ub_packed_rrset_key* dnskey = NULL; 2751 int downprot; 2752 char* reason = NULL; 2753 sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS; 2754 2755 if(rcode == LDNS_RCODE_NOERROR) 2756 dnskey = reply_find_answer_rrset(qinfo, msg->rep); 2757 2758 if(dnskey == NULL) { 2759 /* bad response */ 2760 verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to " 2761 "DNSKEY query."); 2762 2763 if(vq->restart_count < ve->max_restart) { 2764 val_blacklist(&vq->chain_blacklist, qstate->region, 2765 origin, 1); 2766 qstate->errinf = NULL; 2767 vq->restart_count++; 2768 return; 2769 } 2770 vq->key_entry = key_entry_create_bad(qstate->region, 2771 qinfo->qname, qinfo->qname_len, qinfo->qclass, 2772 BOGUS_KEY_TTL, *qstate->env->now); 2773 if(!vq->key_entry) { 2774 log_err("alloc failure in missing dnskey response"); 2775 /* key_entry is NULL for failure in Validate */ 2776 } 2777 errinf_ede(qstate, "No DNSKEY record", LDNS_EDE_DNSKEY_MISSING); 2778 errinf_origin(qstate, origin); 2779 errinf_dname(qstate, "for key", qinfo->qname); 2780 vq->state = VAL_VALIDATE_STATE; 2781 return; 2782 } 2783 if(!vq->ds_rrset) { 2784 log_err("internal error: no DS rrset for new DNSKEY response"); 2785 vq->key_entry = NULL; 2786 vq->state = VAL_VALIDATE_STATE; 2787 return; 2788 } 2789 downprot = qstate->env->cfg->harden_algo_downgrade; 2790 vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env, 2791 ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, qstate); 2792 2793 if(!vq->key_entry) { 2794 log_err("out of memory in verify new DNSKEYs"); 2795 vq->state = VAL_VALIDATE_STATE; 2796 return; 2797 } 2798 /* If the key entry isBad or isNull, then we can move on to the next 2799 * state. */ 2800 if(!key_entry_isgood(vq->key_entry)) { 2801 if(key_entry_isbad(vq->key_entry)) { 2802 if(vq->restart_count < ve->max_restart) { 2803 val_blacklist(&vq->chain_blacklist, 2804 qstate->region, origin, 1); 2805 qstate->errinf = NULL; 2806 vq->restart_count++; 2807 vq->key_entry = old; 2808 return; 2809 } 2810 verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, " 2811 "thus bogus."); 2812 errinf_ede(qstate, reason, reason_bogus); 2813 errinf_origin(qstate, origin); 2814 errinf_dname(qstate, "for key", qinfo->qname); 2815 } 2816 vq->chain_blacklist = NULL; 2817 vq->state = VAL_VALIDATE_STATE; 2818 return; 2819 } 2820 vq->chain_blacklist = NULL; 2821 qstate->errinf = NULL; 2822 2823 /* The DNSKEY validated, so cache it as a trusted key rrset. */ 2824 key_cache_insert(ve->kcache, vq->key_entry, qstate); 2825 2826 /* If good, we stay in the FINDKEY state. */ 2827 log_query_info(VERB_DETAIL, "validated DNSKEY", qinfo); 2828 } 2829 2830 /** 2831 * Process prime response 2832 * Sets the key entry in the state. 2833 * 2834 * @param qstate: query state that is validating and primed a trust anchor. 2835 * @param vq: validator query state 2836 * @param id: module id. 2837 * @param rcode: rcode result value. 2838 * @param msg: result message (if rcode is OK). 2839 * @param origin: the origin of msg. 2840 */ 2841 static void 2842 process_prime_response(struct module_qstate* qstate, struct val_qstate* vq, 2843 int id, int rcode, struct dns_msg* msg, struct sock_list* origin) 2844 { 2845 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2846 struct ub_packed_rrset_key* dnskey_rrset = NULL; 2847 struct trust_anchor* ta = anchor_find(qstate->env->anchors, 2848 vq->trust_anchor_name, vq->trust_anchor_labs, 2849 vq->trust_anchor_len, vq->qchase.qclass); 2850 if(!ta) { 2851 /* trust anchor revoked, restart with less anchors */ 2852 vq->state = VAL_INIT_STATE; 2853 if(!vq->trust_anchor_name) 2854 vq->state = VAL_VALIDATE_STATE; /* break a loop */ 2855 vq->trust_anchor_name = NULL; 2856 return; 2857 } 2858 /* Fetch and validate the keyEntry that corresponds to the 2859 * current trust anchor. */ 2860 if(rcode == LDNS_RCODE_NOERROR) { 2861 dnskey_rrset = reply_find_rrset_section_an(msg->rep, 2862 ta->name, ta->namelen, LDNS_RR_TYPE_DNSKEY, 2863 ta->dclass); 2864 } 2865 2866 if(ta->autr) { 2867 if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset, 2868 qstate)) { 2869 /* trust anchor revoked, restart with less anchors */ 2870 vq->state = VAL_INIT_STATE; 2871 vq->trust_anchor_name = NULL; 2872 return; 2873 } 2874 } 2875 vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id); 2876 lock_basic_unlock(&ta->lock); 2877 if(vq->key_entry) { 2878 if(key_entry_isbad(vq->key_entry) 2879 && vq->restart_count < ve->max_restart) { 2880 val_blacklist(&vq->chain_blacklist, qstate->region, 2881 origin, 1); 2882 qstate->errinf = NULL; 2883 vq->restart_count++; 2884 vq->key_entry = NULL; 2885 vq->state = VAL_INIT_STATE; 2886 return; 2887 } 2888 vq->chain_blacklist = NULL; 2889 errinf_origin(qstate, origin); 2890 errinf_dname(qstate, "for trust anchor", ta->name); 2891 /* store the freshly primed entry in the cache */ 2892 key_cache_insert(ve->kcache, vq->key_entry, qstate); 2893 } 2894 2895 /* If the result of the prime is a null key, skip the FINDKEY state.*/ 2896 if(!vq->key_entry || key_entry_isnull(vq->key_entry) || 2897 key_entry_isbad(vq->key_entry)) { 2898 vq->state = VAL_VALIDATE_STATE; 2899 } 2900 /* the qstate will be reactivated after inform_super is done */ 2901 } 2902 2903 /* 2904 * inform validator super. 2905 * 2906 * @param qstate: query state that finished. 2907 * @param id: module id. 2908 * @param super: the qstate to inform. 2909 */ 2910 void 2911 val_inform_super(struct module_qstate* qstate, int id, 2912 struct module_qstate* super) 2913 { 2914 struct val_qstate* vq = (struct val_qstate*)super->minfo[id]; 2915 log_query_info(VERB_ALGO, "validator: inform_super, sub is", 2916 &qstate->qinfo); 2917 log_query_info(VERB_ALGO, "super is", &super->qinfo); 2918 if(!vq) { 2919 verbose(VERB_ALGO, "super: has no validator state"); 2920 return; 2921 } 2922 if(vq->wait_prime_ta) { 2923 vq->wait_prime_ta = 0; 2924 process_prime_response(super, vq, id, qstate->return_rcode, 2925 qstate->return_msg, qstate->reply_origin); 2926 return; 2927 } 2928 if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) { 2929 process_ds_response(super, vq, id, qstate->return_rcode, 2930 qstate->return_msg, &qstate->qinfo, 2931 qstate->reply_origin); 2932 return; 2933 } else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) { 2934 process_dnskey_response(super, vq, id, qstate->return_rcode, 2935 qstate->return_msg, &qstate->qinfo, 2936 qstate->reply_origin); 2937 return; 2938 } 2939 log_err("internal error in validator: no inform_supers possible"); 2940 } 2941 2942 void 2943 val_clear(struct module_qstate* qstate, int id) 2944 { 2945 if(!qstate) 2946 return; 2947 /* everything is allocated in the region, so assign NULL */ 2948 qstate->minfo[id] = NULL; 2949 } 2950 2951 size_t 2952 val_get_mem(struct module_env* env, int id) 2953 { 2954 struct val_env* ve = (struct val_env*)env->modinfo[id]; 2955 if(!ve) 2956 return 0; 2957 return sizeof(*ve) + key_cache_get_mem(ve->kcache) + 2958 val_neg_get_mem(ve->neg_cache) + 2959 sizeof(size_t)*2*ve->nsec3_keyiter_count; 2960 } 2961 2962 /** 2963 * The validator function block 2964 */ 2965 static struct module_func_block val_block = { 2966 "validator", 2967 &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear, 2968 &val_get_mem 2969 }; 2970 2971 struct module_func_block* 2972 val_get_funcblock(void) 2973 { 2974 return &val_block; 2975 } 2976 2977 const char* 2978 val_state_to_string(enum val_state state) 2979 { 2980 switch(state) { 2981 case VAL_INIT_STATE: return "VAL_INIT_STATE"; 2982 case VAL_FINDKEY_STATE: return "VAL_FINDKEY_STATE"; 2983 case VAL_VALIDATE_STATE: return "VAL_VALIDATE_STATE"; 2984 case VAL_FINISHED_STATE: return "VAL_FINISHED_STATE"; 2985 } 2986 return "UNKNOWN VALIDATOR STATE"; 2987 } 2988 2989