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