1 /*
2  * validator/val_sigcrypt.c - validator signature crypto functions.
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 helper functions for the validator module.
40  * The functions help with signature verification and checking, the
41  * bridging between RR wireformat data and crypto calls.
42  */
43 #include "config.h"
44 #include "validator/val_sigcrypt.h"
45 #include "validator/val_secalgo.h"
46 #include "validator/validator.h"
47 #include "util/data/msgreply.h"
48 #include "util/data/msgparse.h"
49 #include "util/data/dname.h"
50 #include "util/rbtree.h"
51 #include "util/rfc_1982.h"
52 #include "util/module.h"
53 #include "util/net_help.h"
54 #include "util/regional.h"
55 #include "util/config_file.h"
56 #include "sldns/keyraw.h"
57 #include "sldns/sbuffer.h"
58 #include "sldns/parseutil.h"
59 #include "sldns/wire2str.h"
60 
61 #include <ctype.h>
62 #if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
63 #error "Need crypto library to do digital signature cryptography"
64 #endif
65 
66 #ifdef HAVE_OPENSSL_ERR_H
67 #include <openssl/err.h>
68 #endif
69 
70 #ifdef HAVE_OPENSSL_RAND_H
71 #include <openssl/rand.h>
72 #endif
73 
74 #ifdef HAVE_OPENSSL_CONF_H
75 #include <openssl/conf.h>
76 #endif
77 
78 #ifdef HAVE_OPENSSL_ENGINE_H
79 #include <openssl/engine.h>
80 #endif
81 
82 /** return number of rrs in an rrset */
83 static size_t
84 rrset_get_count(struct ub_packed_rrset_key* rrset)
85 {
86 	struct packed_rrset_data* d = (struct packed_rrset_data*)
87 	rrset->entry.data;
88 	if(!d) return 0;
89 	return d->count;
90 }
91 
92 /**
93  * Get RR signature count
94  */
95 static size_t
96 rrset_get_sigcount(struct ub_packed_rrset_key* k)
97 {
98 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
99 	return d->rrsig_count;
100 }
101 
102 /**
103  * Get signature keytag value
104  * @param k: rrset (with signatures)
105  * @param sig_idx: signature index.
106  * @return keytag or 0 if malformed rrsig.
107  */
108 static uint16_t
109 rrset_get_sig_keytag(struct ub_packed_rrset_key* k, size_t sig_idx)
110 {
111 	uint16_t t;
112 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
113 	log_assert(sig_idx < d->rrsig_count);
114 	if(d->rr_len[d->count + sig_idx] < 2+18)
115 		return 0;
116 	memmove(&t, d->rr_data[d->count + sig_idx]+2+16, 2);
117 	return ntohs(t);
118 }
119 
120 /**
121  * Get signature signing algorithm value
122  * @param k: rrset (with signatures)
123  * @param sig_idx: signature index.
124  * @return algo or 0 if malformed rrsig.
125  */
126 static int
127 rrset_get_sig_algo(struct ub_packed_rrset_key* k, size_t sig_idx)
128 {
129 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
130 	log_assert(sig_idx < d->rrsig_count);
131 	if(d->rr_len[d->count + sig_idx] < 2+3)
132 		return 0;
133 	return (int)d->rr_data[d->count + sig_idx][2+2];
134 }
135 
136 /** get rdata pointer and size */
137 static void
138 rrset_get_rdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** rdata,
139 	size_t* len)
140 {
141 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
142 	log_assert(d && idx < (d->count + d->rrsig_count));
143 	*rdata = d->rr_data[idx];
144 	*len = d->rr_len[idx];
145 }
146 
147 uint16_t
148 dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx)
149 {
150 	uint8_t* rdata;
151 	size_t len;
152 	uint16_t f;
153 	rrset_get_rdata(k, idx, &rdata, &len);
154 	if(len < 2+2)
155 		return 0;
156 	memmove(&f, rdata+2, 2);
157 	f = ntohs(f);
158 	return f;
159 }
160 
161 /**
162  * Get DNSKEY protocol value from rdata
163  * @param k: DNSKEY rrset.
164  * @param idx: which key.
165  * @return protocol octet value
166  */
167 static int
168 dnskey_get_protocol(struct ub_packed_rrset_key* k, size_t idx)
169 {
170 	uint8_t* rdata;
171 	size_t len;
172 	rrset_get_rdata(k, idx, &rdata, &len);
173 	if(len < 2+4)
174 		return 0;
175 	return (int)rdata[2+2];
176 }
177 
178 int
179 dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx)
180 {
181 	uint8_t* rdata;
182 	size_t len;
183 	rrset_get_rdata(k, idx, &rdata, &len);
184 	if(len < 2+4)
185 		return 0;
186 	return (int)rdata[2+3];
187 }
188 
189 /** get public key rdata field from a dnskey RR and do some checks */
190 static void
191 dnskey_get_pubkey(struct ub_packed_rrset_key* k, size_t idx,
192 	unsigned char** pk, unsigned int* pklen)
193 {
194 	uint8_t* rdata;
195 	size_t len;
196 	rrset_get_rdata(k, idx, &rdata, &len);
197 	if(len < 2+5) {
198 		*pk = NULL;
199 		*pklen = 0;
200 		return;
201 	}
202 	*pk = (unsigned char*)rdata+2+4;
203 	*pklen = (unsigned)len-2-4;
204 }
205 
206 int
207 ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx)
208 {
209 	uint8_t* rdata;
210 	size_t len;
211 	rrset_get_rdata(k, idx, &rdata, &len);
212 	if(len < 2+3)
213 		return 0;
214 	return (int)rdata[2+2];
215 }
216 
217 int
218 ds_get_digest_algo(struct ub_packed_rrset_key* k, size_t idx)
219 {
220 	uint8_t* rdata;
221 	size_t len;
222 	rrset_get_rdata(k, idx, &rdata, &len);
223 	if(len < 2+4)
224 		return 0;
225 	return (int)rdata[2+3];
226 }
227 
228 uint16_t
229 ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx)
230 {
231 	uint16_t t;
232 	uint8_t* rdata;
233 	size_t len;
234 	rrset_get_rdata(ds_rrset, ds_idx, &rdata, &len);
235 	if(len < 2+2)
236 		return 0;
237 	memmove(&t, rdata+2, 2);
238 	return ntohs(t);
239 }
240 
241 /**
242  * Return pointer to the digest in a DS RR.
243  * @param k: DS rrset.
244  * @param idx: which DS.
245  * @param digest: digest data is returned.
246  *	on error, this is NULL.
247  * @param len: length of digest is returned.
248  *	on error, the length is 0.
249  */
250 static void
251 ds_get_sigdata(struct ub_packed_rrset_key* k, size_t idx, uint8_t** digest,
252         size_t* len)
253 {
254 	uint8_t* rdata;
255 	size_t rdlen;
256 	rrset_get_rdata(k, idx, &rdata, &rdlen);
257 	if(rdlen < 2+5) {
258 		*digest = NULL;
259 		*len = 0;
260 		return;
261 	}
262 	*digest = rdata + 2 + 4;
263 	*len = rdlen - 2 - 4;
264 }
265 
266 /**
267  * Return size of DS digest according to its hash algorithm.
268  * @param k: DS rrset.
269  * @param idx: which DS.
270  * @return size in bytes of digest, or 0 if not supported.
271  */
272 static size_t
273 ds_digest_size_algo(struct ub_packed_rrset_key* k, size_t idx)
274 {
275 	return ds_digest_size_supported(ds_get_digest_algo(k, idx));
276 }
277 
278 /**
279  * Create a DS digest for a DNSKEY entry.
280  *
281  * @param env: module environment. Uses scratch space.
282  * @param dnskey_rrset: DNSKEY rrset.
283  * @param dnskey_idx: index of RR in rrset.
284  * @param ds_rrset: DS rrset
285  * @param ds_idx: index of RR in DS rrset.
286  * @param digest: digest is returned in here (must be correctly sized).
287  * @return false on error.
288  */
289 static int
290 ds_create_dnskey_digest(struct module_env* env,
291 	struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx,
292 	struct ub_packed_rrset_key* ds_rrset, size_t ds_idx,
293 	uint8_t* digest)
294 {
295 	sldns_buffer* b = env->scratch_buffer;
296 	uint8_t* dnskey_rdata;
297 	size_t dnskey_len;
298 	rrset_get_rdata(dnskey_rrset, dnskey_idx, &dnskey_rdata, &dnskey_len);
299 
300 	/* create digest source material in buffer
301 	 * digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
302 	 *	DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. */
303 	sldns_buffer_clear(b);
304 	sldns_buffer_write(b, dnskey_rrset->rk.dname,
305 		dnskey_rrset->rk.dname_len);
306 	query_dname_tolower(sldns_buffer_begin(b));
307 	sldns_buffer_write(b, dnskey_rdata+2, dnskey_len-2); /* skip rdatalen*/
308 	sldns_buffer_flip(b);
309 
310 	return secalgo_ds_digest(ds_get_digest_algo(ds_rrset, ds_idx),
311 		(unsigned char*)sldns_buffer_begin(b), sldns_buffer_limit(b),
312 		(unsigned char*)digest);
313 }
314 
315 int ds_digest_match_dnskey(struct module_env* env,
316 	struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx,
317 	struct ub_packed_rrset_key* ds_rrset, size_t ds_idx)
318 {
319 	uint8_t* ds;	/* DS digest */
320 	size_t dslen;
321 	uint8_t* digest; /* generated digest */
322 	size_t digestlen = ds_digest_size_algo(ds_rrset, ds_idx);
323 
324 	if(digestlen == 0) {
325 		verbose(VERB_QUERY, "DS fail: not supported, or DS RR "
326 			"format error");
327 		return 0; /* not supported, or DS RR format error */
328 	}
329 #ifndef USE_SHA1
330 	if(fake_sha1 && ds_get_digest_algo(ds_rrset, ds_idx)==LDNS_SHA1)
331 		return 1;
332 #endif
333 
334 	/* check digest length in DS with length from hash function */
335 	ds_get_sigdata(ds_rrset, ds_idx, &ds, &dslen);
336 	if(!ds || dslen != digestlen) {
337 		verbose(VERB_QUERY, "DS fail: DS RR algo and digest do not "
338 			"match each other");
339 		return 0; /* DS algorithm and digest do not match */
340 	}
341 
342 	digest = regional_alloc(env->scratch, digestlen);
343 	if(!digest) {
344 		verbose(VERB_QUERY, "DS fail: out of memory");
345 		return 0; /* mem error */
346 	}
347 	if(!ds_create_dnskey_digest(env, dnskey_rrset, dnskey_idx, ds_rrset,
348 		ds_idx, digest)) {
349 		verbose(VERB_QUERY, "DS fail: could not calc key digest");
350 		return 0; /* digest algo failed */
351 	}
352 	if(memcmp(digest, ds, dslen) != 0) {
353 		verbose(VERB_QUERY, "DS fail: digest is different");
354 		return 0; /* digest different */
355 	}
356 	return 1;
357 }
358 
359 int
360 ds_digest_algo_is_supported(struct ub_packed_rrset_key* ds_rrset,
361 	size_t ds_idx)
362 {
363 	return (ds_digest_size_algo(ds_rrset, ds_idx) != 0);
364 }
365 
366 int
367 ds_key_algo_is_supported(struct ub_packed_rrset_key* ds_rrset,
368 	size_t ds_idx)
369 {
370 	return dnskey_algo_id_is_supported(ds_get_key_algo(ds_rrset, ds_idx));
371 }
372 
373 uint16_t
374 dnskey_calc_keytag(struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx)
375 {
376 	uint8_t* data;
377 	size_t len;
378 	rrset_get_rdata(dnskey_rrset, dnskey_idx, &data, &len);
379 	/* do not pass rdatalen to ldns */
380 	return sldns_calc_keytag_raw(data+2, len-2);
381 }
382 
383 int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
384         size_t dnskey_idx)
385 {
386 	return dnskey_algo_id_is_supported(dnskey_get_algo(dnskey_rrset,
387 		dnskey_idx));
388 }
389 
390 int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
391 	size_t dnskey_idx)
392 {
393 #ifdef DEPRECATE_RSA_1024
394 	uint8_t* rdata;
395 	size_t len;
396 	int alg = dnskey_get_algo(dnskey_rrset, dnskey_idx);
397 	size_t keysize;
398 
399 	rrset_get_rdata(dnskey_rrset, dnskey_idx, &rdata, &len);
400 	if(len < 2+4)
401 		return 0;
402 	keysize = sldns_rr_dnskey_key_size_raw(rdata+2+4, len-2-4, alg);
403 
404 	switch((sldns_algorithm)alg) {
405 	case LDNS_RSAMD5:
406 	case LDNS_RSASHA1:
407 	case LDNS_RSASHA1_NSEC3:
408 	case LDNS_RSASHA256:
409 	case LDNS_RSASHA512:
410 		/* reject RSA keys of 1024 bits and shorter */
411 		if(keysize <= 1024)
412 			return 0;
413 		break;
414 	default:
415 		break;
416 	}
417 #else
418 	(void)dnskey_rrset; (void)dnskey_idx;
419 #endif /* DEPRECATE_RSA_1024 */
420 	return 1;
421 }
422 
423 int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset)
424 {
425 	size_t i, num = rrset_get_count(dnskey_rrset);
426 	for(i=0; i<num; i++) {
427 		if(!dnskey_size_is_supported(dnskey_rrset, i))
428 			return 0;
429 	}
430 	return 1;
431 }
432 
433 void algo_needs_init_dnskey_add(struct algo_needs* n,
434         struct ub_packed_rrset_key* dnskey, uint8_t* sigalg)
435 {
436 	uint8_t algo;
437 	size_t i, total = n->num;
438 	size_t num = rrset_get_count(dnskey);
439 
440 	for(i=0; i<num; i++) {
441 		algo = (uint8_t)dnskey_get_algo(dnskey, i);
442 		if(!dnskey_algo_id_is_supported((int)algo))
443 			continue;
444 		if(n->needs[algo] == 0) {
445 			n->needs[algo] = 1;
446 			sigalg[total] = algo;
447 			total++;
448 		}
449 	}
450 	sigalg[total] = 0;
451 	n->num = total;
452 }
453 
454 void algo_needs_init_list(struct algo_needs* n, uint8_t* sigalg)
455 {
456 	uint8_t algo;
457 	size_t total = 0;
458 
459 	memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX);
460 	while( (algo=*sigalg++) != 0) {
461 		log_assert(dnskey_algo_id_is_supported((int)algo));
462 		log_assert(n->needs[algo] == 0);
463 		n->needs[algo] = 1;
464 		total++;
465 	}
466 	n->num = total;
467 }
468 
469 void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds,
470 	int fav_ds_algo, uint8_t* sigalg)
471 {
472 	uint8_t algo;
473 	size_t i, total = 0;
474 	size_t num = rrset_get_count(ds);
475 
476 	memset(n->needs, 0, sizeof(uint8_t)*ALGO_NEEDS_MAX);
477 	for(i=0; i<num; i++) {
478 		if(ds_get_digest_algo(ds, i) != fav_ds_algo)
479 			continue;
480 		algo = (uint8_t)ds_get_key_algo(ds, i);
481 		if(!dnskey_algo_id_is_supported((int)algo))
482 			continue;
483 		log_assert(algo != 0); /* we do not support 0 and is EOS */
484 		if(n->needs[algo] == 0) {
485 			n->needs[algo] = 1;
486 			sigalg[total] = algo;
487 			total++;
488 		}
489 	}
490 	sigalg[total] = 0;
491 	n->num = total;
492 }
493 
494 int algo_needs_set_secure(struct algo_needs* n, uint8_t algo)
495 {
496 	if(n->needs[algo]) {
497 		n->needs[algo] = 0;
498 		n->num --;
499 		if(n->num == 0) /* done! */
500 			return 1;
501 	}
502 	return 0;
503 }
504 
505 void algo_needs_set_bogus(struct algo_needs* n, uint8_t algo)
506 {
507 	if(n->needs[algo]) n->needs[algo] = 2; /* need it, but bogus */
508 }
509 
510 size_t algo_needs_num_missing(struct algo_needs* n)
511 {
512 	return n->num;
513 }
514 
515 int algo_needs_missing(struct algo_needs* n)
516 {
517 	int i, miss = -1;
518 	/* check if a needed algo was bogus - report that;
519 	 * check the first missing algo - report that;
520 	 * or return 0 */
521 	for(i=0; i<ALGO_NEEDS_MAX; i++) {
522 		if(n->needs[i] == 2)
523 			return 0;
524 		if(n->needs[i] == 1 && miss == -1)
525 			miss = i;
526 	}
527 	if(miss != -1) return miss;
528 	return 0;
529 }
530 
531 /**
532  * verify rrset, with dnskey rrset, for a specific rrsig in rrset
533  * @param env: module environment, scratch space is used.
534  * @param ve: validator environment, date settings.
535  * @param now: current time for validation (can be overridden).
536  * @param rrset: to be validated.
537  * @param dnskey: DNSKEY rrset, keyset to try.
538  * @param sig_idx: which signature to try to validate.
539  * @param sortree: reused sorted order. Stored in region. Pass NULL at start,
540  * 	and for a new rrset.
541  * @param reason: if bogus, a string returned, fixed or alloced in scratch.
542  * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
543  * @param section: section of packet where this rrset comes from.
544  * @param qstate: qstate with region.
545  * @return secure if any key signs *this* signature. bogus if no key signs it,
546  *	unchecked on error, or indeterminate if all keys are not supported by
547  *	the crypto library (openssl3+ only).
548  */
549 static enum sec_status
550 dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
551 	time_t now, struct ub_packed_rrset_key* rrset,
552 	struct ub_packed_rrset_key* dnskey, size_t sig_idx,
553 	struct rbtree_type** sortree,
554 	char** reason, sldns_ede_code *reason_bogus,
555 	sldns_pkt_section section, struct module_qstate* qstate)
556 {
557 	/* find matching keys and check them */
558 	enum sec_status sec = sec_status_bogus;
559 	uint16_t tag = rrset_get_sig_keytag(rrset, sig_idx);
560 	int algo = rrset_get_sig_algo(rrset, sig_idx);
561 	size_t i, num = rrset_get_count(dnskey);
562 	size_t numchecked = 0;
563 	size_t numindeterminate = 0;
564 	int buf_canon = 0;
565 	verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
566 	if(!dnskey_algo_id_is_supported(algo)) {
567 		if(reason_bogus)
568 			*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
569 		verbose(VERB_QUERY, "verify sig: unknown algorithm");
570 		return sec_status_insecure;
571 	}
572 
573 	for(i=0; i<num; i++) {
574 		/* see if key matches keytag and algo */
575 		if(algo != dnskey_get_algo(dnskey, i) ||
576 			tag != dnskey_calc_keytag(dnskey, i))
577 			continue;
578 		numchecked ++;
579 
580 		/* see if key verifies */
581 		sec = dnskey_verify_rrset_sig(env->scratch,
582 			env->scratch_buffer, ve, now, rrset, dnskey, i,
583 			sig_idx, sortree, &buf_canon, reason, reason_bogus,
584 			section, qstate);
585 		if(sec == sec_status_secure)
586 			return sec;
587 		else if(sec == sec_status_indeterminate)
588 			numindeterminate ++;
589 	}
590 	if(numchecked == 0) {
591 		*reason = "signatures from unknown keys";
592 		if(reason_bogus)
593 			*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
594 		verbose(VERB_QUERY, "verify: could not find appropriate key");
595 		return sec_status_bogus;
596 	}
597 	if(numindeterminate == numchecked) {
598 		*reason = "unsupported algorithm by crypto library";
599 		if(reason_bogus)
600 			*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
601 		verbose(VERB_ALGO, "verify sig: unsupported algorithm by "
602 			"crypto library");
603 		return sec_status_indeterminate;
604 	}
605 	return sec_status_bogus;
606 }
607 
608 enum sec_status
609 dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
610 	struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
611 	uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
612 	sldns_pkt_section section, struct module_qstate* qstate)
613 {
614 	enum sec_status sec;
615 	size_t i, num;
616 	rbtree_type* sortree = NULL;
617 	/* make sure that for all DNSKEY algorithms there are valid sigs */
618 	struct algo_needs needs;
619 	int alg;
620 
621 	num = rrset_get_sigcount(rrset);
622 	if(num == 0) {
623 		verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
624 			"signatures");
625 		*reason = "no signatures";
626 		if(reason_bogus)
627 			*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
628 		return sec_status_bogus;
629 	}
630 
631 	if(sigalg) {
632 		algo_needs_init_list(&needs, sigalg);
633 		if(algo_needs_num_missing(&needs) == 0) {
634 			verbose(VERB_QUERY, "zone has no known algorithms");
635 			*reason = "zone has no known algorithms";
636 			if(reason_bogus)
637 				*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
638 			return sec_status_insecure;
639 		}
640 	}
641 	for(i=0; i<num; i++) {
642 		sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
643 			dnskey, i, &sortree, reason, reason_bogus,
644 			section, qstate);
645 		/* see which algorithm has been fixed up */
646 		if(sec == sec_status_secure) {
647 			if(!sigalg)
648 				return sec; /* done! */
649 			else if(algo_needs_set_secure(&needs,
650 				(uint8_t)rrset_get_sig_algo(rrset, i)))
651 				return sec; /* done! */
652 		} else if(sigalg && sec == sec_status_bogus) {
653 			algo_needs_set_bogus(&needs,
654 				(uint8_t)rrset_get_sig_algo(rrset, i));
655 		}
656 	}
657 	if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
658 		verbose(VERB_ALGO, "rrset failed to verify: "
659 			"no valid signatures for %d algorithms",
660 			(int)algo_needs_num_missing(&needs));
661 		algo_needs_reason(env, alg, reason, "no signatures");
662 	} else {
663 		verbose(VERB_ALGO, "rrset failed to verify: "
664 			"no valid signatures");
665 	}
666 	return sec_status_bogus;
667 }
668 
669 void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
670 {
671 	char buf[256];
672 	sldns_lookup_table *t = sldns_lookup_by_id(sldns_algorithms, alg);
673 	if(t&&t->name)
674 		snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name);
675 	else	snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s,
676 			(unsigned)alg);
677 	*reason = regional_strdup(env->scratch, buf);
678 	if(!*reason)
679 		*reason = s;
680 }
681 
682 enum sec_status
683 dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
684         struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
685 	size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
686 	sldns_pkt_section section, struct module_qstate* qstate)
687 {
688 	enum sec_status sec;
689 	size_t i, num, numchecked = 0, numindeterminate = 0;
690 	rbtree_type* sortree = NULL;
691 	int buf_canon = 0;
692 	uint16_t tag = dnskey_calc_keytag(dnskey, dnskey_idx);
693 	int algo = dnskey_get_algo(dnskey, dnskey_idx);
694 
695 	num = rrset_get_sigcount(rrset);
696 	if(num == 0) {
697 		verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
698 			"signatures");
699 		*reason = "no signatures";
700 		if(reason_bogus)
701 			*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
702 		return sec_status_bogus;
703 	}
704 	for(i=0; i<num; i++) {
705 		/* see if sig matches keytag and algo */
706 		if(algo != rrset_get_sig_algo(rrset, i) ||
707 			tag != rrset_get_sig_keytag(rrset, i))
708 			continue;
709 		buf_canon = 0;
710 		sec = dnskey_verify_rrset_sig(env->scratch,
711 			env->scratch_buffer, ve, *env->now, rrset,
712 			dnskey, dnskey_idx, i, &sortree, &buf_canon, reason,
713 			reason_bogus, section, qstate);
714 		if(sec == sec_status_secure)
715 			return sec;
716 		numchecked ++;
717 		if(sec == sec_status_indeterminate)
718 			numindeterminate ++;
719 	}
720 	verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
721 	if(!numchecked) {
722 		*reason = "signature for expected key and algorithm missing";
723 		if(reason_bogus)
724 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
725 	} else if(numchecked == numindeterminate) {
726 		verbose(VERB_ALGO, "rrset failed to verify due to algorithm "
727 			"refusal by cryptolib");
728 		if(reason_bogus)
729 			*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
730 		*reason = "algorithm refused by cryptolib";
731 		return sec_status_indeterminate;
732 	}
733 	return sec_status_bogus;
734 }
735 
736 /**
737  * RR entries in a canonical sorted tree of RRs
738  */
739 struct canon_rr {
740 	/** rbtree node, key is this structure */
741 	rbnode_type node;
742 	/** rrset the RR is in */
743 	struct ub_packed_rrset_key* rrset;
744 	/** which RR in the rrset */
745 	size_t rr_idx;
746 };
747 
748 /**
749  * Compare two RR for canonical order, in a field-style sweep.
750  * @param d: rrset data
751  * @param desc: ldns wireformat descriptor.
752  * @param i: first RR to compare
753  * @param j: first RR to compare
754  * @return comparison code.
755  */
756 static int
757 canonical_compare_byfield(struct packed_rrset_data* d,
758 	const sldns_rr_descriptor* desc, size_t i, size_t j)
759 {
760 	/* sweep across rdata, keep track of some state:
761 	 * 	which rr field, and bytes left in field.
762 	 * 	current position in rdata, length left.
763 	 * 	are we in a dname, length left in a label.
764 	 */
765 	int wfi = -1;	/* current wireformat rdata field (rdf) */
766 	int wfj = -1;
767 	uint8_t* di = d->rr_data[i]+2; /* ptr to current rdata byte */
768 	uint8_t* dj = d->rr_data[j]+2;
769 	size_t ilen = d->rr_len[i]-2; /* length left in rdata */
770 	size_t jlen = d->rr_len[j]-2;
771 	int dname_i = 0;  /* true if these bytes are part of a name */
772 	int dname_j = 0;
773 	size_t lablen_i = 0; /* 0 for label length byte,for first byte of rdf*/
774 	size_t lablen_j = 0; /* otherwise remaining length of rdf or label */
775 	int dname_num_i = (int)desc->_dname_count; /* decreased at root label */
776 	int dname_num_j = (int)desc->_dname_count;
777 
778 	/* loop while there are rdata bytes available for both rrs,
779 	 * and still some lowercasing needs to be done; either the dnames
780 	 * have not been reached yet, or they are currently being processed */
781 	while(ilen > 0 && jlen > 0 && (dname_num_i > 0 || dname_num_j > 0)) {
782 		/* compare these two bytes */
783 		/* lowercase if in a dname and not a label length byte */
784 		if( ((dname_i && lablen_i)?(uint8_t)tolower((int)*di):*di)
785 		 != ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj):*dj)
786 		 ) {
787 		  if(((dname_i && lablen_i)?(uint8_t)tolower((int)*di):*di)
788 		  < ((dname_j && lablen_j)?(uint8_t)tolower((int)*dj):*dj))
789 		 	return -1;
790 		    return 1;
791 		}
792 		ilen--;
793 		jlen--;
794 		/* bytes are equal */
795 
796 		/* advance field i */
797 		/* lablen 0 means that this byte is the first byte of the
798 		 * next rdata field; inspect this rdata field and setup
799 		 * to process the rest of this rdata field.
800 		 * The reason to first read the byte, then setup the rdf,
801 		 * is that we are then sure the byte is available and short
802 		 * rdata is handled gracefully (even if it is a formerr). */
803 		if(lablen_i == 0) {
804 			if(dname_i) {
805 				/* scan this dname label */
806 				/* capture length to lowercase */
807 				lablen_i = (size_t)*di;
808 				if(lablen_i == 0) {
809 					/* end root label */
810 					dname_i = 0;
811 					dname_num_i--;
812 					/* if dname num is 0, then the
813 					 * remainder is binary only */
814 					if(dname_num_i == 0)
815 						lablen_i = ilen;
816 				}
817 			} else {
818 				/* scan this rdata field */
819 				wfi++;
820 				if(desc->_wireformat[wfi]
821 					== LDNS_RDF_TYPE_DNAME) {
822 					dname_i = 1;
823 					lablen_i = (size_t)*di;
824 					if(lablen_i == 0) {
825 						dname_i = 0;
826 						dname_num_i--;
827 						if(dname_num_i == 0)
828 							lablen_i = ilen;
829 					}
830 				} else if(desc->_wireformat[wfi]
831 					== LDNS_RDF_TYPE_STR)
832 					lablen_i = (size_t)*di;
833 				else	lablen_i = get_rdf_size(
834 					desc->_wireformat[wfi]) - 1;
835 			}
836 		} else	lablen_i--;
837 
838 		/* advance field j; same as for i */
839 		if(lablen_j == 0) {
840 			if(dname_j) {
841 				lablen_j = (size_t)*dj;
842 				if(lablen_j == 0) {
843 					dname_j = 0;
844 					dname_num_j--;
845 					if(dname_num_j == 0)
846 						lablen_j = jlen;
847 				}
848 			} else {
849 				wfj++;
850 				if(desc->_wireformat[wfj]
851 					== LDNS_RDF_TYPE_DNAME) {
852 					dname_j = 1;
853 					lablen_j = (size_t)*dj;
854 					if(lablen_j == 0) {
855 						dname_j = 0;
856 						dname_num_j--;
857 						if(dname_num_j == 0)
858 							lablen_j = jlen;
859 					}
860 				} else if(desc->_wireformat[wfj]
861 					== LDNS_RDF_TYPE_STR)
862 					lablen_j = (size_t)*dj;
863 				else	lablen_j = get_rdf_size(
864 					desc->_wireformat[wfj]) - 1;
865 			}
866 		} else	lablen_j--;
867 		di++;
868 		dj++;
869 	}
870 	/* end of the loop; because we advanced byte by byte; now we have
871 	 * that the rdata has ended, or that there is a binary remainder */
872 	/* shortest first */
873 	if(ilen == 0 && jlen == 0)
874 		return 0;
875 	if(ilen == 0)
876 		return -1;
877 	if(jlen == 0)
878 		return 1;
879 	/* binary remainder, capture comparison in wfi variable */
880 	if((wfi = memcmp(di, dj, (ilen<jlen)?ilen:jlen)) != 0)
881 		return wfi;
882 	if(ilen < jlen)
883 		return -1;
884 	if(jlen < ilen)
885 		return 1;
886 	return 0;
887 }
888 
889 /**
890  * Compare two RRs in the same RRset and determine their relative
891  * canonical order.
892  * @param rrset: the rrset in which to perform compares.
893  * @param i: first RR to compare
894  * @param j: first RR to compare
895  * @return 0 if RR i== RR j, -1 if <, +1 if >.
896  */
897 static int
898 canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
899 {
900 	struct packed_rrset_data* d = (struct packed_rrset_data*)
901 		rrset->entry.data;
902 	const sldns_rr_descriptor* desc;
903 	uint16_t type = ntohs(rrset->rk.type);
904 	size_t minlen;
905 	int c;
906 
907 	if(i==j)
908 		return 0;
909 
910 	switch(type) {
911 		/* These RR types have only a name as RDATA.
912 		 * This name has to be canonicalized.*/
913 		case LDNS_RR_TYPE_NS:
914 		case LDNS_RR_TYPE_MD:
915 		case LDNS_RR_TYPE_MF:
916 		case LDNS_RR_TYPE_CNAME:
917 		case LDNS_RR_TYPE_MB:
918 		case LDNS_RR_TYPE_MG:
919 		case LDNS_RR_TYPE_MR:
920 		case LDNS_RR_TYPE_PTR:
921 		case LDNS_RR_TYPE_DNAME:
922 			/* the wireread function has already checked these
923 			 * dname's for correctness, and this double checks */
924 			if(!dname_valid(d->rr_data[i]+2, d->rr_len[i]-2) ||
925 				!dname_valid(d->rr_data[j]+2, d->rr_len[j]-2))
926 				return 0;
927 			return query_dname_compare(d->rr_data[i]+2,
928 				d->rr_data[j]+2);
929 
930 		/* These RR types have STR and fixed size rdata fields
931 		 * before one or more name fields that need canonicalizing,
932 		 * and after that a byte-for byte remainder can be compared.
933 		 */
934 		/* type starts with the name; remainder is binary compared */
935 		case LDNS_RR_TYPE_NXT:
936 		/* use rdata field formats */
937 		case LDNS_RR_TYPE_MINFO:
938 		case LDNS_RR_TYPE_RP:
939 		case LDNS_RR_TYPE_SOA:
940 		case LDNS_RR_TYPE_RT:
941 		case LDNS_RR_TYPE_AFSDB:
942 		case LDNS_RR_TYPE_KX:
943 		case LDNS_RR_TYPE_MX:
944 		case LDNS_RR_TYPE_SIG:
945 		/* RRSIG signer name has to be downcased */
946 		case LDNS_RR_TYPE_RRSIG:
947 		case LDNS_RR_TYPE_PX:
948 		case LDNS_RR_TYPE_NAPTR:
949 		case LDNS_RR_TYPE_SRV:
950 			desc = sldns_rr_descript(type);
951 			log_assert(desc);
952 			/* this holds for the types that need canonicalizing */
953 			log_assert(desc->_minimum == desc->_maximum);
954 			return canonical_compare_byfield(d, desc, i, j);
955 
956 		case LDNS_RR_TYPE_HINFO: /* no longer downcased */
957 		case LDNS_RR_TYPE_NSEC:
958 	default:
959 		/* For unknown RR types, or types not listed above,
960 		 * no canonicalization is needed, do binary compare */
961 		/* byte for byte compare, equal means shortest first*/
962 		minlen = d->rr_len[i]-2;
963 		if(minlen > d->rr_len[j]-2)
964 			minlen = d->rr_len[j]-2;
965 		c = memcmp(d->rr_data[i]+2, d->rr_data[j]+2, minlen);
966 		if(c!=0)
967 			return c;
968 		/* rdata equal, shortest is first */
969 		if(d->rr_len[i] < d->rr_len[j])
970 			return -1;
971 		if(d->rr_len[i] > d->rr_len[j])
972 			return 1;
973 		/* rdata equal, length equal */
974 		break;
975 	}
976 	return 0;
977 }
978 
979 int
980 canonical_tree_compare(const void* k1, const void* k2)
981 {
982 	struct canon_rr* r1 = (struct canon_rr*)k1;
983 	struct canon_rr* r2 = (struct canon_rr*)k2;
984 	log_assert(r1->rrset == r2->rrset);
985 	return canonical_compare(r1->rrset, r1->rr_idx, r2->rr_idx);
986 }
987 
988 /**
989  * Sort RRs for rrset in canonical order.
990  * Does not actually canonicalize the RR rdatas.
991  * Does not touch rrsigs.
992  * @param rrset: to sort.
993  * @param d: rrset data.
994  * @param sortree: tree to sort into.
995  * @param rrs: rr storage.
996  */
997 static void
998 canonical_sort(struct ub_packed_rrset_key* rrset, struct packed_rrset_data* d,
999 	rbtree_type* sortree, struct canon_rr* rrs)
1000 {
1001 	size_t i;
1002 	/* insert into rbtree to sort and detect duplicates */
1003 	for(i=0; i<d->count; i++) {
1004 		rrs[i].node.key = &rrs[i];
1005 		rrs[i].rrset = rrset;
1006 		rrs[i].rr_idx = i;
1007 		if(!rbtree_insert(sortree, &rrs[i].node)) {
1008 			/* this was a duplicate */
1009 		}
1010 	}
1011 }
1012 
1013 /**
1014  * Insert canonical owner name into buffer.
1015  * @param buf: buffer to insert into at current position.
1016  * @param k: rrset with its owner name.
1017  * @param sig: signature with signer name and label count.
1018  * 	must be length checked, at least 18 bytes long.
1019  * @param can_owner: position in buffer returned for future use.
1020  * @param can_owner_len: length of canonical owner name.
1021  */
1022 static void
1023 insert_can_owner(sldns_buffer* buf, struct ub_packed_rrset_key* k,
1024 	uint8_t* sig, uint8_t** can_owner, size_t* can_owner_len)
1025 {
1026 	int rrsig_labels = (int)sig[3];
1027 	int fqdn_labels = dname_signame_label_count(k->rk.dname);
1028 	*can_owner = sldns_buffer_current(buf);
1029 	if(rrsig_labels == fqdn_labels) {
1030 		/* no change */
1031 		sldns_buffer_write(buf, k->rk.dname, k->rk.dname_len);
1032 		query_dname_tolower(*can_owner);
1033 		*can_owner_len = k->rk.dname_len;
1034 		return;
1035 	}
1036 	log_assert(rrsig_labels < fqdn_labels);
1037 	/* *. | fqdn(rightmost rrsig_labels) */
1038 	if(rrsig_labels < fqdn_labels) {
1039 		int i;
1040 		uint8_t* nm = k->rk.dname;
1041 		size_t len = k->rk.dname_len;
1042 		/* so skip fqdn_labels-rrsig_labels */
1043 		for(i=0; i<fqdn_labels-rrsig_labels; i++) {
1044 			dname_remove_label(&nm, &len);
1045 		}
1046 		*can_owner_len = len+2;
1047 		sldns_buffer_write(buf, (uint8_t*)"\001*", 2);
1048 		sldns_buffer_write(buf, nm, len);
1049 		query_dname_tolower(*can_owner);
1050 	}
1051 }
1052 
1053 /**
1054  * Canonicalize Rdata in buffer.
1055  * @param buf: buffer at position just after the rdata.
1056  * @param rrset: rrset with type.
1057  * @param len: length of the rdata (including rdatalen uint16).
1058  */
1059 static void
1060 canonicalize_rdata(sldns_buffer* buf, struct ub_packed_rrset_key* rrset,
1061 	size_t len)
1062 {
1063 	uint8_t* datstart = sldns_buffer_current(buf)-len+2;
1064 	switch(ntohs(rrset->rk.type)) {
1065 		case LDNS_RR_TYPE_NXT:
1066 		case LDNS_RR_TYPE_NS:
1067 		case LDNS_RR_TYPE_MD:
1068 		case LDNS_RR_TYPE_MF:
1069 		case LDNS_RR_TYPE_CNAME:
1070 		case LDNS_RR_TYPE_MB:
1071 		case LDNS_RR_TYPE_MG:
1072 		case LDNS_RR_TYPE_MR:
1073 		case LDNS_RR_TYPE_PTR:
1074 		case LDNS_RR_TYPE_DNAME:
1075 			/* type only has a single argument, the name */
1076 			query_dname_tolower(datstart);
1077 			return;
1078 		case LDNS_RR_TYPE_MINFO:
1079 		case LDNS_RR_TYPE_RP:
1080 		case LDNS_RR_TYPE_SOA:
1081 			/* two names after another */
1082 			query_dname_tolower(datstart);
1083 			query_dname_tolower(datstart +
1084 				dname_valid(datstart, len-2));
1085 			return;
1086 		case LDNS_RR_TYPE_RT:
1087 		case LDNS_RR_TYPE_AFSDB:
1088 		case LDNS_RR_TYPE_KX:
1089 		case LDNS_RR_TYPE_MX:
1090 			/* skip fixed part */
1091 			if(len < 2+2+1) /* rdlen, skiplen, 1byteroot */
1092 				return;
1093 			datstart += 2;
1094 			query_dname_tolower(datstart);
1095 			return;
1096 		case LDNS_RR_TYPE_SIG:
1097 		/* downcase the RRSIG, compat with BIND (kept it from SIG) */
1098 		case LDNS_RR_TYPE_RRSIG:
1099 			/* skip fixed part */
1100 			if(len < 2+18+1)
1101 				return;
1102 			datstart += 18;
1103 			query_dname_tolower(datstart);
1104 			return;
1105 		case LDNS_RR_TYPE_PX:
1106 			/* skip, then two names after another */
1107 			if(len < 2+2+1)
1108 				return;
1109 			datstart += 2;
1110 			query_dname_tolower(datstart);
1111 			query_dname_tolower(datstart +
1112 				dname_valid(datstart, len-2-2));
1113 			return;
1114 		case LDNS_RR_TYPE_NAPTR:
1115 			if(len < 2+4)
1116 				return;
1117 			len -= 2+4;
1118 			datstart += 4;
1119 			if(len < (size_t)datstart[0]+1) /* skip text field */
1120 				return;
1121 			len -= (size_t)datstart[0]+1;
1122 			datstart += (size_t)datstart[0]+1;
1123 			if(len < (size_t)datstart[0]+1) /* skip text field */
1124 				return;
1125 			len -= (size_t)datstart[0]+1;
1126 			datstart += (size_t)datstart[0]+1;
1127 			if(len < (size_t)datstart[0]+1) /* skip text field */
1128 				return;
1129 			len -= (size_t)datstart[0]+1;
1130 			datstart += (size_t)datstart[0]+1;
1131 			if(len < 1)	/* check name is at least 1 byte*/
1132 				return;
1133 			query_dname_tolower(datstart);
1134 			return;
1135 		case LDNS_RR_TYPE_SRV:
1136 			/* skip fixed part */
1137 			if(len < 2+6+1)
1138 				return;
1139 			datstart += 6;
1140 			query_dname_tolower(datstart);
1141 			return;
1142 
1143 		/* do not canonicalize NSEC rdata name, compat with
1144 		 * from bind 9.4 signer, where it does not do so */
1145 		case LDNS_RR_TYPE_NSEC: /* type starts with the name */
1146 		case LDNS_RR_TYPE_HINFO: /* not downcased */
1147 		/* A6 not supported */
1148 		default:
1149 			/* nothing to do for unknown types */
1150 			return;
1151 	}
1152 }
1153 
1154 int rrset_canonical_equal(struct regional* region,
1155 	struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
1156 {
1157 	struct rbtree_type sortree1, sortree2;
1158 	struct canon_rr *rrs1, *rrs2, *p1, *p2;
1159 	struct packed_rrset_data* d1=(struct packed_rrset_data*)k1->entry.data;
1160 	struct packed_rrset_data* d2=(struct packed_rrset_data*)k2->entry.data;
1161 	struct ub_packed_rrset_key fk;
1162 	struct packed_rrset_data fd;
1163 	size_t flen[2];
1164 	uint8_t* fdata[2];
1165 
1166 	/* basic compare */
1167 	if(k1->rk.dname_len != k2->rk.dname_len ||
1168 		k1->rk.flags != k2->rk.flags ||
1169 		k1->rk.type != k2->rk.type ||
1170 		k1->rk.rrset_class != k2->rk.rrset_class ||
1171 		query_dname_compare(k1->rk.dname, k2->rk.dname) != 0)
1172 		return 0;
1173 	if(d1->ttl != d2->ttl ||
1174 		d1->count != d2->count ||
1175 		d1->rrsig_count != d2->rrsig_count ||
1176 		d1->trust != d2->trust ||
1177 		d1->security != d2->security)
1178 		return 0;
1179 
1180 	/* init */
1181 	memset(&fk, 0, sizeof(fk));
1182 	memset(&fd, 0, sizeof(fd));
1183 	fk.entry.data = &fd;
1184 	fd.count = 2;
1185 	fd.rr_len = flen;
1186 	fd.rr_data = fdata;
1187 	rbtree_init(&sortree1, &canonical_tree_compare);
1188 	rbtree_init(&sortree2, &canonical_tree_compare);
1189 	if(d1->count > RR_COUNT_MAX || d2->count > RR_COUNT_MAX)
1190 		return 1; /* protection against integer overflow */
1191 	rrs1 = regional_alloc(region, sizeof(struct canon_rr)*d1->count);
1192 	rrs2 = regional_alloc(region, sizeof(struct canon_rr)*d2->count);
1193 	if(!rrs1 || !rrs2) return 1; /* alloc failure */
1194 
1195 	/* sort */
1196 	canonical_sort(k1, d1, &sortree1, rrs1);
1197 	canonical_sort(k2, d2, &sortree2, rrs2);
1198 
1199 	/* compare canonical-sorted RRs for canonical-equality */
1200 	if(sortree1.count != sortree2.count)
1201 		return 0;
1202 	p1 = (struct canon_rr*)rbtree_first(&sortree1);
1203 	p2 = (struct canon_rr*)rbtree_first(&sortree2);
1204 	while(p1 != (struct canon_rr*)RBTREE_NULL &&
1205 		p2 != (struct canon_rr*)RBTREE_NULL) {
1206 		flen[0] = d1->rr_len[p1->rr_idx];
1207 		flen[1] = d2->rr_len[p2->rr_idx];
1208 		fdata[0] = d1->rr_data[p1->rr_idx];
1209 		fdata[1] = d2->rr_data[p2->rr_idx];
1210 
1211 		if(canonical_compare(&fk, 0, 1) != 0)
1212 			return 0;
1213 		p1 = (struct canon_rr*)rbtree_next(&p1->node);
1214 		p2 = (struct canon_rr*)rbtree_next(&p2->node);
1215 	}
1216 	return 1;
1217 }
1218 
1219 /**
1220  * Create canonical form of rrset in the scratch buffer.
1221  * @param region: temporary region.
1222  * @param buf: the buffer to use.
1223  * @param k: the rrset to insert.
1224  * @param sig: RRSIG rdata to include.
1225  * @param siglen: RRSIG rdata len excluding signature field, but inclusive
1226  * 	signer name length.
1227  * @param sortree: if NULL is passed a new sorted rrset tree is built.
1228  * 	Otherwise it is reused.
1229  * @param section: section of packet where this rrset comes from.
1230  * @param qstate: qstate with region.
1231  * @return false on alloc error.
1232  */
1233 static int
1234 rrset_canonical(struct regional* region, sldns_buffer* buf,
1235 	struct ub_packed_rrset_key* k, uint8_t* sig, size_t siglen,
1236 	struct rbtree_type** sortree, sldns_pkt_section section,
1237 	struct module_qstate* qstate)
1238 {
1239 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
1240 	uint8_t* can_owner = NULL;
1241 	size_t can_owner_len = 0;
1242 	struct canon_rr* walk;
1243 	struct canon_rr* rrs;
1244 
1245 	if(!*sortree) {
1246 		*sortree = (struct rbtree_type*)regional_alloc(region,
1247 			sizeof(rbtree_type));
1248 		if(!*sortree)
1249 			return 0;
1250 		if(d->count > RR_COUNT_MAX)
1251 			return 0; /* integer overflow protection */
1252 		rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count);
1253 		if(!rrs) {
1254 			*sortree = NULL;
1255 			return 0;
1256 		}
1257 		rbtree_init(*sortree, &canonical_tree_compare);
1258 		canonical_sort(k, d, *sortree, rrs);
1259 	}
1260 
1261 	sldns_buffer_clear(buf);
1262 	sldns_buffer_write(buf, sig, siglen);
1263 	/* canonicalize signer name */
1264 	query_dname_tolower(sldns_buffer_begin(buf)+18);
1265 	RBTREE_FOR(walk, struct canon_rr*, (*sortree)) {
1266 		/* see if there is enough space left in the buffer */
1267 		if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4
1268 			+ d->rr_len[walk->rr_idx]) {
1269 			log_err("verify: failed to canonicalize, "
1270 				"rrset too big");
1271 			return 0;
1272 		}
1273 		/* determine canonical owner name */
1274 		if(can_owner)
1275 			sldns_buffer_write(buf, can_owner, can_owner_len);
1276 		else	insert_can_owner(buf, k, sig, &can_owner,
1277 				&can_owner_len);
1278 		sldns_buffer_write(buf, &k->rk.type, 2);
1279 		sldns_buffer_write(buf, &k->rk.rrset_class, 2);
1280 		sldns_buffer_write(buf, sig+4, 4);
1281 		sldns_buffer_write(buf, d->rr_data[walk->rr_idx],
1282 			d->rr_len[walk->rr_idx]);
1283 		canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]);
1284 	}
1285 	sldns_buffer_flip(buf);
1286 
1287 	/* Replace RR owner with canonical owner for NSEC records in authority
1288 	 * section, to prevent that a wildcard synthesized NSEC can be used in
1289 	 * the non-existence proves. */
1290 	if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC &&
1291 		section == LDNS_SECTION_AUTHORITY && qstate) {
1292 		k->rk.dname = regional_alloc_init(qstate->region, can_owner,
1293 			can_owner_len);
1294 		if(!k->rk.dname)
1295 			return 0;
1296 		k->rk.dname_len = can_owner_len;
1297 	}
1298 
1299 
1300 	return 1;
1301 }
1302 
1303 int
1304 rrset_canonicalize_to_buffer(struct regional* region, sldns_buffer* buf,
1305 	struct ub_packed_rrset_key* k)
1306 {
1307 	struct rbtree_type* sortree = NULL;
1308 	struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data;
1309 	uint8_t* can_owner = NULL;
1310 	size_t can_owner_len = 0;
1311 	struct canon_rr* walk;
1312 	struct canon_rr* rrs;
1313 
1314 	sortree = (struct rbtree_type*)regional_alloc(region,
1315 		sizeof(rbtree_type));
1316 	if(!sortree)
1317 		return 0;
1318 	if(d->count > RR_COUNT_MAX)
1319 		return 0; /* integer overflow protection */
1320 	rrs = regional_alloc(region, sizeof(struct canon_rr)*d->count);
1321 	if(!rrs) {
1322 		return 0;
1323 	}
1324 	rbtree_init(sortree, &canonical_tree_compare);
1325 	canonical_sort(k, d, sortree, rrs);
1326 
1327 	sldns_buffer_clear(buf);
1328 	RBTREE_FOR(walk, struct canon_rr*, sortree) {
1329 		/* see if there is enough space left in the buffer */
1330 		if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4
1331 			+ d->rr_len[walk->rr_idx]) {
1332 			log_err("verify: failed to canonicalize, "
1333 				"rrset too big");
1334 			return 0;
1335 		}
1336 		/* determine canonical owner name */
1337 		if(can_owner)
1338 			sldns_buffer_write(buf, can_owner, can_owner_len);
1339 		else	{
1340 			can_owner = sldns_buffer_current(buf);
1341 			sldns_buffer_write(buf, k->rk.dname, k->rk.dname_len);
1342 			query_dname_tolower(can_owner);
1343 			can_owner_len = k->rk.dname_len;
1344 		}
1345 		sldns_buffer_write(buf, &k->rk.type, 2);
1346 		sldns_buffer_write(buf, &k->rk.rrset_class, 2);
1347 		sldns_buffer_write_u32(buf, d->rr_ttl[walk->rr_idx]);
1348 		sldns_buffer_write(buf, d->rr_data[walk->rr_idx],
1349 			d->rr_len[walk->rr_idx]);
1350 		canonicalize_rdata(buf, k, d->rr_len[walk->rr_idx]);
1351 	}
1352 	sldns_buffer_flip(buf);
1353 	return 1;
1354 }
1355 
1356 /** pretty print rrsig error with dates */
1357 static void
1358 sigdate_error(const char* str, int32_t expi, int32_t incep, int32_t now)
1359 {
1360 	struct tm tm;
1361 	char expi_buf[16];
1362 	char incep_buf[16];
1363 	char now_buf[16];
1364 	time_t te, ti, tn;
1365 
1366 	if(verbosity < VERB_QUERY)
1367 		return;
1368 	te = (time_t)expi;
1369 	ti = (time_t)incep;
1370 	tn = (time_t)now;
1371 	memset(&tm, 0, sizeof(tm));
1372 	if(gmtime_r(&te, &tm) && strftime(expi_buf, 15, "%Y%m%d%H%M%S", &tm)
1373 	 &&gmtime_r(&ti, &tm) && strftime(incep_buf, 15, "%Y%m%d%H%M%S", &tm)
1374 	 &&gmtime_r(&tn, &tm) && strftime(now_buf, 15, "%Y%m%d%H%M%S", &tm)) {
1375 		log_info("%s expi=%s incep=%s now=%s", str, expi_buf,
1376 			incep_buf, now_buf);
1377 	} else
1378 		log_info("%s expi=%u incep=%u now=%u", str, (unsigned)expi,
1379 			(unsigned)incep, (unsigned)now);
1380 }
1381 
1382 /** check rrsig dates */
1383 static int
1384 check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p,
1385 	uint8_t* incep_p, char** reason, sldns_ede_code *reason_bogus)
1386 {
1387 	/* read out the dates */
1388 	uint32_t expi, incep, now;
1389 	memmove(&expi, expi_p, sizeof(expi));
1390 	memmove(&incep, incep_p, sizeof(incep));
1391 	expi = ntohl(expi);
1392 	incep = ntohl(incep);
1393 
1394 	/* get current date */
1395 	if(ve->date_override) {
1396 		if(ve->date_override == -1) {
1397 			verbose(VERB_ALGO, "date override: ignore date");
1398 			return 1;
1399 		}
1400 		now = ve->date_override;
1401 		verbose(VERB_ALGO, "date override option %d", (int)now);
1402 	} else	now = unow;
1403 
1404 	/* check them */
1405 	if(compare_1982(incep, expi) > 0) {
1406 		sigdate_error("verify: inception after expiration, "
1407 			"signature bad", expi, incep, now);
1408 		*reason = "signature inception after expiration";
1409 		if(reason_bogus){
1410 			/* from RFC8914 on Signature Not Yet Valid: The resolver
1411 			 * attempted to perform DNSSEC validation, but no
1412 			 * signatures are presently valid and at least some are
1413 			 * not yet valid. */
1414 			*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
1415 		}
1416 
1417 		return 0;
1418 	}
1419 	if(compare_1982(incep, now) > 0) {
1420 		/* within skew ? (calc here to avoid calculation normally) */
1421 		uint32_t skew = subtract_1982(incep, expi)/10;
1422 		if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min;
1423 		if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max;
1424 		if(subtract_1982(now, incep) > skew) {
1425 			sigdate_error("verify: signature bad, current time is"
1426 				" before inception date", expi, incep, now);
1427 			*reason = "signature before inception date";
1428 			if(reason_bogus)
1429 				*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
1430 			return 0;
1431 		}
1432 		sigdate_error("verify warning suspicious signature inception "
1433 			" or bad local clock", expi, incep, now);
1434 	}
1435 	if(compare_1982(now, expi) > 0) {
1436 		uint32_t skew = subtract_1982(incep, expi)/10;
1437 		if(skew < (uint32_t)ve->skew_min) skew = ve->skew_min;
1438 		if(skew > (uint32_t)ve->skew_max) skew = ve->skew_max;
1439 		if(subtract_1982(expi, now) > skew) {
1440 			sigdate_error("verify: signature expired", expi,
1441 				incep, now);
1442 			*reason = "signature expired";
1443 			if(reason_bogus)
1444 				*reason_bogus = LDNS_EDE_SIGNATURE_EXPIRED;
1445 			return 0;
1446 		}
1447 		sigdate_error("verify warning suspicious signature expiration "
1448 			" or bad local clock", expi, incep, now);
1449 	}
1450 	return 1;
1451 }
1452 
1453 /** adjust rrset TTL for verified rrset, compare to original TTL and expi */
1454 static void
1455 adjust_ttl(struct val_env* ve, uint32_t unow,
1456 	struct ub_packed_rrset_key* rrset, uint8_t* orig_p,
1457 	uint8_t* expi_p, uint8_t* incep_p)
1458 {
1459 	struct packed_rrset_data* d =
1460 		(struct packed_rrset_data*)rrset->entry.data;
1461 	/* read out the dates */
1462 	int32_t origttl, expittl, expi, incep, now;
1463 	memmove(&origttl, orig_p, sizeof(origttl));
1464 	memmove(&expi, expi_p, sizeof(expi));
1465 	memmove(&incep, incep_p, sizeof(incep));
1466 	expi = ntohl(expi);
1467 	incep = ntohl(incep);
1468 	origttl = ntohl(origttl);
1469 
1470 	/* get current date */
1471 	if(ve->date_override) {
1472 		now = ve->date_override;
1473 	} else	now = (int32_t)unow;
1474 	expittl = (int32_t)((uint32_t)expi - (uint32_t)now);
1475 
1476 	/* so now:
1477 	 * d->ttl: rrset ttl read from message or cache. May be reduced
1478 	 * origttl: original TTL from signature, authoritative TTL max.
1479 	 * MIN_TTL: minimum TTL from config.
1480 	 * expittl: TTL until the signature expires.
1481 	 *
1482 	 * Use the smallest of these, but don't let origttl set the TTL
1483 	 * below the minimum.
1484 	 */
1485 	if(MIN_TTL > (time_t)origttl && d->ttl > MIN_TTL) {
1486 		verbose(VERB_QUERY, "rrset TTL larger than original and minimum"
1487 			" TTL, adjusting TTL downwards to minimum ttl");
1488 		d->ttl = MIN_TTL;
1489 	}
1490 	else if(MIN_TTL <= origttl && d->ttl > (time_t)origttl) {
1491 		verbose(VERB_QUERY, "rrset TTL larger than original TTL, "
1492 		"adjusting TTL downwards to original ttl");
1493 		d->ttl = origttl;
1494 	}
1495 
1496 	if(expittl > 0 && d->ttl > (time_t)expittl) {
1497 		verbose(VERB_ALGO, "rrset TTL larger than sig expiration ttl,"
1498 			" adjusting TTL downwards");
1499 		d->ttl = expittl;
1500 	}
1501 }
1502 
1503 enum sec_status
1504 dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
1505 	struct val_env* ve, time_t now,
1506         struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
1507         size_t dnskey_idx, size_t sig_idx,
1508 	struct rbtree_type** sortree, int* buf_canon,
1509 	char** reason, sldns_ede_code *reason_bogus,
1510 	sldns_pkt_section section, struct module_qstate* qstate)
1511 {
1512 	enum sec_status sec;
1513 	uint8_t* sig;		/* RRSIG rdata */
1514 	size_t siglen;
1515 	size_t rrnum = rrset_get_count(rrset);
1516 	uint8_t* signer;	/* rrsig signer name */
1517 	size_t signer_len;
1518 	unsigned char* sigblock; /* signature rdata field */
1519 	unsigned int sigblock_len;
1520 	uint16_t ktag;		/* DNSKEY key tag */
1521 	unsigned char* key;	/* public key rdata field */
1522 	unsigned int keylen;
1523 	rrset_get_rdata(rrset, rrnum + sig_idx, &sig, &siglen);
1524 	/* min length of rdatalen, fixed rrsig, root signer, 1 byte sig */
1525 	if(siglen < 2+20) {
1526 		verbose(VERB_QUERY, "verify: signature too short");
1527 		*reason = "signature too short";
1528 		if(reason_bogus)
1529 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1530 		return sec_status_bogus;
1531 	}
1532 
1533 	if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) {
1534 		verbose(VERB_QUERY, "verify: dnskey without ZSK flag");
1535 		*reason = "dnskey without ZSK flag";
1536 		if(reason_bogus)
1537 			*reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET;
1538 		return sec_status_bogus;
1539 	}
1540 
1541 	if(dnskey_get_protocol(dnskey, dnskey_idx) != LDNS_DNSSEC_KEYPROTO) {
1542 		/* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */
1543 		verbose(VERB_QUERY, "verify: dnskey has wrong key protocol");
1544 		*reason = "dnskey has wrong protocolnumber";
1545 		if(reason_bogus)
1546 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1547 		return sec_status_bogus;
1548 	}
1549 
1550 	/* verify as many fields in rrsig as possible */
1551 	signer = sig+2+18;
1552 	signer_len = dname_valid(signer, siglen-2-18);
1553 	if(!signer_len) {
1554 		verbose(VERB_QUERY, "verify: malformed signer name");
1555 		*reason = "signer name malformed";
1556 		if(reason_bogus)
1557 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1558 		return sec_status_bogus; /* signer name invalid */
1559 	}
1560 	if(!dname_subdomain_c(rrset->rk.dname, signer)) {
1561 		verbose(VERB_QUERY, "verify: signer name is off-tree");
1562 		*reason = "signer name off-tree";
1563 		if(reason_bogus)
1564 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1565 		return sec_status_bogus; /* signer name offtree */
1566 	}
1567 	sigblock = (unsigned char*)signer+signer_len;
1568 	if(siglen < 2+18+signer_len+1) {
1569 		verbose(VERB_QUERY, "verify: too short, no signature data");
1570 		*reason = "signature too short, no signature data";
1571 		if(reason_bogus)
1572 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1573 		return sec_status_bogus; /* sig rdf is < 1 byte */
1574 	}
1575 	sigblock_len = (unsigned int)(siglen - 2 - 18 - signer_len);
1576 
1577 	/* verify key dname == sig signer name */
1578 	if(query_dname_compare(signer, dnskey->rk.dname) != 0) {
1579 		verbose(VERB_QUERY, "verify: wrong key for rrsig");
1580 		log_nametypeclass(VERB_QUERY, "RRSIG signername is",
1581 			signer, 0, 0);
1582 		log_nametypeclass(VERB_QUERY, "the key name is",
1583 			dnskey->rk.dname, 0, 0);
1584 		*reason = "signer name mismatches key name";
1585 		if(reason_bogus)
1586 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1587 		return sec_status_bogus;
1588 	}
1589 
1590 	/* verify covered type */
1591 	/* memcmp works because type is in network format for rrset */
1592 	if(memcmp(sig+2, &rrset->rk.type, 2) != 0) {
1593 		verbose(VERB_QUERY, "verify: wrong type covered");
1594 		*reason = "signature covers wrong type";
1595 		if(reason_bogus)
1596 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1597 		return sec_status_bogus;
1598 	}
1599 	/* verify keytag and sig algo (possibly again) */
1600 	if((int)sig[2+2] != dnskey_get_algo(dnskey, dnskey_idx)) {
1601 		verbose(VERB_QUERY, "verify: wrong algorithm");
1602 		*reason = "signature has wrong algorithm";
1603 		if(reason_bogus)
1604 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1605 		return sec_status_bogus;
1606 	}
1607 	ktag = htons(dnskey_calc_keytag(dnskey, dnskey_idx));
1608 	if(memcmp(sig+2+16, &ktag, 2) != 0) {
1609 		verbose(VERB_QUERY, "verify: wrong keytag");
1610 		*reason = "signature has wrong keytag";
1611 		if(reason_bogus)
1612 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1613 		return sec_status_bogus;
1614 	}
1615 
1616 	/* verify labels is in a valid range */
1617 	if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) {
1618 		verbose(VERB_QUERY, "verify: labelcount out of range");
1619 		*reason = "signature labelcount out of range";
1620 		if(reason_bogus)
1621 			*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
1622 		return sec_status_bogus;
1623 	}
1624 
1625 	/* original ttl, always ok */
1626 
1627 	if(!*buf_canon) {
1628 		/* create rrset canonical format in buffer, ready for
1629 		 * signature */
1630 		if(!rrset_canonical(region, buf, rrset, sig+2,
1631 			18 + signer_len, sortree, section, qstate)) {
1632 			log_err("verify: failed due to alloc error");
1633 			return sec_status_unchecked;
1634 		}
1635 		*buf_canon = 1;
1636 	}
1637 
1638 	/* check that dnskey is available */
1639 	dnskey_get_pubkey(dnskey, dnskey_idx, &key, &keylen);
1640 	if(!key) {
1641 		verbose(VERB_QUERY, "verify: short DNSKEY RR");
1642 		return sec_status_unchecked;
1643 	}
1644 
1645 	/* verify */
1646 	sec = verify_canonrrset(buf, (int)sig[2+2],
1647 		sigblock, sigblock_len, key, keylen, reason);
1648 
1649 	if(sec == sec_status_secure) {
1650 		/* check if TTL is too high - reduce if so */
1651 		adjust_ttl(ve, now, rrset, sig+2+4, sig+2+8, sig+2+12);
1652 
1653 		/* verify inception, expiration dates
1654 		 * Do this last so that if you ignore expired-sigs the
1655 		 * rest is sure to be OK. */
1656 		if(!check_dates(ve, now, sig+2+8, sig+2+12,
1657 			reason, reason_bogus)) {
1658 			return sec_status_bogus;
1659 		}
1660 	}
1661 
1662 	return sec;
1663 }
1664