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 /* If we have found a CNAME, stop looking for one. 1028 * The iterator has placed the CNAME chain in correct 1029 * order. */ 1030 if (ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME) { 1031 break; 1032 } 1033 } 1034 1035 /* AUTHORITY section */ 1036 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 1037 chase_reply->ns_numrrsets; i++) { 1038 s = chase_reply->rrsets[i]; 1039 1040 /* If this is a positive wildcard response, and we have a 1041 * (just verified) NSEC record, try to use it to 1) prove 1042 * that qname doesn't exist and 2) that the correct wildcard 1043 * was used. */ 1044 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1045 if(val_nsec_proves_positive_wildcard(s, qchase, wc)) { 1046 wc_NSEC_ok = 1; 1047 } 1048 /* if not, continue looking for proof */ 1049 } 1050 1051 /* Otherwise, if this is a positive wildcard response and 1052 * we have NSEC3 records */ 1053 if(wc != NULL && ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 1054 nsec3s_seen = 1; 1055 } 1056 } 1057 1058 /* If this was a positive wildcard response that we haven't already 1059 * proven, and we have NSEC3 records, try to prove it using the NSEC3 1060 * records. */ 1061 if(wc != NULL && !wc_NSEC_ok && nsec3s_seen) { 1062 enum sec_status sec = nsec3_prove_wildcard(env, ve, 1063 chase_reply->rrsets+chase_reply->an_numrrsets, 1064 chase_reply->ns_numrrsets, qchase, kkey, wc); 1065 if(sec == sec_status_insecure) { 1066 verbose(VERB_ALGO, "wildcard CNAME response is " 1067 "insecure"); 1068 chase_reply->security = sec_status_insecure; 1069 return; 1070 } else if(sec == sec_status_secure) 1071 wc_NSEC_ok = 1; 1072 } 1073 1074 /* If after all this, we still haven't proven the positive wildcard 1075 * response, fail. */ 1076 if(wc != NULL && !wc_NSEC_ok) { 1077 verbose(VERB_QUERY, "CNAME response was wildcard " 1078 "expansion and did not prove original data " 1079 "did not exist"); 1080 chase_reply->security = sec_status_bogus; 1081 return; 1082 } 1083 1084 verbose(VERB_ALGO, "Successfully validated CNAME response"); 1085 chase_reply->security = sec_status_secure; 1086 } 1087 1088 /** 1089 * Validate CNAME NOANSWER response, no more data after a CNAME chain. 1090 * This can be a NODATA or a NAME ERROR case, but not both at the same time. 1091 * We don't know because the rcode has been set to NOERROR by the CNAME. 1092 * 1093 * The answer and authority rrsets must already be verified as secure. 1094 * 1095 * @param env: module env for verify. 1096 * @param ve: validator env for verify. 1097 * @param qchase: query that was made. 1098 * @param chase_reply: answer to that query to validate. 1099 * @param kkey: the key entry, which is trusted, and which matches 1100 * the signer of the answer. The key entry isgood(). 1101 */ 1102 static void 1103 validate_cname_noanswer_response(struct module_env* env, struct val_env* ve, 1104 struct query_info* qchase, struct reply_info* chase_reply, 1105 struct key_entry_key* kkey) 1106 { 1107 int nodata_valid_nsec = 0; /* If true, then NODATA has been proven.*/ 1108 uint8_t* ce = NULL; /* for wildcard nodata responses. This is the 1109 proven closest encloser. */ 1110 uint8_t* wc = NULL; /* for wildcard nodata responses. wildcard nsec */ 1111 int nxdomain_valid_nsec = 0; /* if true, namerror has been proven */ 1112 int nxdomain_valid_wnsec = 0; 1113 int nsec3s_seen = 0; /* nsec3s seen */ 1114 struct ub_packed_rrset_key* s; 1115 size_t i; 1116 1117 /* the AUTHORITY section */ 1118 for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+ 1119 chase_reply->ns_numrrsets; i++) { 1120 s = chase_reply->rrsets[i]; 1121 1122 /* If we encounter an NSEC record, try to use it to prove 1123 * NODATA. This needs to handle the ENT NODATA case. 1124 * Also try to prove NAMEERROR, and absence of a wildcard */ 1125 if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC) { 1126 if(nsec_proves_nodata(s, qchase, &wc)) { 1127 nodata_valid_nsec = 1; 1128 /* set wc encloser if wildcard applicable */ 1129 } 1130 if(val_nsec_proves_name_error(s, qchase->qname)) { 1131 ce = nsec_closest_encloser(qchase->qname, s); 1132 nxdomain_valid_nsec = 1; 1133 } 1134 if(val_nsec_proves_no_wc(s, qchase->qname, 1135 qchase->qname_len)) 1136 nxdomain_valid_wnsec = 1; 1137 if(val_nsec_proves_insecuredelegation(s, qchase)) { 1138 verbose(VERB_ALGO, "delegation is insecure"); 1139 chase_reply->security = sec_status_insecure; 1140 return; 1141 } 1142 } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) { 1143 nsec3s_seen = 1; 1144 } 1145 } 1146 1147 /* check to see if we have a wildcard NODATA proof. */ 1148 1149 /* The wildcard NODATA is 1 NSEC proving that qname does not exists 1150 * (and also proving what the closest encloser is), and 1 NSEC 1151 * showing the matching wildcard, which must be *.closest_encloser. */ 1152 if(wc && !ce) 1153 nodata_valid_nsec = 0; 1154 else if(wc && ce) { 1155 if(query_dname_compare(wc, ce) != 0) { 1156 nodata_valid_nsec = 0; 1157 } 1158 } 1159 if(nxdomain_valid_nsec && !nxdomain_valid_wnsec) { 1160 /* name error is missing wildcard denial proof */ 1161 nxdomain_valid_nsec = 0; 1162 } 1163 1164 if(nodata_valid_nsec && nxdomain_valid_nsec) { 1165 verbose(VERB_QUERY, "CNAMEchain to noanswer proves that name " 1166 "exists and not exists, bogus"); 1167 chase_reply->security = sec_status_bogus; 1168 return; 1169 } 1170 if(!nodata_valid_nsec && !nxdomain_valid_nsec && nsec3s_seen) { 1171 int nodata; 1172 enum sec_status sec = nsec3_prove_nxornodata(env, ve, 1173 chase_reply->rrsets+chase_reply->an_numrrsets, 1174 chase_reply->ns_numrrsets, qchase, kkey, &nodata); 1175 if(sec == sec_status_insecure) { 1176 verbose(VERB_ALGO, "CNAMEchain to noanswer response " 1177 "is insecure"); 1178 chase_reply->security = sec_status_insecure; 1179 return; 1180 } else if(sec == sec_status_secure) { 1181 if(nodata) 1182 nodata_valid_nsec = 1; 1183 else nxdomain_valid_nsec = 1; 1184 } 1185 } 1186 1187 if(!nodata_valid_nsec && !nxdomain_valid_nsec) { 1188 verbose(VERB_QUERY, "CNAMEchain to noanswer response failed " 1189 "to prove status with NSEC/NSEC3"); 1190 if(verbosity >= VERB_ALGO) 1191 log_dns_msg("Failed CNAMEnoanswer", qchase, chase_reply); 1192 chase_reply->security = sec_status_bogus; 1193 return; 1194 } 1195 1196 if(nodata_valid_nsec) 1197 verbose(VERB_ALGO, "successfully validated CNAME chain to a " 1198 "NODATA response."); 1199 else verbose(VERB_ALGO, "successfully validated CNAME chain to a " 1200 "NAMEERROR response."); 1201 chase_reply->security = sec_status_secure; 1202 } 1203 1204 /** 1205 * Process init state for validator. 1206 * Process the INIT state. First tier responses start in the INIT state. 1207 * This is where they are vetted for validation suitability, and the initial 1208 * key search is done. 1209 * 1210 * Currently, events the come through this routine will be either promoted 1211 * to FINISHED/CNAME_RESP (no validation needed), FINDKEY (next step to 1212 * validation), or will be (temporarily) retired and a new priming request 1213 * event will be generated. 1214 * 1215 * @param qstate: query state. 1216 * @param vq: validator query state. 1217 * @param ve: validator shared global environment. 1218 * @param id: module id. 1219 * @return true if the event should be processed further on return, false if 1220 * not. 1221 */ 1222 static int 1223 processInit(struct module_qstate* qstate, struct val_qstate* vq, 1224 struct val_env* ve, int id) 1225 { 1226 uint8_t* lookup_name; 1227 size_t lookup_len; 1228 struct trust_anchor* anchor; 1229 enum val_classification subtype = val_classify_response( 1230 qstate->query_flags, &qstate->qinfo, &vq->qchase, 1231 vq->orig_msg->rep, vq->rrset_skip); 1232 if(vq->restart_count > VAL_MAX_RESTART_COUNT) { 1233 verbose(VERB_ALGO, "restart count exceeded"); 1234 return val_error(qstate, id); 1235 } 1236 verbose(VERB_ALGO, "validator classification %s", 1237 val_classification_to_string(subtype)); 1238 if(subtype == VAL_CLASS_REFERRAL && 1239 vq->rrset_skip < vq->orig_msg->rep->rrset_count) { 1240 /* referral uses the rrset name as qchase, to find keys for 1241 * that rrset */ 1242 vq->qchase.qname = vq->orig_msg->rep-> 1243 rrsets[vq->rrset_skip]->rk.dname; 1244 vq->qchase.qname_len = vq->orig_msg->rep-> 1245 rrsets[vq->rrset_skip]->rk.dname_len; 1246 vq->qchase.qtype = ntohs(vq->orig_msg->rep-> 1247 rrsets[vq->rrset_skip]->rk.type); 1248 vq->qchase.qclass = ntohs(vq->orig_msg->rep-> 1249 rrsets[vq->rrset_skip]->rk.rrset_class); 1250 } 1251 lookup_name = vq->qchase.qname; 1252 lookup_len = vq->qchase.qname_len; 1253 /* for type DS look at the parent side for keys/trustanchor */ 1254 /* also for NSEC not at apex */ 1255 if(vq->qchase.qtype == LDNS_RR_TYPE_DS || 1256 (vq->qchase.qtype == LDNS_RR_TYPE_NSEC && 1257 vq->orig_msg->rep->rrset_count > vq->rrset_skip && 1258 ntohs(vq->orig_msg->rep->rrsets[vq->rrset_skip]->rk.type) == 1259 LDNS_RR_TYPE_NSEC && 1260 !(vq->orig_msg->rep->rrsets[vq->rrset_skip]-> 1261 rk.flags&PACKED_RRSET_NSEC_AT_APEX))) { 1262 dname_remove_label(&lookup_name, &lookup_len); 1263 } 1264 1265 val_mark_indeterminate(vq->chase_reply, qstate->env->anchors, 1266 qstate->env->rrset_cache, qstate->env); 1267 vq->key_entry = NULL; 1268 vq->empty_DS_name = NULL; 1269 vq->ds_rrset = 0; 1270 anchor = anchors_lookup(qstate->env->anchors, 1271 lookup_name, lookup_len, vq->qchase.qclass); 1272 1273 /* Determine the signer/lookup name */ 1274 val_find_signer(subtype, &vq->qchase, vq->orig_msg->rep, 1275 vq->rrset_skip, &vq->signer_name, &vq->signer_len); 1276 if(vq->signer_name != NULL && 1277 !dname_subdomain_c(lookup_name, vq->signer_name)) { 1278 log_nametypeclass(VERB_ALGO, "this signer name is not a parent " 1279 "of lookupname, omitted", vq->signer_name, 0, 0); 1280 vq->signer_name = NULL; 1281 } 1282 if(vq->signer_name == NULL) { 1283 log_nametypeclass(VERB_ALGO, "no signer, using", lookup_name, 1284 0, 0); 1285 } else { 1286 lookup_name = vq->signer_name; 1287 lookup_len = vq->signer_len; 1288 log_nametypeclass(VERB_ALGO, "signer is", lookup_name, 0, 0); 1289 } 1290 1291 /* for NXDOMAIN it could be signed by a parent of the trust anchor */ 1292 if(subtype == VAL_CLASS_NAMEERROR && vq->signer_name && 1293 anchor && dname_strict_subdomain_c(anchor->name, lookup_name)){ 1294 lock_basic_unlock(&anchor->lock); 1295 anchor = anchors_lookup(qstate->env->anchors, 1296 lookup_name, lookup_len, vq->qchase.qclass); 1297 if(!anchor) { /* unsigned parent denies anchor*/ 1298 verbose(VERB_QUERY, "unsigned parent zone denies" 1299 " trust anchor, indeterminate"); 1300 vq->chase_reply->security = sec_status_indeterminate; 1301 vq->state = VAL_FINISHED_STATE; 1302 return 1; 1303 } 1304 verbose(VERB_ALGO, "trust anchor NXDOMAIN by signed parent"); 1305 } else if(subtype == VAL_CLASS_POSITIVE && 1306 qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY && 1307 query_dname_compare(lookup_name, qstate->qinfo.qname) == 0) { 1308 /* is a DNSKEY so lookup a bit higher since we want to 1309 * get it from a parent or from trustanchor */ 1310 dname_remove_label(&lookup_name, &lookup_len); 1311 } 1312 1313 if(vq->rrset_skip > 0 || subtype == VAL_CLASS_CNAME || 1314 subtype == VAL_CLASS_REFERRAL) { 1315 /* extract this part of orig_msg into chase_reply for 1316 * the eventual VALIDATE stage */ 1317 val_fill_reply(vq->chase_reply, vq->orig_msg->rep, 1318 vq->rrset_skip, lookup_name, lookup_len, 1319 vq->signer_name); 1320 if(verbosity >= VERB_ALGO) 1321 log_dns_msg("chased extract", &vq->qchase, 1322 vq->chase_reply); 1323 } 1324 1325 vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len, 1326 vq->qchase.qclass, qstate->region, *qstate->env->now); 1327 1328 /* there is no key(from DLV) and no trust anchor */ 1329 if(vq->key_entry == NULL && anchor == NULL) { 1330 /*response isn't under a trust anchor, so we cannot validate.*/ 1331 vq->chase_reply->security = sec_status_indeterminate; 1332 /* go to finished state to cache this result */ 1333 vq->state = VAL_FINISHED_STATE; 1334 return 1; 1335 } 1336 /* if not key, or if keyentry is *above* the trustanchor, i.e. 1337 * the keyentry is based on another (higher) trustanchor */ 1338 else if(vq->key_entry == NULL || (anchor && 1339 dname_strict_subdomain_c(anchor->name, vq->key_entry->name))) { 1340 /* trust anchor is an 'unsigned' trust anchor */ 1341 if(anchor && anchor->numDS == 0 && anchor->numDNSKEY == 0) { 1342 vq->chase_reply->security = sec_status_insecure; 1343 val_mark_insecure(vq->chase_reply, anchor->name, 1344 qstate->env->rrset_cache, qstate->env); 1345 lock_basic_unlock(&anchor->lock); 1346 vq->dlv_checked=1; /* skip DLV check */ 1347 /* go to finished state to cache this result */ 1348 vq->state = VAL_FINISHED_STATE; 1349 return 1; 1350 } 1351 /* fire off a trust anchor priming query. */ 1352 verbose(VERB_DETAIL, "prime trust anchor"); 1353 if(!prime_trust_anchor(qstate, vq, id, anchor)) { 1354 lock_basic_unlock(&anchor->lock); 1355 return val_error(qstate, id); 1356 } 1357 lock_basic_unlock(&anchor->lock); 1358 /* and otherwise, don't continue processing this event. 1359 * (it will be reactivated when the priming query returns). */ 1360 vq->state = VAL_FINDKEY_STATE; 1361 return 0; 1362 } 1363 if(anchor) { 1364 lock_basic_unlock(&anchor->lock); 1365 } 1366 1367 if(key_entry_isnull(vq->key_entry)) { 1368 /* response is under a null key, so we cannot validate 1369 * However, we do set the status to INSECURE, since it is 1370 * essentially proven insecure. */ 1371 vq->chase_reply->security = sec_status_insecure; 1372 val_mark_insecure(vq->chase_reply, vq->key_entry->name, 1373 qstate->env->rrset_cache, qstate->env); 1374 /* go to finished state to cache this result */ 1375 vq->state = VAL_FINISHED_STATE; 1376 return 1; 1377 } else if(key_entry_isbad(vq->key_entry)) { 1378 /* key is bad, chain is bad, reply is bogus */ 1379 errinf_dname(qstate, "key for validation", vq->key_entry->name); 1380 errinf(qstate, "is marked as invalid"); 1381 if(key_entry_get_reason(vq->key_entry)) { 1382 errinf(qstate, "because of a previous"); 1383 errinf(qstate, key_entry_get_reason(vq->key_entry)); 1384 } 1385 /* no retries, stop bothering the authority until timeout */ 1386 vq->restart_count = VAL_MAX_RESTART_COUNT; 1387 vq->chase_reply->security = sec_status_bogus; 1388 vq->state = VAL_FINISHED_STATE; 1389 return 1; 1390 } 1391 1392 /* otherwise, we have our "closest" cached key -- continue 1393 * processing in the next state. */ 1394 vq->state = VAL_FINDKEY_STATE; 1395 return 1; 1396 } 1397 1398 /** 1399 * Process the FINDKEY state. Generally this just calculates the next name 1400 * to query and either issues a DS or a DNSKEY query. It will check to see 1401 * if the correct key has already been reached, in which case it will 1402 * advance the event to the next state. 1403 * 1404 * @param qstate: query state. 1405 * @param vq: validator query state. 1406 * @param id: module id. 1407 * @return true if the event should be processed further on return, false if 1408 * not. 1409 */ 1410 static int 1411 processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id) 1412 { 1413 uint8_t* target_key_name, *current_key_name; 1414 size_t target_key_len; 1415 int strip_lab; 1416 1417 log_query_info(VERB_ALGO, "validator: FindKey", &vq->qchase); 1418 /* We know that state.key_entry is not 0 or bad key -- if it were, 1419 * then previous processing should have directed this event to 1420 * a different state. 1421 * It could be an isnull key, which signals that a DLV was just 1422 * done and the DNSKEY after the DLV failed with dnssec-retry state 1423 * and the DNSKEY has to be performed again. */ 1424 log_assert(vq->key_entry && !key_entry_isbad(vq->key_entry)); 1425 if(key_entry_isnull(vq->key_entry)) { 1426 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1427 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1428 vq->qchase.qclass, BIT_CD)) { 1429 log_err("mem error generating DNSKEY request"); 1430 return val_error(qstate, id); 1431 } 1432 return 0; 1433 } 1434 1435 target_key_name = vq->signer_name; 1436 target_key_len = vq->signer_len; 1437 if(!target_key_name) { 1438 target_key_name = vq->qchase.qname; 1439 target_key_len = vq->qchase.qname_len; 1440 } 1441 1442 current_key_name = vq->key_entry->name; 1443 1444 /* If our current key entry matches our target, then we are done. */ 1445 if(query_dname_compare(target_key_name, current_key_name) == 0) { 1446 vq->state = VAL_VALIDATE_STATE; 1447 return 1; 1448 } 1449 1450 if(vq->empty_DS_name) { 1451 /* if the last empty nonterminal/emptyDS name we detected is 1452 * below the current key, use that name to make progress 1453 * along the chain of trust */ 1454 if(query_dname_compare(target_key_name, 1455 vq->empty_DS_name) == 0) { 1456 /* do not query for empty_DS_name again */ 1457 verbose(VERB_ALGO, "Cannot retrieve DS for signature"); 1458 errinf(qstate, "no signatures"); 1459 errinf_origin(qstate, qstate->reply_origin); 1460 vq->chase_reply->security = sec_status_bogus; 1461 vq->state = VAL_FINISHED_STATE; 1462 return 1; 1463 } 1464 current_key_name = vq->empty_DS_name; 1465 } 1466 1467 log_nametypeclass(VERB_ALGO, "current keyname", current_key_name, 1468 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1469 log_nametypeclass(VERB_ALGO, "target keyname", target_key_name, 1470 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1471 /* assert we are walking down the DNS tree */ 1472 if(!dname_subdomain_c(target_key_name, current_key_name)) { 1473 verbose(VERB_ALGO, "bad signer name"); 1474 vq->chase_reply->security = sec_status_bogus; 1475 vq->state = VAL_FINISHED_STATE; 1476 return 1; 1477 } 1478 /* so this value is >= -1 */ 1479 strip_lab = dname_count_labels(target_key_name) - 1480 dname_count_labels(current_key_name) - 1; 1481 log_assert(strip_lab >= -1); 1482 verbose(VERB_ALGO, "striplab %d", strip_lab); 1483 if(strip_lab > 0) { 1484 dname_remove_labels(&target_key_name, &target_key_len, 1485 strip_lab); 1486 } 1487 log_nametypeclass(VERB_ALGO, "next keyname", target_key_name, 1488 LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN); 1489 1490 /* The next step is either to query for the next DS, or to query 1491 * for the next DNSKEY. */ 1492 if(vq->ds_rrset) 1493 log_nametypeclass(VERB_ALGO, "DS RRset", vq->ds_rrset->rk.dname, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN); 1494 else verbose(VERB_ALGO, "No DS RRset"); 1495 1496 if(vq->ds_rrset && query_dname_compare(vq->ds_rrset->rk.dname, 1497 vq->key_entry->name) != 0) { 1498 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1499 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1500 vq->qchase.qclass, BIT_CD)) { 1501 log_err("mem error generating DNSKEY request"); 1502 return val_error(qstate, id); 1503 } 1504 return 0; 1505 } 1506 1507 if(!vq->ds_rrset || query_dname_compare(vq->ds_rrset->rk.dname, 1508 target_key_name) != 0) { 1509 /* check if there is a cache entry : pick up an NSEC if 1510 * there is no DS, check if that NSEC has DS-bit unset, and 1511 * thus can disprove the secure delagation we seek. 1512 * We can then use that NSEC even in the absence of a SOA 1513 * record that would be required by the iterator to supply 1514 * a completely protocol-correct response. 1515 * Uses negative cache for NSEC3 lookup of DS responses. */ 1516 /* only if cache not blacklisted, of course */ 1517 struct dns_msg* msg; 1518 if(!qstate->blacklist && !vq->chain_blacklist && 1519 (msg=val_find_DS(qstate->env, target_key_name, 1520 target_key_len, vq->qchase.qclass, qstate->region, 1521 vq->key_entry->name)) ) { 1522 verbose(VERB_ALGO, "Process cached DS response"); 1523 process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR, 1524 msg, &msg->qinfo, NULL); 1525 return 1; /* continue processing ds-response results */ 1526 } 1527 if(!generate_request(qstate, id, target_key_name, 1528 target_key_len, LDNS_RR_TYPE_DS, vq->qchase.qclass, 1529 BIT_CD)) { 1530 log_err("mem error generating DS request"); 1531 return val_error(qstate, id); 1532 } 1533 return 0; 1534 } 1535 1536 /* Otherwise, it is time to query for the DNSKEY */ 1537 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 1538 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 1539 vq->qchase.qclass, BIT_CD)) { 1540 log_err("mem error generating DNSKEY request"); 1541 return val_error(qstate, id); 1542 } 1543 1544 return 0; 1545 } 1546 1547 /** 1548 * Process the VALIDATE stage, the init and findkey stages are finished, 1549 * and the right keys are available to validate the response. 1550 * Or, there are no keys available, in order to invalidate the response. 1551 * 1552 * After validation, the status is recorded in the message and rrsets, 1553 * and finished state is started. 1554 * 1555 * @param qstate: query state. 1556 * @param vq: validator query state. 1557 * @param ve: validator shared global environment. 1558 * @param id: module id. 1559 * @return true if the event should be processed further on return, false if 1560 * not. 1561 */ 1562 static int 1563 processValidate(struct module_qstate* qstate, struct val_qstate* vq, 1564 struct val_env* ve, int id) 1565 { 1566 enum val_classification subtype; 1567 1568 if(!vq->key_entry) { 1569 verbose(VERB_ALGO, "validate: no key entry, failed"); 1570 return val_error(qstate, id); 1571 } 1572 1573 /* This is the default next state. */ 1574 vq->state = VAL_FINISHED_STATE; 1575 1576 /* Unsigned responses must be underneath a "null" key entry.*/ 1577 if(key_entry_isnull(vq->key_entry)) { 1578 verbose(VERB_DETAIL, "Verified that %sresponse is INSECURE", 1579 vq->signer_name?"":"unsigned "); 1580 vq->chase_reply->security = sec_status_insecure; 1581 val_mark_insecure(vq->chase_reply, vq->key_entry->name, 1582 qstate->env->rrset_cache, qstate->env); 1583 key_cache_insert(ve->kcache, vq->key_entry, qstate); 1584 return 1; 1585 } 1586 1587 if(key_entry_isbad(vq->key_entry)) { 1588 log_nametypeclass(VERB_DETAIL, "Could not establish a chain " 1589 "of trust to keys for", vq->key_entry->name, 1590 LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class); 1591 vq->chase_reply->security = sec_status_bogus; 1592 errinf(qstate, "while building chain of trust"); 1593 if(vq->restart_count >= VAL_MAX_RESTART_COUNT) 1594 key_cache_insert(ve->kcache, vq->key_entry, qstate); 1595 return 1; 1596 } 1597 1598 /* signerName being null is the indicator that this response was 1599 * unsigned */ 1600 if(vq->signer_name == NULL) { 1601 log_query_info(VERB_ALGO, "processValidate: state has no " 1602 "signer name", &vq->qchase); 1603 verbose(VERB_DETAIL, "Could not establish validation of " 1604 "INSECURE status of unsigned response."); 1605 errinf(qstate, "no signatures"); 1606 errinf_origin(qstate, qstate->reply_origin); 1607 vq->chase_reply->security = sec_status_bogus; 1608 return 1; 1609 } 1610 subtype = val_classify_response(qstate->query_flags, &qstate->qinfo, 1611 &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); 1612 1613 /* check signatures in the message; 1614 * answer and authority must be valid, additional is only checked. */ 1615 if(!validate_msg_signatures(qstate, qstate->env, ve, &vq->qchase, 1616 vq->chase_reply, vq->key_entry)) { 1617 /* workaround bad recursor out there that truncates (even 1618 * with EDNS4k) to 512 by removing RRSIG from auth section 1619 * for positive replies*/ 1620 if((subtype == VAL_CLASS_POSITIVE || subtype == VAL_CLASS_ANY 1621 || subtype == VAL_CLASS_CNAME) && 1622 detect_wrongly_truncated(vq->orig_msg->rep)) { 1623 /* truncate the message some more */ 1624 vq->orig_msg->rep->ns_numrrsets = 0; 1625 vq->orig_msg->rep->ar_numrrsets = 0; 1626 vq->orig_msg->rep->rrset_count = 1627 vq->orig_msg->rep->an_numrrsets; 1628 vq->chase_reply->ns_numrrsets = 0; 1629 vq->chase_reply->ar_numrrsets = 0; 1630 vq->chase_reply->rrset_count = 1631 vq->chase_reply->an_numrrsets; 1632 qstate->errinf = NULL; 1633 } 1634 else { 1635 verbose(VERB_DETAIL, "Validate: message contains " 1636 "bad rrsets"); 1637 return 1; 1638 } 1639 } 1640 1641 switch(subtype) { 1642 case VAL_CLASS_POSITIVE: 1643 verbose(VERB_ALGO, "Validating a positive response"); 1644 validate_positive_response(qstate->env, ve, 1645 &vq->qchase, vq->chase_reply, vq->key_entry); 1646 verbose(VERB_DETAIL, "validate(positive): %s", 1647 sec_status_to_string( 1648 vq->chase_reply->security)); 1649 break; 1650 1651 case VAL_CLASS_NODATA: 1652 verbose(VERB_ALGO, "Validating a nodata response"); 1653 validate_nodata_response(qstate->env, ve, 1654 &vq->qchase, vq->chase_reply, vq->key_entry); 1655 verbose(VERB_DETAIL, "validate(nodata): %s", 1656 sec_status_to_string( 1657 vq->chase_reply->security)); 1658 break; 1659 1660 case VAL_CLASS_NAMEERROR: 1661 verbose(VERB_ALGO, "Validating a nxdomain response"); 1662 validate_nameerror_response(qstate->env, ve, 1663 &vq->qchase, vq->chase_reply, vq->key_entry); 1664 verbose(VERB_DETAIL, "validate(nxdomain): %s", 1665 sec_status_to_string( 1666 vq->chase_reply->security)); 1667 break; 1668 1669 case VAL_CLASS_CNAME: 1670 verbose(VERB_ALGO, "Validating a cname response"); 1671 validate_cname_response(qstate->env, ve, 1672 &vq->qchase, vq->chase_reply, vq->key_entry); 1673 verbose(VERB_DETAIL, "validate(cname): %s", 1674 sec_status_to_string( 1675 vq->chase_reply->security)); 1676 break; 1677 1678 case VAL_CLASS_CNAMENOANSWER: 1679 verbose(VERB_ALGO, "Validating a cname noanswer " 1680 "response"); 1681 validate_cname_noanswer_response(qstate->env, ve, 1682 &vq->qchase, vq->chase_reply, vq->key_entry); 1683 verbose(VERB_DETAIL, "validate(cname_noanswer): %s", 1684 sec_status_to_string( 1685 vq->chase_reply->security)); 1686 break; 1687 1688 case VAL_CLASS_REFERRAL: 1689 verbose(VERB_ALGO, "Validating a referral response"); 1690 validate_referral_response(vq->chase_reply); 1691 verbose(VERB_DETAIL, "validate(referral): %s", 1692 sec_status_to_string( 1693 vq->chase_reply->security)); 1694 break; 1695 1696 case VAL_CLASS_ANY: 1697 verbose(VERB_ALGO, "Validating a positive ANY " 1698 "response"); 1699 validate_any_response(qstate->env, ve, &vq->qchase, 1700 vq->chase_reply, vq->key_entry); 1701 verbose(VERB_DETAIL, "validate(positive_any): %s", 1702 sec_status_to_string( 1703 vq->chase_reply->security)); 1704 break; 1705 1706 default: 1707 log_err("validate: unhandled response subtype: %d", 1708 subtype); 1709 } 1710 if(vq->chase_reply->security == sec_status_bogus) { 1711 if(subtype == VAL_CLASS_POSITIVE) 1712 errinf(qstate, "wildcard"); 1713 else errinf(qstate, val_classification_to_string(subtype)); 1714 errinf(qstate, "proof failed"); 1715 errinf_origin(qstate, qstate->reply_origin); 1716 } 1717 1718 return 1; 1719 } 1720 1721 /** 1722 * Init DLV check. 1723 * Called when a query is determined by other trust anchors to be insecure 1724 * (or indeterminate). Then we look if there is a key in the DLV. 1725 * Performs aggressive negative cache check to see if there is no key. 1726 * Otherwise, spawns a DLV query, and changes to the DLV wait state. 1727 * 1728 * @param qstate: query state. 1729 * @param vq: validator query state. 1730 * @param ve: validator shared global environment. 1731 * @param id: module id. 1732 * @return true if there is no DLV. 1733 * false: processing is finished for the validator operate(). 1734 * This function may exit in three ways: 1735 * o no DLV (agressive cache), so insecure. (true) 1736 * o error - stop processing (false) 1737 * o DLV lookup was started, stop processing (false) 1738 */ 1739 static int 1740 val_dlv_init(struct module_qstate* qstate, struct val_qstate* vq, 1741 struct val_env* ve, int id) 1742 { 1743 uint8_t* nm; 1744 size_t nm_len; 1745 /* there must be a DLV configured */ 1746 log_assert(qstate->env->anchors->dlv_anchor); 1747 /* this bool is true to avoid looping in the DLV checks */ 1748 log_assert(vq->dlv_checked); 1749 1750 /* init the DLV lookup variables */ 1751 vq->dlv_lookup_name = NULL; 1752 vq->dlv_lookup_name_len = 0; 1753 vq->dlv_insecure_at = NULL; 1754 vq->dlv_insecure_at_len = 0; 1755 1756 /* Determine the name for which we want to lookup DLV. 1757 * This name is for the current message, or 1758 * for the current RRset for CNAME, referral subtypes. 1759 * If there is a signer, use that, otherwise the domain name */ 1760 if(vq->signer_name) { 1761 nm = vq->signer_name; 1762 nm_len = vq->signer_len; 1763 } else { 1764 /* use qchase */ 1765 nm = vq->qchase.qname; 1766 nm_len = vq->qchase.qname_len; 1767 if(vq->qchase.qtype == LDNS_RR_TYPE_DS) 1768 dname_remove_label(&nm, &nm_len); 1769 } 1770 log_nametypeclass(VERB_ALGO, "DLV init look", nm, LDNS_RR_TYPE_DS, 1771 vq->qchase.qclass); 1772 log_assert(nm && nm_len); 1773 /* sanity check: no DLV lookups below the DLV anchor itself. 1774 * Like, an securely insecure delegation there makes no sense. */ 1775 if(dname_subdomain_c(nm, qstate->env->anchors->dlv_anchor->name)) { 1776 verbose(VERB_ALGO, "DLV lookup within DLV repository denied"); 1777 return 1; 1778 } 1779 /* concat name (minus root label) + dlv name */ 1780 vq->dlv_lookup_name_len = nm_len - 1 + 1781 qstate->env->anchors->dlv_anchor->namelen; 1782 vq->dlv_lookup_name = regional_alloc(qstate->region, 1783 vq->dlv_lookup_name_len); 1784 if(!vq->dlv_lookup_name) { 1785 log_err("Out of memory preparing DLV lookup"); 1786 return val_error(qstate, id); 1787 } 1788 memmove(vq->dlv_lookup_name, nm, nm_len-1); 1789 memmove(vq->dlv_lookup_name+nm_len-1, 1790 qstate->env->anchors->dlv_anchor->name, 1791 qstate->env->anchors->dlv_anchor->namelen); 1792 log_nametypeclass(VERB_ALGO, "DLV name", vq->dlv_lookup_name, 1793 LDNS_RR_TYPE_DLV, vq->qchase.qclass); 1794 1795 /* determine where the insecure point was determined, the DLV must 1796 * be equal or below that to continue building the trust chain 1797 * down. May be NULL if no trust chain was built yet */ 1798 nm = NULL; 1799 if(vq->key_entry && key_entry_isnull(vq->key_entry)) { 1800 nm = vq->key_entry->name; 1801 nm_len = vq->key_entry->namelen; 1802 } 1803 if(nm) { 1804 vq->dlv_insecure_at_len = nm_len - 1 + 1805 qstate->env->anchors->dlv_anchor->namelen; 1806 vq->dlv_insecure_at = regional_alloc(qstate->region, 1807 vq->dlv_insecure_at_len); 1808 if(!vq->dlv_insecure_at) { 1809 log_err("Out of memory preparing DLV lookup"); 1810 return val_error(qstate, id); 1811 } 1812 memmove(vq->dlv_insecure_at, nm, nm_len-1); 1813 memmove(vq->dlv_insecure_at+nm_len-1, 1814 qstate->env->anchors->dlv_anchor->name, 1815 qstate->env->anchors->dlv_anchor->namelen); 1816 log_nametypeclass(VERB_ALGO, "insecure_at", 1817 vq->dlv_insecure_at, 0, vq->qchase.qclass); 1818 } 1819 1820 /* If we can find the name in the aggressive negative cache, 1821 * give up; insecure is the answer */ 1822 while(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name, 1823 vq->dlv_lookup_name_len, vq->qchase.qclass, 1824 qstate->env->rrset_cache, *qstate->env->now)) { 1825 /* go up */ 1826 dname_remove_label(&vq->dlv_lookup_name, 1827 &vq->dlv_lookup_name_len); 1828 /* too high? */ 1829 if(!dname_subdomain_c(vq->dlv_lookup_name, 1830 qstate->env->anchors->dlv_anchor->name)) { 1831 verbose(VERB_ALGO, "ask above dlv repo"); 1832 return 1; /* Above the repo is insecure */ 1833 } 1834 /* above chain of trust? */ 1835 if(vq->dlv_insecure_at && !dname_subdomain_c( 1836 vq->dlv_lookup_name, vq->dlv_insecure_at)) { 1837 verbose(VERB_ALGO, "ask above insecure endpoint"); 1838 return 1; 1839 } 1840 } 1841 1842 /* perform a lookup for the DLV; with validation */ 1843 vq->state = VAL_DLVLOOKUP_STATE; 1844 if(!generate_request(qstate, id, vq->dlv_lookup_name, 1845 vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV, 1846 vq->qchase.qclass, 0)) { 1847 return val_error(qstate, id); 1848 } 1849 1850 /* Find the closest encloser DLV from the repository. 1851 * then that is used to build another chain of trust 1852 * This may first require a query 'too low' that has NSECs in 1853 * the answer, from which we determine the closest encloser DLV. 1854 * When determine the closest encloser, skip empty nonterminals, 1855 * since we want a nonempty node in the DLV repository. */ 1856 1857 return 0; 1858 } 1859 1860 /** 1861 * The Finished state. The validation status (good or bad) has been determined. 1862 * 1863 * @param qstate: query state. 1864 * @param vq: validator query state. 1865 * @param ve: validator shared global environment. 1866 * @param id: module id. 1867 * @return true if the event should be processed further on return, false if 1868 * not. 1869 */ 1870 static int 1871 processFinished(struct module_qstate* qstate, struct val_qstate* vq, 1872 struct val_env* ve, int id) 1873 { 1874 enum val_classification subtype = val_classify_response( 1875 qstate->query_flags, &qstate->qinfo, &vq->qchase, 1876 vq->orig_msg->rep, vq->rrset_skip); 1877 1878 /* if the result is insecure or indeterminate and we have not 1879 * checked the DLV yet, check the DLV */ 1880 if((vq->chase_reply->security == sec_status_insecure || 1881 vq->chase_reply->security == sec_status_indeterminate) && 1882 qstate->env->anchors->dlv_anchor && !vq->dlv_checked) { 1883 vq->dlv_checked = 1; 1884 if(!val_dlv_init(qstate, vq, ve, id)) 1885 return 0; 1886 } 1887 1888 /* store overall validation result in orig_msg */ 1889 if(vq->rrset_skip == 0) 1890 vq->orig_msg->rep->security = vq->chase_reply->security; 1891 else if(subtype != VAL_CLASS_REFERRAL || 1892 vq->rrset_skip < vq->orig_msg->rep->an_numrrsets + 1893 vq->orig_msg->rep->ns_numrrsets) { 1894 /* ignore sec status of additional section if a referral 1895 * type message skips there and 1896 * use the lowest security status as end result. */ 1897 if(vq->chase_reply->security < vq->orig_msg->rep->security) 1898 vq->orig_msg->rep->security = 1899 vq->chase_reply->security; 1900 } 1901 1902 if(subtype == VAL_CLASS_REFERRAL) { 1903 /* for a referral, move to next unchecked rrset and check it*/ 1904 vq->rrset_skip = val_next_unchecked(vq->orig_msg->rep, 1905 vq->rrset_skip); 1906 if(vq->rrset_skip < vq->orig_msg->rep->rrset_count) { 1907 /* and restart for this rrset */ 1908 verbose(VERB_ALGO, "validator: go to next rrset"); 1909 vq->chase_reply->security = sec_status_unchecked; 1910 vq->dlv_checked = 0; /* can do DLV for this RR */ 1911 vq->state = VAL_INIT_STATE; 1912 return 1; 1913 } 1914 /* referral chase is done */ 1915 } 1916 if(vq->chase_reply->security != sec_status_bogus && 1917 subtype == VAL_CLASS_CNAME) { 1918 /* chase the CNAME; process next part of the message */ 1919 if(!val_chase_cname(&vq->qchase, vq->orig_msg->rep, 1920 &vq->rrset_skip)) { 1921 verbose(VERB_ALGO, "validator: failed to chase CNAME"); 1922 vq->orig_msg->rep->security = sec_status_bogus; 1923 } else { 1924 /* restart process for new qchase at rrset_skip */ 1925 log_query_info(VERB_ALGO, "validator: chased to", 1926 &vq->qchase); 1927 vq->chase_reply->security = sec_status_unchecked; 1928 vq->dlv_checked = 0; /* can do DLV for this RR */ 1929 vq->state = VAL_INIT_STATE; 1930 return 1; 1931 } 1932 } 1933 1934 if(vq->orig_msg->rep->security == sec_status_secure) { 1935 /* If the message is secure, check that all rrsets are 1936 * secure (i.e. some inserted RRset for CNAME chain with 1937 * a different signer name). And drop additional rrsets 1938 * that are not secure (if clean-additional option is set) */ 1939 /* this may cause the msg to be marked bogus */ 1940 val_check_nonsecure(ve, vq->orig_msg->rep); 1941 if(vq->orig_msg->rep->security == sec_status_secure) { 1942 log_query_info(VERB_DETAIL, "validation success", 1943 &qstate->qinfo); 1944 } 1945 } 1946 1947 /* if the result is bogus - set message ttl to bogus ttl to avoid 1948 * endless bogus revalidation */ 1949 if(vq->orig_msg->rep->security == sec_status_bogus) { 1950 /* see if we can try again to fetch data */ 1951 if(vq->restart_count < VAL_MAX_RESTART_COUNT) { 1952 int restart_count = vq->restart_count+1; 1953 verbose(VERB_ALGO, "validation failed, " 1954 "blacklist and retry to fetch data"); 1955 val_blacklist(&qstate->blacklist, qstate->region, 1956 qstate->reply_origin, 0); 1957 qstate->reply_origin = NULL; 1958 qstate->errinf = NULL; 1959 memset(vq, 0, sizeof(*vq)); 1960 vq->restart_count = restart_count; 1961 vq->state = VAL_INIT_STATE; 1962 verbose(VERB_ALGO, "pass back to next module"); 1963 qstate->ext_state[id] = module_restart_next; 1964 return 0; 1965 } 1966 1967 vq->orig_msg->rep->ttl = ve->bogus_ttl; 1968 vq->orig_msg->rep->prefetch_ttl = 1969 PREFETCH_TTL_CALC(vq->orig_msg->rep->ttl); 1970 if(qstate->env->cfg->val_log_level >= 1 && 1971 !qstate->env->cfg->val_log_squelch) { 1972 if(qstate->env->cfg->val_log_level < 2) 1973 log_query_info(0, "validation failure", 1974 &qstate->qinfo); 1975 else { 1976 char* err = errinf_to_str(qstate); 1977 if(err) log_info("%s", err); 1978 free(err); 1979 } 1980 } 1981 /* If we are in permissive mode, bogus gets indeterminate */ 1982 if(ve->permissive_mode) 1983 vq->orig_msg->rep->security = sec_status_indeterminate; 1984 } 1985 1986 /* store results in cache */ 1987 if(qstate->query_flags&BIT_RD) { 1988 /* if secure, this will override cache anyway, no need 1989 * to check if from parentNS */ 1990 if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 1991 vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) { 1992 log_err("out of memory caching validator results"); 1993 } 1994 } else { 1995 /* for a referral, store the verified RRsets */ 1996 /* and this does not get prefetched, so no leeway */ 1997 if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 1998 vq->orig_msg->rep, 1, 0, 0, NULL)) { 1999 log_err("out of memory caching validator results"); 2000 } 2001 } 2002 qstate->return_rcode = LDNS_RCODE_NOERROR; 2003 qstate->return_msg = vq->orig_msg; 2004 qstate->ext_state[id] = module_finished; 2005 return 0; 2006 } 2007 2008 /** 2009 * The DLVLookup state. Process DLV lookups. 2010 * 2011 * @param qstate: query state. 2012 * @param vq: validator query state. 2013 * @param ve: validator shared global environment. 2014 * @param id: module id. 2015 * @return true if the event should be processed further on return, false if 2016 * not. 2017 */ 2018 static int 2019 processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq, 2020 struct val_env* ve, int id) 2021 { 2022 /* see if this we are ready to continue normal resolution */ 2023 /* we may need more DLV lookups */ 2024 if(vq->dlv_status==dlv_error) 2025 verbose(VERB_ALGO, "DLV woke up with status dlv_error"); 2026 else if(vq->dlv_status==dlv_success) 2027 verbose(VERB_ALGO, "DLV woke up with status dlv_success"); 2028 else if(vq->dlv_status==dlv_ask_higher) 2029 verbose(VERB_ALGO, "DLV woke up with status dlv_ask_higher"); 2030 else if(vq->dlv_status==dlv_there_is_no_dlv) 2031 verbose(VERB_ALGO, "DLV woke up with status dlv_there_is_no_dlv"); 2032 else verbose(VERB_ALGO, "DLV woke up with status unknown"); 2033 2034 if(vq->dlv_status == dlv_error) { 2035 verbose(VERB_QUERY, "failed DLV lookup"); 2036 return val_error(qstate, id); 2037 } else if(vq->dlv_status == dlv_success) { 2038 uint8_t* nm; 2039 size_t nmlen; 2040 /* chain continues with DNSKEY, continue in FINDKEY */ 2041 vq->state = VAL_FINDKEY_STATE; 2042 2043 /* strip off the DLV suffix from the name; could result in . */ 2044 log_assert(dname_subdomain_c(vq->ds_rrset->rk.dname, 2045 qstate->env->anchors->dlv_anchor->name)); 2046 nmlen = vq->ds_rrset->rk.dname_len - 2047 qstate->env->anchors->dlv_anchor->namelen + 1; 2048 nm = regional_alloc_init(qstate->region, 2049 vq->ds_rrset->rk.dname, nmlen); 2050 if(!nm) { 2051 log_err("Out of memory in DLVLook"); 2052 return val_error(qstate, id); 2053 } 2054 nm[nmlen-1] = 0; 2055 2056 vq->ds_rrset->rk.dname = nm; 2057 vq->ds_rrset->rk.dname_len = nmlen; 2058 2059 /* create a nullentry for the key so the dnskey lookup 2060 * can be retried after a validation failure for it */ 2061 vq->key_entry = key_entry_create_null(qstate->region, 2062 nm, nmlen, vq->qchase.qclass, 0, 0); 2063 if(!vq->key_entry) { 2064 log_err("Out of memory in DLVLook"); 2065 return val_error(qstate, id); 2066 } 2067 2068 if(!generate_request(qstate, id, vq->ds_rrset->rk.dname, 2069 vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY, 2070 vq->qchase.qclass, BIT_CD)) { 2071 log_err("mem error generating DNSKEY request"); 2072 return val_error(qstate, id); 2073 } 2074 return 0; 2075 } else if(vq->dlv_status == dlv_there_is_no_dlv) { 2076 /* continue with the insecure result we got */ 2077 vq->state = VAL_FINISHED_STATE; 2078 return 1; 2079 } 2080 log_assert(vq->dlv_status == dlv_ask_higher); 2081 2082 /* ask higher, make sure we stay in DLV repo, below dlv_at */ 2083 if(!dname_subdomain_c(vq->dlv_lookup_name, 2084 qstate->env->anchors->dlv_anchor->name)) { 2085 /* just like, there is no DLV */ 2086 verbose(VERB_ALGO, "ask above dlv repo"); 2087 vq->state = VAL_FINISHED_STATE; 2088 return 1; 2089 } 2090 if(vq->dlv_insecure_at && !dname_subdomain_c(vq->dlv_lookup_name, 2091 vq->dlv_insecure_at)) { 2092 /* already checked a chain lower than dlv_lookup_name */ 2093 verbose(VERB_ALGO, "ask above insecure endpoint"); 2094 log_nametypeclass(VERB_ALGO, "enpt", vq->dlv_insecure_at, 0, 0); 2095 vq->state = VAL_FINISHED_STATE; 2096 return 1; 2097 } 2098 2099 /* check negative cache before making new request */ 2100 if(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name, 2101 vq->dlv_lookup_name_len, vq->qchase.qclass, 2102 qstate->env->rrset_cache, *qstate->env->now)) { 2103 /* does not exist, go up one (go higher). */ 2104 dname_remove_label(&vq->dlv_lookup_name, 2105 &vq->dlv_lookup_name_len); 2106 /* limit number of labels, limited number of recursion */ 2107 return processDLVLookup(qstate, vq, ve, id); 2108 } 2109 2110 if(!generate_request(qstate, id, vq->dlv_lookup_name, 2111 vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV, 2112 vq->qchase.qclass, 0)) { 2113 return val_error(qstate, id); 2114 } 2115 2116 return 0; 2117 } 2118 2119 /** 2120 * Handle validator state. 2121 * If a method returns true, the next state is started. If false, then 2122 * processing will stop. 2123 * @param qstate: query state. 2124 * @param vq: validator query state. 2125 * @param ve: validator shared global environment. 2126 * @param id: module id. 2127 */ 2128 static void 2129 val_handle(struct module_qstate* qstate, struct val_qstate* vq, 2130 struct val_env* ve, int id) 2131 { 2132 int cont = 1; 2133 while(cont) { 2134 verbose(VERB_ALGO, "val handle processing q with state %s", 2135 val_state_to_string(vq->state)); 2136 switch(vq->state) { 2137 case VAL_INIT_STATE: 2138 cont = processInit(qstate, vq, ve, id); 2139 break; 2140 case VAL_FINDKEY_STATE: 2141 cont = processFindKey(qstate, vq, id); 2142 break; 2143 case VAL_VALIDATE_STATE: 2144 cont = processValidate(qstate, vq, ve, id); 2145 break; 2146 case VAL_FINISHED_STATE: 2147 cont = processFinished(qstate, vq, ve, id); 2148 break; 2149 case VAL_DLVLOOKUP_STATE: 2150 cont = processDLVLookup(qstate, vq, ve, id); 2151 break; 2152 default: 2153 log_warn("validator: invalid state %d", 2154 vq->state); 2155 cont = 0; 2156 break; 2157 } 2158 } 2159 } 2160 2161 void 2162 val_operate(struct module_qstate* qstate, enum module_ev event, int id, 2163 struct outbound_entry* outbound) 2164 { 2165 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2166 struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id]; 2167 verbose(VERB_QUERY, "validator[module %d] operate: extstate:%s " 2168 "event:%s", id, strextstate(qstate->ext_state[id]), 2169 strmodulevent(event)); 2170 log_query_info(VERB_QUERY, "validator operate: query", 2171 &qstate->qinfo); 2172 if(vq && qstate->qinfo.qname != vq->qchase.qname) 2173 log_query_info(VERB_QUERY, "validator operate: chased to", 2174 &vq->qchase); 2175 (void)outbound; 2176 if(event == module_event_new || 2177 (event == module_event_pass && vq == NULL)) { 2178 /* pass request to next module, to get it */ 2179 verbose(VERB_ALGO, "validator: pass to next module"); 2180 qstate->ext_state[id] = module_wait_module; 2181 return; 2182 } 2183 if(event == module_event_moddone) { 2184 /* check if validation is needed */ 2185 verbose(VERB_ALGO, "validator: nextmodule returned"); 2186 if(!needs_validation(qstate, qstate->return_rcode, 2187 qstate->return_msg)) { 2188 /* no need to validate this */ 2189 if(qstate->return_msg) 2190 qstate->return_msg->rep->security = 2191 sec_status_indeterminate; 2192 qstate->ext_state[id] = module_finished; 2193 return; 2194 } 2195 if(already_validated(qstate->return_msg)) { 2196 qstate->ext_state[id] = module_finished; 2197 return; 2198 } 2199 /* qclass ANY should have validation result from spawned 2200 * queries. If we get here, it is bogus or an internal error */ 2201 if(qstate->qinfo.qclass == LDNS_RR_CLASS_ANY) { 2202 verbose(VERB_ALGO, "cannot validate classANY: bogus"); 2203 if(qstate->return_msg) 2204 qstate->return_msg->rep->security = 2205 sec_status_bogus; 2206 qstate->ext_state[id] = module_finished; 2207 return; 2208 } 2209 /* create state to start validation */ 2210 qstate->ext_state[id] = module_error; /* override this */ 2211 if(!vq) { 2212 vq = val_new(qstate, id); 2213 if(!vq) { 2214 log_err("validator: malloc failure"); 2215 qstate->ext_state[id] = module_error; 2216 return; 2217 } 2218 } else if(!vq->orig_msg) { 2219 if(!val_new_getmsg(qstate, vq)) { 2220 log_err("validator: malloc failure"); 2221 qstate->ext_state[id] = module_error; 2222 return; 2223 } 2224 } 2225 val_handle(qstate, vq, ve, id); 2226 return; 2227 } 2228 if(event == module_event_pass) { 2229 qstate->ext_state[id] = module_error; /* override this */ 2230 /* continue processing, since val_env exists */ 2231 val_handle(qstate, vq, ve, id); 2232 return; 2233 } 2234 log_err("validator: bad event %s", strmodulevent(event)); 2235 qstate->ext_state[id] = module_error; 2236 return; 2237 } 2238 2239 /** 2240 * Evaluate the response to a priming request. 2241 * 2242 * @param dnskey_rrset: DNSKEY rrset (can be NULL if none) in prime reply. 2243 * (this rrset is allocated in the wrong region, not the qstate). 2244 * @param ta: trust anchor. 2245 * @param qstate: qstate that needs key. 2246 * @param id: module id. 2247 * @return new key entry or NULL on allocation failure. 2248 * The key entry will either contain a validated DNSKEY rrset, or 2249 * represent a Null key (query failed, but validation did not), or a 2250 * Bad key (validation failed). 2251 */ 2252 static struct key_entry_key* 2253 primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, 2254 struct trust_anchor* ta, struct module_qstate* qstate, int id) 2255 { 2256 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2257 struct key_entry_key* kkey = NULL; 2258 enum sec_status sec = sec_status_unchecked; 2259 char* reason = NULL; 2260 int downprot = 1; 2261 2262 if(!dnskey_rrset) { 2263 log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- " 2264 "could not fetch DNSKEY rrset", 2265 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2266 if(qstate->env->cfg->harden_dnssec_stripped) { 2267 errinf(qstate, "no DNSKEY rrset"); 2268 kkey = key_entry_create_bad(qstate->region, ta->name, 2269 ta->namelen, ta->dclass, BOGUS_KEY_TTL, 2270 *qstate->env->now); 2271 } else kkey = key_entry_create_null(qstate->region, ta->name, 2272 ta->namelen, ta->dclass, NULL_KEY_TTL, 2273 *qstate->env->now); 2274 if(!kkey) { 2275 log_err("out of memory: allocate fail prime key"); 2276 return NULL; 2277 } 2278 return kkey; 2279 } 2280 /* attempt to verify with trust anchor DS and DNSKEY */ 2281 kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve, 2282 dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot, 2283 &reason); 2284 if(!kkey) { 2285 log_err("out of memory: verifying prime TA"); 2286 return NULL; 2287 } 2288 if(key_entry_isgood(kkey)) 2289 sec = sec_status_secure; 2290 else 2291 sec = sec_status_bogus; 2292 verbose(VERB_DETAIL, "validate keys with anchor(DS): %s", 2293 sec_status_to_string(sec)); 2294 2295 if(sec != sec_status_secure) { 2296 log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- " 2297 "DNSKEY rrset is not secure", 2298 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2299 /* NOTE: in this case, we should probably reject the trust 2300 * anchor for longer, perhaps forever. */ 2301 if(qstate->env->cfg->harden_dnssec_stripped) { 2302 errinf(qstate, reason); 2303 kkey = key_entry_create_bad(qstate->region, ta->name, 2304 ta->namelen, ta->dclass, BOGUS_KEY_TTL, 2305 *qstate->env->now); 2306 } else kkey = key_entry_create_null(qstate->region, ta->name, 2307 ta->namelen, ta->dclass, NULL_KEY_TTL, 2308 *qstate->env->now); 2309 if(!kkey) { 2310 log_err("out of memory: allocate null prime key"); 2311 return NULL; 2312 } 2313 return kkey; 2314 } 2315 2316 log_nametypeclass(VERB_DETAIL, "Successfully primed trust anchor", 2317 ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); 2318 return kkey; 2319 } 2320 2321 /** 2322 * In inform supers, with the resulting message and rcode and the current 2323 * keyset in the super state, validate the DS response, returning a KeyEntry. 2324 * 2325 * @param qstate: query state that is validating and asked for a DS. 2326 * @param vq: validator query state 2327 * @param id: module id. 2328 * @param rcode: rcode result value. 2329 * @param msg: result message (if rcode is OK). 2330 * @param qinfo: from the sub query state, query info. 2331 * @param ke: the key entry to return. It returns 2332 * is_bad if the DS response fails to validate, is_null if the 2333 * DS response indicated an end to secure space, is_good if the DS 2334 * validated. It returns ke=NULL if the DS response indicated that the 2335 * request wasn't a delegation point. 2336 * @return 0 on servfail error (malloc failure). 2337 */ 2338 static int 2339 ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq, 2340 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2341 struct key_entry_key** ke) 2342 { 2343 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2344 char* reason = NULL; 2345 enum val_classification subtype; 2346 if(rcode != LDNS_RCODE_NOERROR) { 2347 char* rc = ldns_pkt_rcode2str(rcode); 2348 /* errors here pretty much break validation */ 2349 verbose(VERB_DETAIL, "DS response was error, thus bogus"); 2350 errinf(qstate, rc); 2351 errinf(qstate, "no DS"); 2352 free(rc); 2353 goto return_bogus; 2354 } 2355 2356 subtype = val_classify_response(BIT_RD, qinfo, qinfo, msg->rep, 0); 2357 if(subtype == VAL_CLASS_POSITIVE) { 2358 struct ub_packed_rrset_key* ds; 2359 enum sec_status sec; 2360 ds = reply_find_answer_rrset(qinfo, msg->rep); 2361 /* If there was no DS rrset, then we have mis-classified 2362 * this message. */ 2363 if(!ds) { 2364 log_warn("internal error: POSITIVE DS response was " 2365 "missing DS."); 2366 errinf(qstate, "no DS record"); 2367 goto return_bogus; 2368 } 2369 /* Verify only returns BOGUS or SECURE. If the rrset is 2370 * bogus, then we are done. */ 2371 sec = val_verify_rrset_entry(qstate->env, ve, ds, 2372 vq->key_entry, &reason); 2373 if(sec != sec_status_secure) { 2374 verbose(VERB_DETAIL, "DS rrset in DS response did " 2375 "not verify"); 2376 errinf(qstate, reason); 2377 goto return_bogus; 2378 } 2379 2380 /* If the DS rrset validates, we still have to make sure 2381 * that they are usable. */ 2382 if(!val_dsset_isusable(ds)) { 2383 /* If they aren't usable, then we treat it like 2384 * there was no DS. */ 2385 *ke = key_entry_create_null(qstate->region, 2386 qinfo->qname, qinfo->qname_len, qinfo->qclass, 2387 ub_packed_rrset_ttl(ds), *qstate->env->now); 2388 return (*ke) != NULL; 2389 } 2390 2391 /* Otherwise, we return the positive response. */ 2392 log_query_info(VERB_DETAIL, "validated DS", qinfo); 2393 *ke = key_entry_create_rrset(qstate->region, 2394 qinfo->qname, qinfo->qname_len, qinfo->qclass, ds, 2395 NULL, *qstate->env->now); 2396 return (*ke) != NULL; 2397 } else if(subtype == VAL_CLASS_NODATA || 2398 subtype == VAL_CLASS_NAMEERROR) { 2399 /* NODATA means that the qname exists, but that there was 2400 * no DS. This is a pretty normal case. */ 2401 uint32_t proof_ttl = 0; 2402 enum sec_status sec; 2403 2404 /* make sure there are NSECs or NSEC3s with signatures */ 2405 if(!val_has_signed_nsecs(msg->rep, &reason)) { 2406 verbose(VERB_ALGO, "no NSECs: %s", reason); 2407 errinf(qstate, reason); 2408 goto return_bogus; 2409 } 2410 2411 /* For subtype Name Error. 2412 * attempt ANS 2.8.1.0 compatibility where it sets rcode 2413 * to nxdomain, but really this is an Nodata/Noerror response. 2414 * Find and prove the empty nonterminal in that case */ 2415 2416 /* Try to prove absence of the DS with NSEC */ 2417 sec = val_nsec_prove_nodata_dsreply( 2418 qstate->env, ve, qinfo, msg->rep, vq->key_entry, 2419 &proof_ttl, &reason); 2420 switch(sec) { 2421 case sec_status_secure: 2422 verbose(VERB_DETAIL, "NSEC RRset for the " 2423 "referral proved no DS."); 2424 *ke = key_entry_create_null(qstate->region, 2425 qinfo->qname, qinfo->qname_len, 2426 qinfo->qclass, proof_ttl, 2427 *qstate->env->now); 2428 return (*ke) != NULL; 2429 case sec_status_insecure: 2430 verbose(VERB_DETAIL, "NSEC RRset for the " 2431 "referral proved not a delegation point"); 2432 *ke = NULL; 2433 return 1; 2434 case sec_status_bogus: 2435 verbose(VERB_DETAIL, "NSEC RRset for the " 2436 "referral did not prove no DS."); 2437 errinf(qstate, reason); 2438 goto return_bogus; 2439 case sec_status_unchecked: 2440 default: 2441 /* NSEC proof did not work, try next */ 2442 break; 2443 } 2444 2445 sec = nsec3_prove_nods(qstate->env, ve, 2446 msg->rep->rrsets + msg->rep->an_numrrsets, 2447 msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason); 2448 switch(sec) { 2449 case sec_status_insecure: 2450 /* case insecure also continues to unsigned 2451 * space. If nsec3-iter-count too high or 2452 * optout, then treat below as unsigned */ 2453 case sec_status_secure: 2454 verbose(VERB_DETAIL, "NSEC3s for the " 2455 "referral proved no DS."); 2456 *ke = key_entry_create_null(qstate->region, 2457 qinfo->qname, qinfo->qname_len, 2458 qinfo->qclass, proof_ttl, 2459 *qstate->env->now); 2460 return (*ke) != NULL; 2461 case sec_status_indeterminate: 2462 verbose(VERB_DETAIL, "NSEC3s for the " 2463 "referral proved no delegation"); 2464 *ke = NULL; 2465 return 1; 2466 case sec_status_bogus: 2467 verbose(VERB_DETAIL, "NSEC3s for the " 2468 "referral did not prove no DS."); 2469 errinf(qstate, reason); 2470 goto return_bogus; 2471 case sec_status_unchecked: 2472 default: 2473 /* NSEC3 proof did not work */ 2474 break; 2475 } 2476 2477 /* Apparently, no available NSEC/NSEC3 proved NODATA, so 2478 * this is BOGUS. */ 2479 verbose(VERB_DETAIL, "DS %s ran out of options, so return " 2480 "bogus", val_classification_to_string(subtype)); 2481 errinf(qstate, "no DS but also no proof of that"); 2482 goto return_bogus; 2483 } else if(subtype == VAL_CLASS_CNAME || 2484 subtype == VAL_CLASS_CNAMENOANSWER) { 2485 /* if the CNAME matches the exact name we want and is signed 2486 * properly, then also, we are sure that no DS exists there, 2487 * much like a NODATA proof */ 2488 enum sec_status sec; 2489 struct ub_packed_rrset_key* cname; 2490 cname = reply_find_rrset_section_an(msg->rep, qinfo->qname, 2491 qinfo->qname_len, LDNS_RR_TYPE_CNAME, qinfo->qclass); 2492 if(!cname) { 2493 errinf(qstate, "validator classified CNAME but no " 2494 "CNAME of the queried name for DS"); 2495 goto return_bogus; 2496 } 2497 if(((struct packed_rrset_data*)cname->entry.data)->rrsig_count 2498 == 0) { 2499 if(msg->rep->an_numrrsets != 0 && ntohs(msg->rep-> 2500 rrsets[0]->rk.type)==LDNS_RR_TYPE_DNAME) { 2501 errinf(qstate, "DS got DNAME answer"); 2502 } else { 2503 errinf(qstate, "DS got unsigned CNAME answer"); 2504 } 2505 goto return_bogus; 2506 } 2507 sec = val_verify_rrset_entry(qstate->env, ve, cname, 2508 vq->key_entry, &reason); 2509 if(sec == sec_status_secure) { 2510 verbose(VERB_ALGO, "CNAME validated, " 2511 "proof that DS does not exist"); 2512 /* and that it is not a referral point */ 2513 *ke = NULL; 2514 return 1; 2515 } 2516 errinf(qstate, "CNAME in DS response was not secure."); 2517 errinf(qstate, reason); 2518 goto return_bogus; 2519 } else { 2520 verbose(VERB_QUERY, "Encountered an unhandled type of " 2521 "DS response, thus bogus."); 2522 errinf(qstate, "no DS and"); 2523 if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) { 2524 char* rc = ldns_pkt_rcode2str( 2525 FLAGS_GET_RCODE(msg->rep->flags)); 2526 errinf(qstate, rc); 2527 free(rc); 2528 } else errinf(qstate, val_classification_to_string(subtype)); 2529 errinf(qstate, "message fails to prove that"); 2530 goto return_bogus; 2531 } 2532 return_bogus: 2533 *ke = key_entry_create_bad(qstate->region, qinfo->qname, 2534 qinfo->qname_len, qinfo->qclass, 2535 BOGUS_KEY_TTL, *qstate->env->now); 2536 return (*ke) != NULL; 2537 } 2538 2539 /** 2540 * Process DS response. Called from inform_supers. 2541 * Because it is in inform_supers, the mesh itself is busy doing callbacks 2542 * for a state that is to be deleted soon; don't touch the mesh; instead 2543 * set a state in the super, as the super will be reactivated soon. 2544 * Perform processing to determine what state to set in the super. 2545 * 2546 * @param qstate: query state that is validating and asked for a DS. 2547 * @param vq: validator query state 2548 * @param id: module id. 2549 * @param rcode: rcode result value. 2550 * @param msg: result message (if rcode is OK). 2551 * @param qinfo: from the sub query state, query info. 2552 * @param origin: the origin of msg. 2553 */ 2554 static void 2555 process_ds_response(struct module_qstate* qstate, struct val_qstate* vq, 2556 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2557 struct sock_list* origin) 2558 { 2559 struct key_entry_key* dske = NULL; 2560 uint8_t* olds = vq->empty_DS_name; 2561 vq->empty_DS_name = NULL; 2562 if(!ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske)) { 2563 log_err("malloc failure in process_ds_response"); 2564 vq->key_entry = NULL; /* make it error */ 2565 vq->state = VAL_VALIDATE_STATE; 2566 return; 2567 } 2568 if(dske == NULL) { 2569 vq->empty_DS_name = regional_alloc_init(qstate->region, 2570 qinfo->qname, qinfo->qname_len); 2571 if(!vq->empty_DS_name) { 2572 log_err("malloc failure in empty_DS_name"); 2573 vq->key_entry = NULL; /* make it error */ 2574 vq->state = VAL_VALIDATE_STATE; 2575 return; 2576 } 2577 vq->empty_DS_len = qinfo->qname_len; 2578 vq->chain_blacklist = NULL; 2579 /* ds response indicated that we aren't on a delegation point. 2580 * Keep the forState.state on FINDKEY. */ 2581 } else if(key_entry_isgood(dske)) { 2582 vq->ds_rrset = key_entry_get_rrset(dske, qstate->region); 2583 if(!vq->ds_rrset) { 2584 log_err("malloc failure in process DS"); 2585 vq->key_entry = NULL; /* make it error */ 2586 vq->state = VAL_VALIDATE_STATE; 2587 return; 2588 } 2589 vq->chain_blacklist = NULL; /* fresh blacklist for next part*/ 2590 /* Keep the forState.state on FINDKEY. */ 2591 } else if(key_entry_isbad(dske) 2592 && vq->restart_count < VAL_MAX_RESTART_COUNT) { 2593 vq->empty_DS_name = olds; 2594 val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); 2595 qstate->errinf = NULL; 2596 vq->restart_count++; 2597 } else { 2598 if(key_entry_isbad(dske)) { 2599 errinf_origin(qstate, origin); 2600 errinf_dname(qstate, "for DS", qinfo->qname); 2601 } 2602 /* NOTE: the reason for the DS to be not good (that is, 2603 * either bad or null) should have been logged by 2604 * dsResponseToKE. */ 2605 vq->key_entry = dske; 2606 /* The FINDKEY phase has ended, so move on. */ 2607 vq->state = VAL_VALIDATE_STATE; 2608 } 2609 } 2610 2611 /** 2612 * Process DNSKEY response. Called from inform_supers. 2613 * Sets the key entry in the state. 2614 * Because it is in inform_supers, the mesh itself is busy doing callbacks 2615 * for a state that is to be deleted soon; don't touch the mesh; instead 2616 * set a state in the super, as the super will be reactivated soon. 2617 * Perform processing to determine what state to set in the super. 2618 * 2619 * @param qstate: query state that is validating and asked for a DNSKEY. 2620 * @param vq: validator query state 2621 * @param id: module id. 2622 * @param rcode: rcode result value. 2623 * @param msg: result message (if rcode is OK). 2624 * @param qinfo: from the sub query state, query info. 2625 * @param origin: the origin of msg. 2626 */ 2627 static void 2628 process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq, 2629 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo, 2630 struct sock_list* origin) 2631 { 2632 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2633 struct key_entry_key* old = vq->key_entry; 2634 struct ub_packed_rrset_key* dnskey = NULL; 2635 int downprot; 2636 char* reason = NULL; 2637 2638 if(rcode == LDNS_RCODE_NOERROR) 2639 dnskey = reply_find_answer_rrset(qinfo, msg->rep); 2640 2641 if(dnskey == NULL) { 2642 /* bad response */ 2643 verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to " 2644 "DNSKEY query."); 2645 if(vq->restart_count < VAL_MAX_RESTART_COUNT) { 2646 val_blacklist(&vq->chain_blacklist, qstate->region, 2647 origin, 1); 2648 qstate->errinf = NULL; 2649 vq->restart_count++; 2650 return; 2651 } 2652 vq->key_entry = key_entry_create_bad(qstate->region, 2653 qinfo->qname, qinfo->qname_len, qinfo->qclass, 2654 BOGUS_KEY_TTL, *qstate->env->now); 2655 if(!vq->key_entry) { 2656 log_err("alloc failure in missing dnskey response"); 2657 /* key_entry is NULL for failure in Validate */ 2658 } 2659 errinf(qstate, "No DNSKEY record"); 2660 errinf_origin(qstate, origin); 2661 errinf_dname(qstate, "for key", qinfo->qname); 2662 vq->state = VAL_VALIDATE_STATE; 2663 return; 2664 } 2665 if(!vq->ds_rrset) { 2666 log_err("internal error: no DS rrset for new DNSKEY response"); 2667 vq->key_entry = NULL; 2668 vq->state = VAL_VALIDATE_STATE; 2669 return; 2670 } 2671 downprot = 1; 2672 vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env, 2673 ve, dnskey, vq->ds_rrset, downprot, &reason); 2674 2675 if(!vq->key_entry) { 2676 log_err("out of memory in verify new DNSKEYs"); 2677 vq->state = VAL_VALIDATE_STATE; 2678 return; 2679 } 2680 /* If the key entry isBad or isNull, then we can move on to the next 2681 * state. */ 2682 if(!key_entry_isgood(vq->key_entry)) { 2683 if(key_entry_isbad(vq->key_entry)) { 2684 if(vq->restart_count < VAL_MAX_RESTART_COUNT) { 2685 val_blacklist(&vq->chain_blacklist, 2686 qstate->region, origin, 1); 2687 qstate->errinf = NULL; 2688 vq->restart_count++; 2689 vq->key_entry = old; 2690 return; 2691 } 2692 verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, " 2693 "thus bogus."); 2694 errinf(qstate, reason); 2695 errinf_origin(qstate, origin); 2696 errinf_dname(qstate, "for key", qinfo->qname); 2697 } 2698 vq->chain_blacklist = NULL; 2699 vq->state = VAL_VALIDATE_STATE; 2700 return; 2701 } 2702 vq->chain_blacklist = NULL; 2703 qstate->errinf = NULL; 2704 2705 /* The DNSKEY validated, so cache it as a trusted key rrset. */ 2706 key_cache_insert(ve->kcache, vq->key_entry, qstate); 2707 2708 /* If good, we stay in the FINDKEY state. */ 2709 log_query_info(VERB_DETAIL, "validated DNSKEY", qinfo); 2710 } 2711 2712 /** 2713 * Process prime response 2714 * Sets the key entry in the state. 2715 * 2716 * @param qstate: query state that is validating and primed a trust anchor. 2717 * @param vq: validator query state 2718 * @param id: module id. 2719 * @param rcode: rcode result value. 2720 * @param msg: result message (if rcode is OK). 2721 * @param origin: the origin of msg. 2722 */ 2723 static void 2724 process_prime_response(struct module_qstate* qstate, struct val_qstate* vq, 2725 int id, int rcode, struct dns_msg* msg, struct sock_list* origin) 2726 { 2727 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2728 struct ub_packed_rrset_key* dnskey_rrset = NULL; 2729 struct trust_anchor* ta = anchor_find(qstate->env->anchors, 2730 vq->trust_anchor_name, vq->trust_anchor_labs, 2731 vq->trust_anchor_len, vq->qchase.qclass); 2732 if(!ta) { 2733 /* trust anchor revoked, restart with less anchors */ 2734 vq->state = VAL_INIT_STATE; 2735 if(!vq->trust_anchor_name) 2736 vq->state = VAL_VALIDATE_STATE; /* break a loop */ 2737 vq->trust_anchor_name = NULL; 2738 return; 2739 } 2740 /* Fetch and validate the keyEntry that corresponds to the 2741 * current trust anchor. */ 2742 if(rcode == LDNS_RCODE_NOERROR) { 2743 dnskey_rrset = reply_find_rrset_section_an(msg->rep, 2744 ta->name, ta->namelen, LDNS_RR_TYPE_DNSKEY, 2745 ta->dclass); 2746 } 2747 if(ta->autr) { 2748 if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset)) { 2749 /* trust anchor revoked, restart with less anchors */ 2750 vq->state = VAL_INIT_STATE; 2751 vq->trust_anchor_name = NULL; 2752 return; 2753 } 2754 } 2755 vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id); 2756 lock_basic_unlock(&ta->lock); 2757 if(vq->key_entry) { 2758 if(key_entry_isbad(vq->key_entry) 2759 && vq->restart_count < VAL_MAX_RESTART_COUNT) { 2760 val_blacklist(&vq->chain_blacklist, qstate->region, 2761 origin, 1); 2762 qstate->errinf = NULL; 2763 vq->restart_count++; 2764 vq->key_entry = NULL; 2765 vq->state = VAL_INIT_STATE; 2766 return; 2767 } 2768 vq->chain_blacklist = NULL; 2769 errinf_origin(qstate, origin); 2770 errinf_dname(qstate, "for trust anchor", ta->name); 2771 /* store the freshly primed entry in the cache */ 2772 key_cache_insert(ve->kcache, vq->key_entry, qstate); 2773 } 2774 2775 /* If the result of the prime is a null key, skip the FINDKEY state.*/ 2776 if(!vq->key_entry || key_entry_isnull(vq->key_entry) || 2777 key_entry_isbad(vq->key_entry)) { 2778 vq->state = VAL_VALIDATE_STATE; 2779 } 2780 /* the qstate will be reactivated after inform_super is done */ 2781 } 2782 2783 /** 2784 * Process DLV response. Called from inform_supers. 2785 * Because it is in inform_supers, the mesh itself is busy doing callbacks 2786 * for a state that is to be deleted soon; don't touch the mesh; instead 2787 * set a state in the super, as the super will be reactivated soon. 2788 * Perform processing to determine what state to set in the super. 2789 * 2790 * @param qstate: query state that is validating and asked for a DLV. 2791 * @param vq: validator query state 2792 * @param id: module id. 2793 * @param rcode: rcode result value. 2794 * @param msg: result message (if rcode is OK). 2795 * @param qinfo: from the sub query state, query info. 2796 */ 2797 static void 2798 process_dlv_response(struct module_qstate* qstate, struct val_qstate* vq, 2799 int id, int rcode, struct dns_msg* msg, struct query_info* qinfo) 2800 { 2801 struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; 2802 2803 verbose(VERB_ALGO, "process dlv response to super"); 2804 if(rcode != LDNS_RCODE_NOERROR) { 2805 /* lookup failed, set in vq to give up */ 2806 vq->dlv_status = dlv_error; 2807 verbose(VERB_ALGO, "response is error"); 2808 return; 2809 } 2810 if(msg->rep->security != sec_status_secure) { 2811 vq->dlv_status = dlv_error; 2812 verbose(VERB_ALGO, "response is not secure, %s", 2813 sec_status_to_string(msg->rep->security)); 2814 return; 2815 } 2816 /* was the lookup a success? validated DLV? */ 2817 if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NOERROR && 2818 msg->rep->an_numrrsets == 1 && 2819 msg->rep->security == sec_status_secure && 2820 ntohs(msg->rep->rrsets[0]->rk.type) == LDNS_RR_TYPE_DLV && 2821 ntohs(msg->rep->rrsets[0]->rk.rrset_class) == qinfo->qclass && 2822 query_dname_compare(msg->rep->rrsets[0]->rk.dname, 2823 vq->dlv_lookup_name) == 0) { 2824 /* yay! it is just like a DS */ 2825 vq->ds_rrset = (struct ub_packed_rrset_key*) 2826 regional_alloc_init(qstate->region, 2827 msg->rep->rrsets[0], sizeof(*vq->ds_rrset)); 2828 if(!vq->ds_rrset) { 2829 log_err("out of memory in process_dlv"); 2830 return; 2831 } 2832 vq->ds_rrset->entry.key = vq->ds_rrset; 2833 vq->ds_rrset->rk.dname = (uint8_t*)regional_alloc_init( 2834 qstate->region, vq->ds_rrset->rk.dname, 2835 vq->ds_rrset->rk.dname_len); 2836 if(!vq->ds_rrset->rk.dname) { 2837 log_err("out of memory in process_dlv"); 2838 vq->dlv_status = dlv_error; 2839 return; 2840 } 2841 vq->ds_rrset->entry.data = regional_alloc_init(qstate->region, 2842 vq->ds_rrset->entry.data, 2843 packed_rrset_sizeof(vq->ds_rrset->entry.data)); 2844 if(!vq->ds_rrset->entry.data) { 2845 log_err("out of memory in process_dlv"); 2846 vq->dlv_status = dlv_error; 2847 return; 2848 } 2849 packed_rrset_ptr_fixup(vq->ds_rrset->entry.data); 2850 /* make vq do a DNSKEY query next up */ 2851 vq->dlv_status = dlv_success; 2852 return; 2853 } 2854 /* store NSECs into negative cache */ 2855 val_neg_addreply(ve->neg_cache, msg->rep); 2856 2857 /* was the lookup a failure? 2858 * if we have to go up into the DLV for a higher DLV anchor 2859 * then set this in the vq, so it can make queries when activated. 2860 * See if the NSECs indicate that we should look for higher DLV 2861 * or, that there is no DLV securely */ 2862 if(!val_nsec_check_dlv(qinfo, msg->rep, &vq->dlv_lookup_name, 2863 &vq->dlv_lookup_name_len)) { 2864 vq->dlv_status = dlv_error; 2865 verbose(VERB_ALGO, "nsec error"); 2866 return; 2867 } 2868 if(!dname_subdomain_c(vq->dlv_lookup_name, 2869 qstate->env->anchors->dlv_anchor->name)) { 2870 vq->dlv_status = dlv_there_is_no_dlv; 2871 return; 2872 } 2873 vq->dlv_status = dlv_ask_higher; 2874 } 2875 2876 /* 2877 * inform validator super. 2878 * 2879 * @param qstate: query state that finished. 2880 * @param id: module id. 2881 * @param super: the qstate to inform. 2882 */ 2883 void 2884 val_inform_super(struct module_qstate* qstate, int id, 2885 struct module_qstate* super) 2886 { 2887 struct val_qstate* vq = (struct val_qstate*)super->minfo[id]; 2888 log_query_info(VERB_ALGO, "validator: inform_super, sub is", 2889 &qstate->qinfo); 2890 log_query_info(VERB_ALGO, "super is", &super->qinfo); 2891 if(!vq) { 2892 verbose(VERB_ALGO, "super: has no validator state"); 2893 return; 2894 } 2895 if(vq->wait_prime_ta) { 2896 vq->wait_prime_ta = 0; 2897 process_prime_response(super, vq, id, qstate->return_rcode, 2898 qstate->return_msg, qstate->reply_origin); 2899 return; 2900 } 2901 if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) { 2902 process_ds_response(super, vq, id, qstate->return_rcode, 2903 qstate->return_msg, &qstate->qinfo, 2904 qstate->reply_origin); 2905 return; 2906 } else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) { 2907 process_dnskey_response(super, vq, id, qstate->return_rcode, 2908 qstate->return_msg, &qstate->qinfo, 2909 qstate->reply_origin); 2910 return; 2911 } else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DLV) { 2912 process_dlv_response(super, vq, id, qstate->return_rcode, 2913 qstate->return_msg, &qstate->qinfo); 2914 return; 2915 } 2916 log_err("internal error in validator: no inform_supers possible"); 2917 } 2918 2919 void 2920 val_clear(struct module_qstate* qstate, int id) 2921 { 2922 if(!qstate) 2923 return; 2924 /* everything is allocated in the region, so assign NULL */ 2925 qstate->minfo[id] = NULL; 2926 } 2927 2928 size_t 2929 val_get_mem(struct module_env* env, int id) 2930 { 2931 struct val_env* ve = (struct val_env*)env->modinfo[id]; 2932 if(!ve) 2933 return 0; 2934 return sizeof(*ve) + key_cache_get_mem(ve->kcache) + 2935 val_neg_get_mem(ve->neg_cache) + 2936 sizeof(size_t)*2*ve->nsec3_keyiter_count; 2937 } 2938 2939 /** 2940 * The validator function block 2941 */ 2942 static struct module_func_block val_block = { 2943 "validator", 2944 &val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear, 2945 &val_get_mem 2946 }; 2947 2948 struct module_func_block* 2949 val_get_funcblock(void) 2950 { 2951 return &val_block; 2952 } 2953 2954 const char* 2955 val_state_to_string(enum val_state state) 2956 { 2957 switch(state) { 2958 case VAL_INIT_STATE: return "VAL_INIT_STATE"; 2959 case VAL_FINDKEY_STATE: return "VAL_FINDKEY_STATE"; 2960 case VAL_VALIDATE_STATE: return "VAL_VALIDATE_STATE"; 2961 case VAL_FINISHED_STATE: return "VAL_FINISHED_STATE"; 2962 case VAL_DLVLOOKUP_STATE: return "VAL_DLVLOOKUP_STATE"; 2963 } 2964 return "UNKNOWN VALIDATOR STATE"; 2965 } 2966 2967