blob: 3151cdb4fc5127f1526bc4e2d97face4851968b6 [file] [log] [blame]
Giovanni Bajo9940aba2012-04-23 00:32:01 +02001#include <string.h>
Giovanni Bajo366dfcb2012-04-25 17:40:47 +02002#include "dnsmasq.h"
3#include "dnssec-crypto.h"
Giovanni Bajo9940aba2012-04-23 00:32:01 +02004#include <openssl/evp.h>
5
Giovanni Bajo366dfcb2012-04-25 17:40:47 +02006typedef struct VACTX_rsasha1
Giovanni Bajo9940aba2012-04-23 00:32:01 +02007{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +02008 VerifyAlgCtx base;
9 unsigned char *sig;
10 unsigned siglen;
11 union
12 {
13 EVP_MD_CTX hash;
14 unsigned char digest[20];
15 };
16} VACTX_rsasha1;
17
18typedef struct VACTX_rsasha256
19{
20 VerifyAlgCtx base;
21 unsigned char *sig;
22 unsigned siglen;
Giovanni Bajo9940aba2012-04-23 00:32:01 +020023 union
24 {
25 EVP_MD_CTX hash;
Giovanni Bajob573aeb2012-04-24 02:21:50 +020026 unsigned char digest[32];
Giovanni Bajo9940aba2012-04-23 00:32:01 +020027 };
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020028} VACTX_rsasha256;
Giovanni Bajo9940aba2012-04-23 00:32:01 +020029
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020030#define POOL_SIZE 1
31static union _Pool
Giovanni Bajo9940aba2012-04-23 00:32:01 +020032{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020033 VACTX_rsasha1 rsasha1;
34 VACTX_rsasha256 rsasha256;
35} Pool[POOL_SIZE];
36static char pool_used = 0;
37
38static int rsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
39{
40 VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
41 ctx->sig = data;
42 ctx->siglen = len;
Giovanni Bajob573aeb2012-04-24 02:21:50 +020043 return 1;
44}
45
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020046static int rsasha256_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
Giovanni Bajob573aeb2012-04-24 02:21:50 +020047{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020048 VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
49 ctx->sig = data;
50 ctx->siglen = len;
Giovanni Bajo9940aba2012-04-23 00:32:01 +020051 return 1;
52}
53
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020054static void rsasha1_begin_data(VerifyAlgCtx *ctx_)
Giovanni Bajo9940aba2012-04-23 00:32:01 +020055{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020056 VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
57 EVP_MD_CTX_init(&ctx->hash);
58 EVP_DigestInit_ex(&ctx->hash, EVP_sha1(), NULL);
Giovanni Bajob573aeb2012-04-24 02:21:50 +020059}
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020060static void rsasha256_begin_data(VerifyAlgCtx *ctx_)
Giovanni Bajob573aeb2012-04-24 02:21:50 +020061{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020062 VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
63 EVP_MD_CTX_init(&ctx->hash);
64 EVP_DigestInit_ex(&ctx->hash, EVP_sha256(), NULL);
Giovanni Bajo9940aba2012-04-23 00:32:01 +020065}
66
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020067static void rsasha1_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len)
Giovanni Bajo9940aba2012-04-23 00:32:01 +020068{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020069 VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
70 EVP_DigestUpdate(&ctx->hash, data, len);
Giovanni Bajob573aeb2012-04-24 02:21:50 +020071}
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020072static void rsasha256_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len)
Giovanni Bajob573aeb2012-04-24 02:21:50 +020073{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020074 VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
75 EVP_DigestUpdate(&ctx->hash, data, len);
Giovanni Bajo9940aba2012-04-23 00:32:01 +020076}
77
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020078static void rsasha1_end_data(VerifyAlgCtx *ctx_)
Giovanni Bajo9940aba2012-04-23 00:32:01 +020079{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020080 VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
Giovanni Bajo9940aba2012-04-23 00:32:01 +020081 unsigned char digest[20];
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020082 EVP_DigestFinal(&ctx->hash, digest, NULL);
83 memcpy(ctx->digest, digest, 20);
Giovanni Bajob573aeb2012-04-24 02:21:50 +020084}
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020085static void rsasha256_end_data(VerifyAlgCtx *ctx_)
Giovanni Bajob573aeb2012-04-24 02:21:50 +020086{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020087 VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
Giovanni Bajob573aeb2012-04-24 02:21:50 +020088 unsigned char digest[32];
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020089 EVP_DigestFinal(&ctx->hash, digest, NULL);
90 memcpy(ctx->digest, digest, 32);
Giovanni Bajo9940aba2012-04-23 00:32:01 +020091}
92
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020093static int rsasha1_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len)
Giovanni Bajo9940aba2012-04-23 00:32:01 +020094{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020095 VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
Giovanni Bajo9940aba2012-04-23 00:32:01 +020096 return 0;
97}
98
Giovanni Bajo366dfcb2012-04-25 17:40:47 +020099static int rsasha256_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len)
Giovanni Bajob573aeb2012-04-24 02:21:50 +0200100{
Giovanni Bajo366dfcb2012-04-25 17:40:47 +0200101 VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
Giovanni Bajob573aeb2012-04-24 02:21:50 +0200102 return 0;
103}
104
Giovanni Bajo366dfcb2012-04-25 17:40:47 +0200105#define DEFINE_VALG(alg) \
106 int alg ## _set_signature(VerifyAlgCtx *ctx, unsigned char *data, unsigned len); \
107 void alg ## _begin_data(VerifyAlgCtx *ctx); \
108 void alg ## _add_data(VerifyAlgCtx *ctx, void *data, unsigned len); \
109 void alg ## _end_data(VerifyAlgCtx *ctx); \
110 int alg ## _verify(VerifyAlgCtx *ctx, unsigned char *key, unsigned key_len) \
111 /**/
112
113#define VALG_VTABLE(alg) { \
114 alg ## _set_signature, \
115 alg ## _begin_data, \
116 alg ## _add_data, \
117 alg ## _end_data, \
118 alg ## _verify \
119 } /**/
120
121DEFINE_VALG(rsasha1);
122DEFINE_VALG(rsasha256);
123
124/* Updated registry that merges various RFCs:
125 https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */
126static const VerifyAlg valgs[] =
127{
128 {0,0,0,0,0}, /* 0: reserved */
129 {0,0,0,0,0}, /* 1: RSAMD5 */
130 {0,0,0,0,0}, /* 2: DH */
131 {0,0,0,0,0}, /* 3: DSA */
132 {0,0,0,0,0}, /* 4: ECC */
133 VALG_VTABLE(rsasha1), /* 5: RSASHA1 */
134 {0,0,0,0,0}, /* 6: DSA-NSEC3-SHA1 */
135 {0,0,0,0,0}, /* 7: RSASHA1-NSEC3-SHA1 */
136 VALG_VTABLE(rsasha256), /* 8: RSASHA256 */
137 {0,0,0,0,0}, /* 9: unassigned */
138 {0,0,0,0,0}, /* 10: RSASHA512 */
139 {0,0,0,0,0}, /* 11: unassigned */
140 {0,0,0,0,0}, /* 12: ECC-GOST */
141 {0,0,0,0,0}, /* 13: ECDSAP256SHA256 */
142 {0,0,0,0,0}, /* 14: ECDSAP384SHA384 */
143};
144
145static const int valgctx_size[] =
146{
147 0, /* 0: reserved */
148 0, /* 1: RSAMD5 */
149 0, /* 2: DH */
150 0, /* 3: DSA */
151 0, /* 4: ECC */
152 sizeof(VACTX_rsasha1), /* 5: RSASHA1 */
153 0, /* 6: DSA-NSEC3-SHA1 */
154 0, /* 7: RSASHA1-NSEC3-SHA1 */
155 sizeof(VACTX_rsasha256), /* 8: RSASHA256 */
156 0, /* 9: unassigned */
157 0, /* 10: RSASHA512 */
158 0, /* 11: unassigned */
159 0, /* 12: ECC-GOST */
160 0, /* 13: ECDSAP256SHA256 */
161 0, /* 14: ECDSAP384SHA384 */
162};
163
164int verifyalg_supported(int algo)
165{
166 return (algo < countof(valgctx_size) && valgctx_size[algo] != 0);
167}
168
169VerifyAlgCtx* verifyalg_alloc(int algo)
170{
171 int i;
172 VerifyAlgCtx *ret = 0;
173
174 if (!verifyalg_supported(algo))
175 return 0;
176
177 if (pool_used == (1<<POOL_SIZE)-1)
178 ret = whine_malloc(valgctx_size[algo]);
179 else
180 for (i = 0; i < POOL_SIZE; ++i)
181 if (!(pool_used & (1 << i)))
182 {
183 ret = &Pool[i];
184 pool_used |= 1 << i;
185 break;
186 }
187
188 if (ret)
189 ret->vtbl = &valgs[algo];
190 return ret;
191}
192
193void verifyalg_free(VerifyAlgCtx *a)
194{
195 int pool_idx = ((char*)a - (char*)&Pool[0]) / sizeof(Pool[0]);
196 if (pool_idx < 0 || pool_idx >= POOL_SIZE)
197 {
198 free(a);
199 return;
200 }
201
202 pool_used &= ~(1 << pool_idx);
203}
Giovanni Bajo6759b992012-04-25 18:03:24 +0200204
205int verifyalg_algonum(VerifyAlgCtx *a)
206{
207 int num = a->vtbl - valgs;
208 if (num < 0 || num >= countof(valgs))
209 return -1;
210 return num;
211}