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_PARAM_BUILD_H
30 # include <openssl/param_build.h>
31 #else
32 # ifdef HAVE_OPENSSL_RSA_H
33 # include <openssl/rsa.h>
34 # endif
35 # ifdef HAVE_OPENSSL_DSA_H
36 # include <openssl/dsa.h>
37 # endif
38 #endif
39 #endif /* HAVE_SSL */
40
41 size_t
sldns_rr_dnskey_key_size_raw(const unsigned char * keydata,const size_t len,int alg)42 sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
43 const size_t len, int alg)
44 {
45 /* for DSA keys */
46 uint8_t t;
47
48 /* for RSA keys */
49 uint16_t exp;
50 uint16_t int16;
51
52 switch ((sldns_algorithm)alg) {
53 case LDNS_DSA:
54 case LDNS_DSA_NSEC3:
55 if (len > 0) {
56 t = keydata[0];
57 return (64 + t*8)*8;
58 } else {
59 return 0;
60 }
61 break;
62 case LDNS_RSAMD5:
63 case LDNS_RSASHA1:
64 case LDNS_RSASHA1_NSEC3:
65 #ifdef USE_SHA2
66 case LDNS_RSASHA256:
67 case LDNS_RSASHA512:
68 #endif
69 if (len > 0) {
70 if (keydata[0] == 0) {
71 /* big exponent */
72 if (len > 3) {
73 memmove(&int16, keydata + 1, 2);
74 exp = ntohs(int16);
75 return (len - exp - 3)*8;
76 } else {
77 return 0;
78 }
79 } else {
80 exp = keydata[0];
81 return (len-exp-1)*8;
82 }
83 } else {
84 return 0;
85 }
86 break;
87 #ifdef USE_GOST
88 case LDNS_ECC_GOST:
89 return 512;
90 #endif
91 #ifdef USE_ECDSA
92 case LDNS_ECDSAP256SHA256:
93 return 256;
94 case LDNS_ECDSAP384SHA384:
95 return 384;
96 #endif
97 #ifdef USE_ED25519
98 case LDNS_ED25519:
99 return 256;
100 #endif
101 #ifdef USE_ED448
102 case LDNS_ED448:
103 return 456;
104 #endif
105 default:
106 return 0;
107 }
108 }
109
sldns_calc_keytag_raw(uint8_t * key,size_t keysize)110 uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
111 {
112 if(keysize < 4) {
113 return 0;
114 }
115 /* look at the algorithm field, copied from 2535bis */
116 if (key[3] == LDNS_RSAMD5) {
117 uint16_t ac16 = 0;
118 if (keysize > 4) {
119 memmove(&ac16, key + keysize - 3, 2);
120 }
121 ac16 = ntohs(ac16);
122 return (uint16_t) ac16;
123 } else {
124 size_t i;
125 uint32_t ac32 = 0;
126 for (i = 0; i < keysize; ++i) {
127 ac32 += (i & 1) ? key[i] : key[i] << 8;
128 }
129 ac32 += (ac32 >> 16) & 0xFFFF;
130 return (uint16_t) (ac32 & 0xFFFF);
131 }
132 }
133
134 #ifdef HAVE_SSL
135 #ifdef USE_GOST
136 /** store GOST engine reference loaded into OpenSSL library */
137 ENGINE* sldns_gost_engine = NULL;
138
139 int
sldns_key_EVP_load_gost_id(void)140 sldns_key_EVP_load_gost_id(void)
141 {
142 static int gost_id = 0;
143 const EVP_PKEY_ASN1_METHOD* meth;
144 ENGINE* e;
145
146 if(gost_id) return gost_id;
147
148 /* see if configuration loaded gost implementation from other engine*/
149 meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
150 if(meth) {
151 EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
152 return gost_id;
153 }
154
155 /* see if engine can be loaded already */
156 e = ENGINE_by_id("gost");
157 if(!e) {
158 /* load it ourself, in case statically linked */
159 ENGINE_load_builtin_engines();
160 ENGINE_load_dynamic();
161 e = ENGINE_by_id("gost");
162 }
163 if(!e) {
164 /* no gost engine in openssl */
165 return 0;
166 }
167 if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
168 ENGINE_finish(e);
169 ENGINE_free(e);
170 return 0;
171 }
172
173 meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
174 if(!meth) {
175 /* algo not found */
176 ENGINE_finish(e);
177 ENGINE_free(e);
178 return 0;
179 }
180 /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
181 * on some platforms this frees up the meth and unloads gost stuff */
182 sldns_gost_engine = e;
183
184 EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
185 return gost_id;
186 }
187
sldns_key_EVP_unload_gost(void)188 void sldns_key_EVP_unload_gost(void)
189 {
190 if(sldns_gost_engine) {
191 ENGINE_finish(sldns_gost_engine);
192 ENGINE_free(sldns_gost_engine);
193 sldns_gost_engine = NULL;
194 }
195 }
196 #endif /* USE_GOST */
197
198 /* Retrieve params as BIGNUM from raw buffer */
199 static int
sldns_key_dsa_buf_bignum(unsigned char * key,size_t len,BIGNUM ** p,BIGNUM ** q,BIGNUM ** g,BIGNUM ** y)200 sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
201 BIGNUM** q, BIGNUM** g, BIGNUM** y)
202 {
203 uint8_t T;
204 uint16_t length;
205 uint16_t offset;
206
207 if(len == 0)
208 return 0;
209 T = (uint8_t)key[0];
210 length = (64 + T * 8);
211 offset = 1;
212
213 if (T > 8) {
214 return 0;
215 }
216 if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
217 return 0;
218
219 *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
220 offset += SHA_DIGEST_LENGTH;
221
222 *p = BN_bin2bn(key+offset, (int)length, NULL);
223 offset += length;
224
225 *g = BN_bin2bn(key+offset, (int)length, NULL);
226 offset += length;
227
228 *y = BN_bin2bn(key+offset, (int)length, NULL);
229
230 if(!*q || !*p || !*g || !*y) {
231 BN_free(*q);
232 BN_free(*p);
233 BN_free(*g);
234 BN_free(*y);
235 return 0;
236 }
237 return 1;
238 }
239
240 #ifndef HAVE_OSSL_PARAM_BLD_NEW
241 DSA *
sldns_key_buf2dsa_raw(unsigned char * key,size_t len)242 sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
243 {
244 DSA *dsa;
245 BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
246 if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
247 return NULL;
248 }
249 /* create the key and set its properties */
250 if(!(dsa = DSA_new())) {
251 return NULL;
252 }
253 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
254 (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
255 #ifndef S_SPLINT_S
256 dsa->p = P;
257 dsa->q = Q;
258 dsa->g = G;
259 dsa->pub_key = Y;
260 #endif /* splint */
261
262 #else /* OPENSSL_VERSION_NUMBER */
263 if (!DSA_set0_pqg(dsa, P, Q, G)) {
264 /* QPG not yet attached, need to free */
265 BN_free(Q);
266 BN_free(P);
267 BN_free(G);
268
269 DSA_free(dsa);
270 BN_free(Y);
271 return NULL;
272 }
273 if (!DSA_set0_key(dsa, Y, NULL)) {
274 /* QPG attached, cleaned up by DSA_fre() */
275 DSA_free(dsa);
276 BN_free(Y);
277 return NULL;
278 }
279 #endif
280
281 return dsa;
282 }
283 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
284
sldns_key_dsa2pkey_raw(unsigned char * key,size_t len)285 EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
286 {
287 #ifdef HAVE_OSSL_PARAM_BLD_NEW
288 EVP_PKEY* evp_key = NULL;
289 EVP_PKEY_CTX* ctx;
290 BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
291 OSSL_PARAM_BLD* param_bld;
292 OSSL_PARAM* params = NULL;
293 if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
294 return NULL;
295 }
296
297 param_bld = OSSL_PARAM_BLD_new();
298 if(!param_bld) {
299 BN_free(p);
300 BN_free(q);
301 BN_free(g);
302 BN_free(y);
303 return NULL;
304 }
305 if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
306 !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
307 !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
308 !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
309 OSSL_PARAM_BLD_free(param_bld);
310 BN_free(p);
311 BN_free(q);
312 BN_free(g);
313 BN_free(y);
314 return NULL;
315 }
316 params = OSSL_PARAM_BLD_to_param(param_bld);
317 OSSL_PARAM_BLD_free(param_bld);
318
319 ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
320 if(!ctx) {
321 OSSL_PARAM_free(params);
322 BN_free(p);
323 BN_free(q);
324 BN_free(g);
325 BN_free(y);
326 return NULL;
327 }
328 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
329 EVP_PKEY_CTX_free(ctx);
330 OSSL_PARAM_free(params);
331 BN_free(p);
332 BN_free(q);
333 BN_free(g);
334 BN_free(y);
335 return NULL;
336 }
337 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
338 EVP_PKEY_CTX_free(ctx);
339 OSSL_PARAM_free(params);
340 BN_free(p);
341 BN_free(q);
342 BN_free(g);
343 BN_free(y);
344 return NULL;
345 }
346
347 EVP_PKEY_CTX_free(ctx);
348 OSSL_PARAM_free(params);
349 BN_free(p);
350 BN_free(q);
351 BN_free(g);
352 BN_free(y);
353 return evp_key;
354 #else
355 DSA* dsa;
356 EVP_PKEY* evp_key = EVP_PKEY_new();
357 if(!evp_key) {
358 return NULL;
359 }
360 dsa = sldns_key_buf2dsa_raw(key, len);
361 if(!dsa) {
362 EVP_PKEY_free(evp_key);
363 return NULL;
364 }
365 if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
366 DSA_free(dsa);
367 EVP_PKEY_free(evp_key);
368 return NULL;
369 }
370 return evp_key;
371 #endif
372 }
373
374 /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
375 static int
sldns_key_rsa_buf_bignum(unsigned char * key,size_t len,BIGNUM ** n,BIGNUM ** e)376 sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
377 BIGNUM** e)
378 {
379 uint16_t offset;
380 uint16_t exp;
381 uint16_t int16;
382
383 if (len == 0)
384 return 0;
385 if (key[0] == 0) {
386 if(len < 3)
387 return 0;
388 memmove(&int16, key+1, 2);
389 exp = ntohs(int16);
390 offset = 3;
391 } else {
392 exp = key[0];
393 offset = 1;
394 }
395
396 /* key length at least one */
397 if(len < (size_t)offset + exp + 1)
398 return 0;
399
400 /* Exponent */
401 *e = BN_new();
402 if(!*e) return 0;
403 (void) BN_bin2bn(key+offset, (int)exp, *e);
404 offset += exp;
405
406 /* Modulus */
407 *n = BN_new();
408 if(!*n) {
409 BN_free(*e);
410 return 0;
411 }
412 /* length of the buffer must match the key length! */
413 (void) BN_bin2bn(key+offset, (int)(len - offset), *n);
414 return 1;
415 }
416
417 #ifndef HAVE_OSSL_PARAM_BLD_NEW
418 RSA *
sldns_key_buf2rsa_raw(unsigned char * key,size_t len)419 sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
420 {
421 BIGNUM* modulus = NULL;
422 BIGNUM* exponent = NULL;
423 RSA *rsa;
424 if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
425 return NULL;
426 rsa = RSA_new();
427 if(!rsa) {
428 BN_free(exponent);
429 BN_free(modulus);
430 return NULL;
431 }
432 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
433 (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
434 #ifndef S_SPLINT_S
435 rsa->n = modulus;
436 rsa->e = exponent;
437 #endif /* splint */
438
439 #else /* OPENSSL_VERSION_NUMBER */
440 if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
441 BN_free(exponent);
442 BN_free(modulus);
443 RSA_free(rsa);
444 return NULL;
445 }
446 #endif
447
448 return rsa;
449 }
450 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
451
sldns_key_rsa2pkey_raw(unsigned char * key,size_t len)452 EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
453 {
454 #ifdef HAVE_OSSL_PARAM_BLD_NEW
455 EVP_PKEY* evp_key = NULL;
456 EVP_PKEY_CTX* ctx;
457 BIGNUM *n=NULL, *e=NULL;
458 OSSL_PARAM_BLD* param_bld;
459 OSSL_PARAM* params = NULL;
460
461 if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
462 return NULL;
463 }
464
465 param_bld = OSSL_PARAM_BLD_new();
466 if(!param_bld) {
467 BN_free(n);
468 BN_free(e);
469 return NULL;
470 }
471 if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
472 OSSL_PARAM_BLD_free(param_bld);
473 BN_free(n);
474 BN_free(e);
475 return NULL;
476 }
477 if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
478 OSSL_PARAM_BLD_free(param_bld);
479 BN_free(n);
480 BN_free(e);
481 return NULL;
482 }
483 params = OSSL_PARAM_BLD_to_param(param_bld);
484 OSSL_PARAM_BLD_free(param_bld);
485
486 ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
487 if(!ctx) {
488 OSSL_PARAM_free(params);
489 BN_free(n);
490 BN_free(e);
491 return NULL;
492 }
493 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
494 EVP_PKEY_CTX_free(ctx);
495 OSSL_PARAM_free(params);
496 BN_free(n);
497 BN_free(e);
498 return NULL;
499 }
500 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
501 EVP_PKEY_CTX_free(ctx);
502 OSSL_PARAM_free(params);
503 BN_free(n);
504 BN_free(e);
505 return NULL;
506 }
507
508 EVP_PKEY_CTX_free(ctx);
509 OSSL_PARAM_free(params);
510 BN_free(n);
511 BN_free(e);
512 return evp_key;
513 #else
514 RSA* rsa;
515 EVP_PKEY *evp_key = EVP_PKEY_new();
516 if(!evp_key) {
517 return NULL;
518 }
519 rsa = sldns_key_buf2rsa_raw(key, len);
520 if(!rsa) {
521 EVP_PKEY_free(evp_key);
522 return NULL;
523 }
524 if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
525 RSA_free(rsa);
526 EVP_PKEY_free(evp_key);
527 return NULL;
528 }
529 return evp_key;
530 #endif
531 }
532
533 #ifdef USE_GOST
534 EVP_PKEY*
sldns_gost2pkey_raw(unsigned char * key,size_t keylen)535 sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
536 {
537 /* prefix header for X509 encoding */
538 uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
539 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
540 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
541 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
542 unsigned char encoded[37+64];
543 const unsigned char* pp;
544 if(keylen != 64) {
545 /* key wrong size */
546 return NULL;
547 }
548
549 /* create evp_key */
550 memmove(encoded, asn, 37);
551 memmove(encoded+37, key, 64);
552 pp = (unsigned char*)&encoded[0];
553
554 return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
555 }
556 #endif /* USE_GOST */
557
558 #ifdef USE_ECDSA
559 EVP_PKEY*
sldns_ecdsa2pkey_raw(unsigned char * key,size_t keylen,uint8_t algo)560 sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
561 {
562 #ifdef HAVE_OSSL_PARAM_BLD_NEW
563 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
564 EVP_PKEY *evp_key = NULL;
565 EVP_PKEY_CTX* ctx;
566 OSSL_PARAM_BLD* param_bld;
567 OSSL_PARAM* params = NULL;
568 char* group = NULL;
569
570 /* check length, which uncompressed must be 2 bignums */
571 if(algo == LDNS_ECDSAP256SHA256) {
572 if(keylen != 2*256/8) return NULL;
573 group = "prime256v1";
574 } else if(algo == LDNS_ECDSAP384SHA384) {
575 if(keylen != 2*384/8) return NULL;
576 group = "P-384";
577 } else {
578 return NULL;
579 }
580 if(keylen+1 > sizeof(buf)) { /* sanity check */
581 return NULL;
582 }
583 /* prepend the 0x04 for uncompressed format */
584 buf[0] = POINT_CONVERSION_UNCOMPRESSED;
585 memmove(buf+1, key, keylen);
586
587 param_bld = OSSL_PARAM_BLD_new();
588 if(!param_bld) {
589 return NULL;
590 }
591 if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
592 !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
593 OSSL_PARAM_BLD_free(param_bld);
594 return NULL;
595 }
596 params = OSSL_PARAM_BLD_to_param(param_bld);
597 OSSL_PARAM_BLD_free(param_bld);
598
599 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
600 if(!ctx) {
601 OSSL_PARAM_free(params);
602 return NULL;
603 }
604 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
605 EVP_PKEY_CTX_free(ctx);
606 OSSL_PARAM_free(params);
607 return NULL;
608 }
609 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
610 EVP_PKEY_CTX_free(ctx);
611 OSSL_PARAM_free(params);
612 return NULL;
613 }
614 EVP_PKEY_CTX_free(ctx);
615 OSSL_PARAM_free(params);
616 return evp_key;
617 #else
618 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
619 const unsigned char* pp = buf;
620 EVP_PKEY *evp_key;
621 EC_KEY *ec;
622 /* check length, which uncompressed must be 2 bignums */
623 if(algo == LDNS_ECDSAP256SHA256) {
624 if(keylen != 2*256/8) return NULL;
625 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
626 } else if(algo == LDNS_ECDSAP384SHA384) {
627 if(keylen != 2*384/8) return NULL;
628 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
629 } else ec = NULL;
630 if(!ec) return NULL;
631 if(keylen+1 > sizeof(buf)) { /* sanity check */
632 EC_KEY_free(ec);
633 return NULL;
634 }
635 /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
636 * of openssl) for uncompressed data */
637 buf[0] = POINT_CONVERSION_UNCOMPRESSED;
638 memmove(buf+1, key, keylen);
639 if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
640 EC_KEY_free(ec);
641 return NULL;
642 }
643 evp_key = EVP_PKEY_new();
644 if(!evp_key) {
645 EC_KEY_free(ec);
646 return NULL;
647 }
648 if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
649 EVP_PKEY_free(evp_key);
650 EC_KEY_free(ec);
651 return NULL;
652 }
653 return evp_key;
654 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
655 }
656 #endif /* USE_ECDSA */
657
658 #ifdef USE_ED25519
659 EVP_PKEY*
sldns_ed255192pkey_raw(const unsigned char * key,size_t keylen)660 sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
661 {
662 /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
663 uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
664 0x70, 0x03, 0x21, 0x00};
665 int pre_len = 12;
666 uint8_t buf[256];
667 EVP_PKEY *evp_key;
668 /* pp gets modified by d2i() */
669 const unsigned char* pp = (unsigned char*)buf;
670 if(keylen != 32 || keylen + pre_len > sizeof(buf))
671 return NULL; /* wrong length */
672 memmove(buf, pre, pre_len);
673 memmove(buf+pre_len, key, keylen);
674 evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
675 return evp_key;
676 }
677 #endif /* USE_ED25519 */
678
679 #ifdef USE_ED448
680 EVP_PKEY*
sldns_ed4482pkey_raw(const unsigned char * key,size_t keylen)681 sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
682 {
683 /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
684 uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
685 0x71, 0x03, 0x3a, 0x00};
686 int pre_len = 12;
687 uint8_t buf[256];
688 EVP_PKEY *evp_key;
689 /* pp gets modified by d2i() */
690 const unsigned char* pp = (unsigned char*)buf;
691 if(keylen != 57 || keylen + pre_len > sizeof(buf))
692 return NULL; /* wrong length */
693 memmove(buf, pre, pre_len);
694 memmove(buf+pre_len, key, keylen);
695 evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
696 return evp_key;
697 }
698 #endif /* USE_ED448 */
699
700 int
sldns_digest_evp(unsigned char * data,unsigned int len,unsigned char * dest,const EVP_MD * md)701 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
702 const EVP_MD* md)
703 {
704 EVP_MD_CTX* ctx;
705 ctx = EVP_MD_CTX_create();
706 if(!ctx)
707 return 0;
708 if(!EVP_DigestInit_ex(ctx, md, NULL) ||
709 !EVP_DigestUpdate(ctx, data, len) ||
710 !EVP_DigestFinal_ex(ctx, dest, NULL)) {
711 EVP_MD_CTX_destroy(ctx);
712 return 0;
713 }
714 EVP_MD_CTX_destroy(ctx);
715 return 1;
716 }
717 #endif /* HAVE_SSL */
718