]>
Commit | Line | Data |
---|---|---|
1e1b03d5 MF |
1 | From 14a4ae883d51130d33da7133287e8867c64bab65 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> | |
3 | Date: Thu, 17 Dec 2015 17:23:03 +0000 | |
4 | Subject: [PATCH] Do a better job of determining which DNSSEC sig algos are | |
5 | supported. | |
6 | ||
7 | --- | |
8 | src/dnssec.c | 52 +++++++++++++++++++++++++++++++++++++--------------- | |
9 | 1 file changed, 37 insertions(+), 15 deletions(-) | |
10 | ||
11 | diff --git a/src/dnssec.c b/src/dnssec.c | |
12 | index 1f8c954..82394ee 100644 | |
13 | --- a/src/dnssec.c | |
14 | +++ b/src/dnssec.c | |
15 | @@ -65,10 +65,9 @@ static char *algo_digest_name(int algo) | |
16 | case 8: return "sha256"; | |
17 | case 10: return "sha512"; | |
18 | case 12: return "gosthash94"; | |
19 | -#ifndef NO_NETTLE_ECC | |
20 | case 13: return "sha256"; | |
21 | case 14: return "sha384"; | |
22 | -#endif | |
23 | + | |
24 | default: return NULL; | |
25 | } | |
26 | } | |
27 | @@ -129,13 +128,15 @@ static int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char | |
28 | } | |
29 | ||
30 | static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
31 | - unsigned char *digest, int algo) | |
32 | + unsigned char *digest, size_t digest_len, int algo) | |
33 | { | |
34 | unsigned char *p; | |
35 | size_t exp_len; | |
36 | ||
37 | static struct rsa_public_key *key = NULL; | |
38 | static mpz_t sig_mpz; | |
39 | + | |
40 | + (void)digest_len; | |
41 | ||
42 | if (key == NULL) | |
43 | { | |
44 | @@ -181,7 +182,7 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, | |
45 | } | |
46 | ||
47 | static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
48 | - unsigned char *digest, int algo) | |
49 | + unsigned char *digest, size_t digest_len, int algo) | |
50 | { | |
51 | unsigned char *p; | |
52 | unsigned int t; | |
53 | @@ -189,6 +190,8 @@ static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, | |
54 | static struct dsa_public_key *key = NULL; | |
55 | static struct dsa_signature *sig_struct; | |
56 | ||
57 | + (void)digest_len; | |
58 | + | |
59 | if (key == NULL) | |
60 | { | |
61 | if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) || | |
62 | @@ -292,26 +295,45 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len | |
63 | } | |
64 | #endif | |
65 | ||
66 | -static int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
67 | - unsigned char *digest, size_t digest_len, int algo) | |
68 | +static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
69 | + unsigned char *digest, size_t digest_len, int algo) | |
70 | { | |
71 | - (void)digest_len; | |
72 | - | |
73 | + | |
74 | + /* Enure at runtime that we have support for this digest */ | |
75 | + if (!hash_find(algo_digest_name(algo))) | |
76 | + return NULL; | |
77 | + | |
78 | + /* This switch defines which sig algorithms we support, can't introspect Nettle for that. */ | |
79 | switch (algo) | |
80 | { | |
81 | case 1: case 5: case 7: case 8: case 10: | |
82 | - return dnsmasq_rsa_verify(key_data, key_len, sig, sig_len, digest, algo); | |
83 | + return dnsmasq_rsa_verify; | |
84 | ||
85 | case 3: case 6: | |
86 | - return dnsmasq_dsa_verify(key_data, key_len, sig, sig_len, digest, algo); | |
87 | + return dnsmasq_dsa_verify; | |
88 | ||
89 | #ifndef NO_NETTLE_ECC | |
90 | case 13: case 14: | |
91 | - return dnsmasq_ecdsa_verify(key_data, key_len, sig, sig_len, digest, digest_len, algo); | |
92 | + return dnsmasq_ecdsa_verify; | |
93 | #endif | |
94 | } | |
95 | ||
96 | - return 0; | |
97 | + return NULL; | |
98 | +} | |
99 | + | |
100 | +static int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
101 | + unsigned char *digest, size_t digest_len, int algo) | |
102 | +{ | |
103 | + | |
104 | + int (*func)(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len, | |
105 | + unsigned char *digest, size_t digest_len, int algo); | |
106 | + | |
107 | + func = verify_func(algo); | |
108 | + | |
109 | + if (!func) | |
110 | + return 0; | |
111 | + | |
112 | + return (*func)(key_data, key_len, sig, sig_len, digest, digest_len, algo); | |
113 | } | |
114 | ||
115 | /* Convert from presentation format to wire format, in place. | |
116 | @@ -732,7 +754,7 @@ static int explore_rrset(struct dns_header *header, size_t plen, int class, int | |
117 | if (check_date_range(sig_inception, sig_expiration) && | |
118 | labels <= name_labels && | |
119 | type_covered == type && | |
120 | - algo_digest_name(algo)) | |
121 | + verify_func(algo)) | |
122 | { | |
123 | if (!expand_workspace(&sigs, &sig_sz, sigidx)) | |
124 | return 0; | |
125 | @@ -1865,7 +1887,7 @@ static int zone_status(char *name, int class, char *keyname, time_t now) | |
126 | if (crecp->flags & F_DNSSECOK) | |
127 | return STAT_INSECURE; /* proved no DS here */ | |
128 | } | |
129 | - else if (!ds_digest_name(crecp->addr.ds.digest) || !algo_digest_name(crecp->addr.ds.algo)) | |
130 | + else if (!hash_find(ds_digest_name(crecp->addr.ds.digest)) || !verify_func(crecp->addr.ds.algo)) | |
131 | return STAT_INSECURE; /* algo we can't use - insecure */ | |
132 | else | |
133 | secure_ds = 1; | |
134 | @@ -1887,7 +1909,7 @@ static int zone_status(char *name, int class, char *keyname, time_t now) | |
135 | ||
136 | do | |
137 | { | |
138 | - if (crecp->uid == (unsigned int)class && !algo_digest_name(crecp->addr.key.algo)) | |
139 | + if (crecp->uid == (unsigned int)class && !verify_func(crecp->addr.key.algo)) | |
140 | return STAT_INSECURE; | |
141 | } | |
142 | while ((crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))); | |
143 | -- | |
144 | 1.7.10.4 | |
145 |