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