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