]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/dnssec.c
bug fix, avoids infinite loop in forwarding code.
[people/ms/dnsmasq.git] / src / dnssec.c
CommitLineData
8d41ebd8 1/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
0fc2f313 2 and Copyright (c) 2012-2014 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>
24#include <nettle/nettle-meta.h>
25#include <gmp.h>
c3e0b9b6 26
e292e93d
GB
27#define SERIAL_UNDEF -100
28#define SERIAL_EQ 0
29#define SERIAL_LT -1
30#define SERIAL_GT 1
31
86bec2d3
SK
32/* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
33static char *ds_digest_name(int digest)
34{
35 switch (digest)
36 {
37 case 1: return "sha1";
38 case 2: return "sha256";
39 case 3: return "gosthash94";
40 case 4: return "sha384";
41 default: return NULL;
42 }
43}
44
45/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
46static char *algo_digest_name(int algo)
47{
48 switch (algo)
49 {
50 case 1: return "md5";
51 case 3: return "sha1";
52 case 5: return "sha1";
53 case 6: return "sha1";
54 case 7: return "sha1";
55 case 8: return "sha256";
56 case 10: return "sha512";
57 case 12: return "gosthash94";
58 case 13: return "sha256";
59 case 14: return "sha384";
60 default: return NULL;
61 }
62}
63
64/* Find pointer to correct hash function in nettle library */
65static const struct nettle_hash *hash_find(char *name)
66{
67 int i;
68
69 if (!name)
70 return NULL;
71
72 for (i = 0; nettle_hashes[i]; i++)
73 {
74 if (strcmp(nettle_hashes[i]->name, name) == 0)
75 return nettle_hashes[i];
76 }
77
78 return NULL;
79}
80
81/* expand ctx and digest memory allocations if necessary and init hash function */
82static int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
83{
84 static void *ctx = NULL;
85 static unsigned char *digest = NULL;
86 static unsigned int ctx_sz = 0;
87 static unsigned int digest_sz = 0;
88
89 void *new;
90
91 if (ctx_sz < hash->context_size)
92 {
93 if (!(new = whine_malloc(hash->context_size)))
94 return 0;
95 if (ctx)
96 free(ctx);
97 ctx = new;
98 ctx_sz = hash->context_size;
99 }
100
101 if (digest_sz < hash->digest_size)
102 {
103 if (!(new = whine_malloc(hash->digest_size)))
104 return 0;
105 if (digest)
106 free(digest);
107 digest = new;
108 digest_sz = hash->digest_size;
109 }
110
111 *ctxp = ctx;
112 *digestp = digest;
113
114 hash->init(ctx);
115
116 return 1;
117}
118
119static int rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
120 unsigned char *digest, int algo)
121{
122 unsigned char *p;
123 size_t exp_len;
124
125 static struct rsa_public_key *key = NULL;
126 static mpz_t sig_mpz;
127
128 if (key == NULL)
129 {
130 if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
131 return 0;
132
133 nettle_rsa_public_key_init(key);
134 mpz_init(sig_mpz);
135 }
136
137 if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
138 return 0;
139
140 key_len--;
141 if ((exp_len = *p++) == 0)
142 {
143 GETSHORT(exp_len, p);
144 key_len -= 2;
145 }
146
147 if (exp_len >= key_len)
148 return 0;
149
150 key->size = key_len - exp_len;
151 mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
152 mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
153
154 mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
155
156 switch (algo)
157 {
158 case 1:
159 return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
160 case 5: case 7:
161 return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
162 case 8:
163 return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
164 case 10:
165 return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
166 }
167
168 return 0;
169}
170
171static int dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
172 unsigned char *digest, int algo)
173{
174 unsigned char *p;
175 unsigned int t;
176
177 static struct dsa_public_key *key = NULL;
178 static struct dsa_signature *sig_struct;
179
180 if (key == NULL)
181 {
182 if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
183 !(key = whine_malloc(sizeof(struct dsa_public_key))))
184 return 0;
185
186 nettle_dsa_public_key_init(key);
187 nettle_dsa_signature_init(sig_struct);
188 }
189
190 if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
191 return 0;
192
193 t = *p++;
194
195 if (key_len < (213 + (t * 24)))
196 return 0;
197
198 mpz_import(key->q, 20, 1, 1, 0, 0, p); p += 20;
199 mpz_import(key->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
200 mpz_import(key->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
201 mpz_import(key->y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
202
203 mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
204 mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
205
206 (void)algo;
207
208 return nettle_dsa_sha1_verify_digest(key, digest, sig_struct);
209}
210
211static int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
212 unsigned char *digest, int algo)
213{
214 switch (algo)
215 {
216 case 1: case 5: case 7: case 8: case 10:
217 return rsa_verify(key_data, key_len, sig, sig_len, digest, algo);
218
219 case 3: case 6:
220 return dsa_verify(key_data, key_len, sig, sig_len, digest, algo);
221 }
222
223 return 0;
224}
225
0fc2f313
SK
226/* Convert from presentation format to wire format, in place.
227 Also map UC -> LC.
228 Note that using extract_name to get presentation format
229 then calling to_wire() removes compression and maps case,
230 thus generating names in canonical form.
231 Calling to_wire followed by from_wire is almost an identity,
232 except that the UC remains mapped to LC.
233*/
234static int to_wire(char *name)
7f0485cf 235{
0fc2f313
SK
236 unsigned char *l, *p, term;
237 int len;
238
239 for (l = (unsigned char*)name; *l != 0; l = p)
240 {
241 for (p = l; *p != '.' && *p != 0; p++)
242 if (*p >= 'A' && *p <= 'Z')
243 *p = *p - 'A' + 'a';
244
245 term = *p;
246
247 if ((len = p - l) != 0)
248 memmove(l+1, l, len);
249 *l = len;
250
251 p++;
252
253 if (term == 0)
254 *p = 0;
255 }
256
257 return l + 1 - (unsigned char *)name;
7f0485cf
GB
258}
259
0fc2f313
SK
260/* Note: no compression allowed in input. */
261static void from_wire(char *name)
13e435eb 262{
0fc2f313
SK
263 unsigned char *l;
264 int len;
13e435eb 265
0fc2f313 266 for (l = (unsigned char *)name; *l != 0; l += len+1)
13e435eb 267 {
0fc2f313
SK
268 len = *l;
269 memmove(l, l+1, len);
270 l[len] = '.';
13e435eb 271 }
7f0485cf 272
0fc2f313 273 *(l-1) = 0;
13e435eb
GB
274}
275
5ada8885
SK
276/* Input in presentation format */
277static int count_labels(char *name)
278{
279 int i;
280
281 if (*name == 0)
282 return 0;
283
284 for (i = 0; *name; name++)
285 if (*name == '.')
286 i++;
287
288 return i+1;
289}
290
5f8e58f4
SK
291/* Implement RFC1982 wrapped compare for 32-bit numbers */
292static int serial_compare_32(unsigned long s1, unsigned long s2)
293{
294 if (s1 == s2)
295 return SERIAL_EQ;
0ca895f5 296
5f8e58f4
SK
297 if ((s1 < s2 && (s2 - s1) < (1UL<<31)) ||
298 (s1 > s2 && (s1 - s2) > (1UL<<31)))
299 return SERIAL_LT;
300 if ((s1 < s2 && (s2 - s1) > (1UL<<31)) ||
301 (s1 > s2 && (s1 - s2) < (1UL<<31)))
302 return SERIAL_GT;
303 return SERIAL_UNDEF;
304}
0852d76b 305
5f8e58f4
SK
306/* Check whether today/now is between date_start and date_end */
307static int check_date_range(unsigned long date_start, unsigned long date_end)
0852d76b 308{
5f8e58f4
SK
309 unsigned long curtime = time(0);
310
311 /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
312 return serial_compare_32(curtime, date_start) == SERIAL_GT
313 && serial_compare_32(curtime, date_end) == SERIAL_LT;
314}
f119ed38 315
5f8e58f4
SK
316static u16 *get_desc(int type)
317{
318 /* List of RRtypes which include domains in the data.
319 0 -> domain
320 integer -> no of plain bytes
321 -1 -> end
322
323 zero is not a valid RRtype, so the final entry is returned for
324 anything which needs no mangling.
325 */
326
327 static u16 rr_desc[] =
328 {
329 T_NS, 0, -1,
330 T_MD, 0, -1,
331 T_MF, 0, -1,
332 T_CNAME, 0, -1,
333 T_SOA, 0, 0, -1,
334 T_MB, 0, -1,
335 T_MG, 0, -1,
336 T_MR, 0, -1,
337 T_PTR, 0, -1,
338 T_MINFO, 0, 0, -1,
339 T_MX, 2, 0, -1,
340 T_RP, 0, 0, -1,
341 T_AFSDB, 2, 0, -1,
342 T_RT, 2, 0, -1,
343 T_SIG, 18, 0, -1,
344 T_PX, 2, 0, 0, -1,
345 T_NXT, 0, -1,
346 T_KX, 2, 0, -1,
347 T_SRV, 6, 0, -1,
348 T_DNAME, 0, -1,
5f8e58f4
SK
349 0, -1 /* wildcard/catchall */
350 };
351
352 u16 *p = rr_desc;
353
354 while (*p != type && *p != 0)
355 while (*p++ != (u16)-1);
f119ed38 356
5f8e58f4
SK
357 return p+1;
358}
0852d76b 359
5f8e58f4
SK
360/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
361 data, pointed to by *p, should be used raw. */
362static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff,
363 unsigned char **p, u16 **desc)
364{
365 int d = **desc;
366
367 (*desc)++;
368
369 /* No more data needs mangling */
370 if (d == (u16)-1)
371 return 0;
372
373 if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
374 /* domain-name, canonicalise */
375 return to_wire(buff);
376 else
377 {
378 /* plain data preceding a domain-name, don't run off the end of the data */
379 if ((end - *p) < d)
380 d = end - *p;
381
382 if (d != 0)
383 {
384 memcpy(buff, *p, d);
385 *p += d;
386 }
387
388 return d;
389 }
0852d76b
GB
390}
391
5f8e58f4
SK
392/* Bubble sort the RRset into the canonical order.
393 Note that the byte-streams from two RRs may get unsynced: consider
394 RRs which have two domain-names at the start and then other data.
395 The domain-names may have different lengths in each RR, but sort equal
396
397 ------------
398 |abcde|fghi|
399 ------------
400 |abcd|efghi|
401 ------------
402
403 leaving the following bytes as deciding the order. Hence the nasty left1 and left2 variables.
404*/
405
406static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int rrsetidx,
407 unsigned char **rrset, char *buff1, char *buff2)
c3e0b9b6 408{
5f8e58f4 409 int swap, quit, i;
0fc2f313 410
5f8e58f4
SK
411 do
412 {
413 for (swap = 0, i = 0; i < rrsetidx-1; i++)
414 {
415 int rdlen1, rdlen2, left1, left2, len1, len2, len, rc;
416 u16 *dp1, *dp2;
417 unsigned char *end1, *end2;
418 unsigned char *p1 = skip_name(rrset[i], header, plen, 10);
419 unsigned char *p2 = skip_name(rrset[i+1], header, plen, 10);
420
421 p1 += 8; /* skip class, type, ttl */
422 GETSHORT(rdlen1, p1);
423 end1 = p1 + rdlen1;
424
425 p2 += 8; /* skip class, type, ttl */
426 GETSHORT(rdlen2, p2);
427 end2 = p2 + rdlen2;
428
429 dp1 = dp2 = rr_desc;
430
1486a9c7 431 for (quit = 0, left1 = 0, left2 = 0, len1 = 0, len2 = 0; !quit;)
5f8e58f4 432 {
1486a9c7
SK
433 if (left1 != 0)
434 memmove(buff1, buff1 + len1 - left1, left1);
435
5f8e58f4
SK
436 if ((len1 = get_rdata(header, plen, end1, buff1 + left1, &p1, &dp1)) == 0)
437 {
438 quit = 1;
439 len1 = end1 - p1;
440 memcpy(buff1 + left1, p1, len1);
441 }
442 len1 += left1;
443
1486a9c7
SK
444 if (left2 != 0)
445 memmove(buff2, buff2 + len2 - left2, left2);
446
5f8e58f4
SK
447 if ((len2 = get_rdata(header, plen, end2, buff2 + left2, &p2, &dp2)) == 0)
448 {
449 quit = 1;
450 len2 = end2 - p2;
451 memcpy(buff2 + left2, p2, len2);
452 }
453 len2 += left2;
454
455 if (len1 > len2)
1486a9c7 456 left1 = len1 - len2, left2 = 0, len = len2;
5f8e58f4 457 else
1486a9c7 458 left2 = len2 - len1, left1 = 0, len = len1;
5f8e58f4
SK
459
460 rc = memcmp(buff1, buff2, len);
461
4619d946 462 if (rc > 0 || (rc == 0 && quit && len1 > len2))
5f8e58f4
SK
463 {
464 unsigned char *tmp = rrset[i+1];
465 rrset[i+1] = rrset[i];
466 rrset[i] = tmp;
467 swap = quit = 1;
468 }
469 }
470 }
471 } while (swap);
472}
c3e0b9b6 473
5f8e58f4
SK
474/* Validate a single RRset (class, type, name) in the supplied DNS reply
475 Return code:
476 STAT_SECURE if it validates.
477 STAT_INSECURE can't validate (no RRSIG, bad packet).
478 STAT_BOGUS signature is wrong.
479 STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
480
481 if key is non-NULL, use that key, which has the algo and tag given in the params of those names,
482 otherwise find the key in the cache.
483*/
484static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class,
485 int type, char *name, char *keyname, struct blockdata *key, int keylen, int algo_in, int keytag_in)
486{
487 static unsigned char **rrset = NULL, **sigs = NULL;
488 static int rrset_sz = 0, sig_sz = 0;
0fc2f313 489
5f8e58f4 490 unsigned char *p;
5ada8885 491 int rrsetidx, sigidx, res, rdlen, j, name_labels;
5f8e58f4
SK
492 struct crec *crecp = NULL;
493 int type_covered, algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag;
494 u16 *rr_desc = get_desc(type);
c3e0b9b6 495
5f8e58f4
SK
496 if (!(p = skip_questions(header, plen)))
497 return STAT_INSECURE;
c3e0b9b6 498
5ada8885
SK
499 name_labels = count_labels(name); /* For 4035 5.3.2 check */
500
501 /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
5f8e58f4
SK
502 for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount);
503 j != 0; j--)
504 {
505 unsigned char *pstart, *pdata;
5ada8885 506 int stype, sclass;
c3e0b9b6 507
5f8e58f4
SK
508 pstart = p;
509
510 if (!(res = extract_name(header, plen, &p, name, 0, 10)))
511 return STAT_INSECURE; /* bad packet */
512
513 GETSHORT(stype, p);
514 GETSHORT(sclass, p);
5ada8885 515 p += 4; /* TTL */
5f8e58f4
SK
516
517 pdata = p;
c3e0b9b6 518
5f8e58f4
SK
519 GETSHORT(rdlen, p);
520
5f8e58f4
SK
521 if (res == 1 && sclass == class)
522 {
523 if (stype == type)
524 {
525 if (rrsetidx == rrset_sz)
526 {
527 unsigned char **new;
528
529 /* expand */
530 if (!(new = whine_malloc((rrset_sz + 5) * sizeof(unsigned char **))))
531 return STAT_INSECURE;
532
533 if (rrset)
534 {
535 memcpy(new, rrset, rrset_sz * sizeof(unsigned char **));
536 free(rrset);
537 }
538
539 rrset = new;
540 rrset_sz += 5;
541 }
542 rrset[rrsetidx++] = pstart;
543 }
544
545 if (stype == T_RRSIG)
546 {
5ada8885
SK
547 if (rdlen < 18)
548 return STAT_INSECURE; /* bad packet */
549
550 GETSHORT(type_covered, p);
551 algo = *p++;
552 labels = *p++;
553 p += 4; /* orig_ttl */
554 GETLONG(sig_expiration, p);
555 GETLONG(sig_inception, p);
556 p = pdata + 2; /* restore for ADD_RDLEN */
557
558 if (type_covered == type &&
559 check_date_range(sig_inception, sig_expiration) &&
86bec2d3 560 hash_find(algo_digest_name(algo)) &&
5ada8885
SK
561 labels <= name_labels)
562 {
563 if (sigidx == sig_sz)
564 {
565 unsigned char **new;
566
567 /* expand */
568 if (!(new = whine_malloc((sig_sz + 5) * sizeof(unsigned char **))))
569 return STAT_INSECURE;
570
571 if (sigs)
572 {
573 memcpy(new, sigs, sig_sz * sizeof(unsigned char **));
574 free(sigs);
575 }
576
577 sigs = new;
578 sig_sz += 5;
579 }
580
581 sigs[sigidx++] = pdata;
582 }
5f8e58f4
SK
583 }
584 }
585
586 if (!ADD_RDLEN(header, p, plen, rdlen))
587 return STAT_INSECURE;
588 }
c3e0b9b6 589
5f8e58f4
SK
590 /* RRset empty, no RRSIGs */
591 if (rrsetidx == 0 || sigidx == 0)
592 return STAT_INSECURE;
593
594 /* Sort RRset records into canonical order.
595 Note that at this point keyname and name buffs are
596 unused, and used as workspace by the sort. */
597 sort_rrset(header, plen, rr_desc, rrsetidx, rrset, name, keyname);
598
599 /* Now try all the sigs to try and find one which validates */
600 for (j = 0; j <sigidx; j++)
601 {
86bec2d3
SK
602 unsigned char *psav, *sig;
603 int i, wire_len, sig_len;
604 const struct nettle_hash *hash;
605 void *ctx;
606 unsigned char *digest;
5f8e58f4
SK
607 u32 nsigttl;
608
609 p = sigs[j];
5ada8885 610 GETSHORT(rdlen, p); /* rdlen >= 18 checked previously */
5f8e58f4
SK
611 psav = p;
612
5ada8885 613 p += 2; /* type_covered - already checked */
5f8e58f4
SK
614 algo = *p++;
615 labels = *p++;
616 GETLONG(orig_ttl, p);
5ada8885 617 p += 8; /* sig_expiration and sig_inception */
5f8e58f4
SK
618 GETSHORT(key_tag, p);
619
5f8e58f4
SK
620 if (!extract_name(header, plen, &p, keyname, 1, 0))
621 return STAT_INSECURE;
622
623 /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
624 if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
625 return STAT_NEED_KEY;
626
86bec2d3
SK
627 sig = p;
628 sig_len = rdlen - (p - psav);
629
630 if (!(hash = hash_find(algo_digest_name(algo))) ||
631 !hash_init(hash, &ctx, &digest))
632 continue;
5f8e58f4
SK
633
634 nsigttl = htonl(orig_ttl);
635
86bec2d3 636 hash->update(ctx, 18, psav);
5f8e58f4 637 wire_len = to_wire(keyname);
86bec2d3 638 hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
5f8e58f4
SK
639 from_wire(keyname);
640
5f8e58f4
SK
641 for (i = 0; i < rrsetidx; ++i)
642 {
643 int seg;
644 unsigned char *end, *cp;
5ada8885 645 char *name_start = name;
5f8e58f4
SK
646 u16 len, *dp;
647
648 p = rrset[i];
649 if (!extract_name(header, plen, &p, name, 1, 10))
650 return STAT_INSECURE;
5ada8885
SK
651
652 /* if more labels than in RRsig name, hash *.<no labels in rrsig labels field> 4035 5.3.2 */
653 if (labels < name_labels)
654 {
655 int k;
656 for (k = name_labels - labels; k != 0; k--)
657 while (*name_start != '.' && *name_start != 0)
658 name_start++;
659 name_start--;
660 *name_start = '*';
661 }
662
663 wire_len = to_wire(name_start);
86bec2d3
SK
664 hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name_start);
665 hash->update(ctx, 4, p); /* class and type */
666 hash->update(ctx, 4, (unsigned char *)&nsigttl);
5f8e58f4
SK
667
668 p += 8; /* skip class, type, ttl */
669 GETSHORT(rdlen, p);
5ada8885
SK
670 if (!CHECK_LEN(header, p, plen, rdlen))
671 return STAT_INSECURE;
672
5f8e58f4
SK
673 end = p + rdlen;
674
675 /* canonicalise rdata and calculate length of same, use name buffer as workspace */
676 cp = p;
677 dp = rr_desc;
678 for (len = 0; (seg = get_rdata(header, plen, end, name, &cp, &dp)) != 0; len += seg);
679 len += end - cp;
680 len = htons(len);
86bec2d3 681 hash->update(ctx, 2, (unsigned char *)&len);
5f8e58f4
SK
682
683 /* Now canonicalise again and digest. */
684 cp = p;
685 dp = rr_desc;
686 while ((seg = get_rdata(header, plen, end, name, &cp, &dp)))
86bec2d3 687 hash->update(ctx, seg, (unsigned char *)name);
5f8e58f4 688 if (cp != end)
86bec2d3 689 hash->update(ctx, end - cp, cp);
5f8e58f4 690 }
86bec2d3
SK
691
692 hash->digest(ctx, hash->digest_size, digest);
693
5ada8885
SK
694 /* namebuff used for workspace above, restore to leave unchanged on exit */
695 p = (unsigned char*)(rrset[0]);
696 extract_name(header, plen, &p, name, 1, 0);
697
5f8e58f4
SK
698 if (key)
699 {
700 if (algo_in == algo && keytag_in == key_tag &&
86bec2d3 701 verify(key, keylen, sig, sig_len, digest, algo))
5f8e58f4
SK
702 return STAT_SECURE;
703 }
704 else
705 {
706 /* iterate through all possible keys 4035 5.3.1 */
707 for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))
708 if (crecp->addr.key.algo == algo && crecp->addr.key.keytag == key_tag &&
86bec2d3 709 verify(crecp->addr.key.keydata, crecp->uid, sig, sig_len, digest, algo))
5f8e58f4
SK
710 return STAT_SECURE;
711 }
712 }
713
714 return STAT_BOGUS;
715}
716
0fc2f313 717/* The DNS packet is expected to contain the answer to a DNSKEY query.
5f8e58f4 718 Leave name of query in name.
c3e0b9b6
SK
719 Put all DNSKEYs in the answer which are valid into the cache.
720 return codes:
721 STAT_INSECURE bad packet, no DNSKEYs in reply.
722 STAT_SECURE At least one valid DNSKEY found and in cache.
0fc2f313
SK
723 STAT_BOGUS No DNSKEYs found, which can be validated with DS,
724 or self-sign for DNSKEY RRset is not valid.
725 STAT_NEED_DS DS records to validate a key not found, name in keyname
c3e0b9b6
SK
726*/
727int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
728{
0fc2f313 729 unsigned char *psave, *p = (unsigned char *)(header+1);
c3e0b9b6 730 struct crec *crecp, *recp1;
0fc2f313 731 int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag;
c3e0b9b6
SK
732 struct blockdata *key;
733
5f8e58f4
SK
734 if (ntohs(header->qdcount) != 1 ||
735 !extract_name(header, plen, &p, name, 1, 4))
736 {
737 strcpy(name, "<none>");
738 return STAT_INSECURE;
739 }
740
c3e0b9b6
SK
741 GETSHORT(qtype, p);
742 GETSHORT(qclass, p);
743
0fc2f313 744 if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
c3e0b9b6
SK
745 return STAT_INSECURE;
746
0fc2f313
SK
747 /* See if we have cached a DS record which validates this key */
748 if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
749 {
750 strcpy(keyname, name);
751 return STAT_NEED_DS;
752 }
753
c3e0b9b6
SK
754 cache_start_insert();
755
0fc2f313
SK
756 /* NOTE, we need to find ONE DNSKEY which matches the DS */
757 for (valid = 0, j = ntohs(header->ancount); j != 0; j--)
c3e0b9b6
SK
758 {
759 /* Ensure we have type, class TTL and length */
0fc2f313 760 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
c3e0b9b6
SK
761 return STAT_INSECURE; /* bad packet */
762
763 GETSHORT(qtype, p);
764 GETSHORT(qclass, p);
765 GETLONG(ttl, p);
766 GETSHORT(rdlen, p);
767
0fc2f313 768 if (qclass != class || qtype != T_DNSKEY || rc == 2)
c3e0b9b6 769 {
0fc2f313
SK
770 if (ADD_RDLEN(header, p, plen, rdlen))
771 continue;
772
773 return STAT_INSECURE; /* bad packet */
c3e0b9b6
SK
774 }
775
0fc2f313
SK
776 if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
777 return STAT_INSECURE; /* bad packet */
778
779 psave = p;
c3e0b9b6 780
c3e0b9b6 781 GETSHORT(flags, p);
0fc2f313
SK
782 if (*p++ != 3)
783 return STAT_INSECURE;
c3e0b9b6 784 algo = *p++;
0fc2f313 785 keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
c3e0b9b6 786
0fc2f313
SK
787 /* Put the key into the cache. Note that if the validation fails, we won't
788 call cache_end_insert() and this will never be committed. */
789 if ((key = blockdata_alloc((char*)p, rdlen - 4)) &&
790 (recp1 = cache_insert(name, NULL, now, ttl, F_FORWARD | F_DNSKEY)))
c3e0b9b6 791 {
0fc2f313
SK
792 recp1->uid = rdlen - 4;
793 recp1->addr.key.keydata = key;
794 recp1->addr.key.algo = algo;
795 recp1->addr.key.keytag = keytag;
c3e0b9b6
SK
796 }
797
0fc2f313
SK
798 p = psave;
799 if (!ADD_RDLEN(header, p, plen, rdlen))
800 return STAT_INSECURE; /* bad packet */
c3e0b9b6 801
0fc2f313
SK
802 /* Already determined that message is OK. Just loop stuffing cache */
803 if (valid || !key)
804 continue;
805
806 for (recp1 = crecp; recp1; recp1 = cache_find_by_name(recp1, name, now, F_DS))
86bec2d3
SK
807 {
808 void *ctx;
809 unsigned char *digest, *ds_digest;
810 const struct nettle_hash *hash;
811
812 if (recp1->addr.key.algo == algo &&
813 recp1->addr.key.keytag == keytag &&
814 (flags & 0x100) && /* zone key flag */
815 (hash = hash_find(ds_digest_name(recp1->addr.key.digest))) &&
816 hash_init(hash, &ctx, &digest))
0fc2f313 817
86bec2d3
SK
818 {
819 int wire_len = to_wire(name);
820
821 /* Note that digest may be different between DSs, so
822 we can't move this outside the loop. */
823 hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name);
824 hash->update(ctx, (unsigned int)rdlen, psave);
825 hash->digest(ctx, hash->digest_size, digest);
826
827 from_wire(name);
828
829 if (recp1->uid == (int)hash->digest_size &&
830 (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->uid, NULL)) &&
4619d946 831 memcmp(ds_digest, digest, recp1->uid) == 0 &&
86bec2d3
SK
832 validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, key, rdlen - 4, algo, keytag))
833 {
834 struct all_addr a;
835 valid = 1;
836 a.addr.keytag = keytag;
837 log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %u");
838 break;
839 }
840 }
841 }
c3e0b9b6 842 }
c3e0b9b6 843
0fc2f313
SK
844 if (valid)
845 {
846 /* commit cache insert. */
847 cache_end_insert();
848 return STAT_SECURE;
849 }
850
851 log_query(F_UPSTREAM, name, NULL, "BOGUS DNSKEY");
852 return STAT_BOGUS;
c3e0b9b6 853}
0fc2f313 854
c3e0b9b6 855/* The DNS packet is expected to contain the answer to a DS query
0fc2f313 856 Leave name of DS query in name.
c3e0b9b6
SK
857 Put all DSs in the answer which are valid into the cache.
858 return codes:
0fc2f313 859 STAT_INSECURE bad packet, no DS in reply.
c3e0b9b6
SK
860 STAT_SECURE At least one valid DS found and in cache.
861 STAT_BOGUS At least one DS found, which fails validation.
862 STAT_NEED_DNSKEY DNSKEY records to validate a DS not found, name in keyname
863*/
864
865int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
866{
0fc2f313
SK
867 unsigned char *psave, *p = (unsigned char *)(header+1);
868 struct crec *crecp;
e0c0ad3b 869 int qtype, qclass, val, j;
c3e0b9b6
SK
870 struct blockdata *key;
871
5f8e58f4
SK
872 if (ntohs(header->qdcount) != 1 ||
873 !extract_name(header, plen, &p, name, 1, 4))
874 {
875 strcpy(name, "<none>");
876 return STAT_INSECURE;
877 }
878
c3e0b9b6
SK
879 GETSHORT(qtype, p);
880 GETSHORT(qclass, p);
881
0fc2f313 882 if (qtype != T_DS || qclass != class || ntohs(header->ancount) == 0)
c3e0b9b6 883 return STAT_INSECURE;
0fc2f313
SK
884
885 val = validate_rrset(now, header, plen, class, T_DS, name, keyname, NULL, 0, 0, 0);
886
887 if (val == STAT_BOGUS)
888 log_query(F_UPSTREAM, name, NULL, "BOGUS DS");
c3e0b9b6
SK
889
890 /* failed to validate or missing key. */
891 if (val != STAT_SECURE)
892 return val;
893
894 cache_start_insert();
895
e0c0ad3b 896 for (j = ntohs(header->ancount); j != 0; j--)
c3e0b9b6 897 {
0fc2f313 898 int ttl, rdlen, rc, algo, digest, keytag;
c3e0b9b6
SK
899
900 /* Ensure we have type, class TTL and length */
901 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
902 return STAT_INSECURE; /* bad packet */
903
904 GETSHORT(qtype, p);
905 GETSHORT(qclass, p);
906 GETLONG(ttl, p);
907 GETSHORT(rdlen, p);
908
909 /* check type, class and name, skip if not in DS rrset */
0fc2f313 910 if (qclass == class && qtype == T_DS && rc == 1)
c3e0b9b6 911 {
0fc2f313
SK
912 if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
913 return STAT_INSECURE; /* bad packet */
914
915 psave = p;
916 GETSHORT(keytag, p);
917 algo = *p++;
918 digest = *p++;
c3e0b9b6
SK
919
920 /* We've proved that the DS is OK, store it in the cache */
0fc2f313
SK
921 if ((key = blockdata_alloc((char*)p, rdlen - 4)) &&
922 (crecp = cache_insert(name, NULL, now, ttl, F_FORWARD | F_DS)))
c3e0b9b6 923 {
0fc2f313
SK
924 struct all_addr a;
925 a.addr.keytag = keytag;
926 log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %u");
927 crecp->addr.key.digest = digest;
c3e0b9b6
SK
928 crecp->addr.key.keydata = key;
929 crecp->addr.key.algo = algo;
0fc2f313 930 crecp->addr.key.keytag = keytag;
b6e9e7c3 931 crecp->uid = rdlen - 4;
c3e0b9b6 932 }
0fc2f313
SK
933 else
934 return STAT_INSECURE; /* cache problem */
935
936 p = psave;
c3e0b9b6 937 }
0fc2f313
SK
938
939 if (!ADD_RDLEN(header, p, plen, rdlen))
940 return STAT_INSECURE; /* bad packet */
941
c3e0b9b6
SK
942 }
943
944 cache_end_insert();
945
0fc2f313 946 return STAT_SECURE;
c3e0b9b6
SK
947}
948
c5f4ec7d
SK
949/* 4034 6.1 */
950static int hostname_cmp(const char *a, const char *b)
951{
dbf72123
SK
952 char *sa, *ea, *ca, *sb, *eb, *cb;
953 unsigned char ac, bc;
954
955 sa = ea = (char *)a + strlen(a);
956 sb = eb = (char *)b + strlen(b);
957
c5f4ec7d
SK
958 while (1)
959 {
dbf72123
SK
960 while (sa != a && *(sa-1) != '.')
961 sa--;
c5f4ec7d 962
dbf72123
SK
963 while (sb != b && *(sb-1) != '.')
964 sb--;
965
966 ca = sa;
967 cb = sb;
968
969 while (1)
970 {
971 if (ca == ea)
972 {
973 if (cb == eb)
974 break;
975
976 return -1;
977 }
c5f4ec7d 978
dbf72123
SK
979 if (cb == eb)
980 return 1;
981
982 ac = (unsigned char) *ca++;
983 bc = (unsigned char) *cb++;
984
985 if (ac >= 'A' && ac <= 'Z')
986 ac += 'a' - 'A';
987 if (bc >= 'A' && bc <= 'Z')
988 bc += 'a' - 'A';
989
979cdf9b 990 if (ac < bc)
dbf72123
SK
991 return -1;
992 else if (ac != bc)
993 return 1;
994 }
c5f4ec7d 995
dbf72123
SK
996
997 if (sa == a)
c5f4ec7d 998 {
dbf72123
SK
999 if (sb == b)
1000 return 0;
c5f4ec7d 1001
dbf72123 1002 return -1;
c5f4ec7d
SK
1003 }
1004
dbf72123
SK
1005 if (sb == b)
1006 return 1;
c5f4ec7d 1007
dbf72123
SK
1008 ea = sa--;
1009 eb = sb--;
c5f4ec7d
SK
1010 }
1011}
1012
1013
0fc2f313
SK
1014/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
1015int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class)
adca3e9c 1016{
0fc2f313
SK
1017 unsigned char *ans_start, *p1, *p2;
1018 int type1, class1, rdlen1, type2, class2, rdlen2;
c5f4ec7d 1019 int i, j, rc, have_nsec, have_nsec_equal, cname_count = 5;
adca3e9c 1020
c5f4ec7d 1021 if ((RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR) || ntohs(header->qdcount) != 1)
72ae2f3d 1022 return STAT_INSECURE;
c5f4ec7d 1023
0fc2f313
SK
1024 if (!(ans_start = skip_questions(header, plen)))
1025 return STAT_INSECURE;
1026
1027 for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
adca3e9c 1028 {
0fc2f313
SK
1029 if (!extract_name(header, plen, &p1, name, 1, 10))
1030 return STAT_INSECURE; /* bad packet */
1031
1032 GETSHORT(type1, p1);
1033 GETSHORT(class1, p1);
1034 p1 += 4; /* TTL */
1035 GETSHORT(rdlen1, p1);
1036
1037 /* Don't try and validate RRSIGs! */
1038 if (type1 != T_RRSIG)
1039 {
1040 /* Check if we've done this RRset already */
1041 for (p2 = ans_start, j = 0; j < i; j++)
1042 {
1043 if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
1044 return STAT_INSECURE; /* bad packet */
1045
1046 GETSHORT(type2, p2);
1047 GETSHORT(class2, p2);
1048 p2 += 4; /* TTL */
1049 GETSHORT(rdlen2, p2);
1050
1051 if (type2 == type1 && class2 == class1 && rc == 1)
1052 break; /* Done it before: name, type, class all match. */
1053
1054 if (!ADD_RDLEN(header, p2, plen, rdlen2))
1055 return STAT_INSECURE;
1056 }
1057
1058 /* Not done, validate now */
1059 if (j == i && (rc = validate_rrset(now, header, plen, class1, type1, name, keyname, NULL, 0, 0, 0)) != STAT_SECURE)
1060 {
1061 *class = class1; /* Class for DS or DNSKEY */
1062 return rc;
1063 }
1064 }
adca3e9c 1065
0fc2f313
SK
1066 if (!ADD_RDLEN(header, p1, plen, rdlen1))
1067 return STAT_INSECURE;
adca3e9c
GB
1068 }
1069
c5f4ec7d
SK
1070 /* OK, all the RRsets validate, now see if we have a NODATA or NXDOMAIN reply */
1071
1072 p1 = (unsigned char *)(header+1);
1073
1074 if (!extract_name(header, plen, &p1, name, 1, 4))
1075 return STAT_INSECURE;
1076
1077 GETSHORT(type1, p1);
1078 GETSHORT(class1, p1);
1079
1080 cname_loop:
1081 for (j = ntohs(header->ancount); j != 0; j--)
1082 {
1083 if (!(rc = extract_name(header, plen, &p1, name, 0, 10)))
1084 return STAT_INSECURE; /* bad packet */
1085
1086 GETSHORT(type2, p1);
1087 GETSHORT(class2, p1);
1088 p1 += 4; /* TTL */
1089 GETSHORT(rdlen2, p1);
1090
1091 if (rc == 1 && class1 == class2)
1092 {
1093 /* Do we have an answer for the question? */
1094 if (type1 == type2)
1095 return RCODE(header) == NXDOMAIN ? STAT_INSECURE : STAT_SECURE;
1096 else if (type2 == T_CNAME)
1097 {
1098 /* looped CNAMES */
1099 if (!cname_count-- ||
1100 !extract_name(header, plen, &p1, name, 1, 0) ||
1101 !(p1 = skip_questions(header, plen)))
1102 return STAT_INSECURE;
1103
1104 goto cname_loop;
1105 }
1106 }
1107
1108 if (!ADD_RDLEN(header, p1, plen, rdlen2))
1109 return STAT_INSECURE;
1110 }
1111
1112 /* NXDOMAIN or NODATA reply, look for NSEC records to support that.
1113 At this point, p1 points to the start of the auth section.
1114 Use keyname as workspace */
1115 for (have_nsec = 0, have_nsec_equal = 0, p2 = NULL, rdlen2 = 0, j = ntohs(header->nscount); j != 0; j--)
1116 {
1117 unsigned char *nsec_start = p1;
1118 if (!extract_name(header, plen, &p1, keyname, 1, 10))
1119 return STAT_INSECURE; /* bad packet */
1120
1121 GETSHORT(type2, p1);
1122 GETSHORT(class2, p1);
1123 p1 += 4; /* TTL */
1124 GETSHORT(rdlen1, p1);
1125
1126 if (class1 == class2 && type2 == T_NSEC)
1127 {
1128 have_nsec = 1;
1129 rc = hostname_cmp(name, keyname);
1130
1131 if (rc >= 0)
1132 {
1133 if (p2)
1134 {
1135 unsigned char *psave = p2;
1136 /* new NSEC is smaller than name,
1137 is it bigger than previous one? */
1138
1139 /* get previous one into name buffer */
1140 if (!extract_name(header, plen, &psave, name, 1, 0))
1141 return STAT_INSECURE; /* bad packet */
1142
1143 if (hostname_cmp(name, keyname) < 0)
1144 {
1145 p2 = nsec_start;
1146 rdlen2 = rdlen1;
1147 }
1148
1149 /* restore query name */
1150 psave = (unsigned char *)(header+1);
1151 if (!extract_name(header, plen, &psave, name, 1, 0))
1152 return STAT_INSECURE;
1153 }
1154 else
1155 {
1156 /* There was no previous best candidate */
1157 p2 = nsec_start;
1158 rdlen2 = rdlen1;
1159 }
1160 }
1161
1162 if (rc == 0)
1163 have_nsec_equal = 1;
1164 }
1165
1166 if (!ADD_RDLEN(header, p1, plen, rdlen1))
1167 return STAT_INSECURE;
1168 }
1169
1170
1171 if (p2)
1172 {
1173 unsigned char *psave;
1174 p2 = skip_name(p2, header, plen, 0);
1175 p2 += 10; /* type, class, ttl, rdlen */
1176 psave = p2;
1177 extract_name(header, plen, &p2, keyname, 1, 0);
1178 rdlen2 -= p2 - psave;
1179 }
1180
1181 /* At this point, have_nsec is set if there's at least one NSEC
1182 have_nsec_equal is set if there's an NSEC with the same name as the query;
1183 p2 points to the type bit maps of the biggest NSEC smaller than or equal to the query
1184 or NULL if the query is smaller than all of them.
1185 Keyname holds the next domain name for that NSEC.
1186 rdlen2 is the length of the bitmap field */
1187
1188
1189 if (RCODE(header) == NOERROR && have_nsec_equal)
1190 {
1191 int offset = (type1 & 0xff) >> 3;
1192 int mask = 0x80 >> (type1 & 0x07);
1193
1194 while (rdlen2 >= 2)
1195 {
1196 if (p2[0] == type1 >> 8)
1197 {
1198 /* Does the NSEC say our type exists? */
1199 if (offset < p2[1] &&
1200 (p2[offset+2] & mask) != 0)
1201 return STAT_INSECURE;
1202
1203 break; /* finshed checking */
1204 }
1205
1206 rdlen2 -= p2[1];
1207 p2 += p2[1];
1208 }
1209
1210 return STAT_SECURE;
1211 }
1212
1213 if (RCODE(header) == NXDOMAIN && have_nsec)
1214 {
1215 if (!p2 || hostname_cmp(name, keyname) < 0)
1216 return STAT_SECURE; /* Before the first, or in a proven gap */
1217 }
1218
1219 return STAT_INSECURE;
e292e93d
GB
1220}
1221
c3e0b9b6 1222
3471f181 1223/* Compute keytag (checksum to quickly index a key). See RFC4034 */
0fc2f313 1224int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
3471f181 1225{
75ffc9bf
GB
1226 if (alg == 1)
1227 {
1228 /* Algorithm 1 (RSAMD5) has a different (older) keytag calculation algorithm.
1229 See RFC4034, Appendix B.1 */
0fc2f313 1230 return key[keylen-4] * 256 + key[keylen-3];
75ffc9bf
GB
1231 }
1232 else
1233 {
1234 unsigned long ac;
1235 int i;
1236
0fc2f313
SK
1237 ac = ((htons(flags) >> 8) | ((htons(flags) << 8) & 0xff00)) + 0x300 + alg;
1238 for (i = 0; i < keylen; ++i)
1239 ac += (i & 1) ? key[i] : key[i] << 8;
1240 ac += (ac >> 16) & 0xffff;
1241 return ac & 0xffff;
0304d28f 1242 }
3471f181 1243}
e292e93d 1244
5f8e58f4
SK
1245size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr)
1246{
1247 unsigned char *p;
1248 char types[20];
1249
1250 querystr("dnssec", types, type);
1251
1252 if (addr->sa.sa_family == AF_INET)
1253 log_query(F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types);
1254#ifdef HAVE_IPV6
1255 else
1256 log_query(F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types);
1257#endif
1258
1259 header->qdcount = htons(1);
1260 header->ancount = htons(0);
1261 header->nscount = htons(0);
1262 header->arcount = htons(0);
e292e93d 1263
5f8e58f4
SK
1264 header->hb3 = HB3_RD;
1265 SET_OPCODE(header, QUERY);
1266 header->hb4 = HB4_CD;
1267
1268 /* ID filled in later */
1269
1270 p = (unsigned char *)(header+1);
1271
1272 p = do_rfc1035_name(p, name);
1273 *p++ = 0;
1274 PUTSHORT(type, p);
1275 PUTSHORT(class, p);
1276
1277 return add_do_bit(header, p - (unsigned char *)header, end);
1278}
1279
0fc2f313 1280#endif /* HAVE_DNSSEC */