]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/dnssec.c
Update DNSSEC timestamp file on process TERM.
[people/ms/dnsmasq.git] / src / dnssec.c
CommitLineData
8d41ebd8 1/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
aff33962 2 and Copyright (c) 2012-2015 Simon Kelley
8d41ebd8
GB
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 dated June, 1991, or
7 (at your option) version 3 dated 29 June, 2007.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
e292e93d
GB
17
18#include "dnsmasq.h"
0fc2f313
SK
19
20#ifdef HAVE_DNSSEC
21
86bec2d3
SK
22#include <nettle/rsa.h>
23#include <nettle/dsa.h>
c152dc84
SK
24#ifndef NO_NETTLE_ECC
25# include <nettle/ecdsa.h>
26# include <nettle/ecc-curve.h>
27#endif
86bec2d3 28#include <nettle/nettle-meta.h>
063efb33
SK
29#include <nettle/bignum.h>
30
cdb755c5
SK
31/* Nettle-3.0 moved to a new API for DSA. We use a name that's defined in the new API
32 to detect Nettle-3, and invoke the backwards compatibility mode. */
33#ifdef dsa_params_init
34#include <nettle/dsa-compat.h>
35#endif
36
f6e62e2a 37#include <utime.h>
c3e0b9b6 38
e292e93d
GB
39#define SERIAL_UNDEF -100
40#define SERIAL_EQ 0
41#define SERIAL_LT -1
42#define SERIAL_GT 1
43
86bec2d3
SK
44/* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
45static char *ds_digest_name(int digest)
46{
47 switch (digest)
48 {
49 case 1: return "sha1";
50 case 2: return "sha256";
51 case 3: return "gosthash94";
52 case 4: return "sha384";
53 default: return NULL;
54 }
55}
56
57/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
58static char *algo_digest_name(int algo)
59{
60 switch (algo)
61 {
62 case 1: return "md5";
63 case 3: return "sha1";
64 case 5: return "sha1";
65 case 6: return "sha1";
66 case 7: return "sha1";
67 case 8: return "sha256";
68 case 10: return "sha512";
69 case 12: return "gosthash94";
70 case 13: return "sha256";
71 case 14: return "sha384";
72 default: return NULL;
73 }
74}
75
76/* Find pointer to correct hash function in nettle library */
77static const struct nettle_hash *hash_find(char *name)
78{
79 int i;
80
81 if (!name)
82 return NULL;
83
84 for (i = 0; nettle_hashes[i]; i++)
85 {
86 if (strcmp(nettle_hashes[i]->name, name) == 0)
87 return nettle_hashes[i];
88 }
89
90 return NULL;
91}
92
93/* expand ctx and digest memory allocations if necessary and init hash function */
94static int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
95{
96 static void *ctx = NULL;
97 static unsigned char *digest = NULL;
98 static unsigned int ctx_sz = 0;
99 static unsigned int digest_sz = 0;
100
101 void *new;
102
103 if (ctx_sz < hash->context_size)
104 {
105 if (!(new = whine_malloc(hash->context_size)))
106 return 0;
107 if (ctx)
108 free(ctx);
109 ctx = new;
110 ctx_sz = hash->context_size;
111 }
112
113 if (digest_sz < hash->digest_size)
114 {
115 if (!(new = whine_malloc(hash->digest_size)))
116 return 0;
117 if (digest)
118 free(digest);
119 digest = new;
120 digest_sz = hash->digest_size;
121 }
122
123 *ctxp = ctx;
124 *digestp = digest;
125
126 hash->init(ctx);
127
128 return 1;
129}
130
cdb755c5
SK
131static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
132 unsigned char *digest, int algo)
86bec2d3
SK
133{
134 unsigned char *p;
135 size_t exp_len;
136
137 static struct rsa_public_key *key = NULL;
138 static mpz_t sig_mpz;
139
140 if (key == NULL)
141 {
142 if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
143 return 0;
144
145 nettle_rsa_public_key_init(key);
146 mpz_init(sig_mpz);
147 }
148
149 if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
150 return 0;
151
152 key_len--;
153 if ((exp_len = *p++) == 0)
154 {
155 GETSHORT(exp_len, p);
156 key_len -= 2;
157 }
158
159 if (exp_len >= key_len)
160 return 0;
161
162 key->size = key_len - exp_len;
163 mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
164 mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
165
166 mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
167
168 switch (algo)
169 {
170 case 1:
171 return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
172 case 5: case 7:
173 return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
174 case 8:
175 return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
176 case 10:
177 return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
178 }
179
180 return 0;
181}
182
cdb755c5
SK
183static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
184 unsigned char *digest, int algo)
86bec2d3
SK
185{
186 unsigned char *p;
187 unsigned int t;
188
189 static struct dsa_public_key *key = NULL;
190 static struct dsa_signature *sig_struct;
191
192 if (key == NULL)
193 {
194 if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
195 !(key = whine_malloc(sizeof(struct dsa_public_key))))
196 return 0;
197
198 nettle_dsa_public_key_init(key);
199 nettle_dsa_signature_init(sig_struct);
200 }
201
202 if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
203 return 0;
204
205 t = *p++;
206
207 if (key_len < (213 + (t * 24)))
208 return 0;
ebe95a83 209
86bec2d3
SK
210 mpz_import(key->q, 20, 1, 1, 0, 0, p); p += 20;
211 mpz_import(key->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
212 mpz_import(key->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
213 mpz_import(key->y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
214
215 mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
216 mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
217
218 (void)algo;
ebe95a83 219
86bec2d3
SK
220 return nettle_dsa_sha1_verify_digest(key, digest, sig_struct);
221}
222
c152dc84
SK
223#ifndef NO_NETTLE_ECC
224static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len,
225 unsigned char *sig, size_t sig_len,
ebe95a83
SK
226 unsigned char *digest, size_t digest_len, int algo)
227{
228 unsigned char *p;
229 unsigned int t;
230 struct ecc_point *key;
231
232 static struct ecc_point *key_256 = NULL, *key_384 = NULL;
233 static mpz_t x, y;
234 static struct dsa_signature *sig_struct;
235
236 if (!sig_struct)
237 {
238 if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
239 return 0;
240
241 nettle_dsa_signature_init(sig_struct);
242 mpz_init(x);
243 mpz_init(y);
244 }
245
246 switch (algo)
247 {
248 case 13:
249 if (!key_256)
250 {
251 if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
252 return 0;
253
254 nettle_ecc_point_init(key_256, &nettle_secp_256r1);
255 }
256
257 key = key_256;
258 t = 32;
259 break;
260
261 case 14:
262 if (!key_384)
263 {
264 if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
265 return 0;
266
267 nettle_ecc_point_init(key_384, &nettle_secp_384r1);
268 }
269
270 key = key_384;
271 t = 48;
272 break;
273
274 default:
275 return 0;
276 }
277
278 if (sig_len != 2*t || key_len != 2*t ||
6ef15b34 279 !(p = blockdata_retrieve(key_data, key_len, NULL)))
ebe95a83
SK
280 return 0;
281
282 mpz_import(x, t , 1, 1, 0, 0, p);
283 mpz_import(y, t , 1, 1, 0, 0, p + t);
284
285 if (!ecc_point_set(key, x, y))
286 return 0;
287
288 mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
289 mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
290
291 return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
292}
c152dc84
SK
293#endif
294
86bec2d3 295static int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
ebe95a83 296 unsigned char *digest, size_t digest_len, int algo)
86bec2d3 297{
7b1eae4f
SK
298 (void)digest_len;
299
86bec2d3
SK
300 switch (algo)
301 {
302 case 1: case 5: case 7: case 8: case 10:
cdb755c5 303 return dnsmasq_rsa_verify(key_data, key_len, sig, sig_len, digest, algo);
86bec2d3
SK
304
305 case 3: case 6:
cdb755c5 306 return dnsmasq_dsa_verify(key_data, key_len, sig, sig_len, digest, algo);
c152dc84
SK
307
308#ifndef NO_NETTLE_ECC
ebe95a83
SK
309 case 13: case 14:
310 return dnsmasq_ecdsa_verify(key_data, key_len, sig, sig_len, digest, digest_len, algo);
c152dc84
SK
311#endif
312 }
86bec2d3
SK
313
314 return 0;
315}
316
0fc2f313
SK
317/* Convert from presentation format to wire format, in place.
318 Also map UC -> LC.
319 Note that using extract_name to get presentation format
320 then calling to_wire() removes compression and maps case,
321 thus generating names in canonical form.
322 Calling to_wire followed by from_wire is almost an identity,
323 except that the UC remains mapped to LC.
cbe379ad
SK
324
325 Note that both /000 and '.' are allowed within labels. These get
326 represented in presentation format using NAME_ESCAPE as an escape
327 character. In theory, if all the characters in a name were /000 or
328 '.' or NAME_ESCAPE then all would have to be escaped, so the
329 presentation format would be twice as long as the spec (1024).
330 The buffers are all delcared as 2049 (allowing for the trailing zero)
331 for this reason.
0fc2f313
SK
332*/
333static int to_wire(char *name)
7f0485cf 334{
cbe379ad 335 unsigned char *l, *p, *q, term;
0fc2f313
SK
336 int len;
337
338 for (l = (unsigned char*)name; *l != 0; l = p)
339 {
340 for (p = l; *p != '.' && *p != 0; p++)
341 if (*p >= 'A' && *p <= 'Z')
342 *p = *p - 'A' + 'a';
cbe379ad 343 else if (*p == NAME_ESCAPE)
b8f16556
SK
344 {
345 for (q = p; *q; q++)
cbe379ad 346 *q = *(q+1);
b8f16556
SK
347 (*p)--;
348 }
0fc2f313
SK
349 term = *p;
350
351 if ((len = p - l) != 0)
352 memmove(l+1, l, len);
353 *l = len;
354
355 p++;
356
357 if (term == 0)
358 *p = 0;
359 }
360
361 return l + 1 - (unsigned char *)name;
7f0485cf
GB
362}
363
0fc2f313
SK
364/* Note: no compression allowed in input. */
365static void from_wire(char *name)
13e435eb 366{
cbe379ad 367 unsigned char *l, *p, *last;
0fc2f313 368 int len;
cbe379ad
SK
369
370 for (last = (unsigned char *)name; *last != 0; last += *last+1);
371
0fc2f313 372 for (l = (unsigned char *)name; *l != 0; l += len+1)
13e435eb 373 {
0fc2f313
SK
374 len = *l;
375 memmove(l, l+1, len);
cbe379ad
SK
376 for (p = l; p < l + len; p++)
377 if (*p == '.' || *p == 0 || *p == NAME_ESCAPE)
378 {
379 memmove(p+1, p, 1 + last - p);
380 len++;
b8f16556
SK
381 *p++ = NAME_ESCAPE;
382 (*p)++;
cbe379ad
SK
383 }
384
0fc2f313 385 l[len] = '.';
13e435eb 386 }
7f0485cf 387
e3f14558 388 if ((char *)l != name)
bd9b3cf5 389 *(l-1) = 0;
13e435eb
GB
390}
391
5ada8885
SK
392/* Input in presentation format */
393static int count_labels(char *name)
394{
395 int i;
396
397 if (*name == 0)
398 return 0;
399
400 for (i = 0; *name; name++)
401 if (*name == '.')
402 i++;
403
404 return i+1;
405}
406
5f8e58f4
SK
407/* Implement RFC1982 wrapped compare for 32-bit numbers */
408static int serial_compare_32(unsigned long s1, unsigned long s2)
409{
410 if (s1 == s2)
411 return SERIAL_EQ;
0ca895f5 412
5f8e58f4
SK
413 if ((s1 < s2 && (s2 - s1) < (1UL<<31)) ||
414 (s1 > s2 && (s1 - s2) > (1UL<<31)))
415 return SERIAL_LT;
416 if ((s1 < s2 && (s2 - s1) > (1UL<<31)) ||
417 (s1 > s2 && (s1 - s2) < (1UL<<31)))
418 return SERIAL_GT;
419 return SERIAL_UNDEF;
420}
0852d76b 421
f6e62e2a
SK
422/* Called at startup. If the timestamp file is configured and exists, put its mtime on
423 timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
360f2513
SK
424 return -1 -> Cannot create file.
425 0 -> not using timestamp, or timestamp exists and is in past.
426 1 -> timestamp exists and is in future.
f6e62e2a 427*/
360f2513 428
f6e62e2a 429static time_t timestamp_time;
f6e62e2a 430
360f2513 431int setup_timestamp(void)
f6e62e2a
SK
432{
433 struct stat statbuf;
434
34b5d194 435 daemon->back_to_the_future = 0;
f6e62e2a 436
360f2513 437 if (!daemon->timestamp_file)
f6e62e2a
SK
438 return 0;
439
440 if (stat(daemon->timestamp_file, &statbuf) != -1)
441 {
442 timestamp_time = statbuf.st_mtime;
443 check_and_exit:
444 if (difftime(timestamp_time, time(0)) <= 0)
445 {
446 /* time already OK, update timestamp, and do key checking from the start. */
447 if (utime(daemon->timestamp_file, NULL) == -1)
448 my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
34b5d194 449 daemon->back_to_the_future = 1;
f6e62e2a
SK
450 return 0;
451 }
452 return 1;
453 }
454
455 if (errno == ENOENT)
456 {
360f2513
SK
457 /* NB. for explanation of O_EXCL flag, see comment on pidfile in dnsmasq.c */
458 int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
f6e62e2a
SK
459 if (fd != -1)
460 {
461 struct utimbuf timbuf;
462
463 close(fd);
464
465 timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
360f2513 466 if (utime(daemon->timestamp_file, &timbuf) == 0)
f6e62e2a
SK
467 goto check_and_exit;
468 }
469 }
470
360f2513 471 return -1;
f6e62e2a
SK
472}
473
5f8e58f4
SK
474/* Check whether today/now is between date_start and date_end */
475static int check_date_range(unsigned long date_start, unsigned long date_end)
0852d76b 476{
f6e62e2a
SK
477 unsigned long curtime = time(0);
478
e98bd52e 479 /* Checking timestamps may be temporarily disabled */
f6e62e2a
SK
480
481 /* If the current time if _before_ the timestamp
482 on our persistent timestamp file, then assume the
483 time if not yet correct, and don't check the
484 key timestamps. As soon as the current time is
485 later then the timestamp, update the timestamp
486 and start checking keys */
487 if (daemon->timestamp_file)
488 {
34b5d194 489 if (daemon->back_to_the_future == 0 && difftime(timestamp_time, curtime) <= 0)
f6e62e2a
SK
490 {
491 if (utime(daemon->timestamp_file, NULL) != 0)
492 my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
493
34b5d194 494 daemon->back_to_the_future = 1;
f6e62e2a
SK
495 set_option_bool(OPT_DNSSEC_TIME);
496 queue_event(EVENT_RELOAD); /* purge cache */
497 }
498
34b5d194 499 if (daemon->back_to_the_future == 0)
f6e62e2a
SK
500 return 1;
501 }
502 else if (option_bool(OPT_DNSSEC_TIME))
e98bd52e
SK
503 return 1;
504
5f8e58f4
SK
505 /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
506 return serial_compare_32(curtime, date_start) == SERIAL_GT
507 && serial_compare_32(curtime, date_end) == SERIAL_LT;
508}
f119ed38 509
5f8e58f4
SK
510static u16 *get_desc(int type)
511{
512 /* List of RRtypes which include domains in the data.
513 0 -> domain
514 integer -> no of plain bytes
515 -1 -> end
516
517 zero is not a valid RRtype, so the final entry is returned for
518 anything which needs no mangling.
519 */
520
521 static u16 rr_desc[] =
522 {
523 T_NS, 0, -1,
524 T_MD, 0, -1,
525 T_MF, 0, -1,
526 T_CNAME, 0, -1,
527 T_SOA, 0, 0, -1,
528 T_MB, 0, -1,
529 T_MG, 0, -1,
530 T_MR, 0, -1,
531 T_PTR, 0, -1,
532 T_MINFO, 0, 0, -1,
533 T_MX, 2, 0, -1,
534 T_RP, 0, 0, -1,
535 T_AFSDB, 2, 0, -1,
536 T_RT, 2, 0, -1,
537 T_SIG, 18, 0, -1,
538 T_PX, 2, 0, 0, -1,
539 T_NXT, 0, -1,
540 T_KX, 2, 0, -1,
541 T_SRV, 6, 0, -1,
542 T_DNAME, 0, -1,
5f8e58f4
SK
543 0, -1 /* wildcard/catchall */
544 };
545
546 u16 *p = rr_desc;
547
548 while (*p != type && *p != 0)
549 while (*p++ != (u16)-1);
f119ed38 550
5f8e58f4
SK
551 return p+1;
552}
0852d76b 553
5f8e58f4
SK
554/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
555 data, pointed to by *p, should be used raw. */
094b5c3d 556static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
5f8e58f4
SK
557 unsigned char **p, u16 **desc)
558{
559 int d = **desc;
560
5f8e58f4
SK
561 /* No more data needs mangling */
562 if (d == (u16)-1)
094b5c3d
SK
563 {
564 /* If there's more data than we have space for, just return what fits,
565 we'll get called again for more chunks */
566 if (end - *p > bufflen)
567 {
568 memcpy(buff, *p, bufflen);
569 *p += bufflen;
570 return bufflen;
571 }
572
573 return 0;
574 }
575
576 (*desc)++;
5f8e58f4 577
394ff492 578 if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
5f8e58f4
SK
579 /* domain-name, canonicalise */
580 return to_wire(buff);
581 else
582 {
583 /* plain data preceding a domain-name, don't run off the end of the data */
584 if ((end - *p) < d)
585 d = end - *p;
586
587 if (d != 0)
588 {
589 memcpy(buff, *p, d);
590 *p += d;
591 }
592
593 return d;
594 }
0852d76b
GB
595}
596
613ad15d
SK
597static int expand_workspace(unsigned char ***wkspc, int *sz, int new)
598{
599 unsigned char **p;
600 int new_sz = *sz;
601
602 if (new_sz > new)
603 return 1;
604
605 if (new >= 100)
606 return 0;
607
608 new_sz += 5;
609
610 if (!(p = whine_malloc((new_sz) * sizeof(unsigned char **))))
611 return 0;
612
613 if (*wkspc)
614 {
615 memcpy(p, *wkspc, *sz * sizeof(unsigned char **));
616 free(*wkspc);
617 }
618
619 *wkspc = p;
620 *sz = new_sz;
00a5b5d4
SK
621
622 return 1;
613ad15d
SK
623}
624
5f8e58f4
SK
625/* Bubble sort the RRset into the canonical order.
626 Note that the byte-streams from two RRs may get unsynced: consider
627 RRs which have two domain-names at the start and then other data.
628 The domain-names may have different lengths in each RR, but sort equal
629
630 ------------
631 |abcde|fghi|
632 ------------
633 |abcd|efghi|
634 ------------
635
636 leaving the following bytes as deciding the order. Hence the nasty left1 and left2 variables.
637*/
638
639static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx,
640 unsigned char **rrset, char *buff1, char *buff2)
c3e0b9b6 641{
5f8e58f4 642 int swap, quit, i;
0fc2f313 643
5f8e58f4
SK
644 do
645 {
646 for (swap = 0, i = 0; i < rrsetidx-1; i++)
647 {
648 int rdlen1, rdlen2, left1, left2, len1, len2, len, rc;
649 u16 *dp1, *dp2;
650 unsigned char *end1, *end2;
5107ace1
SK
651 /* Note that these have been determined to be OK previously,
652 so we don't need to check for NULL return here. */
5f8e58f4
SK
653 unsigned char *p1 = skip_name(rrset[i], header, plen, 10);
654 unsigned char *p2 = skip_name(rrset[i+1], header, plen, 10);
655
656 p1 += 8; /* skip class, type, ttl */
657 GETSHORT(rdlen1, p1);
658 end1 = p1 + rdlen1;
659
660 p2 += 8; /* skip class, type, ttl */
661 GETSHORT(rdlen2, p2);
662 end2 = p2 + rdlen2;
663
664 dp1 = dp2 = rr_desc;
665
1486a9c7 666 for (quit = 0, left1 = 0, left2 = 0, len1 = 0, len2 = 0; !quit;)
5f8e58f4 667 {
1486a9c7
SK
668 if (left1 != 0)
669 memmove(buff1, buff1 + len1 - left1, left1);
670
cbe379ad 671 if ((len1 = get_rdata(header, plen, end1, buff1 + left1, (MAXDNAME * 2) - left1, &p1, &dp1)) == 0)
5f8e58f4
SK
672 {
673 quit = 1;
674 len1 = end1 - p1;
675 memcpy(buff1 + left1, p1, len1);
676 }
677 len1 += left1;
678
1486a9c7
SK
679 if (left2 != 0)
680 memmove(buff2, buff2 + len2 - left2, left2);
681
cbe379ad 682 if ((len2 = get_rdata(header, plen, end2, buff2 + left2, (MAXDNAME *2) - left2, &p2, &dp2)) == 0)
5f8e58f4
SK
683 {
684 quit = 1;
685 len2 = end2 - p2;
686 memcpy(buff2 + left2, p2, len2);
687 }
688 len2 += left2;
689
690 if (len1 > len2)
1486a9c7 691 left1 = len1 - len2, left2 = 0, len = len2;
5f8e58f4 692 else
1486a9c7 693 left2 = len2 - len1, left1 = 0, len = len1;
5f8e58f4 694
6fd6dacb 695 rc = (len == 0) ? 0 : memcmp(buff1, buff2, len);
5f8e58f4 696
4619d946 697 if (rc > 0 || (rc == 0 && quit && len1 > len2))
5f8e58f4
SK
698 {
699 unsigned char *tmp = rrset[i+1];
700 rrset[i+1] = rrset[i];
701 rrset[i] = tmp;
702 swap = quit = 1;
703 }
6fd6dacb
SK
704 else if (rc < 0)
705 quit = 1;
5f8e58f4
SK
706 }
707 }
708 } while (swap);
709}
c3e0b9b6 710
5f8e58f4
SK
711/* Validate a single RRset (class, type, name) in the supplied DNS reply
712 Return code:
713 STAT_SECURE if it validates.
5107ace1 714 STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
fbc52057 715 (In this case *wildcard_out points to the "body" of the wildcard within name.)
00a5b5d4 716 STAT_NO_SIG no RRsigs found.
87070192
SK
717 STAT_INSECURE RRset empty.
718 STAT_BOGUS signature is wrong, bad packet.
5f8e58f4
SK
719 STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
720
721 if key is non-NULL, use that key, which has the algo and tag given in the params of those names,
722 otherwise find the key in the cache.
5107ace1
SK
723
724 name is unchanged on exit. keyname is used as workspace and trashed.
5f8e58f4 725*/
fbc52057
SK
726static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type,
727 char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen, int algo_in, int keytag_in)
5f8e58f4
SK
728{
729 static unsigned char **rrset = NULL, **sigs = NULL;
730 static int rrset_sz = 0, sig_sz = 0;
0fc2f313 731
5f8e58f4 732 unsigned char *p;
5ada8885 733 int rrsetidx, sigidx, res, rdlen, j, name_labels;
5f8e58f4
SK
734 struct crec *crecp = NULL;
735 int type_covered, algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag;
736 u16 *rr_desc = get_desc(type);
83d2ed09
SK
737
738 if (wildcard_out)
739 *wildcard_out = NULL;
740
5f8e58f4 741 if (!(p = skip_questions(header, plen)))
87070192 742 return STAT_BOGUS;
83d2ed09 743
5ada8885
SK
744 name_labels = count_labels(name); /* For 4035 5.3.2 check */
745
746 /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
5f8e58f4
SK
747 for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount);
748 j != 0; j--)
749 {
750 unsigned char *pstart, *pdata;
b98d22c1 751 int stype, sclass;
c3e0b9b6 752
5f8e58f4
SK
753 pstart = p;
754
755 if (!(res = extract_name(header, plen, &p, name, 0, 10)))
87070192 756 return STAT_BOGUS; /* bad packet */
5f8e58f4
SK
757
758 GETSHORT(stype, p);
759 GETSHORT(sclass, p);
b98d22c1 760 p += 4; /* TTL */
5f8e58f4
SK
761
762 pdata = p;
c3e0b9b6 763
5f8e58f4
SK
764 GETSHORT(rdlen, p);
765
e7829aef 766 if (!CHECK_LEN(header, p, plen, rdlen))
87070192 767 return STAT_BOGUS;
e7829aef 768
5f8e58f4
SK
769 if (res == 1 && sclass == class)
770 {
771 if (stype == type)
772 {
613ad15d 773 if (!expand_workspace(&rrset, &rrset_sz, rrsetidx))
87070192 774 return STAT_BOGUS;
613ad15d 775
5f8e58f4
SK
776 rrset[rrsetidx++] = pstart;
777 }
778
779 if (stype == T_RRSIG)
780 {
613ad15d 781 if (rdlen < 18)
87070192 782 return STAT_BOGUS; /* bad packet */
613ad15d
SK
783
784 GETSHORT(type_covered, p);
785
786 if (type_covered == type)
787 {
788 if (!expand_workspace(&sigs, &sig_sz, sigidx))
87070192 789 return STAT_BOGUS;
613ad15d
SK
790
791 sigs[sigidx++] = pdata;
792 }
793
794 p = pdata + 2; /* restore for ADD_RDLEN */
5f8e58f4
SK
795 }
796 }
613ad15d 797
5f8e58f4 798 if (!ADD_RDLEN(header, p, plen, rdlen))
87070192 799 return STAT_BOGUS;
5f8e58f4 800 }
c3e0b9b6 801
00a5b5d4
SK
802 /* RRset empty */
803 if (rrsetidx == 0)
5f8e58f4 804 return STAT_INSECURE;
00a5b5d4
SK
805
806 /* no RRSIGs */
807 if (sigidx == 0)
808 return STAT_NO_SIG;
5f8e58f4
SK
809
810 /* Sort RRset records into canonical order.
d387380a 811 Note that at this point keyname and daemon->workspacename buffs are
5f8e58f4 812 unused, and used as workspace by the sort. */
d387380a 813 sort_rrset(header, plen, rr_desc, rrsetidx, rrset, daemon->workspacename, keyname);
5f8e58f4
SK
814
815 /* Now try all the sigs to try and find one which validates */
816 for (j = 0; j <sigidx; j++)
817 {
d387380a 818 unsigned char *psav, *sig, *digest;
86bec2d3
SK
819 int i, wire_len, sig_len;
820 const struct nettle_hash *hash;
821 void *ctx;
d387380a 822 char *name_start;
5f8e58f4
SK
823 u32 nsigttl;
824
825 p = sigs[j];
5ada8885 826 GETSHORT(rdlen, p); /* rdlen >= 18 checked previously */
5f8e58f4
SK
827 psav = p;
828
5ada8885 829 p += 2; /* type_covered - already checked */
5f8e58f4
SK
830 algo = *p++;
831 labels = *p++;
832 GETLONG(orig_ttl, p);
e7829aef
SK
833 GETLONG(sig_expiration, p);
834 GETLONG(sig_inception, p);
5f8e58f4
SK
835 GETSHORT(key_tag, p);
836
394ff492 837 if (!extract_name(header, plen, &p, keyname, 1, 0))
87070192 838 return STAT_BOGUS;
d387380a
SK
839
840 /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
841 the name of the zone containing the RRset. We can't tell that
842 for certain, but we can check that the RRset name is equal to
843 or encloses the signers name, which should be enough to stop
844 an attacker using signatures made with the key of an unrelated
845 zone he controls. Note that the root key is always allowed. */
846 if (*keyname != 0)
847 {
848 int failed = 0;
849
850 for (name_start = name; !hostname_isequal(name_start, keyname); )
851 if ((name_start = strchr(name_start, '.')))
852 name_start++; /* chop a label off and try again */
853 else
854 {
855 failed = 1;
856 break;
857 }
858
859 /* Bad sig, try another */
860 if (failed)
861 continue;
862 }
5f8e58f4 863
d387380a 864 /* Other 5.3.1 checks */
e7829aef
SK
865 if (!check_date_range(sig_inception, sig_expiration) ||
866 labels > name_labels ||
867 !(hash = hash_find(algo_digest_name(algo))) ||
868 !hash_init(hash, &ctx, &digest))
869 continue;
870
5f8e58f4
SK
871 /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
872 if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
873 return STAT_NEED_KEY;
874
86bec2d3
SK
875 sig = p;
876 sig_len = rdlen - (p - psav);
e7829aef 877
5f8e58f4
SK
878 nsigttl = htonl(orig_ttl);
879
86bec2d3 880 hash->update(ctx, 18, psav);
5f8e58f4 881 wire_len = to_wire(keyname);
86bec2d3 882 hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
5f8e58f4
SK
883 from_wire(keyname);
884
5f8e58f4
SK
885 for (i = 0; i < rrsetidx; ++i)
886 {
887 int seg;
888 unsigned char *end, *cp;
889 u16 len, *dp;
d387380a 890
5f8e58f4 891 p = rrset[i];
394ff492 892 if (!extract_name(header, plen, &p, name, 1, 10))
87070192 893 return STAT_BOGUS;
5ada8885 894
d387380a
SK
895 name_start = name;
896
5ada8885
SK
897 /* if more labels than in RRsig name, hash *.<no labels in rrsig labels field> 4035 5.3.2 */
898 if (labels < name_labels)
899 {
900 int k;
901 for (k = name_labels - labels; k != 0; k--)
fbc52057
SK
902 {
903 while (*name_start != '.' && *name_start != 0)
904 name_start++;
0b1008d3 905 if (k != 1 && *name_start == '.')
fbc52057
SK
906 name_start++;
907 }
908
909 if (wildcard_out)
910 *wildcard_out = name_start+1;
911
5ada8885
SK
912 name_start--;
913 *name_start = '*';
914 }
915
916 wire_len = to_wire(name_start);
86bec2d3
SK
917 hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name_start);
918 hash->update(ctx, 4, p); /* class and type */
919 hash->update(ctx, 4, (unsigned char *)&nsigttl);
5f8e58f4
SK
920
921 p += 8; /* skip class, type, ttl */
922 GETSHORT(rdlen, p);
5ada8885 923 if (!CHECK_LEN(header, p, plen, rdlen))
87070192 924 return STAT_BOGUS;
5ada8885 925
5f8e58f4
SK
926 end = p + rdlen;
927
cbe379ad
SK
928 /* canonicalise rdata and calculate length of same, use name buffer as workspace.
929 Note that name buffer is twice MAXDNAME long in DNSSEC mode. */
5f8e58f4
SK
930 cp = p;
931 dp = rr_desc;
cbe379ad 932 for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)) != 0; len += seg);
5f8e58f4
SK
933 len += end - cp;
934 len = htons(len);
86bec2d3 935 hash->update(ctx, 2, (unsigned char *)&len);
5f8e58f4
SK
936
937 /* Now canonicalise again and digest. */
938 cp = p;
939 dp = rr_desc;
cbe379ad 940 while ((seg = get_rdata(header, plen, end, name, MAXDNAME * 2, &cp, &dp)))
86bec2d3 941 hash->update(ctx, seg, (unsigned char *)name);
5f8e58f4 942 if (cp != end)
86bec2d3 943 hash->update(ctx, end - cp, cp);
5f8e58f4 944 }
86bec2d3
SK
945
946 hash->digest(ctx, hash->digest_size, digest);
947
5ada8885
SK
948 /* namebuff used for workspace above, restore to leave unchanged on exit */
949 p = (unsigned char*)(rrset[0]);
394ff492 950 extract_name(header, plen, &p, name, 1, 0);
5ada8885 951
5f8e58f4
SK
952 if (key)
953 {
954 if (algo_in == algo && keytag_in == key_tag &&
ebe95a83 955 verify(key, keylen, sig, sig_len, digest, hash->digest_size, algo))
5f8e58f4
SK
956 return STAT_SECURE;
957 }
958 else
959 {
960 /* iterate through all possible keys 4035 5.3.1 */
961 for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))
51ea3ca2
SK
962 if (crecp->addr.key.algo == algo &&
963 crecp->addr.key.keytag == key_tag &&
3f7483e8 964 crecp->uid == (unsigned int)class &&
ebe95a83 965 verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
5107ace1 966 return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE;
5f8e58f4
SK
967 }
968 }
969
970 return STAT_BOGUS;
971}
972
0fc2f313 973/* The DNS packet is expected to contain the answer to a DNSKEY query.
c3e0b9b6
SK
974 Put all DNSKEYs in the answer which are valid into the cache.
975 return codes:
97e618a0 976 STAT_SECURE At least one valid DNSKEY found and in cache.
0fc2f313 977 STAT_BOGUS No DNSKEYs found, which can be validated with DS,
87070192 978 or self-sign for DNSKEY RRset is not valid, bad packet.
0fc2f313 979 STAT_NEED_DS DS records to validate a key not found, name in keyname
c3e0b9b6
SK
980*/
981int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
982{
0fc2f313 983 unsigned char *psave, *p = (unsigned char *)(header+1);
c3e0b9b6 984 struct crec *crecp, *recp1;
8d718cbb 985 int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag, type_covered;
c3e0b9b6 986 struct blockdata *key;
51ea3ca2 987 struct all_addr a;
c3e0b9b6 988
5f8e58f4 989 if (ntohs(header->qdcount) != 1 ||
394ff492 990 !extract_name(header, plen, &p, name, 1, 4))
87070192 991 return STAT_BOGUS;
5f8e58f4 992
c3e0b9b6
SK
993 GETSHORT(qtype, p);
994 GETSHORT(qclass, p);
995
97e618a0 996 if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
f01d7be6 997 return STAT_BOGUS;
c3e0b9b6 998
b8eac191 999 /* See if we have cached a DS record which validates this key */
0fc2f313
SK
1000 if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
1001 {
1002 strcpy(keyname, name);
1003 return STAT_NEED_DS;
1004 }
b8eac191
SK
1005
1006 /* If we've cached that DS provably doesn't exist, result must be INSECURE */
1007 if (crecp->flags & F_NEG)
fe3992f9 1008 return STAT_INSECURE_DS;
b8eac191 1009
0fc2f313 1010 /* NOTE, we need to find ONE DNSKEY which matches the DS */
e7829aef 1011 for (valid = 0, j = ntohs(header->ancount); j != 0 && !valid; j--)
c3e0b9b6
SK
1012 {
1013 /* Ensure we have type, class TTL and length */
0fc2f313 1014 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
87070192 1015 return STAT_BOGUS; /* bad packet */
c3e0b9b6
SK
1016
1017 GETSHORT(qtype, p);
1018 GETSHORT(qclass, p);
1019 GETLONG(ttl, p);
1020 GETSHORT(rdlen, p);
6f468103 1021
0fc2f313 1022 if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
87070192 1023 return STAT_BOGUS; /* bad packet */
0fc2f313 1024
6f468103
SK
1025 if (qclass != class || qtype != T_DNSKEY || rc == 2)
1026 {
1027 p += rdlen;
1028 continue;
1029 }
1030
0fc2f313 1031 psave = p;
c3e0b9b6 1032
c3e0b9b6 1033 GETSHORT(flags, p);
0fc2f313 1034 if (*p++ != 3)
f01d7be6 1035 return STAT_BOGUS;
c3e0b9b6 1036 algo = *p++;
0fc2f313 1037 keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
e7829aef 1038 key = NULL;
c3e0b9b6 1039
e7829aef
SK
1040 /* key must have zone key flag set */
1041 if (flags & 0x100)
1042 key = blockdata_alloc((char*)p, rdlen - 4);
c3e0b9b6 1043
0fc2f313 1044 p = psave;
e7829aef 1045
0fc2f313 1046 if (!ADD_RDLEN(header, p, plen, rdlen))
8d718cbb
SK
1047 {
1048 if (key)
1049 blockdata_free(key);
87070192 1050 return STAT_BOGUS; /* bad packet */
8d718cbb
SK
1051 }
1052
e7829aef
SK
1053 /* No zone key flag or malloc failure */
1054 if (!key)
0fc2f313
SK
1055 continue;
1056
1057 for (recp1 = crecp; recp1; recp1 = cache_find_by_name(recp1, name, now, F_DS))
86bec2d3
SK
1058 {
1059 void *ctx;
1060 unsigned char *digest, *ds_digest;
1061 const struct nettle_hash *hash;
1062
51ea3ca2
SK
1063 if (recp1->addr.ds.algo == algo &&
1064 recp1->addr.ds.keytag == keytag &&
3f7483e8 1065 recp1->uid == (unsigned int)class &&
51ea3ca2 1066 (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) &&
86bec2d3 1067 hash_init(hash, &ctx, &digest))
0fc2f313 1068
86bec2d3
SK
1069 {
1070 int wire_len = to_wire(name);
1071
1072 /* Note that digest may be different between DSs, so
1073 we can't move this outside the loop. */
1074 hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name);
1075 hash->update(ctx, (unsigned int)rdlen, psave);
1076 hash->digest(ctx, hash->digest_size, digest);
1077
1078 from_wire(name);
1079
824202ef
SK
1080 if (recp1->addr.ds.keylen == (int)hash->digest_size &&
1081 (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
1082 memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
fbc52057 1083 validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, NULL, key, rdlen - 4, algo, keytag) == STAT_SECURE)
86bec2d3 1084 {
86bec2d3 1085 valid = 1;
86bec2d3
SK
1086 break;
1087 }
1088 }
1089 }
e7829aef 1090 blockdata_free(key);
c3e0b9b6 1091 }
c3e0b9b6 1092
0fc2f313
SK
1093 if (valid)
1094 {
8d718cbb 1095 /* DNSKEY RRset determined to be OK, now cache it and the RRsigs that sign it. */
e7829aef
SK
1096 cache_start_insert();
1097
1098 p = skip_questions(header, plen);
1099
1100 for (j = ntohs(header->ancount); j != 0; j--)
1101 {
1102 /* Ensure we have type, class TTL and length */
1103 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
1104 return STAT_INSECURE; /* bad packet */
1105
1106 GETSHORT(qtype, p);
1107 GETSHORT(qclass, p);
1108 GETLONG(ttl, p);
1109 GETSHORT(rdlen, p);
8d718cbb
SK
1110
1111 if (!CHECK_LEN(header, p, plen, rdlen))
87070192 1112 return STAT_BOGUS; /* bad packet */
e7829aef 1113
8d718cbb 1114 if (qclass == class && rc == 1)
e7829aef 1115 {
8d718cbb 1116 psave = p;
e7829aef 1117
8d718cbb
SK
1118 if (qtype == T_DNSKEY)
1119 {
1120 if (rdlen < 4)
87070192 1121 return STAT_BOGUS; /* bad packet */
8d718cbb
SK
1122
1123 GETSHORT(flags, p);
1124 if (*p++ != 3)
f01d7be6 1125 return STAT_BOGUS;
8d718cbb
SK
1126 algo = *p++;
1127 keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
1128
1129 /* Cache needs to known class for DNSSEC stuff */
1130 a.addr.dnssec.class = class;
1131
1132 if ((key = blockdata_alloc((char*)p, rdlen - 4)))
1133 {
1134 if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
1135 blockdata_free(key);
1136 else
1137 {
1138 a.addr.keytag = keytag;
25cf5e37 1139 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %u");
8d718cbb
SK
1140
1141 recp1->addr.key.keylen = rdlen - 4;
1142 recp1->addr.key.keydata = key;
1143 recp1->addr.key.algo = algo;
1144 recp1->addr.key.keytag = keytag;
1145 recp1->addr.key.flags = flags;
8d718cbb
SK
1146 }
1147 }
1148 }
1149 else if (qtype == T_RRSIG)
1150 {
1151 /* RRSIG, cache if covers DNSKEY RRset */
1152 if (rdlen < 18)
87070192 1153 return STAT_BOGUS; /* bad packet */
8d718cbb
SK
1154
1155 GETSHORT(type_covered, p);
1156
1157 if (type_covered == T_DNSKEY)
1158 {
1159 a.addr.dnssec.class = class;
1160 a.addr.dnssec.type = type_covered;
1161
1162 algo = *p++;
1163 p += 13; /* labels, orig_ttl, expiration, inception */
1164 GETSHORT(keytag, p);
1165 if ((key = blockdata_alloc((char*)psave, rdlen)))
1166 {
1167 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS)))
1168 blockdata_free(key);
1169 else
1170 {
8d718cbb
SK
1171 crecp->addr.sig.keydata = key;
1172 crecp->addr.sig.keylen = rdlen;
1173 crecp->addr.sig.keytag = keytag;
1174 crecp->addr.sig.type_covered = type_covered;
1175 crecp->addr.sig.algo = algo;
1176 }
1177 }
1178 }
1179 }
e7829aef 1180
8d718cbb 1181 p = psave;
e7829aef 1182 }
8d718cbb 1183
e7829aef 1184 if (!ADD_RDLEN(header, p, plen, rdlen))
87070192 1185 return STAT_BOGUS; /* bad packet */
e7829aef
SK
1186 }
1187
0fc2f313
SK
1188 /* commit cache insert. */
1189 cache_end_insert();
1190 return STAT_SECURE;
1191 }
1192
25cf5e37 1193 log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DNSKEY");
0fc2f313 1194 return STAT_BOGUS;
c3e0b9b6 1195}
0fc2f313 1196
c3e0b9b6
SK
1197/* The DNS packet is expected to contain the answer to a DS query
1198 Put all DSs in the answer which are valid into the cache.
1199 return codes:
c3e0b9b6 1200 STAT_SECURE At least one valid DS found and in cache.
00a5b5d4 1201 STAT_NO_DS It's proved there's no DS here.
97e618a0
SK
1202 STAT_NO_NS It's proved there's no DS _or_ NS here.
1203 STAT_BOGUS no DS in reply or not signed, fails validation, bad packet.
0b8a5a30 1204 STAT_NEED_KEY DNSKEY records to validate a DS not found, name in keyname
c3e0b9b6
SK
1205*/
1206
1207int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
1208{
51ea3ca2 1209 unsigned char *p = (unsigned char *)(header+1);
97e618a0 1210 int qtype, qclass, val, i, neganswer, nons;
c3e0b9b6 1211
5f8e58f4 1212 if (ntohs(header->qdcount) != 1 ||
b8eac191 1213 !(p = skip_name(p, header, plen, 4)))
87070192 1214 return STAT_BOGUS;
8d718cbb 1215
c3e0b9b6
SK
1216 GETSHORT(qtype, p);
1217 GETSHORT(qclass, p);
1218
b47b04c8
SK
1219 if (qtype != T_DS || qclass != class)
1220 val = STAT_BOGUS;
1221 else
97e618a0
SK
1222 val = dnssec_validate_reply(now, header, plen, name, keyname, NULL, &neganswer, &nons);
1223 /* Note dnssec_validate_reply() will have cached positive answers */
1224
e3ec6f0b 1225 if (val == STAT_INSECURE)
97e618a0 1226 val = STAT_BOGUS;
e3ec6f0b 1227
b8eac191 1228 p = (unsigned char *)(header+1);
394ff492 1229 extract_name(header, plen, &p, name, 1, 4);
b8eac191
SK
1230 p += 4; /* qtype, qclass */
1231
00a5b5d4 1232 if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
97e618a0 1233 val = STAT_BOGUS;
d389e019
SK
1234
1235 /* If we return STAT_NO_SIG, name contains the name of the DS query */
1236 if (val == STAT_NO_SIG)
1237 {
1238 *keyname = 0;
1239 return val;
1240 }
1241
0b8a5a30
SK
1242 /* If the key needed to validate the DS is on the same domain as the DS, we'll
1243 loop getting nowhere. Stop that now. This can happen of the DS answer comes
1244 from the DS's zone, and not the parent zone. */
1245 if (val == STAT_BOGUS || (val == STAT_NEED_KEY && hostname_isequal(name, keyname)))
b8eac191 1246 {
25cf5e37 1247 log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, "BOGUS DS");
97e618a0
SK
1248 return STAT_BOGUS;
1249 }
1250
1251 /* By here, the answer is proved secure, and a positive answer has been cached. */
1252 if (val == STAT_SECURE && neganswer)
1253 {
1254 int rdlen, flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
b8eac191
SK
1255 unsigned long ttl, minttl = ULONG_MAX;
1256 struct all_addr a;
00a5b5d4
SK
1257
1258 if (RCODE(header) == NXDOMAIN)
1259 flags |= F_NXDOMAIN;
1260
97e618a0
SK
1261 /* We only cache validated DS records, DNSSECOK flag hijacked
1262 to store presence/absence of NS. */
1263 if (nons)
1264 flags &= ~F_DNSSECOK;
b8eac191
SK
1265
1266 for (i = ntohs(header->nscount); i != 0; i--)
1267 {
00a5b5d4 1268 if (!(p = skip_name(p, header, plen, 0)))
87070192 1269 return STAT_BOGUS;
b8eac191
SK
1270
1271 GETSHORT(qtype, p);
1272 GETSHORT(qclass, p);
1273 GETLONG(ttl, p);
1274 GETSHORT(rdlen, p);
1275
00a5b5d4 1276 if (!CHECK_LEN(header, p, plen, rdlen))
87070192 1277 return STAT_BOGUS; /* bad packet */
00a5b5d4
SK
1278
1279 if (qclass != class || qtype != T_SOA)
b8eac191
SK
1280 {
1281 p += rdlen;
1282 continue;
1283 }
1284
1285 if (ttl < minttl)
1286 minttl = ttl;
1287
1288 /* MNAME */
1289 if (!(p = skip_name(p, header, plen, 0)))
87070192 1290 return STAT_BOGUS;
b8eac191
SK
1291 /* RNAME */
1292 if (!(p = skip_name(p, header, plen, 20)))
87070192 1293 return STAT_BOGUS;
b8eac191
SK
1294 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
1295
1296 GETLONG(ttl, p); /* minTTL */
1297 if (ttl < minttl)
1298 minttl = ttl;
00a5b5d4
SK
1299
1300 break;
b8eac191
SK
1301 }
1302
00a5b5d4
SK
1303 if (i != 0)
1304 {
1305 cache_start_insert();
1306
1307 a.addr.dnssec.class = class;
1308 cache_insert(name, &a, now, ttl, flags);
1309
97e618a0
SK
1310 cache_end_insert();
1311
25cf5e37 1312 log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no delegation" : "no DS");
00a5b5d4 1313 }
b8eac191 1314
97e618a0 1315 return nons ? STAT_NO_NS : STAT_NO_DS;
b8eac191
SK
1316 }
1317
51ea3ca2 1318 return val;
c3e0b9b6
SK
1319}
1320
c5f4ec7d
SK
1321/* 4034 6.1 */
1322static int hostname_cmp(const char *a, const char *b)
1323{
dbf72123
SK
1324 char *sa, *ea, *ca, *sb, *eb, *cb;
1325 unsigned char ac, bc;
1326
1327 sa = ea = (char *)a + strlen(a);
1328 sb = eb = (char *)b + strlen(b);
1329
c5f4ec7d
SK
1330 while (1)
1331 {
dbf72123
SK
1332 while (sa != a && *(sa-1) != '.')
1333 sa--;
c5f4ec7d 1334
dbf72123
SK
1335 while (sb != b && *(sb-1) != '.')
1336 sb--;
1337
1338 ca = sa;
1339 cb = sb;
1340
1341 while (1)
1342 {
1343 if (ca == ea)
1344 {
1345 if (cb == eb)
1346 break;
1347
1348 return -1;
1349 }
c5f4ec7d 1350
dbf72123
SK
1351 if (cb == eb)
1352 return 1;
1353
1354 ac = (unsigned char) *ca++;
1355 bc = (unsigned char) *cb++;
1356
1357 if (ac >= 'A' && ac <= 'Z')
1358 ac += 'a' - 'A';
1359 if (bc >= 'A' && bc <= 'Z')
1360 bc += 'a' - 'A';
1361
979cdf9b 1362 if (ac < bc)
dbf72123
SK
1363 return -1;
1364 else if (ac != bc)
1365 return 1;
1366 }
c5f4ec7d 1367
dbf72123
SK
1368
1369 if (sa == a)
c5f4ec7d 1370 {
dbf72123
SK
1371 if (sb == b)
1372 return 0;
c5f4ec7d 1373
dbf72123 1374 return -1;
c5f4ec7d
SK
1375 }
1376
dbf72123
SK
1377 if (sb == b)
1378 return 1;
c5f4ec7d 1379
dbf72123
SK
1380 ea = sa--;
1381 eb = sb--;
c5f4ec7d
SK
1382 }
1383}
1384
5107ace1
SK
1385/* Find all the NSEC or NSEC3 records in a reply.
1386 return an array of pointers to them. */
1387static int find_nsec_records(struct dns_header *header, size_t plen, unsigned char ***nsecsetp, int *nsecsetl, int class_reqd)
1388{
1389 static unsigned char **nsecset = NULL;
1390 static int nsecset_sz = 0;
1391
87070192 1392 int type_found = 0;
5107ace1
SK
1393 unsigned char *p = skip_questions(header, plen);
1394 int type, class, rdlen, i, nsecs_found;
1395
1396 /* Move to NS section */
1397 if (!p || !(p = skip_section(p, ntohs(header->ancount), header, plen)))
1398 return 0;
1399
1400 for (nsecs_found = 0, i = ntohs(header->nscount); i != 0; i--)
1401 {
1402 unsigned char *pstart = p;
1403
1404 if (!(p = skip_name(p, header, plen, 10)))
1405 return 0;
1406
1407 GETSHORT(type, p);
1408 GETSHORT(class, p);
1409 p += 4; /* TTL */
1410 GETSHORT(rdlen, p);
1411
1412 if (class == class_reqd && (type == T_NSEC || type == T_NSEC3))
1413 {
1414 /* No mixed NSECing 'round here, thankyouverymuch */
1415 if (type_found == T_NSEC && type == T_NSEC3)
1416 return 0;
1417 if (type_found == T_NSEC3 && type == T_NSEC)
1418 return 0;
1419
1420 type_found = type;
1421
613ad15d
SK
1422 if (!expand_workspace(&nsecset, &nsecset_sz, nsecs_found))
1423 return 0;
1424
5107ace1
SK
1425 nsecset[nsecs_found++] = pstart;
1426 }
613ad15d 1427
5107ace1
SK
1428 if (!ADD_RDLEN(header, p, plen, rdlen))
1429 return 0;
1430 }
1431
1432 *nsecsetp = nsecset;
1433 *nsecsetl = nsecs_found;
1434
1435 return type_found;
1436}
1437
24187530 1438static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count,
97e618a0 1439 char *workspace1, char *workspace2, char *name, int type, int *nons)
5107ace1
SK
1440{
1441 int i, rc, rdlen;
1442 unsigned char *p, *psave;
1443 int offset = (type & 0xff) >> 3;
1444 int mask = 0x80 >> (type & 0x07);
97e618a0
SK
1445
1446 if (nons)
1447 *nons = 0;
5107ace1
SK
1448
1449 /* Find NSEC record that proves name doesn't exist */
1450 for (i = 0; i < nsec_count; i++)
1451 {
1452 p = nsecs[i];
394ff492 1453 if (!extract_name(header, plen, &p, workspace1, 1, 10))
87070192 1454 return STAT_BOGUS;
5107ace1
SK
1455 p += 8; /* class, type, TTL */
1456 GETSHORT(rdlen, p);
1457 psave = p;
394ff492 1458 if (!extract_name(header, plen, &p, workspace2, 1, 10))
87070192 1459 return STAT_BOGUS;
5107ace1
SK
1460
1461 rc = hostname_cmp(workspace1, name);
1462
1463 if (rc == 0)
1464 {
f01d7be6
SK
1465 /* 4035 para 5.4. Last sentence */
1466 if (type == T_NSEC || type == T_RRSIG)
1467 return STAT_SECURE;
1468
5107ace1
SK
1469 /* NSEC with the same name as the RR we're testing, check
1470 that the type in question doesn't appear in the type map */
1471 rdlen -= p - psave;
1472 /* rdlen is now length of type map, and p points to it */
1473
97e618a0
SK
1474 /* If we can prove that there's no NS record, return that information. */
1475 if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) == 0)
1476 *nons = 1;
1477
5107ace1
SK
1478 while (rdlen >= 2)
1479 {
1480 if (!CHECK_LEN(header, p, plen, rdlen))
87070192 1481 return STAT_BOGUS;
5107ace1
SK
1482
1483 if (p[0] == type >> 8)
1484 {
1485 /* Does the NSEC say our type exists? */
a857daa3 1486 if (offset < p[1] && (p[offset+2] & mask) != 0)
5107ace1
SK
1487 return STAT_BOGUS;
1488
1489 break; /* finshed checking */
1490 }
1491
1492 rdlen -= p[1];
1493 p += p[1];
1494 }
1495
1496 return STAT_SECURE;
1497 }
1498 else if (rc == -1)
1499 {
1500 /* Normal case, name falls between NSEC name and next domain name,
1501 wrap around case, name falls between NSEC name (rc == -1) and end */
4d25cf89 1502 if (hostname_cmp(workspace2, name) >= 0 || hostname_cmp(workspace1, workspace2) >= 0)
5107ace1
SK
1503 return STAT_SECURE;
1504 }
1505 else
1506 {
1507 /* wrap around case, name falls between start and next domain name */
4d25cf89 1508 if (hostname_cmp(workspace1, workspace2) >= 0 && hostname_cmp(workspace2, name) >=0 )
5107ace1
SK
1509 return STAT_SECURE;
1510 }
1511 }
1512
1513 return STAT_BOGUS;
1514}
1515
1516/* return digest length, or zero on error */
1517static int hash_name(char *in, unsigned char **out, struct nettle_hash const *hash,
1518 unsigned char *salt, int salt_len, int iterations)
1519{
1520 void *ctx;
1521 unsigned char *digest;
1522 int i;
1523
1524 if (!hash_init(hash, &ctx, &digest))
1525 return 0;
1526
1527 hash->update(ctx, to_wire(in), (unsigned char *)in);
1528 hash->update(ctx, salt_len, salt);
1529 hash->digest(ctx, hash->digest_size, digest);
1530
1531 for(i = 0; i < iterations; i++)
1532 {
1533 hash->update(ctx, hash->digest_size, digest);
1534 hash->update(ctx, salt_len, salt);
1535 hash->digest(ctx, hash->digest_size, digest);
1536 }
1537
1538 from_wire(in);
1539
1540 *out = digest;
1541 return hash->digest_size;
1542}
1543
1544/* Decode base32 to first "." or end of string */
1545static int base32_decode(char *in, unsigned char *out)
1546{
a857daa3 1547 int oc, on, c, mask, i;
5107ace1
SK
1548 unsigned char *p = out;
1549
a857daa3 1550 for (c = *in, oc = 0, on = 0; c != 0 && c != '.'; c = *++in)
5107ace1 1551 {
5107ace1
SK
1552 if (c >= '0' && c <= '9')
1553 c -= '0';
1554 else if (c >= 'a' && c <= 'v')
1555 c -= 'a', c += 10;
1556 else if (c >= 'A' && c <= 'V')
1557 c -= 'A', c += 10;
1558 else
1559 return 0;
1560
1561 for (mask = 0x10, i = 0; i < 5; i++)
1562 {
a857daa3
SK
1563 if (c & mask)
1564 oc |= 1;
1565 mask = mask >> 1;
1566 if (((++on) & 7) == 0)
1567 *p++ = oc;
1568 oc = oc << 1;
5107ace1
SK
1569 }
1570 }
1571
1572 if ((on & 7) != 0)
1573 return 0;
1574
1575 return p - out;
1576}
1577
fbc52057 1578static int check_nsec3_coverage(struct dns_header *header, size_t plen, int digest_len, unsigned char *digest, int type,
97e618a0 1579 char *workspace1, char *workspace2, unsigned char **nsecs, int nsec_count, int *nons)
fbc52057
SK
1580{
1581 int i, hash_len, salt_len, base32_len, rdlen;
1582 unsigned char *p, *psave;
1583
1584 for (i = 0; i < nsec_count; i++)
1585 if ((p = nsecs[i]))
1586 {
394ff492 1587 if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
fbc52057
SK
1588 !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
1589 return 0;
1590
1591 p += 8; /* class, type, TTL */
1592 GETSHORT(rdlen, p);
1593 psave = p;
1594 p += 4; /* algo, flags, iterations */
1595 salt_len = *p++; /* salt_len */
1596 p += salt_len; /* salt */
1597 hash_len = *p++; /* p now points to next hashed name */
1598
1599 if (!CHECK_LEN(header, p, plen, hash_len))
1600 return 0;
1601
1602 if (digest_len == base32_len && hash_len == base32_len)
1603 {
1604 int rc = memcmp(workspace2, digest, digest_len);
1605
1606 if (rc == 0)
1607 {
1608 /* We found an NSEC3 whose hashed name exactly matches the query, so
1609 we just need to check the type map. p points to the RR data for the record. */
1610
1611 int offset = (type & 0xff) >> 3;
1612 int mask = 0x80 >> (type & 0x07);
1613
1614 p += hash_len; /* skip next-domain hash */
1615 rdlen -= p - psave;
1616
1617 if (!CHECK_LEN(header, p, plen, rdlen))
1618 return 0;
1619
97e618a0
SK
1620 /* If we can prove that there's no NS record, return that information. */
1621 if (nons && rdlen >= 2 && p[0] == 0 && (p[2] & (0x80 >> T_NS)) == 0)
1622 *nons = 1;
1623
fbc52057
SK
1624 while (rdlen >= 2)
1625 {
1626 if (p[0] == type >> 8)
1627 {
1628 /* Does the NSEC3 say our type exists? */
1629 if (offset < p[1] && (p[offset+2] & mask) != 0)
1630 return STAT_BOGUS;
1631
1632 break; /* finshed checking */
1633 }
1634
1635 rdlen -= p[1];
1636 p += p[1];
1637 }
1638
1639 return 1;
1640 }
4d25cf89 1641 else if (rc < 0)
fbc52057
SK
1642 {
1643 /* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
1644 wrap around case, name-hash falls between NSEC3 name-hash and end */
4d25cf89 1645 if (memcmp(p, digest, digest_len) >= 0 || memcmp(workspace2, p, digest_len) >= 0)
fbc52057
SK
1646 return 1;
1647 }
1648 else
1649 {
1650 /* wrap around case, name falls between start and next domain name */
4d25cf89 1651 if (memcmp(workspace2, p, digest_len) >= 0 && memcmp(p, digest, digest_len) >= 0)
fbc52057
SK
1652 return 1;
1653 }
1654 }
1655 }
1656 return 0;
1657}
1658
24187530 1659static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count,
97e618a0 1660 char *workspace1, char *workspace2, char *name, int type, char *wildname, int *nons)
5107ace1 1661{
a857daa3 1662 unsigned char *salt, *p, *digest;
fbc52057 1663 int digest_len, i, iterations, salt_len, base32_len, algo = 0;
5107ace1
SK
1664 struct nettle_hash const *hash;
1665 char *closest_encloser, *next_closest, *wildcard;
97e618a0
SK
1666
1667 if (nons)
1668 *nons = 0;
1669
5107ace1
SK
1670 /* Look though the NSEC3 records to find the first one with
1671 an algorithm we support (currently only algo == 1).
1672
1673 Take the algo, iterations, and salt of that record
1674 as the ones we're going to use, and prune any
1675 that don't match. */
1676
1677 for (i = 0; i < nsec_count; i++)
1678 {
1679 if (!(p = skip_name(nsecs[i], header, plen, 15)))
87070192 1680 return STAT_BOGUS; /* bad packet */
5107ace1
SK
1681
1682 p += 10; /* type, class, TTL, rdlen */
1683 algo = *p++;
1684
1685 if (algo == 1)
1686 break; /* known algo */
1687 }
1688
1689 /* No usable NSEC3s */
1690 if (i == nsec_count)
1691 return STAT_BOGUS;
1692
1693 p++; /* flags */
1694 GETSHORT (iterations, p);
1695 salt_len = *p++;
1696 salt = p;
1697 if (!CHECK_LEN(header, salt, plen, salt_len))
87070192 1698 return STAT_BOGUS; /* bad packet */
5107ace1
SK
1699
1700 /* Now prune so we only have NSEC3 records with same iterations, salt and algo */
1701 for (i = 0; i < nsec_count; i++)
1702 {
1703 unsigned char *nsec3p = nsecs[i];
1704 int this_iter;
1705
1706 nsecs[i] = NULL; /* Speculative, will be restored if OK. */
1707
1708 if (!(p = skip_name(nsec3p, header, plen, 15)))
87070192 1709 return STAT_BOGUS; /* bad packet */
5107ace1
SK
1710
1711 p += 10; /* type, class, TTL, rdlen */
1712
1713 if (*p++ != algo)
1714 continue;
1715
1716 p++; /* flags */
1717
a857daa3 1718 GETSHORT(this_iter, p);
5107ace1
SK
1719 if (this_iter != iterations)
1720 continue;
1721
1722 if (salt_len != *p++)
1723 continue;
1724
1725 if (!CHECK_LEN(header, p, plen, salt_len))
87070192 1726 return STAT_BOGUS; /* bad packet */
5107ace1
SK
1727
1728 if (memcmp(p, salt, salt_len) != 0)
1729 continue;
1730
1731 /* All match, put the pointer back */
1732 nsecs[i] = nsec3p;
1733 }
1734
1735 /* Algo is checked as 1 above */
1736 if (!(hash = hash_find("sha1")))
87070192 1737 return STAT_BOGUS;
5107ace1 1738
fbc52057
SK
1739 if ((digest_len = hash_name(name, &digest, hash, salt, salt_len, iterations)) == 0)
1740 return STAT_BOGUS;
1741
97e618a0 1742 if (check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, nons))
fbc52057
SK
1743 return STAT_SECURE;
1744
1745 /* Can't find an NSEC3 which covers the name directly, we need the "closest encloser NSEC3"
1746 or an answer inferred from a wildcard record. */
5107ace1
SK
1747 closest_encloser = name;
1748 next_closest = NULL;
1749
1750 do
1751 {
1752 if (*closest_encloser == '.')
1753 closest_encloser++;
c5f4ec7d 1754
fbc52057
SK
1755 if (wildname && hostname_isequal(closest_encloser, wildname))
1756 break;
1757
a857daa3 1758 if ((digest_len = hash_name(closest_encloser, &digest, hash, salt, salt_len, iterations)) == 0)
87070192 1759 return STAT_BOGUS;
5107ace1
SK
1760
1761 for (i = 0; i < nsec_count; i++)
1762 if ((p = nsecs[i]))
1763 {
394ff492 1764 if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
a857daa3 1765 !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
87070192 1766 return STAT_BOGUS;
5107ace1 1767
a857daa3
SK
1768 if (digest_len == base32_len &&
1769 memcmp(digest, workspace2, digest_len) == 0)
5107ace1
SK
1770 break; /* Gotit */
1771 }
1772
1773 if (i != nsec_count)
1774 break;
1775
1776 next_closest = closest_encloser;
1777 }
1778 while ((closest_encloser = strchr(closest_encloser, '.')));
1779
fbc52057 1780 if (!closest_encloser)
5107ace1
SK
1781 return STAT_BOGUS;
1782
24187530 1783 /* Look for NSEC3 that proves the non-existence of the next-closest encloser */
a857daa3 1784 if ((digest_len = hash_name(next_closest, &digest, hash, salt, salt_len, iterations)) == 0)
87070192 1785 return STAT_BOGUS;
5107ace1 1786
97e618a0 1787 if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL))
87070192 1788 return STAT_BOGUS;
5107ace1 1789
fbc52057
SK
1790 /* Finally, check that there's no seat of wildcard synthesis */
1791 if (!wildname)
1792 {
1793 if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
1794 return STAT_BOGUS;
1795
1796 wildcard--;
1797 *wildcard = '*';
1798
1799 if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
1800 return STAT_BOGUS;
1801
97e618a0 1802 if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count, NULL))
fbc52057
SK
1803 return STAT_BOGUS;
1804 }
5107ace1 1805
fbc52057 1806 return STAT_SECURE;
5107ace1
SK
1807}
1808
0fc2f313 1809/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
51ea3ca2 1810/* Returns are the same as validate_rrset, plus the class if the missing key is in *class */
97e618a0
SK
1811int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname,
1812 int *class, int *neganswer, int *nons)
adca3e9c 1813{
00a5b5d4
SK
1814 unsigned char *ans_start, *qname, *p1, *p2, **nsecs;
1815 int type1, class1, rdlen1, type2, class2, rdlen2, qclass, qtype;
1fbe4d2f 1816 int i, j, rc, nsec_count, cname_count = CNAME_CHAIN;
00a5b5d4 1817 int nsec_type = 0, have_answer = 0;
adca3e9c 1818
00a5b5d4
SK
1819 if (neganswer)
1820 *neganswer = 0;
1821
87070192 1822 if (RCODE(header) == SERVFAIL || ntohs(header->qdcount) != 1)
e3ec15af
SK
1823 return STAT_BOGUS;
1824
87070192 1825 if (RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR)
72ae2f3d 1826 return STAT_INSECURE;
00a5b5d4
SK
1827
1828 qname = p1 = (unsigned char *)(header+1);
c5f4ec7d 1829
394ff492 1830 if (!extract_name(header, plen, &p1, name, 1, 4))
87070192 1831 return STAT_BOGUS;
00a5b5d4
SK
1832
1833 GETSHORT(qtype, p1);
1834 GETSHORT(qclass, p1);
1835 ans_start = p1;
9d1b22aa
SK
1836
1837 if (qtype == T_ANY)
1838 have_answer = 1;
00a5b5d4
SK
1839
1840 /* Can't validate an RRISG query */
1841 if (qtype == T_RRSIG)
0fc2f313 1842 return STAT_INSECURE;
00a5b5d4
SK
1843
1844 cname_loop:
1845 for (j = ntohs(header->ancount); j != 0; j--)
1846 {
1847 /* leave pointer to missing name in qname */
1848
1849 if (!(rc = extract_name(header, plen, &p1, name, 0, 10)))
87070192 1850 return STAT_BOGUS; /* bad packet */
00a5b5d4
SK
1851
1852 GETSHORT(type2, p1);
1853 GETSHORT(class2, p1);
1854 p1 += 4; /* TTL */
1855 GETSHORT(rdlen2, p1);
1856
1857 if (rc == 1 && qclass == class2)
1858 {
1859 /* Do we have an answer for the question? */
1860 if (type2 == qtype)
1861 {
1862 have_answer = 1;
1863 break;
1864 }
1865 else if (type2 == T_CNAME)
1866 {
1867 qname = p1;
1868
1869 /* looped CNAMES */
394ff492 1870 if (!cname_count-- || !extract_name(header, plen, &p1, name, 1, 0))
87070192 1871 return STAT_BOGUS;
00a5b5d4
SK
1872
1873 p1 = ans_start;
1874 goto cname_loop;
1875 }
1876 }
1877
1878 if (!ADD_RDLEN(header, p1, plen, rdlen2))
87070192 1879 return STAT_BOGUS;
00a5b5d4 1880 }
0fc2f313 1881
00a5b5d4
SK
1882 if (neganswer && !have_answer)
1883 *neganswer = 1;
e3ec6f0b 1884
0575610f
SK
1885 /* No data, therefore no sigs */
1886 if (ntohs(header->ancount) + ntohs(header->nscount) == 0)
e3ec6f0b
SK
1887 {
1888 *keyname = 0;
1889 return STAT_NO_SIG;
1890 }
1891
0fc2f313 1892 for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
adca3e9c 1893 {
394ff492 1894 if (!extract_name(header, plen, &p1, name, 1, 10))
87070192 1895 return STAT_BOGUS; /* bad packet */
0fc2f313
SK
1896
1897 GETSHORT(type1, p1);
1898 GETSHORT(class1, p1);
1899 p1 += 4; /* TTL */
1900 GETSHORT(rdlen1, p1);
1901
1902 /* Don't try and validate RRSIGs! */
1903 if (type1 != T_RRSIG)
1904 {
1905 /* Check if we've done this RRset already */
1906 for (p2 = ans_start, j = 0; j < i; j++)
1907 {
1908 if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
87070192 1909 return STAT_BOGUS; /* bad packet */
0fc2f313
SK
1910
1911 GETSHORT(type2, p2);
1912 GETSHORT(class2, p2);
1913 p2 += 4; /* TTL */
1914 GETSHORT(rdlen2, p2);
1915
1916 if (type2 == type1 && class2 == class1 && rc == 1)
1917 break; /* Done it before: name, type, class all match. */
1918
1919 if (!ADD_RDLEN(header, p2, plen, rdlen2))
87070192 1920 return STAT_BOGUS;
0fc2f313
SK
1921 }
1922
1923 /* Not done, validate now */
51ea3ca2 1924 if (j == i)
0fc2f313 1925 {
8d718cbb
SK
1926 int ttl, keytag, algo, digest, type_covered;
1927 unsigned char *psave;
1928 struct all_addr a;
1929 struct blockdata *key;
1930 struct crec *crecp;
fbc52057 1931 char *wildname;
5e321739 1932 int have_wildcard = 0;
fbc52057
SK
1933
1934 rc = validate_rrset(now, header, plen, class1, type1, name, keyname, &wildname, NULL, 0, 0, 0);
5107ace1
SK
1935
1936 if (rc == STAT_SECURE_WILDCARD)
1937 {
5e321739
SK
1938 have_wildcard = 1;
1939
5107ace1 1940 /* An attacker replay a wildcard answer with a different
a857daa3 1941 answer and overlay a genuine RR. To prove this
5107ace1 1942 hasn't happened, the answer must prove that
a857daa3 1943 the gennuine record doesn't exist. Check that here. */
87070192
SK
1944 if (!nsec_type && !(nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, class1)))
1945 return STAT_BOGUS; /* No NSECs or bad packet */
5107ace1
SK
1946
1947 if (nsec_type == T_NSEC)
97e618a0 1948 rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1, NULL);
5107ace1 1949 else
97e618a0
SK
1950 rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename,
1951 keyname, name, type1, wildname, NULL);
1952
5107ace1
SK
1953 if (rc != STAT_SECURE)
1954 return rc;
1955 }
1956 else if (rc != STAT_SECURE)
51ea3ca2
SK
1957 {
1958 if (class)
1959 *class = class1; /* Class for DS or DNSKEY */
e3ec6f0b
SK
1960
1961 if (rc == STAT_NO_SIG)
1962 {
1963 /* If we dropped off the end of a CNAME chain, return
1964 STAT_NO_SIG and the last name is keyname. This is used for proving non-existence
1965 if DS records in CNAME chains. */
1966 if (cname_count == CNAME_CHAIN || i < ntohs(header->ancount))
1967 /* No CNAME chain, or no sig in answer section, return empty name. */
1968 *keyname = 0;
1969 else if (!extract_name(header, plen, &qname, keyname, 1, 0))
1970 return STAT_BOGUS;
1971 }
1972
51ea3ca2
SK
1973 return rc;
1974 }
5107ace1 1975
8d718cbb
SK
1976 /* Cache RRsigs in answer section, and if we just validated a DS RRset, cache it */
1977 cache_start_insert();
1978
1979 for (p2 = ans_start, j = 0; j < ntohs(header->ancount); j++)
51ea3ca2 1980 {
8d718cbb 1981 if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
87070192 1982 return STAT_BOGUS; /* bad packet */
51ea3ca2 1983
8d718cbb
SK
1984 GETSHORT(type2, p2);
1985 GETSHORT(class2, p2);
1986 GETLONG(ttl, p2);
1987 GETSHORT(rdlen2, p2);
1988
1989 if (!CHECK_LEN(header, p2, plen, rdlen2))
87070192 1990 return STAT_BOGUS; /* bad packet */
8d718cbb
SK
1991
1992 if (class2 == class1 && rc == 1)
1993 {
1994 psave = p2;
1995
1996 if (type1 == T_DS && type2 == T_DS)
51ea3ca2 1997 {
8d718cbb 1998 if (rdlen2 < 4)
87070192 1999 return STAT_BOGUS; /* bad packet */
8d718cbb 2000
51ea3ca2
SK
2001 GETSHORT(keytag, p2);
2002 algo = *p2++;
2003 digest = *p2++;
2004
2005 /* Cache needs to known class for DNSSEC stuff */
2006 a.addr.dnssec.class = class2;
2007
8d718cbb 2008 if ((key = blockdata_alloc((char*)p2, rdlen2 - 4)))
51ea3ca2 2009 {
8d718cbb
SK
2010 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
2011 blockdata_free(key);
2012 else
2013 {
2014 a.addr.keytag = keytag;
25cf5e37 2015 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %u");
8d718cbb
SK
2016 crecp->addr.ds.digest = digest;
2017 crecp->addr.ds.keydata = key;
2018 crecp->addr.ds.algo = algo;
2019 crecp->addr.ds.keytag = keytag;
8d718cbb
SK
2020 crecp->addr.ds.keylen = rdlen2 - 4;
2021 }
2022 }
2023 }
2024 else if (type2 == T_RRSIG)
2025 {
2026 if (rdlen2 < 18)
87070192 2027 return STAT_BOGUS; /* bad packet */
51ea3ca2 2028
8d718cbb
SK
2029 GETSHORT(type_covered, p2);
2030
2031 if (type_covered == type1 &&
2032 (type_covered == T_A || type_covered == T_AAAA ||
2033 type_covered == T_CNAME || type_covered == T_DS ||
2034 type_covered == T_DNSKEY || type_covered == T_PTR))
2035 {
2036 a.addr.dnssec.type = type_covered;
c8ca33f8 2037 a.addr.dnssec.class = class1;
8d718cbb
SK
2038
2039 algo = *p2++;
2040 p2 += 13; /* labels, orig_ttl, expiration, inception */
2041 GETSHORT(keytag, p2);
2042
5e321739
SK
2043 /* We don't cache sigs for wildcard answers, because to reproduce the
2044 answer from the cache will require one or more NSEC/NSEC3 records
2045 which we don't cache. The lack of the RRSIG ensures that a query for
2046 this RRset asking for a secure answer will always be forwarded. */
2047 if (!have_wildcard && (key = blockdata_alloc((char*)psave, rdlen2)))
8d718cbb
SK
2048 {
2049 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS)))
2050 blockdata_free(key);
2051 else
2052 {
8d718cbb
SK
2053 crecp->addr.sig.keydata = key;
2054 crecp->addr.sig.keylen = rdlen2;
2055 crecp->addr.sig.keytag = keytag;
2056 crecp->addr.sig.type_covered = type_covered;
2057 crecp->addr.sig.algo = algo;
2058 }
2059 }
2060 }
51ea3ca2
SK
2061 }
2062
8d718cbb 2063 p2 = psave;
51ea3ca2
SK
2064 }
2065
8d718cbb 2066 if (!ADD_RDLEN(header, p2, plen, rdlen2))
87070192 2067 return STAT_BOGUS; /* bad packet */
51ea3ca2 2068 }
8d718cbb
SK
2069
2070 cache_end_insert();
0fc2f313
SK
2071 }
2072 }
adca3e9c 2073
0fc2f313 2074 if (!ADD_RDLEN(header, p1, plen, rdlen1))
87070192 2075 return STAT_BOGUS;
adca3e9c
GB
2076 }
2077
c5f4ec7d 2078 /* OK, all the RRsets validate, now see if we have a NODATA or NXDOMAIN reply */
00a5b5d4
SK
2079 if (have_answer)
2080 return STAT_SECURE;
2081
5107ace1 2082 /* NXDOMAIN or NODATA reply, prove that (name, class1, type1) can't exist */
5107ace1 2083 /* First marshall the NSEC records, if we've not done it previously */
87070192 2084 if (!nsec_type && !(nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, qclass)))
e3ec6f0b
SK
2085 {
2086 /* No NSEC records. If we dropped off the end of a CNAME chain, return
2087 STAT_NO_SIG and the last name is keyname. This is used for proving non-existence
2088 if DS records in CNAME chains. */
2089 if (cname_count == CNAME_CHAIN) /* No CNAME chain, return empty name. */
2090 *keyname = 0;
2091 else if (!extract_name(header, plen, &qname, keyname, 1, 0))
2092 return STAT_BOGUS;
2093 return STAT_NO_SIG; /* No NSECs, this is probably a dangling CNAME pointing into
2094 an unsigned zone. Return STAT_NO_SIG to cause this to be proved. */
2095 }
00a5b5d4
SK
2096
2097 /* Get name of missing answer */
394ff492 2098 if (!extract_name(header, plen, &qname, name, 1, 0))
87070192 2099 return STAT_BOGUS;
5107ace1
SK
2100
2101 if (nsec_type == T_NSEC)
97e618a0 2102 return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, nons);
5107ace1 2103 else
97e618a0 2104 return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, NULL, nons);
e292e93d
GB
2105}
2106
00a5b5d4
SK
2107/* Chase the CNAME chain in the packet until the first record which _doesn't validate.
2108 Needed for proving answer in unsigned space.
2109 Return STAT_NEED_*
2110 STAT_BOGUS - error
2111 STAT_INSECURE - name of first non-secure record in name
2112*/
2113int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname)
2114{
2115 unsigned char *p = (unsigned char *)(header+1);
c07d30dc 2116 int type, class, qclass, rdlen, j, rc;
1fbe4d2f 2117 int cname_count = CNAME_CHAIN;
13480e8c 2118 char *wildname;
00a5b5d4
SK
2119
2120 /* Get question */
394ff492 2121 if (!extract_name(header, plen, &p, name, 1, 4))
00a5b5d4
SK
2122 return STAT_BOGUS;
2123
c07d30dc 2124 p +=2; /* type */
00a5b5d4
SK
2125 GETSHORT(qclass, p);
2126
2127 while (1)
2128 {
2129 for (j = ntohs(header->ancount); j != 0; j--)
2130 {
2131 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
2132 return STAT_BOGUS; /* bad packet */
2133
2134 GETSHORT(type, p);
2135 GETSHORT(class, p);
2136 p += 4; /* TTL */
2137 GETSHORT(rdlen, p);
2138
2139 /* Not target, loop */
2140 if (rc == 2 || qclass != class)
2141 {
2142 if (!ADD_RDLEN(header, p, plen, rdlen))
2143 return STAT_BOGUS;
2144 continue;
2145 }
2146
2147 /* Got to end of CNAME chain. */
2148 if (type != T_CNAME)
2149 return STAT_INSECURE;
2150
2151 /* validate CNAME chain, return if insecure or need more data */
13480e8c
SK
2152 rc = validate_rrset(now, header, plen, class, type, name, keyname, &wildname, NULL, 0, 0, 0);
2153
2154 if (rc == STAT_SECURE_WILDCARD)
2155 {
2156 int nsec_type, nsec_count, i;
2157 unsigned char **nsecs;
2158
2159 /* An attacker can replay a wildcard answer with a different
2160 answer and overlay a genuine RR. To prove this
2161 hasn't happened, the answer must prove that
2162 the genuine record doesn't exist. Check that here. */
2163 if (!(nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, class)))
2164 return STAT_BOGUS; /* No NSECs or bad packet */
2165
2166 /* Note that we're called here because something didn't validate in validate_reply,
2167 so we can't assume that any NSEC records have been validated. We do them by steam here */
2168
2169 for (i = 0; i < nsec_count; i++)
2170 {
2171 unsigned char *p1 = nsecs[i];
2172
2173 if (!extract_name(header, plen, &p1, daemon->workspacename, 1, 0))
2174 return STAT_BOGUS;
2175
2176 rc = validate_rrset(now, header, plen, class, nsec_type, daemon->workspacename, keyname, NULL, NULL, 0, 0, 0);
2177
d3699bb6
SK
2178 /* NSECs can't be wildcards. */
2179 if (rc == STAT_SECURE_WILDCARD)
2180 rc = STAT_BOGUS;
2181
13480e8c
SK
2182 if (rc != STAT_SECURE)
2183 return rc;
2184 }
2185
2186 if (nsec_type == T_NSEC)
2187 rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type, NULL);
2188 else
2189 rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename,
2190 keyname, name, type, wildname, NULL);
2191
2192 if (rc != STAT_SECURE)
2193 return rc;
2194 }
2195
00a5b5d4
SK
2196 if (rc != STAT_SECURE)
2197 {
2198 if (rc == STAT_NO_SIG)
2199 rc = STAT_INSECURE;
2200 return rc;
2201 }
2202
2203 /* Loop down CNAME chain/ */
2204 if (!cname_count-- ||
394ff492 2205 !extract_name(header, plen, &p, name, 1, 0) ||
00a5b5d4
SK
2206 !(p = skip_questions(header, plen)))
2207 return STAT_BOGUS;
2208
2209 break;
2210 }
2211
2212 /* End of CNAME chain */
2213 return STAT_INSECURE;
2214 }
2215}
2216
2217
3471f181 2218/* Compute keytag (checksum to quickly index a key). See RFC4034 */
0fc2f313 2219int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
3471f181 2220{
75ffc9bf
GB
2221 if (alg == 1)
2222 {
2223 /* Algorithm 1 (RSAMD5) has a different (older) keytag calculation algorithm.
2224 See RFC4034, Appendix B.1 */
0fc2f313 2225 return key[keylen-4] * 256 + key[keylen-3];
75ffc9bf
GB
2226 }
2227 else
2228 {
1633e308 2229 unsigned long ac = flags + 0x300 + alg;
75ffc9bf
GB
2230 int i;
2231
0fc2f313
SK
2232 for (i = 0; i < keylen; ++i)
2233 ac += (i & 1) ? key[i] : key[i] << 8;
1633e308 2234
0fc2f313
SK
2235 ac += (ac >> 16) & 0xffff;
2236 return ac & 0xffff;
0304d28f 2237 }
3471f181 2238}
e292e93d 2239
a77cec8d
SK
2240size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class,
2241 int type, union mysockaddr *addr, int edns_pktsz)
5f8e58f4
SK
2242{
2243 unsigned char *p;
610e782a 2244 char *types = querystr("dnssec-query", type);
a77cec8d 2245 size_t ret;
5f8e58f4
SK
2246
2247 if (addr->sa.sa_family == AF_INET)
25cf5e37 2248 log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types);
5f8e58f4
SK
2249#ifdef HAVE_IPV6
2250 else
25cf5e37 2251 log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types);
5f8e58f4
SK
2252#endif
2253
2254 header->qdcount = htons(1);
2255 header->ancount = htons(0);
2256 header->nscount = htons(0);
2257 header->arcount = htons(0);
e292e93d 2258
5f8e58f4
SK
2259 header->hb3 = HB3_RD;
2260 SET_OPCODE(header, QUERY);
5b3bf921
SK
2261 /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
2262 this allows it to select auth servers when one is returning bad data. */
2263 header->hb4 = option_bool(OPT_DNSSEC_DEBUG) ? HB4_CD : 0;
5f8e58f4
SK
2264
2265 /* ID filled in later */
2266
2267 p = (unsigned char *)(header+1);
2268
2269 p = do_rfc1035_name(p, name);
2270 *p++ = 0;
2271 PUTSHORT(type, p);
2272 PUTSHORT(class, p);
2273
a77cec8d
SK
2274 ret = add_do_bit(header, p - (unsigned char *)header, end);
2275
2276 if (find_pseudoheader(header, ret, NULL, &p, NULL))
2277 PUTSHORT(edns_pktsz, p);
2278
2279 return ret;
5f8e58f4 2280}
8a9be9e4 2281
613ad15d
SK
2282/* Go through a domain name, find "pointers" and fix them up based on how many bytes
2283 we've chopped out of the packet, or check they don't point into an elided part. */
2284static int check_name(unsigned char **namep, struct dns_header *header, size_t plen, int fixup, unsigned char **rrs, int rr_count)
2285{
2286 unsigned char *ansp = *namep;
2287
2288 while(1)
2289 {
2290 unsigned int label_type;
2291
2292 if (!CHECK_LEN(header, ansp, plen, 1))
2293 return 0;
2294
2295 label_type = (*ansp) & 0xc0;
2296
2297 if (label_type == 0xc0)
2298 {
2299 /* pointer for compression. */
00a5b5d4
SK
2300 unsigned int offset;
2301 int i;
613ad15d
SK
2302 unsigned char *p;
2303
2304 if (!CHECK_LEN(header, ansp, plen, 2))
2305 return 0;
2306
2307 offset = ((*ansp++) & 0x3f) << 8;
2308 offset |= *ansp++;
2309
2310 p = offset + (unsigned char *)header;
2311
2312 for (i = 0; i < rr_count; i++)
2313 if (p < rrs[i])
2314 break;
2315 else
2316 if (i & 1)
2317 offset -= rrs[i] - rrs[i-1];
2318
2319 /* does the pointer end up in an elided RR? */
2320 if (i & 1)
00a5b5d4 2321 return 0;
613ad15d
SK
2322
2323 /* No, scale the pointer */
2324 if (fixup)
2325 {
2326 ansp -= 2;
2327 *ansp++ = (offset >> 8) | 0xc0;
2328 *ansp++ = offset & 0xff;
2329 }
2330 break;
2331 }
2332 else if (label_type == 0x80)
2333 return 0; /* reserved */
2334 else if (label_type == 0x40)
2335 {
2336 /* Extended label type */
2337 unsigned int count;
2338
2339 if (!CHECK_LEN(header, ansp, plen, 2))
2340 return 0;
2341
2342 if (((*ansp++) & 0x3f) != 1)
2343 return 0; /* we only understand bitstrings */
2344
2345 count = *(ansp++); /* Bits in bitstring */
2346
2347 if (count == 0) /* count == 0 means 256 bits */
2348 ansp += 32;
2349 else
2350 ansp += ((count-1)>>3)+1;
2351 }
2352 else
2353 { /* label type == 0 Bottom six bits is length */
2354 unsigned int len = (*ansp++) & 0x3f;
2355
2356 if (!ADD_RDLEN(header, ansp, plen, len))
2357 return 0;
2358
2359 if (len == 0)
2360 break; /* zero length label marks the end. */
2361 }
2362 }
2363
2364 *namep = ansp;
2365
2366 return 1;
2367}
2368
2369/* Go through RRs and check or fixup the domain names contained within */
2370static int check_rrs(unsigned char *p, struct dns_header *header, size_t plen, int fixup, unsigned char **rrs, int rr_count)
2371{
2372 int i, type, class, rdlen;
00a5b5d4 2373 unsigned char *pp;
613ad15d 2374
50f86ce8 2375 for (i = 0; i < ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount); i++)
613ad15d 2376 {
00a5b5d4
SK
2377 pp = p;
2378
2379 if (!(p = skip_name(p, header, plen, 10)))
2380 return 0;
613ad15d
SK
2381
2382 GETSHORT(type, p);
2383 GETSHORT(class, p);
2384 p += 4; /* TTL */
2385 GETSHORT(rdlen, p);
00a5b5d4 2386
613ad15d
SK
2387 if (type != T_NSEC && type != T_NSEC3 && type != T_RRSIG)
2388 {
00a5b5d4
SK
2389 /* fixup name of RR */
2390 if (!check_name(&pp, header, plen, fixup, rrs, rr_count))
2391 return 0;
2392
613ad15d
SK
2393 if (class == C_IN)
2394 {
2395 u16 *d;
14db4212
SK
2396
2397 for (pp = p, d = get_desc(type); *d != (u16)-1; d++)
613ad15d
SK
2398 {
2399 if (*d != 0)
2400 pp += *d;
2401 else if (!check_name(&pp, header, plen, fixup, rrs, rr_count))
2402 return 0;
2403 }
2404 }
2405 }
2406
2407 if (!ADD_RDLEN(header, p, plen, rdlen))
2408 return 0;
2409 }
2410
2411 return 1;
2412}
2413
2414
2415size_t filter_rrsigs(struct dns_header *header, size_t plen)
2416{
2417 static unsigned char **rrs;
2418 static int rr_sz = 0;
2419
2420 unsigned char *p = (unsigned char *)(header+1);
50f86ce8 2421 int i, rdlen, qtype, qclass, rr_found, chop_an, chop_ns, chop_ar;
613ad15d
SK
2422
2423 if (ntohs(header->qdcount) != 1 ||
2424 !(p = skip_name(p, header, plen, 4)))
2425 return plen;
2426
2427 GETSHORT(qtype, p);
2428 GETSHORT(qclass, p);
2429
2430 /* First pass, find pointers to start and end of all the records we wish to elide:
2431 records added for DNSSEC, unless explicity queried for */
50f86ce8
SK
2432 for (rr_found = 0, chop_ns = 0, chop_an = 0, chop_ar = 0, i = 0;
2433 i < ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount);
2434 i++)
613ad15d
SK
2435 {
2436 unsigned char *pstart = p;
2437 int type, class;
2438
2439 if (!(p = skip_name(p, header, plen, 10)))
2440 return plen;
2441
2442 GETSHORT(type, p);
2443 GETSHORT(class, p);
2444 p += 4; /* TTL */
2445 GETSHORT(rdlen, p);
2446
2447 if ((type == T_NSEC || type == T_NSEC3 || type == T_RRSIG) &&
2448 (type != qtype || class != qclass))
2449 {
2450 if (!expand_workspace(&rrs, &rr_sz, rr_found + 1))
2451 return plen;
2452
2453 rrs[rr_found++] = pstart;
2454
2455 if (!ADD_RDLEN(header, p, plen, rdlen))
2456 return plen;
2457
2458 rrs[rr_found++] = p;
2459
2460 if (i < ntohs(header->ancount))
2461 chop_an++;
e6096e64 2462 else if (i < (ntohs(header->nscount) + ntohs(header->ancount)))
613ad15d 2463 chop_ns++;
50f86ce8
SK
2464 else
2465 chop_ar++;
613ad15d
SK
2466 }
2467 else if (!ADD_RDLEN(header, p, plen, rdlen))
2468 return plen;
2469 }
2470
2471 /* Nothing to do. */
2472 if (rr_found == 0)
2473 return plen;
2474
2475 /* Second pass, look for pointers in names in the records we're keeping and make sure they don't
2476 point to records we're going to elide. This is theoretically possible, but unlikely. If
2477 it happens, we give up and leave the answer unchanged. */
2478 p = (unsigned char *)(header+1);
2479
2480 /* question first */
2481 if (!check_name(&p, header, plen, 0, rrs, rr_found))
2482 return plen;
2483 p += 4; /* qclass, qtype */
2484
2485 /* Now answers and NS */
2486 if (!check_rrs(p, header, plen, 0, rrs, rr_found))
2487 return plen;
2488
2489 /* Third pass, elide records */
2490 for (p = rrs[0], i = 1; i < rr_found; i += 2)
2491 {
2492 unsigned char *start = rrs[i];
2493 unsigned char *end = (i != rr_found - 1) ? rrs[i+1] : ((unsigned char *)(header+1)) + plen;
2494
2495 memmove(p, start, end-start);
2496 p += end-start;
2497 }
2498
2499 plen = p - (unsigned char *)header;
2500 header->ancount = htons(ntohs(header->ancount) - chop_an);
2501 header->nscount = htons(ntohs(header->nscount) - chop_ns);
50f86ce8
SK
2502 header->arcount = htons(ntohs(header->arcount) - chop_ar);
2503
613ad15d
SK
2504 /* Fourth pass, fix up pointers in the remaining records */
2505 p = (unsigned char *)(header+1);
2506
2507 check_name(&p, header, plen, 1, rrs, rr_found);
2508 p += 4; /* qclass, qtype */
2509
2510 check_rrs(p, header, plen, 1, rrs, rr_found);
2511
2512 return plen;
2513}
2514
8a9be9e4
SK
2515unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name)
2516{
2517 int q;
2518 unsigned int len;
2519 unsigned char *p = (unsigned char *)(header+1);
2520 const struct nettle_hash *hash;
2521 void *ctx;
2522 unsigned char *digest;
5f8e58f4 2523
8a9be9e4
SK
2524 if (!(hash = hash_find("sha1")) || !hash_init(hash, &ctx, &digest))
2525 return NULL;
2526
2527 for (q = ntohs(header->qdcount); q != 0; q--)
2528 {
394ff492 2529 if (!extract_name(header, plen, &p, name, 1, 4))
7d23a66f 2530 break; /* bad packet */
8a9be9e4
SK
2531
2532 len = to_wire(name);
2533 hash->update(ctx, len, (unsigned char *)name);
2534 /* CRC the class and type as well */
2535 hash->update(ctx, 4, p);
2536
2537 p += 4;
2538 if (!CHECK_LEN(header, p, plen, 0))
7d23a66f 2539 break; /* bad packet */
8a9be9e4 2540 }
703c7ff4
SK
2541
2542 hash->digest(ctx, hash->digest_size, digest);
8a9be9e4
SK
2543 return digest;
2544}
2545
0fc2f313 2546#endif /* HAVE_DNSSEC */