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 #ifdef USE_DSA
199 /* Retrieve params as BIGNUM from raw buffer */
200 static int
sldns_key_dsa_buf_bignum(unsigned char * key,size_t len,BIGNUM ** p,BIGNUM ** q,BIGNUM ** g,BIGNUM ** y)201 sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
202 BIGNUM** q, BIGNUM** g, BIGNUM** y)
203 {
204 uint8_t T;
205 uint16_t length;
206 uint16_t offset;
207
208 if(len == 0)
209 return 0;
210 T = (uint8_t)key[0];
211 length = (64 + T * 8);
212 offset = 1;
213
214 if (T > 8) {
215 return 0;
216 }
217 if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
218 return 0;
219
220 *q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
221 offset += SHA_DIGEST_LENGTH;
222
223 *p = BN_bin2bn(key+offset, (int)length, NULL);
224 offset += length;
225
226 *g = BN_bin2bn(key+offset, (int)length, NULL);
227 offset += length;
228
229 *y = BN_bin2bn(key+offset, (int)length, NULL);
230
231 if(!*q || !*p || !*g || !*y) {
232 BN_free(*q);
233 BN_free(*p);
234 BN_free(*g);
235 BN_free(*y);
236 return 0;
237 }
238 return 1;
239 }
240
241 #ifndef HAVE_OSSL_PARAM_BLD_NEW
242 DSA *
sldns_key_buf2dsa_raw(unsigned char * key,size_t len)243 sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
244 {
245 DSA *dsa;
246 BIGNUM *Q=NULL, *P=NULL, *G=NULL, *Y=NULL;
247 if(!sldns_key_dsa_buf_bignum(key, len, &P, &Q, &G, &Y)) {
248 return NULL;
249 }
250 /* create the key and set its properties */
251 if(!(dsa = DSA_new())) {
252 return NULL;
253 }
254 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
255 (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
256 #ifndef S_SPLINT_S
257 dsa->p = P;
258 dsa->q = Q;
259 dsa->g = G;
260 dsa->pub_key = Y;
261 #endif /* splint */
262
263 #else /* OPENSSL_VERSION_NUMBER */
264 if (!DSA_set0_pqg(dsa, P, Q, G)) {
265 /* QPG not yet attached, need to free */
266 BN_free(Q);
267 BN_free(P);
268 BN_free(G);
269
270 DSA_free(dsa);
271 BN_free(Y);
272 return NULL;
273 }
274 if (!DSA_set0_key(dsa, Y, NULL)) {
275 /* QPG attached, cleaned up by DSA_free() */
276 DSA_free(dsa);
277 BN_free(Y);
278 return NULL;
279 }
280 #endif
281
282 return dsa;
283 }
284 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
285
sldns_key_dsa2pkey_raw(unsigned char * key,size_t len)286 EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
287 {
288 #ifdef HAVE_OSSL_PARAM_BLD_NEW
289 EVP_PKEY* evp_key = NULL;
290 EVP_PKEY_CTX* ctx;
291 BIGNUM *p=NULL, *q=NULL, *g=NULL, *y=NULL;
292 OSSL_PARAM_BLD* param_bld;
293 OSSL_PARAM* params = NULL;
294 if(!sldns_key_dsa_buf_bignum(key, len, &p, &q, &g, &y)) {
295 return NULL;
296 }
297
298 param_bld = OSSL_PARAM_BLD_new();
299 if(!param_bld) {
300 BN_free(p);
301 BN_free(q);
302 BN_free(g);
303 BN_free(y);
304 return NULL;
305 }
306 if(!OSSL_PARAM_BLD_push_BN(param_bld, "p", p) ||
307 !OSSL_PARAM_BLD_push_BN(param_bld, "g", g) ||
308 !OSSL_PARAM_BLD_push_BN(param_bld, "q", q) ||
309 !OSSL_PARAM_BLD_push_BN(param_bld, "pub", y)) {
310 OSSL_PARAM_BLD_free(param_bld);
311 BN_free(p);
312 BN_free(q);
313 BN_free(g);
314 BN_free(y);
315 return NULL;
316 }
317 params = OSSL_PARAM_BLD_to_param(param_bld);
318 OSSL_PARAM_BLD_free(param_bld);
319
320 ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
321 if(!ctx) {
322 OSSL_PARAM_free(params);
323 BN_free(p);
324 BN_free(q);
325 BN_free(g);
326 BN_free(y);
327 return NULL;
328 }
329 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
330 EVP_PKEY_CTX_free(ctx);
331 OSSL_PARAM_free(params);
332 BN_free(p);
333 BN_free(q);
334 BN_free(g);
335 BN_free(y);
336 return NULL;
337 }
338 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
339 EVP_PKEY_CTX_free(ctx);
340 OSSL_PARAM_free(params);
341 BN_free(p);
342 BN_free(q);
343 BN_free(g);
344 BN_free(y);
345 return NULL;
346 }
347
348 EVP_PKEY_CTX_free(ctx);
349 OSSL_PARAM_free(params);
350 BN_free(p);
351 BN_free(q);
352 BN_free(g);
353 BN_free(y);
354 return evp_key;
355 #else
356 DSA* dsa;
357 EVP_PKEY* evp_key = EVP_PKEY_new();
358 if(!evp_key) {
359 return NULL;
360 }
361 dsa = sldns_key_buf2dsa_raw(key, len);
362 if(!dsa) {
363 EVP_PKEY_free(evp_key);
364 return NULL;
365 }
366 if(EVP_PKEY_assign_DSA(evp_key, dsa) == 0) {
367 DSA_free(dsa);
368 EVP_PKEY_free(evp_key);
369 return NULL;
370 }
371 return evp_key;
372 #endif
373 }
374 #endif /* USE_DSA */
375
376 /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
377 static int
sldns_key_rsa_buf_bignum(unsigned char * key,size_t len,BIGNUM ** n,BIGNUM ** e)378 sldns_key_rsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** n,
379 BIGNUM** e)
380 {
381 uint16_t offset;
382 uint16_t exp;
383 uint16_t int16;
384
385 if (len == 0)
386 return 0;
387 if (key[0] == 0) {
388 if(len < 3)
389 return 0;
390 memmove(&int16, key+1, 2);
391 exp = ntohs(int16);
392 offset = 3;
393 } else {
394 exp = key[0];
395 offset = 1;
396 }
397
398 /* key length at least one */
399 if(len < (size_t)offset + exp + 1)
400 return 0;
401
402 /* Exponent */
403 *e = BN_new();
404 if(!*e) return 0;
405 (void) BN_bin2bn(key+offset, (int)exp, *e);
406 offset += exp;
407
408 /* Modulus */
409 *n = BN_new();
410 if(!*n) {
411 BN_free(*e);
412 return 0;
413 }
414 /* length of the buffer must match the key length! */
415 (void) BN_bin2bn(key+offset, (int)(len - offset), *n);
416 return 1;
417 }
418
419 #ifndef HAVE_OSSL_PARAM_BLD_NEW
420 RSA *
sldns_key_buf2rsa_raw(unsigned char * key,size_t len)421 sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
422 {
423 BIGNUM* modulus = NULL;
424 BIGNUM* exponent = NULL;
425 RSA *rsa;
426 if(!sldns_key_rsa_buf_bignum(key, len, &modulus, &exponent))
427 return NULL;
428 rsa = RSA_new();
429 if(!rsa) {
430 BN_free(exponent);
431 BN_free(modulus);
432 return NULL;
433 }
434 #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
435 (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
436 #ifndef S_SPLINT_S
437 rsa->n = modulus;
438 rsa->e = exponent;
439 #endif /* splint */
440
441 #else /* OPENSSL_VERSION_NUMBER */
442 if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
443 BN_free(exponent);
444 BN_free(modulus);
445 RSA_free(rsa);
446 return NULL;
447 }
448 #endif
449
450 return rsa;
451 }
452 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
453
sldns_key_rsa2pkey_raw(unsigned char * key,size_t len)454 EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
455 {
456 #ifdef HAVE_OSSL_PARAM_BLD_NEW
457 EVP_PKEY* evp_key = NULL;
458 EVP_PKEY_CTX* ctx;
459 BIGNUM *n=NULL, *e=NULL;
460 OSSL_PARAM_BLD* param_bld;
461 OSSL_PARAM* params = NULL;
462
463 if(!sldns_key_rsa_buf_bignum(key, len, &n, &e)) {
464 return NULL;
465 }
466
467 param_bld = OSSL_PARAM_BLD_new();
468 if(!param_bld) {
469 BN_free(n);
470 BN_free(e);
471 return NULL;
472 }
473 if(!OSSL_PARAM_BLD_push_BN(param_bld, "n", n)) {
474 OSSL_PARAM_BLD_free(param_bld);
475 BN_free(n);
476 BN_free(e);
477 return NULL;
478 }
479 if(!OSSL_PARAM_BLD_push_BN(param_bld, "e", e)) {
480 OSSL_PARAM_BLD_free(param_bld);
481 BN_free(n);
482 BN_free(e);
483 return NULL;
484 }
485 params = OSSL_PARAM_BLD_to_param(param_bld);
486 OSSL_PARAM_BLD_free(param_bld);
487
488 ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
489 if(!ctx) {
490 OSSL_PARAM_free(params);
491 BN_free(n);
492 BN_free(e);
493 return NULL;
494 }
495 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
496 EVP_PKEY_CTX_free(ctx);
497 OSSL_PARAM_free(params);
498 BN_free(n);
499 BN_free(e);
500 return NULL;
501 }
502 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
503 EVP_PKEY_CTX_free(ctx);
504 OSSL_PARAM_free(params);
505 BN_free(n);
506 BN_free(e);
507 return NULL;
508 }
509
510 EVP_PKEY_CTX_free(ctx);
511 OSSL_PARAM_free(params);
512 BN_free(n);
513 BN_free(e);
514 return evp_key;
515 #else
516 RSA* rsa;
517 EVP_PKEY *evp_key = EVP_PKEY_new();
518 if(!evp_key) {
519 return NULL;
520 }
521 rsa = sldns_key_buf2rsa_raw(key, len);
522 if(!rsa) {
523 EVP_PKEY_free(evp_key);
524 return NULL;
525 }
526 if(EVP_PKEY_assign_RSA(evp_key, rsa) == 0) {
527 RSA_free(rsa);
528 EVP_PKEY_free(evp_key);
529 return NULL;
530 }
531 return evp_key;
532 #endif
533 }
534
535 #ifdef USE_GOST
536 EVP_PKEY*
sldns_gost2pkey_raw(unsigned char * key,size_t keylen)537 sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
538 {
539 /* prefix header for X509 encoding */
540 uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
541 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
542 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
543 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
544 unsigned char encoded[37+64];
545 const unsigned char* pp;
546 if(keylen != 64) {
547 /* key wrong size */
548 return NULL;
549 }
550
551 /* create evp_key */
552 memmove(encoded, asn, 37);
553 memmove(encoded+37, key, 64);
554 pp = (unsigned char*)&encoded[0];
555
556 return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
557 }
558 #endif /* USE_GOST */
559
560 #ifdef USE_ECDSA
561 EVP_PKEY*
sldns_ecdsa2pkey_raw(unsigned char * key,size_t keylen,uint8_t algo)562 sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
563 {
564 #ifdef HAVE_OSSL_PARAM_BLD_NEW
565 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
566 EVP_PKEY *evp_key = NULL;
567 EVP_PKEY_CTX* ctx;
568 OSSL_PARAM_BLD* param_bld;
569 OSSL_PARAM* params = NULL;
570 char* group = NULL;
571
572 /* check length, which uncompressed must be 2 bignums */
573 if(algo == LDNS_ECDSAP256SHA256) {
574 if(keylen != 2*256/8) return NULL;
575 group = "prime256v1";
576 } else if(algo == LDNS_ECDSAP384SHA384) {
577 if(keylen != 2*384/8) return NULL;
578 group = "P-384";
579 } else {
580 return NULL;
581 }
582 if(keylen+1 > sizeof(buf)) { /* sanity check */
583 return NULL;
584 }
585 /* prepend the 0x04 for uncompressed format */
586 buf[0] = POINT_CONVERSION_UNCOMPRESSED;
587 memmove(buf+1, key, keylen);
588
589 param_bld = OSSL_PARAM_BLD_new();
590 if(!param_bld) {
591 return NULL;
592 }
593 if(!OSSL_PARAM_BLD_push_utf8_string(param_bld, "group", group, 0) ||
594 !OSSL_PARAM_BLD_push_octet_string(param_bld, "pub", buf, keylen+1)) {
595 OSSL_PARAM_BLD_free(param_bld);
596 return NULL;
597 }
598 params = OSSL_PARAM_BLD_to_param(param_bld);
599 OSSL_PARAM_BLD_free(param_bld);
600
601 ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
602 if(!ctx) {
603 OSSL_PARAM_free(params);
604 return NULL;
605 }
606 if(EVP_PKEY_fromdata_init(ctx) <= 0) {
607 EVP_PKEY_CTX_free(ctx);
608 OSSL_PARAM_free(params);
609 return NULL;
610 }
611 if(EVP_PKEY_fromdata(ctx, &evp_key, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
612 EVP_PKEY_CTX_free(ctx);
613 OSSL_PARAM_free(params);
614 return NULL;
615 }
616 EVP_PKEY_CTX_free(ctx);
617 OSSL_PARAM_free(params);
618 return evp_key;
619 #else
620 unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
621 const unsigned char* pp = buf;
622 EVP_PKEY *evp_key;
623 EC_KEY *ec;
624 /* check length, which uncompressed must be 2 bignums */
625 if(algo == LDNS_ECDSAP256SHA256) {
626 if(keylen != 2*256/8) return NULL;
627 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
628 } else if(algo == LDNS_ECDSAP384SHA384) {
629 if(keylen != 2*384/8) return NULL;
630 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
631 } else ec = NULL;
632 if(!ec) return NULL;
633 if(keylen+1 > sizeof(buf)) { /* sanity check */
634 EC_KEY_free(ec);
635 return NULL;
636 }
637 /* prepend the 0x02 (from docs) (or actually 0x04 from implementation
638 * of openssl) for uncompressed data */
639 buf[0] = POINT_CONVERSION_UNCOMPRESSED;
640 memmove(buf+1, key, keylen);
641 if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
642 EC_KEY_free(ec);
643 return NULL;
644 }
645 evp_key = EVP_PKEY_new();
646 if(!evp_key) {
647 EC_KEY_free(ec);
648 return NULL;
649 }
650 if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
651 EVP_PKEY_free(evp_key);
652 EC_KEY_free(ec);
653 return NULL;
654 }
655 return evp_key;
656 #endif /* HAVE_OSSL_PARAM_BLD_NEW */
657 }
658 #endif /* USE_ECDSA */
659
660 #ifdef USE_ED25519
661 EVP_PKEY*
sldns_ed255192pkey_raw(const unsigned char * key,size_t keylen)662 sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
663 {
664 /* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
665 uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
666 0x70, 0x03, 0x21, 0x00};
667 int pre_len = 12;
668 uint8_t buf[256];
669 EVP_PKEY *evp_key;
670 /* pp gets modified by d2i() */
671 const unsigned char* pp = (unsigned char*)buf;
672 if(keylen != 32 || keylen + pre_len > sizeof(buf))
673 return NULL; /* wrong length */
674 memmove(buf, pre, pre_len);
675 memmove(buf+pre_len, key, keylen);
676 evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
677 return evp_key;
678 }
679 #endif /* USE_ED25519 */
680
681 #ifdef USE_ED448
682 EVP_PKEY*
sldns_ed4482pkey_raw(const unsigned char * key,size_t keylen)683 sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
684 {
685 /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
686 uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
687 0x71, 0x03, 0x3a, 0x00};
688 int pre_len = 12;
689 uint8_t buf[256];
690 EVP_PKEY *evp_key;
691 /* pp gets modified by d2i() */
692 const unsigned char* pp = (unsigned char*)buf;
693 if(keylen != 57 || keylen + pre_len > sizeof(buf))
694 return NULL; /* wrong length */
695 memmove(buf, pre, pre_len);
696 memmove(buf+pre_len, key, keylen);
697 evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
698 return evp_key;
699 }
700 #endif /* USE_ED448 */
701
702 int
sldns_digest_evp(unsigned char * data,unsigned int len,unsigned char * dest,const EVP_MD * md)703 sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
704 const EVP_MD* md)
705 {
706 EVP_MD_CTX* ctx;
707 ctx = EVP_MD_CTX_create();
708 if(!ctx)
709 return 0;
710 if(!EVP_DigestInit_ex(ctx, md, NULL) ||
711 !EVP_DigestUpdate(ctx, data, len) ||
712 !EVP_DigestFinal_ex(ctx, dest, NULL)) {
713 EVP_MD_CTX_destroy(ctx);
714 return 0;
715 }
716 EVP_MD_CTX_destroy(ctx);
717 return 1;
718 }
719 #endif /* HAVE_SSL */
720