]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/dnssec.c
Make DNSEC default, add build-depends for same, bump version.
[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 459
6fd6dacb 460 rc = (len == 0) ? 0 : memcmp(buff1, buff2, len);
5f8e58f4 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 }
6fd6dacb
SK
469 else if (rc < 0)
470 quit = 1;
5f8e58f4
SK
471 }
472 }
473 } while (swap);
474}
c3e0b9b6 475
5f8e58f4
SK
476/* Validate a single RRset (class, type, name) in the supplied DNS reply
477 Return code:
478 STAT_SECURE if it validates.
479 STAT_INSECURE can't validate (no RRSIG, bad packet).
480 STAT_BOGUS signature is wrong.
481 STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
482
483 if key is non-NULL, use that key, which has the algo and tag given in the params of those names,
484 otherwise find the key in the cache.
485*/
486static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class,
e7829aef 487 int type, char *name, char *keyname, struct blockdata *key, int keylen, int algo_in, int keytag_in)
5f8e58f4
SK
488{
489 static unsigned char **rrset = NULL, **sigs = NULL;
490 static int rrset_sz = 0, sig_sz = 0;
0fc2f313 491
5f8e58f4 492 unsigned char *p;
5ada8885 493 int rrsetidx, sigidx, res, rdlen, j, name_labels;
5f8e58f4
SK
494 struct crec *crecp = NULL;
495 int type_covered, algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag;
496 u16 *rr_desc = get_desc(type);
c3e0b9b6 497
5f8e58f4
SK
498 if (!(p = skip_questions(header, plen)))
499 return STAT_INSECURE;
c3e0b9b6 500
5ada8885
SK
501 name_labels = count_labels(name); /* For 4035 5.3.2 check */
502
503 /* look for RRSIGs for this RRset and get pointers to each RR in the set. */
5f8e58f4
SK
504 for (rrsetidx = 0, sigidx = 0, j = ntohs(header->ancount) + ntohs(header->nscount);
505 j != 0; j--)
506 {
507 unsigned char *pstart, *pdata;
e7829aef 508 int stype, sclass, ttl;
c3e0b9b6 509
5f8e58f4
SK
510 pstart = p;
511
512 if (!(res = extract_name(header, plen, &p, name, 0, 10)))
513 return STAT_INSECURE; /* bad packet */
514
515 GETSHORT(stype, p);
516 GETSHORT(sclass, p);
e7829aef 517 GETLONG(ttl, p);
5f8e58f4
SK
518
519 pdata = p;
c3e0b9b6 520
5f8e58f4
SK
521 GETSHORT(rdlen, p);
522
e7829aef
SK
523 if (!CHECK_LEN(header, p, plen, rdlen))
524 return STAT_INSECURE;
525
5f8e58f4
SK
526 if (res == 1 && sclass == class)
527 {
528 if (stype == type)
529 {
530 if (rrsetidx == rrset_sz)
531 {
532 unsigned char **new;
533
534 /* expand */
535 if (!(new = whine_malloc((rrset_sz + 5) * sizeof(unsigned char **))))
536 return STAT_INSECURE;
537
538 if (rrset)
539 {
540 memcpy(new, rrset, rrset_sz * sizeof(unsigned char **));
541 free(rrset);
542 }
543
544 rrset = new;
545 rrset_sz += 5;
546 }
547 rrset[rrsetidx++] = pstart;
548 }
549
550 if (stype == T_RRSIG)
551 {
5ada8885
SK
552 if (rdlen < 18)
553 return STAT_INSECURE; /* bad packet */
554
555 GETSHORT(type_covered, p);
5ada8885 556
e7829aef 557 if (type_covered == type)
5ada8885
SK
558 {
559 if (sigidx == sig_sz)
560 {
561 unsigned char **new;
562
563 /* expand */
564 if (!(new = whine_malloc((sig_sz + 5) * sizeof(unsigned char **))))
565 return STAT_INSECURE;
566
567 if (sigs)
568 {
569 memcpy(new, sigs, sig_sz * sizeof(unsigned char **));
570 free(sigs);
571 }
572
573 sigs = new;
574 sig_sz += 5;
575 }
576
577 sigs[sigidx++] = pdata;
e7829aef 578 }
e7829aef 579 p = pdata + 2; /* restore for ADD_RDLEN */
5f8e58f4
SK
580 }
581 }
582
583 if (!ADD_RDLEN(header, p, plen, rdlen))
584 return STAT_INSECURE;
585 }
c3e0b9b6 586
5f8e58f4
SK
587 /* RRset empty, no RRSIGs */
588 if (rrsetidx == 0 || sigidx == 0)
589 return STAT_INSECURE;
590
591 /* Sort RRset records into canonical order.
592 Note that at this point keyname and name buffs are
593 unused, and used as workspace by the sort. */
594 sort_rrset(header, plen, rr_desc, rrsetidx, rrset, name, keyname);
595
596 /* Now try all the sigs to try and find one which validates */
597 for (j = 0; j <sigidx; j++)
598 {
86bec2d3
SK
599 unsigned char *psav, *sig;
600 int i, wire_len, sig_len;
601 const struct nettle_hash *hash;
602 void *ctx;
603 unsigned char *digest;
5f8e58f4
SK
604 u32 nsigttl;
605
606 p = sigs[j];
5ada8885 607 GETSHORT(rdlen, p); /* rdlen >= 18 checked previously */
5f8e58f4
SK
608 psav = p;
609
5ada8885 610 p += 2; /* type_covered - already checked */
5f8e58f4
SK
611 algo = *p++;
612 labels = *p++;
613 GETLONG(orig_ttl, p);
e7829aef
SK
614 GETLONG(sig_expiration, p);
615 GETLONG(sig_inception, p);
5f8e58f4
SK
616 GETSHORT(key_tag, p);
617
5f8e58f4
SK
618 if (!extract_name(header, plen, &p, keyname, 1, 0))
619 return STAT_INSECURE;
620
e7829aef
SK
621 if (!check_date_range(sig_inception, sig_expiration) ||
622 labels > name_labels ||
623 !(hash = hash_find(algo_digest_name(algo))) ||
624 !hash_init(hash, &ctx, &digest))
625 continue;
626
5f8e58f4
SK
627 /* OK, we have the signature record, see if the relevant DNSKEY is in the cache. */
628 if (!key && !(crecp = cache_find_by_name(NULL, keyname, now, F_DNSKEY)))
629 return STAT_NEED_KEY;
630
86bec2d3
SK
631 sig = p;
632 sig_len = rdlen - (p - psav);
e7829aef 633
5f8e58f4
SK
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))
51ea3ca2
SK
708 if (crecp->addr.key.algo == algo &&
709 crecp->addr.key.keytag == key_tag &&
824202ef
SK
710 crecp->uid == class &&
711 verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, algo))
5f8e58f4
SK
712 return STAT_SECURE;
713 }
714 }
715
716 return STAT_BOGUS;
717}
718
0fc2f313 719/* The DNS packet is expected to contain the answer to a DNSKEY query.
c3e0b9b6
SK
720 Put all DNSKEYs in the answer which are valid into the cache.
721 return codes:
722 STAT_INSECURE bad packet, no DNSKEYs in reply.
723 STAT_SECURE At least one valid DNSKEY found and in cache.
0fc2f313
SK
724 STAT_BOGUS No DNSKEYs found, which can be validated with DS,
725 or self-sign for DNSKEY RRset is not valid.
726 STAT_NEED_DS DS records to validate a key not found, name in keyname
c3e0b9b6
SK
727*/
728int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
729{
0fc2f313 730 unsigned char *psave, *p = (unsigned char *)(header+1);
c3e0b9b6 731 struct crec *crecp, *recp1;
8d718cbb 732 int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag, type_covered;
c3e0b9b6 733 struct blockdata *key;
51ea3ca2 734 struct all_addr a;
c3e0b9b6 735
5f8e58f4
SK
736 if (ntohs(header->qdcount) != 1 ||
737 !extract_name(header, plen, &p, name, 1, 4))
8d718cbb 738 return STAT_INSECURE;
5f8e58f4 739
c3e0b9b6
SK
740 GETSHORT(qtype, p);
741 GETSHORT(qclass, p);
742
0fc2f313 743 if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
c3e0b9b6
SK
744 return STAT_INSECURE;
745
0fc2f313
SK
746 /* See if we have cached a DS record which validates this key */
747 if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
748 {
749 strcpy(keyname, name);
750 return STAT_NEED_DS;
751 }
752
0fc2f313 753 /* NOTE, we need to find ONE DNSKEY which matches the DS */
e7829aef 754 for (valid = 0, j = ntohs(header->ancount); j != 0 && !valid; j--)
c3e0b9b6
SK
755 {
756 /* Ensure we have type, class TTL and length */
0fc2f313 757 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
c3e0b9b6
SK
758 return STAT_INSECURE; /* bad packet */
759
760 GETSHORT(qtype, p);
761 GETSHORT(qclass, p);
762 GETLONG(ttl, p);
763 GETSHORT(rdlen, p);
6f468103 764
0fc2f313
SK
765 if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
766 return STAT_INSECURE; /* bad packet */
767
6f468103
SK
768 if (qclass != class || qtype != T_DNSKEY || rc == 2)
769 {
770 p += rdlen;
771 continue;
772 }
773
0fc2f313 774 psave = p;
c3e0b9b6 775
c3e0b9b6 776 GETSHORT(flags, p);
0fc2f313
SK
777 if (*p++ != 3)
778 return STAT_INSECURE;
c3e0b9b6 779 algo = *p++;
0fc2f313 780 keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
e7829aef 781 key = NULL;
c3e0b9b6 782
e7829aef
SK
783 /* key must have zone key flag set */
784 if (flags & 0x100)
785 key = blockdata_alloc((char*)p, rdlen - 4);
c3e0b9b6 786
0fc2f313 787 p = psave;
e7829aef 788
0fc2f313 789 if (!ADD_RDLEN(header, p, plen, rdlen))
8d718cbb
SK
790 {
791 if (key)
792 blockdata_free(key);
793 return STAT_INSECURE; /* bad packet */
794 }
795
e7829aef
SK
796 /* No zone key flag or malloc failure */
797 if (!key)
0fc2f313
SK
798 continue;
799
800 for (recp1 = crecp; recp1; recp1 = cache_find_by_name(recp1, name, now, F_DS))
86bec2d3
SK
801 {
802 void *ctx;
803 unsigned char *digest, *ds_digest;
804 const struct nettle_hash *hash;
805
51ea3ca2
SK
806 if (recp1->addr.ds.algo == algo &&
807 recp1->addr.ds.keytag == keytag &&
824202ef 808 recp1->uid == class &&
51ea3ca2 809 (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) &&
86bec2d3 810 hash_init(hash, &ctx, &digest))
0fc2f313 811
86bec2d3
SK
812 {
813 int wire_len = to_wire(name);
814
815 /* Note that digest may be different between DSs, so
816 we can't move this outside the loop. */
817 hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name);
818 hash->update(ctx, (unsigned int)rdlen, psave);
819 hash->digest(ctx, hash->digest_size, digest);
820
821 from_wire(name);
822
824202ef
SK
823 if (recp1->addr.ds.keylen == (int)hash->digest_size &&
824 (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
825 memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
f6a2b793 826 validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, key, rdlen - 4, algo, keytag) == STAT_SECURE)
86bec2d3 827 {
86bec2d3 828 valid = 1;
86bec2d3
SK
829 break;
830 }
831 }
832 }
e7829aef 833 blockdata_free(key);
c3e0b9b6 834 }
c3e0b9b6 835
0fc2f313
SK
836 if (valid)
837 {
8d718cbb 838 /* DNSKEY RRset determined to be OK, now cache it and the RRsigs that sign it. */
e7829aef
SK
839 cache_start_insert();
840
841 p = skip_questions(header, plen);
842
843 for (j = ntohs(header->ancount); j != 0; j--)
844 {
845 /* Ensure we have type, class TTL and length */
846 if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
847 return STAT_INSECURE; /* bad packet */
848
849 GETSHORT(qtype, p);
850 GETSHORT(qclass, p);
851 GETLONG(ttl, p);
852 GETSHORT(rdlen, p);
8d718cbb
SK
853
854 if (!CHECK_LEN(header, p, plen, rdlen))
e7829aef 855 return STAT_INSECURE; /* bad packet */
e7829aef 856
8d718cbb 857 if (qclass == class && rc == 1)
e7829aef 858 {
8d718cbb 859 psave = p;
e7829aef 860
8d718cbb
SK
861 if (qtype == T_DNSKEY)
862 {
863 if (rdlen < 4)
864 return STAT_INSECURE; /* bad packet */
865
866 GETSHORT(flags, p);
867 if (*p++ != 3)
868 return STAT_INSECURE;
869 algo = *p++;
870 keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
871
872 /* Cache needs to known class for DNSSEC stuff */
873 a.addr.dnssec.class = class;
874
875 if ((key = blockdata_alloc((char*)p, rdlen - 4)))
876 {
877 if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
878 blockdata_free(key);
879 else
880 {
881 a.addr.keytag = keytag;
882 log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %u");
883
884 recp1->addr.key.keylen = rdlen - 4;
885 recp1->addr.key.keydata = key;
886 recp1->addr.key.algo = algo;
887 recp1->addr.key.keytag = keytag;
888 recp1->addr.key.flags = flags;
889 recp1->uid = class;
890 }
891 }
892 }
893 else if (qtype == T_RRSIG)
894 {
895 /* RRSIG, cache if covers DNSKEY RRset */
896 if (rdlen < 18)
897 return STAT_INSECURE; /* bad packet */
898
899 GETSHORT(type_covered, p);
900
901 if (type_covered == T_DNSKEY)
902 {
903 a.addr.dnssec.class = class;
904 a.addr.dnssec.type = type_covered;
905
906 algo = *p++;
907 p += 13; /* labels, orig_ttl, expiration, inception */
908 GETSHORT(keytag, p);
909 if ((key = blockdata_alloc((char*)psave, rdlen)))
910 {
911 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS)))
912 blockdata_free(key);
913 else
914 {
915 crecp->uid = class;
916 crecp->addr.sig.keydata = key;
917 crecp->addr.sig.keylen = rdlen;
918 crecp->addr.sig.keytag = keytag;
919 crecp->addr.sig.type_covered = type_covered;
920 crecp->addr.sig.algo = algo;
921 }
922 }
923 }
924 }
e7829aef 925
8d718cbb 926 p = psave;
e7829aef 927 }
8d718cbb 928
e7829aef
SK
929 if (!ADD_RDLEN(header, p, plen, rdlen))
930 return STAT_INSECURE; /* bad packet */
931 }
932
0fc2f313
SK
933 /* commit cache insert. */
934 cache_end_insert();
935 return STAT_SECURE;
936 }
937
938 log_query(F_UPSTREAM, name, NULL, "BOGUS DNSKEY");
939 return STAT_BOGUS;
c3e0b9b6 940}
0fc2f313 941
c3e0b9b6
SK
942/* The DNS packet is expected to contain the answer to a DS query
943 Put all DSs in the answer which are valid into the cache.
944 return codes:
0fc2f313 945 STAT_INSECURE bad packet, no DS in reply.
c3e0b9b6
SK
946 STAT_SECURE At least one valid DS found and in cache.
947 STAT_BOGUS At least one DS found, which fails validation.
948 STAT_NEED_DNSKEY DNSKEY records to validate a DS not found, name in keyname
949*/
950
951int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
952{
51ea3ca2
SK
953 unsigned char *p = (unsigned char *)(header+1);
954 int qtype, qclass, val;
c3e0b9b6 955
5f8e58f4
SK
956 if (ntohs(header->qdcount) != 1 ||
957 !extract_name(header, plen, &p, name, 1, 4))
8d718cbb
SK
958 return STAT_INSECURE;
959
c3e0b9b6
SK
960 GETSHORT(qtype, p);
961 GETSHORT(qclass, p);
962
0fc2f313 963 if (qtype != T_DS || qclass != class || ntohs(header->ancount) == 0)
c3e0b9b6 964 return STAT_INSECURE;
0fc2f313 965
51ea3ca2
SK
966 val = dnssec_validate_reply(now, header, plen, name, keyname, NULL);
967
0fc2f313 968 if (val == STAT_BOGUS)
8d718cbb
SK
969 {
970 p = (unsigned char *)(header+1);
971 extract_name(header, plen, &p, name, 1, 4);
972 log_query(F_UPSTREAM, name, NULL, "BOGUS DS");
973 }
c3e0b9b6 974
51ea3ca2 975 return val;
c3e0b9b6
SK
976}
977
c5f4ec7d
SK
978/* 4034 6.1 */
979static int hostname_cmp(const char *a, const char *b)
980{
dbf72123
SK
981 char *sa, *ea, *ca, *sb, *eb, *cb;
982 unsigned char ac, bc;
983
984 sa = ea = (char *)a + strlen(a);
985 sb = eb = (char *)b + strlen(b);
986
c5f4ec7d
SK
987 while (1)
988 {
dbf72123
SK
989 while (sa != a && *(sa-1) != '.')
990 sa--;
c5f4ec7d 991
dbf72123
SK
992 while (sb != b && *(sb-1) != '.')
993 sb--;
994
995 ca = sa;
996 cb = sb;
997
998 while (1)
999 {
1000 if (ca == ea)
1001 {
1002 if (cb == eb)
1003 break;
1004
1005 return -1;
1006 }
c5f4ec7d 1007
dbf72123
SK
1008 if (cb == eb)
1009 return 1;
1010
1011 ac = (unsigned char) *ca++;
1012 bc = (unsigned char) *cb++;
1013
1014 if (ac >= 'A' && ac <= 'Z')
1015 ac += 'a' - 'A';
1016 if (bc >= 'A' && bc <= 'Z')
1017 bc += 'a' - 'A';
1018
979cdf9b 1019 if (ac < bc)
dbf72123
SK
1020 return -1;
1021 else if (ac != bc)
1022 return 1;
1023 }
c5f4ec7d 1024
dbf72123
SK
1025
1026 if (sa == a)
c5f4ec7d 1027 {
dbf72123
SK
1028 if (sb == b)
1029 return 0;
c5f4ec7d 1030
dbf72123 1031 return -1;
c5f4ec7d
SK
1032 }
1033
dbf72123
SK
1034 if (sb == b)
1035 return 1;
c5f4ec7d 1036
dbf72123
SK
1037 ea = sa--;
1038 eb = sb--;
c5f4ec7d
SK
1039 }
1040}
1041
1042
0fc2f313 1043/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
51ea3ca2 1044/* Returns are the same as validate_rrset, plus the class if the missing key is in *class */
0fc2f313 1045int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int *class)
adca3e9c 1046{
0fc2f313
SK
1047 unsigned char *ans_start, *p1, *p2;
1048 int type1, class1, rdlen1, type2, class2, rdlen2;
c5f4ec7d 1049 int i, j, rc, have_nsec, have_nsec_equal, cname_count = 5;
adca3e9c 1050
c5f4ec7d 1051 if ((RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR) || ntohs(header->qdcount) != 1)
72ae2f3d 1052 return STAT_INSECURE;
c5f4ec7d 1053
0fc2f313
SK
1054 if (!(ans_start = skip_questions(header, plen)))
1055 return STAT_INSECURE;
1056
1057 for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
adca3e9c 1058 {
0fc2f313
SK
1059 if (!extract_name(header, plen, &p1, name, 1, 10))
1060 return STAT_INSECURE; /* bad packet */
1061
1062 GETSHORT(type1, p1);
1063 GETSHORT(class1, p1);
1064 p1 += 4; /* TTL */
1065 GETSHORT(rdlen1, p1);
1066
1067 /* Don't try and validate RRSIGs! */
1068 if (type1 != T_RRSIG)
1069 {
1070 /* Check if we've done this RRset already */
1071 for (p2 = ans_start, j = 0; j < i; j++)
1072 {
1073 if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
1074 return STAT_INSECURE; /* bad packet */
1075
1076 GETSHORT(type2, p2);
1077 GETSHORT(class2, p2);
1078 p2 += 4; /* TTL */
1079 GETSHORT(rdlen2, p2);
1080
1081 if (type2 == type1 && class2 == class1 && rc == 1)
1082 break; /* Done it before: name, type, class all match. */
1083
1084 if (!ADD_RDLEN(header, p2, plen, rdlen2))
1085 return STAT_INSECURE;
1086 }
1087
1088 /* Not done, validate now */
51ea3ca2 1089 if (j == i)
0fc2f313 1090 {
8d718cbb
SK
1091 int ttl, keytag, algo, digest, type_covered;
1092 unsigned char *psave;
1093 struct all_addr a;
1094 struct blockdata *key;
1095 struct crec *crecp;
1096
51ea3ca2
SK
1097 if ((rc = validate_rrset(now, header, plen, class1, type1, name, keyname, NULL, 0, 0, 0)) != STAT_SECURE)
1098 {
1099 if (class)
1100 *class = class1; /* Class for DS or DNSKEY */
1101 return rc;
1102 }
1103
8d718cbb
SK
1104 /* Cache RRsigs in answer section, and if we just validated a DS RRset, cache it */
1105 cache_start_insert();
1106
1107 for (p2 = ans_start, j = 0; j < ntohs(header->ancount); j++)
51ea3ca2 1108 {
8d718cbb
SK
1109 if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
1110 return STAT_INSECURE; /* bad packet */
51ea3ca2 1111
8d718cbb
SK
1112 GETSHORT(type2, p2);
1113 GETSHORT(class2, p2);
1114 GETLONG(ttl, p2);
1115 GETSHORT(rdlen2, p2);
1116
1117 if (!CHECK_LEN(header, p2, plen, rdlen2))
1118 return STAT_INSECURE; /* bad packet */
1119
1120 if (class2 == class1 && rc == 1)
1121 {
1122 psave = p2;
1123
1124 if (type1 == T_DS && type2 == T_DS)
51ea3ca2 1125 {
8d718cbb
SK
1126 if (rdlen2 < 4)
1127 return STAT_INSECURE; /* bad packet */
1128
51ea3ca2
SK
1129 GETSHORT(keytag, p2);
1130 algo = *p2++;
1131 digest = *p2++;
1132
1133 /* Cache needs to known class for DNSSEC stuff */
1134 a.addr.dnssec.class = class2;
1135
8d718cbb 1136 if ((key = blockdata_alloc((char*)p2, rdlen2 - 4)))
51ea3ca2 1137 {
8d718cbb
SK
1138 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
1139 blockdata_free(key);
1140 else
1141 {
1142 a.addr.keytag = keytag;
1143 log_query(F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %u");
1144 crecp->addr.ds.digest = digest;
1145 crecp->addr.ds.keydata = key;
1146 crecp->addr.ds.algo = algo;
1147 crecp->addr.ds.keytag = keytag;
1148 crecp->uid = class2;
1149 crecp->addr.ds.keylen = rdlen2 - 4;
1150 }
1151 }
1152 }
1153 else if (type2 == T_RRSIG)
1154 {
1155 if (rdlen2 < 18)
1156 return STAT_INSECURE; /* bad packet */
51ea3ca2 1157
8d718cbb
SK
1158 GETSHORT(type_covered, p2);
1159
1160 if (type_covered == type1 &&
1161 (type_covered == T_A || type_covered == T_AAAA ||
1162 type_covered == T_CNAME || type_covered == T_DS ||
1163 type_covered == T_DNSKEY || type_covered == T_PTR))
1164 {
1165 a.addr.dnssec.type = type_covered;
1166
1167 algo = *p2++;
1168 p2 += 13; /* labels, orig_ttl, expiration, inception */
1169 GETSHORT(keytag, p2);
1170
1171 if ((key = blockdata_alloc((char*)psave, rdlen2)))
1172 {
1173 if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS)))
1174 blockdata_free(key);
1175 else
1176 {
1177 crecp->uid = class1;
1178 crecp->addr.sig.keydata = key;
1179 crecp->addr.sig.keylen = rdlen2;
1180 crecp->addr.sig.keytag = keytag;
1181 crecp->addr.sig.type_covered = type_covered;
1182 crecp->addr.sig.algo = algo;
1183 }
1184 }
1185 }
51ea3ca2
SK
1186 }
1187
8d718cbb 1188 p2 = psave;
51ea3ca2
SK
1189 }
1190
8d718cbb
SK
1191 if (!ADD_RDLEN(header, p2, plen, rdlen2))
1192 return STAT_INSECURE; /* bad packet */
51ea3ca2 1193 }
8d718cbb
SK
1194
1195 cache_end_insert();
0fc2f313
SK
1196 }
1197 }
adca3e9c 1198
0fc2f313
SK
1199 if (!ADD_RDLEN(header, p1, plen, rdlen1))
1200 return STAT_INSECURE;
adca3e9c
GB
1201 }
1202
c5f4ec7d
SK
1203 /* OK, all the RRsets validate, now see if we have a NODATA or NXDOMAIN reply */
1204
1205 p1 = (unsigned char *)(header+1);
1206
1207 if (!extract_name(header, plen, &p1, name, 1, 4))
1208 return STAT_INSECURE;
1209
1210 GETSHORT(type1, p1);
1211 GETSHORT(class1, p1);
1212
51ea3ca2
SK
1213 /* Can't validate RRSIG query */
1214 if (type1 == T_RRSIG)
1215 return STAT_INSECURE;
1216
c5f4ec7d
SK
1217 cname_loop:
1218 for (j = ntohs(header->ancount); j != 0; j--)
1219 {
1220 if (!(rc = extract_name(header, plen, &p1, name, 0, 10)))
1221 return STAT_INSECURE; /* bad packet */
1222
1223 GETSHORT(type2, p1);
1224 GETSHORT(class2, p1);
1225 p1 += 4; /* TTL */
1226 GETSHORT(rdlen2, p1);
1227
1228 if (rc == 1 && class1 == class2)
1229 {
1230 /* Do we have an answer for the question? */
1231 if (type1 == type2)
1232 return RCODE(header) == NXDOMAIN ? STAT_INSECURE : STAT_SECURE;
1233 else if (type2 == T_CNAME)
1234 {
1235 /* looped CNAMES */
1236 if (!cname_count-- ||
1237 !extract_name(header, plen, &p1, name, 1, 0) ||
1238 !(p1 = skip_questions(header, plen)))
1239 return STAT_INSECURE;
1240
1241 goto cname_loop;
1242 }
1243 }
1244
1245 if (!ADD_RDLEN(header, p1, plen, rdlen2))
1246 return STAT_INSECURE;
1247 }
1248
1249 /* NXDOMAIN or NODATA reply, look for NSEC records to support that.
1250 At this point, p1 points to the start of the auth section.
1251 Use keyname as workspace */
1252 for (have_nsec = 0, have_nsec_equal = 0, p2 = NULL, rdlen2 = 0, j = ntohs(header->nscount); j != 0; j--)
1253 {
1254 unsigned char *nsec_start = p1;
1255 if (!extract_name(header, plen, &p1, keyname, 1, 10))
1256 return STAT_INSECURE; /* bad packet */
1257
1258 GETSHORT(type2, p1);
1259 GETSHORT(class2, p1);
1260 p1 += 4; /* TTL */
1261 GETSHORT(rdlen1, p1);
1262
1263 if (class1 == class2 && type2 == T_NSEC)
1264 {
1265 have_nsec = 1;
1266 rc = hostname_cmp(name, keyname);
1267
1268 if (rc >= 0)
1269 {
1270 if (p2)
1271 {
1272 unsigned char *psave = p2;
1273 /* new NSEC is smaller than name,
1274 is it bigger than previous one? */
1275
1276 /* get previous one into name buffer */
1277 if (!extract_name(header, plen, &psave, name, 1, 0))
1278 return STAT_INSECURE; /* bad packet */
1279
1280 if (hostname_cmp(name, keyname) < 0)
1281 {
1282 p2 = nsec_start;
1283 rdlen2 = rdlen1;
1284 }
1285
1286 /* restore query name */
1287 psave = (unsigned char *)(header+1);
1288 if (!extract_name(header, plen, &psave, name, 1, 0))
1289 return STAT_INSECURE;
1290 }
1291 else
1292 {
1293 /* There was no previous best candidate */
1294 p2 = nsec_start;
1295 rdlen2 = rdlen1;
1296 }
1297 }
1298
1299 if (rc == 0)
1300 have_nsec_equal = 1;
1301 }
1302
1303 if (!ADD_RDLEN(header, p1, plen, rdlen1))
1304 return STAT_INSECURE;
1305 }
1306
1307
1308 if (p2)
1309 {
1310 unsigned char *psave;
1311 p2 = skip_name(p2, header, plen, 0);
1312 p2 += 10; /* type, class, ttl, rdlen */
1313 psave = p2;
1314 extract_name(header, plen, &p2, keyname, 1, 0);
1315 rdlen2 -= p2 - psave;
1316 }
1317
1318 /* At this point, have_nsec is set if there's at least one NSEC
1319 have_nsec_equal is set if there's an NSEC with the same name as the query;
1320 p2 points to the type bit maps of the biggest NSEC smaller than or equal to the query
1321 or NULL if the query is smaller than all of them.
1322 Keyname holds the next domain name for that NSEC.
1323 rdlen2 is the length of the bitmap field */
1324
1325
1326 if (RCODE(header) == NOERROR && have_nsec_equal)
1327 {
1328 int offset = (type1 & 0xff) >> 3;
1329 int mask = 0x80 >> (type1 & 0x07);
1330
1331 while (rdlen2 >= 2)
1332 {
1333 if (p2[0] == type1 >> 8)
1334 {
1335 /* Does the NSEC say our type exists? */
1336 if (offset < p2[1] &&
1337 (p2[offset+2] & mask) != 0)
1338 return STAT_INSECURE;
1339
1340 break; /* finshed checking */
1341 }
1342
1343 rdlen2 -= p2[1];
1344 p2 += p2[1];
1345 }
1346
1347 return STAT_SECURE;
1348 }
1349
1350 if (RCODE(header) == NXDOMAIN && have_nsec)
1351 {
1352 if (!p2 || hostname_cmp(name, keyname) < 0)
1353 return STAT_SECURE; /* Before the first, or in a proven gap */
1354 }
1355
1356 return STAT_INSECURE;
e292e93d
GB
1357}
1358
c3e0b9b6 1359
3471f181 1360/* Compute keytag (checksum to quickly index a key). See RFC4034 */
0fc2f313 1361int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
3471f181 1362{
75ffc9bf
GB
1363 if (alg == 1)
1364 {
1365 /* Algorithm 1 (RSAMD5) has a different (older) keytag calculation algorithm.
1366 See RFC4034, Appendix B.1 */
0fc2f313 1367 return key[keylen-4] * 256 + key[keylen-3];
75ffc9bf
GB
1368 }
1369 else
1370 {
1371 unsigned long ac;
1372 int i;
1373
0fc2f313
SK
1374 ac = ((htons(flags) >> 8) | ((htons(flags) << 8) & 0xff00)) + 0x300 + alg;
1375 for (i = 0; i < keylen; ++i)
1376 ac += (i & 1) ? key[i] : key[i] << 8;
1377 ac += (ac >> 16) & 0xffff;
1378 return ac & 0xffff;
0304d28f 1379 }
3471f181 1380}
e292e93d 1381
5f8e58f4
SK
1382size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr)
1383{
1384 unsigned char *p;
1385 char types[20];
1386
b5dbfd14 1387 querystr("dnssec-query", types, type);
5f8e58f4
SK
1388
1389 if (addr->sa.sa_family == AF_INET)
1390 log_query(F_DNSSEC | F_IPV4, name, (struct all_addr *)&addr->in.sin_addr, types);
1391#ifdef HAVE_IPV6
1392 else
1393 log_query(F_DNSSEC | F_IPV6, name, (struct all_addr *)&addr->in6.sin6_addr, types);
1394#endif
1395
1396 header->qdcount = htons(1);
1397 header->ancount = htons(0);
1398 header->nscount = htons(0);
1399 header->arcount = htons(0);
e292e93d 1400
5f8e58f4
SK
1401 header->hb3 = HB3_RD;
1402 SET_OPCODE(header, QUERY);
5b3bf921
SK
1403 /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
1404 this allows it to select auth servers when one is returning bad data. */
1405 header->hb4 = option_bool(OPT_DNSSEC_DEBUG) ? HB4_CD : 0;
5f8e58f4
SK
1406
1407 /* ID filled in later */
1408
1409 p = (unsigned char *)(header+1);
1410
1411 p = do_rfc1035_name(p, name);
1412 *p++ = 0;
1413 PUTSHORT(type, p);
1414 PUTSHORT(class, p);
1415
1416 return add_do_bit(header, p - (unsigned char *)header, end);
1417}
8a9be9e4
SK
1418
1419unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name)
1420{
1421 int q;
1422 unsigned int len;
1423 unsigned char *p = (unsigned char *)(header+1);
1424 const struct nettle_hash *hash;
1425 void *ctx;
1426 unsigned char *digest;
5f8e58f4 1427
8a9be9e4
SK
1428 if (!(hash = hash_find("sha1")) || !hash_init(hash, &ctx, &digest))
1429 return NULL;
1430
1431 for (q = ntohs(header->qdcount); q != 0; q--)
1432 {
1433 if (!extract_name(header, plen, &p, name, 1, 4))
7d23a66f 1434 break; /* bad packet */
8a9be9e4
SK
1435
1436 len = to_wire(name);
1437 hash->update(ctx, len, (unsigned char *)name);
1438 /* CRC the class and type as well */
1439 hash->update(ctx, 4, p);
1440
1441 p += 4;
1442 if (!CHECK_LEN(header, p, plen, 0))
7d23a66f 1443 break; /* bad packet */
8a9be9e4 1444 }
703c7ff4
SK
1445
1446 hash->digest(ctx, hash->digest_size, digest);
8a9be9e4
SK
1447 return digest;
1448}
1449
0fc2f313 1450#endif /* HAVE_DNSSEC */