]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/sldns/keyraw.c
Fix multiple vulnerabilities in unbound.
[FreeBSD/FreeBSD.git] / contrib / unbound / sldns / keyraw.c
1 /*
2  * keyraw.c - raw key operations and conversions
3  *
4  * (c) NLnet Labs, 2004-2008
5  *
6  * See the file LICENSE for the license
7  */
8 /**
9  * \file
10  * Implementation of raw DNSKEY functions (work on wire rdata).
11  */
12
13 #include "config.h"
14 #include "sldns/keyraw.h"
15 #include "sldns/rrdef.h"
16
17 #ifdef HAVE_SSL
18 #include <openssl/ssl.h>
19 #include <openssl/evp.h>
20 #include <openssl/rand.h>
21 #include <openssl/err.h>
22 #include <openssl/md5.h>
23 #ifdef HAVE_OPENSSL_ENGINE_H
24 #  include <openssl/engine.h>
25 #endif
26 #ifdef HAVE_OPENSSL_BN_H
27 #include <openssl/bn.h>
28 #endif
29 #ifdef HAVE_OPENSSL_RSA_H
30 #include <openssl/rsa.h>
31 #endif
32 #ifdef HAVE_OPENSSL_DSA_H
33 #include <openssl/dsa.h>
34 #endif
35 #endif /* HAVE_SSL */
36
37 size_t
38 sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
39         const size_t len, int alg)
40 {
41         /* for DSA keys */
42         uint8_t t;
43         
44         /* for RSA keys */
45         uint16_t exp;
46         uint16_t int16;
47         
48         switch ((sldns_algorithm)alg) {
49         case LDNS_DSA:
50         case LDNS_DSA_NSEC3:
51                 if (len > 0) {
52                         t = keydata[0];
53                         return (64 + t*8)*8;
54                 } else {
55                         return 0;
56                 }
57                 break;
58         case LDNS_RSAMD5:
59         case LDNS_RSASHA1:
60         case LDNS_RSASHA1_NSEC3:
61 #ifdef USE_SHA2
62         case LDNS_RSASHA256:
63         case LDNS_RSASHA512:
64 #endif
65                 if (len > 0) {
66                         if (keydata[0] == 0) {
67                                 /* big exponent */
68                                 if (len > 3) {
69                                         memmove(&int16, keydata + 1, 2);
70                                         exp = ntohs(int16);
71                                         return (len - exp - 3)*8;
72                                 } else {
73                                         return 0;
74                                 }
75                         } else {
76                                 exp = keydata[0];
77                                 return (len-exp-1)*8;
78                         }
79                 } else {
80                         return 0;
81                 }
82                 break;
83 #ifdef USE_GOST
84         case LDNS_ECC_GOST:
85                 return 512;
86 #endif
87 #ifdef USE_ECDSA
88         case LDNS_ECDSAP256SHA256:
89                 return 256;
90         case LDNS_ECDSAP384SHA384:
91                 return 384;
92 #endif
93 #ifdef USE_ED25519
94         case LDNS_ED25519:
95                 return 256;
96 #endif
97 #ifdef USE_ED448
98         case LDNS_ED448:
99                 return 456;
100 #endif
101         default:
102                 return 0;
103         }
104 }
105
106 uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
107 {
108         if(keysize < 4) {
109                 return 0;
110         }
111         /* look at the algorithm field, copied from 2535bis */
112         if (key[3] == LDNS_RSAMD5) {
113                 uint16_t ac16 = 0;
114                 if (keysize > 4) {
115                         memmove(&ac16, key + keysize - 3, 2);
116                 }
117                 ac16 = ntohs(ac16);
118                 return (uint16_t) ac16;
119         } else {
120                 size_t i;
121                 uint32_t ac32 = 0;
122                 for (i = 0; i < keysize; ++i) {
123                         ac32 += (i & 1) ? key[i] : key[i] << 8;
124                 }
125                 ac32 += (ac32 >> 16) & 0xFFFF;
126                 return (uint16_t) (ac32 & 0xFFFF);
127         }
128 }
129
130 #ifdef HAVE_SSL
131 #ifdef USE_GOST
132 /** store GOST engine reference loaded into OpenSSL library */
133 ENGINE* sldns_gost_engine = NULL;
134
135 int
136 sldns_key_EVP_load_gost_id(void)
137 {
138         static int gost_id = 0;
139         const EVP_PKEY_ASN1_METHOD* meth;
140         ENGINE* e;
141
142         if(gost_id) return gost_id;
143
144         /* see if configuration loaded gost implementation from other engine*/
145         meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
146         if(meth) {
147                 EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
148                 return gost_id;
149         }
150
151         /* see if engine can be loaded already */
152         e = ENGINE_by_id("gost");
153         if(!e) {
154                 /* load it ourself, in case statically linked */
155                 ENGINE_load_builtin_engines();
156                 ENGINE_load_dynamic();
157                 e = ENGINE_by_id("gost");
158         }
159         if(!e) {
160                 /* no gost engine in openssl */
161                 return 0;
162         }
163         if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
164                 ENGINE_finish(e);
165                 ENGINE_free(e);
166                 return 0;
167         }
168
169         meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
170         if(!meth) {
171                 /* algo not found */
172                 ENGINE_finish(e);
173                 ENGINE_free(e);
174                 return 0;
175         }
176         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
177          * on some platforms this frees up the meth and unloads gost stuff */
178         sldns_gost_engine = e;
179         
180         EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
181         return gost_id;
182
183
184 void sldns_key_EVP_unload_gost(void)
185 {
186         if(sldns_gost_engine) {
187                 ENGINE_finish(sldns_gost_engine);
188                 ENGINE_free(sldns_gost_engine);
189                 sldns_gost_engine = NULL;
190         }
191 }
192 #endif /* USE_GOST */
193
194 DSA *
195 sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
196 {
197         uint8_t T;
198         uint16_t length;
199         uint16_t offset;
200         DSA *dsa;
201         BIGNUM *Q; BIGNUM *P;
202         BIGNUM *G; BIGNUM *Y;
203
204         if(len == 0)
205                 return NULL;
206         T = (uint8_t)key[0];
207         length = (64 + T * 8);
208         offset = 1;
209
210         if (T > 8) {
211                 return NULL;
212         }
213         if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
214                 return NULL;
215
216         Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
217         offset += SHA_DIGEST_LENGTH;
218
219         P = BN_bin2bn(key+offset, (int)length, NULL);
220         offset += length;
221
222         G = BN_bin2bn(key+offset, (int)length, NULL);
223         offset += length;
224
225         Y = BN_bin2bn(key+offset, (int)length, NULL);
226
227         /* create the key and set its properties */
228         if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
229                 BN_free(Q);
230                 BN_free(P);
231                 BN_free(G);
232                 BN_free(Y);
233                 return NULL;
234         }
235 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
236 #ifndef S_SPLINT_S
237         dsa->p = P;
238         dsa->q = Q;
239         dsa->g = G;
240         dsa->pub_key = Y;
241 #endif /* splint */
242
243 #else /* OPENSSL_VERSION_NUMBER */
244         if (!DSA_set0_pqg(dsa, P, Q, G)) {
245                 /* QPG not yet attached, need to free */
246                 BN_free(Q);
247                 BN_free(P);
248                 BN_free(G);
249
250                 DSA_free(dsa);
251                 BN_free(Y);
252                 return NULL;
253         }
254         if (!DSA_set0_key(dsa, Y, NULL)) {
255                 /* QPG attached, cleaned up by DSA_fre() */
256                 DSA_free(dsa);
257                 BN_free(Y);
258                 return NULL;
259         }
260 #endif
261
262         return dsa;
263 }
264
265 RSA *
266 sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
267 {
268         uint16_t offset;
269         uint16_t exp;
270         uint16_t int16;
271         RSA *rsa;
272         BIGNUM *modulus;
273         BIGNUM *exponent;
274
275         if (len == 0)
276                 return NULL;
277         if (key[0] == 0) {
278                 if(len < 3)
279                         return NULL;
280                 memmove(&int16, key+1, 2);
281                 exp = ntohs(int16);
282                 offset = 3;
283         } else {
284                 exp = key[0];
285                 offset = 1;
286         }
287
288         /* key length at least one */
289         if(len < (size_t)offset + exp + 1)
290                 return NULL;
291
292         /* Exponent */
293         exponent = BN_new();
294         if(!exponent) return NULL;
295         (void) BN_bin2bn(key+offset, (int)exp, exponent);
296         offset += exp;
297
298         /* Modulus */
299         modulus = BN_new();
300         if(!modulus) {
301                 BN_free(exponent);
302                 return NULL;
303         }
304         /* length of the buffer must match the key length! */
305         (void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
306
307         rsa = RSA_new();
308         if(!rsa) {
309                 BN_free(exponent);
310                 BN_free(modulus);
311                 return NULL;
312         }
313 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
314 #ifndef S_SPLINT_S
315         rsa->n = modulus;
316         rsa->e = exponent;
317 #endif /* splint */
318
319 #else /* OPENSSL_VERSION_NUMBER */
320         if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
321                 BN_free(exponent);
322                 BN_free(modulus);
323                 RSA_free(rsa);
324                 return NULL;
325         }
326 #endif
327
328         return rsa;
329 }
330
331 #ifdef USE_GOST
332 EVP_PKEY*
333 sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
334 {
335         /* prefix header for X509 encoding */
336         uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 
337                 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 
338                 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 
339                 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
340         unsigned char encoded[37+64];
341         const unsigned char* pp;
342         if(keylen != 64) {
343                 /* key wrong size */
344                 return NULL;
345         }
346
347         /* create evp_key */
348         memmove(encoded, asn, 37);
349         memmove(encoded+37, key, 64);
350         pp = (unsigned char*)&encoded[0];
351
352         return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
353 }
354 #endif /* USE_GOST */
355
356 #ifdef USE_ECDSA
357 EVP_PKEY*
358 sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
359 {
360         unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
361         const unsigned char* pp = buf;
362         EVP_PKEY *evp_key;
363         EC_KEY *ec;
364         /* check length, which uncompressed must be 2 bignums */
365         if(algo == LDNS_ECDSAP256SHA256) {
366                 if(keylen != 2*256/8) return NULL;
367                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
368         } else if(algo == LDNS_ECDSAP384SHA384) {
369                 if(keylen != 2*384/8) return NULL;
370                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
371         } else    ec = NULL;
372         if(!ec) return NULL;
373         if(keylen+1 > sizeof(buf)) { /* sanity check */
374                 EC_KEY_free(ec);
375                 return NULL;
376         }
377         /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
378          * of openssl) for uncompressed data */
379         buf[0] = POINT_CONVERSION_UNCOMPRESSED;
380         memmove(buf+1, key, keylen);
381         if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
382                 EC_KEY_free(ec);
383                 return NULL;
384         }
385         evp_key = EVP_PKEY_new();
386         if(!evp_key) {
387                 EC_KEY_free(ec);
388                 return NULL;
389         }
390         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
391                 EVP_PKEY_free(evp_key);
392                 EC_KEY_free(ec);
393                 return NULL;
394         }
395         return evp_key;
396 }
397 #endif /* USE_ECDSA */
398
399 #ifdef USE_ED25519
400 EVP_PKEY*
401 sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
402 {
403         /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
404         uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
405                 0x70, 0x03, 0x21, 0x00};
406         int pre_len = 12;
407         uint8_t buf[256];
408         EVP_PKEY *evp_key;
409         /* pp gets modified by d2i() */
410         const unsigned char* pp = (unsigned char*)buf;
411         if(keylen != 32 || keylen + pre_len > sizeof(buf))
412                 return NULL; /* wrong length */
413         memmove(buf, pre, pre_len);
414         memmove(buf+pre_len, key, keylen);
415         evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
416         return evp_key;
417 }
418 #endif /* USE_ED25519 */
419
420 #ifdef USE_ED448
421 EVP_PKEY*
422 sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
423 {
424         /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
425         uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
426                 0x71, 0x03, 0x3a, 0x00};
427         int pre_len = 12;
428         uint8_t buf[256];
429         EVP_PKEY *evp_key;
430         /* pp gets modified by d2i() */
431         const unsigned char* pp = (unsigned char*)buf;
432         if(keylen != 57 || keylen + pre_len > sizeof(buf))
433                 return NULL; /* wrong length */
434         memmove(buf, pre, pre_len);
435         memmove(buf+pre_len, key, keylen);
436         evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
437         return evp_key;
438 }
439 #endif /* USE_ED448 */
440
441 int
442 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
443         const EVP_MD* md)
444 {
445         EVP_MD_CTX* ctx;
446         ctx = EVP_MD_CTX_create();
447         if(!ctx)
448                 return 0;
449         if(!EVP_DigestInit_ex(ctx, md, NULL) ||
450                 !EVP_DigestUpdate(ctx, data, len) ||
451                 !EVP_DigestFinal_ex(ctx, dest, NULL)) {
452                 EVP_MD_CTX_destroy(ctx);
453                 return 0;
454         }
455         EVP_MD_CTX_destroy(ctx);
456         return 1;
457 }
458 #endif /* HAVE_SSL */