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