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