xref: /dragonfly/contrib/ldns/keys.c (revision 89656a4e)
1 /*
2  * keys.c handle private keys for use in DNSSEC
3  *
4  * This module should hide some of the openSSL complexities
5  * and give a general interface for private keys and hmac
6  * handling
7  *
8  * (c) NLnet Labs, 2004-2006
9  *
10  * See the file LICENSE for the license
11  */
12 
13 #include <ldns/config.h>
14 
15 #include <ldns/ldns.h>
16 
17 #ifdef HAVE_SSL
18 #include <openssl/ssl.h>
19 #ifndef OPENSSL_NO_ENGINE
20 #include <openssl/engine.h>
21 #endif
22 #include <openssl/rand.h>
23 #endif /* HAVE_SSL */
24 
25 ldns_lookup_table ldns_signing_algorithms[] = {
26         { LDNS_SIGN_RSAMD5, "RSAMD5" },
27         { LDNS_SIGN_RSASHA1, "RSASHA1" },
28         { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
29 #ifdef USE_SHA2
30         { LDNS_SIGN_RSASHA256, "RSASHA256" },
31         { LDNS_SIGN_RSASHA512, "RSASHA512" },
32 #endif
33 #ifdef USE_GOST
34         { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
35 #endif
36 #ifdef USE_ECDSA
37         { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
38         { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
39 #endif
40 #ifdef USE_ED25519
41 	{ LDNS_SIGN_ED25519, "ED25519" },
42 #endif
43 #ifdef USE_ED448
44 	{ LDNS_SIGN_ED448, "ED448" },
45 #endif
46 #ifdef USE_DSA
47         { LDNS_SIGN_DSA, "DSA" },
48         { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
49 #endif
50         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
51         { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
52         { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
53         { LDNS_SIGN_HMACSHA224, "hmac-sha224" },
54         { LDNS_SIGN_HMACSHA384, "hmac-sha384" },
55         { LDNS_SIGN_HMACSHA512, "hmac-sha512" },
56         { 0, NULL }
57 };
58 
59 ldns_key_list *
60 ldns_key_list_new(void)
61 {
62 	ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
63 	if (!key_list) {
64 		return NULL;
65 	} else {
66 		key_list->_key_count = 0;
67 		key_list->_keys = NULL;
68 		return key_list;
69 	}
70 }
71 
72 ldns_key *
73 ldns_key_new(void)
74 {
75 	ldns_key *newkey;
76 
77 	newkey = LDNS_MALLOC(ldns_key);
78 	if (!newkey) {
79 		return NULL;
80 	} else {
81 		/* some defaults - not sure wether to do this */
82 		ldns_key_set_use(newkey, true);
83 		ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
84 		ldns_key_set_origttl(newkey, 0);
85 		ldns_key_set_keytag(newkey, 0);
86 		ldns_key_set_inception(newkey, 0);
87 		ldns_key_set_expiration(newkey, 0);
88 		ldns_key_set_pubkey_owner(newkey, NULL);
89 #ifdef HAVE_SSL
90 		ldns_key_set_evp_key(newkey, NULL);
91 #endif /* HAVE_SSL */
92 		ldns_key_set_hmac_key(newkey, NULL);
93 		ldns_key_set_external_key(newkey, NULL);
94 		return newkey;
95 	}
96 }
97 
98 ldns_status
99 ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
100 {
101 	return ldns_key_new_frm_fp_l(k, fp, NULL);
102 }
103 
104 #if defined(HAVE_SSL) && !defined(OPENSSL_NO_ENGINE)
105 ldns_status
106 ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
107 {
108 	ldns_key *k;
109 
110 	k = ldns_key_new();
111         if(!k) return LDNS_STATUS_MEM_ERR;
112 #ifndef S_SPLINT_S
113 	k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
114         if(!k->_key.key) {
115                 ldns_key_free(k);
116                 return LDNS_STATUS_ERR;
117         }
118 	ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
119 	if (!k->_key.key) {
120                 ldns_key_free(k);
121 		return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
122 	}
123 #endif /* splint */
124 	*key = k;
125 	return LDNS_STATUS_OK;
126 }
127 #endif
128 
129 #ifdef USE_GOST
130 /** store GOST engine reference loaded into OpenSSL library */
131 ENGINE* ldns_gost_engine = NULL;
132 
133 int
134 ldns_key_EVP_load_gost_id(void)
135 {
136 	static int gost_id = 0;
137 	const EVP_PKEY_ASN1_METHOD* meth;
138 	ENGINE* e;
139 
140 	if(gost_id) return gost_id;
141 
142 	/* see if configuration loaded gost implementation from other engine*/
143 	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
144 	if(meth) {
145 		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
146 		return gost_id;
147 	}
148 
149 	/* see if engine can be loaded already */
150 	e = ENGINE_by_id("gost");
151 	if(!e) {
152 		/* load it ourself, in case statically linked */
153 		ENGINE_load_builtin_engines();
154 		ENGINE_load_dynamic();
155 		e = ENGINE_by_id("gost");
156 	}
157 	if(!e) {
158 		/* no gost engine in openssl */
159 		return 0;
160 	}
161 	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
162 		ENGINE_finish(e);
163 		ENGINE_free(e);
164 		return 0;
165 	}
166 
167 	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
168 	if(!meth) {
169 		/* algo not found */
170 		ENGINE_finish(e);
171 		ENGINE_free(e);
172 		return 0;
173 	}
174         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
175          * on some platforms this frees up the meth and unloads gost stuff */
176         ldns_gost_engine = e;
177 
178 	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
179 	return gost_id;
180 }
181 
182 void ldns_key_EVP_unload_gost(void)
183 {
184         if(ldns_gost_engine) {
185                 ENGINE_finish(ldns_gost_engine);
186                 ENGINE_free(ldns_gost_engine);
187                 ldns_gost_engine = NULL;
188         }
189 }
190 
191 /** read GOST private key */
192 static EVP_PKEY*
193 ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
194 {
195 	char token[16384];
196 	const unsigned char* pp;
197 	int gost_id;
198 	EVP_PKEY* pkey;
199 	ldns_rdf* b64rdf = NULL;
200 
201 	gost_id = ldns_key_EVP_load_gost_id();
202 	if(!gost_id)
203 		return NULL;
204 
205 	if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n",
206 		sizeof(token), line_nr) == -1)
207 		return NULL;
208 	while(strlen(token) < 96) {
209 		/* read more b64 from the file, b64 split on multiple lines */
210 		if(ldns_fget_token_l(fp, token+strlen(token), "\n",
211 			sizeof(token)-strlen(token), line_nr) == -1)
212 			return NULL;
213 	}
214 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
215 		return NULL;
216 	pp = (unsigned char*)ldns_rdf_data(b64rdf);
217 	pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf));
218 	ldns_rdf_deep_free(b64rdf);
219 	return pkey;
220 }
221 #endif
222 
223 #ifdef USE_ECDSA
224 /** calculate public key from private key */
225 static int
226 ldns_EC_KEY_calc_public(EC_KEY* ec)
227 {
228         EC_POINT* pub_key;
229         const EC_GROUP* group;
230         group = EC_KEY_get0_group(ec);
231         pub_key = EC_POINT_new(group);
232         if(!pub_key) return 0;
233         if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
234                 EC_POINT_free(pub_key);
235                 return 0;
236         }
237         if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
238                 NULL, NULL, NULL)) {
239                 EC_POINT_free(pub_key);
240                 return 0;
241         }
242         if(EC_KEY_set_public_key(ec, pub_key) == 0) {
243                 EC_POINT_free(pub_key);
244                 return 0;
245         }
246         EC_POINT_free(pub_key);
247         return 1;
248 }
249 
250 /** read ECDSA private key */
251 static EVP_PKEY*
252 ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
253 {
254 	char token[16384];
255         ldns_rdf* b64rdf = NULL;
256         unsigned char* pp;
257         BIGNUM* bn;
258         EVP_PKEY* evp_key;
259         EC_KEY* ec;
260 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
261 		sizeof(token), line_nr) == -1)
262 		return NULL;
263 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
264 		return NULL;
265         pp = (unsigned char*)ldns_rdf_data(b64rdf);
266 
267         if(alg == LDNS_ECDSAP256SHA256)
268                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
269         else if(alg == LDNS_ECDSAP384SHA384)
270                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
271         else    ec = NULL;
272         if(!ec) {
273 	        ldns_rdf_deep_free(b64rdf);
274                 return NULL;
275         }
276 	bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL);
277 	ldns_rdf_deep_free(b64rdf);
278         if(!bn) {
279                 EC_KEY_free(ec);
280                 return NULL;
281         }
282         EC_KEY_set_private_key(ec, bn);
283         BN_free(bn);
284         if(!ldns_EC_KEY_calc_public(ec)) {
285                 EC_KEY_free(ec);
286                 return NULL;
287         }
288 
289         evp_key = EVP_PKEY_new();
290         if(!evp_key) {
291                 EC_KEY_free(ec);
292                 return NULL;
293         }
294         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
295 		EVP_PKEY_free(evp_key);
296                 EC_KEY_free(ec);
297                 return NULL;
298 	}
299         return evp_key;
300 }
301 #endif
302 
303 #ifdef USE_ED25519
304 /** turn private key buffer into EC_KEY structure */
305 static EC_KEY*
306 ldns_ed25519_priv_raw(uint8_t* pkey, int plen)
307 {
308 	const unsigned char* pp;
309 	uint8_t buf[256];
310 	int buflen = 0;
311 	uint8_t pre[] = {0x30, 0x32, 0x02, 0x01, 0x01, 0x04, 0x20};
312 	int pre_len = 7;
313 	uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
314 		0x01, 0xda, 0x47, 0x0f, 0x01};
315 	int post_len = 13;
316 	int i;
317 	/* ASN looks like this for ED25519
318 	 * 30320201010420 <32byteskey>
319 	 * andparameters a00b06092b06010401da470f01
320 	 * (noparameters, preamble is 30250201010420).
321 	 * the key is reversed (little endian).
322 	 */
323 	buflen = pre_len + plen + post_len;
324 	if((size_t)buflen > sizeof(buf))
325 		return NULL;
326 	memmove(buf, pre, pre_len);
327 	/* reverse the pkey into the buf */
328 	for(i=0; i<plen; i++)
329 		buf[pre_len+i] = pkey[plen-1-i];
330 	memmove(buf+pre_len+plen, post, post_len);
331 	pp = buf;
332 	return d2i_ECPrivateKey(NULL, &pp, buflen);
333 }
334 
335 /** read ED25519 private key */
336 static EVP_PKEY*
337 ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr)
338 {
339 	char token[16384];
340         ldns_rdf* b64rdf = NULL;
341         EVP_PKEY* evp_key;
342         EC_KEY* ec;
343 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
344 		sizeof(token), line_nr) == -1)
345 		return NULL;
346 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
347 		return NULL;
348 
349 	/* we use d2i_ECPrivateKey because it calculates the public key
350 	 * from the private part, which others, EC_KEY_set_private_key,
351 	 * and o2i methods, do not do */
352 	/* for that the private key has to be encoded in ASN1 notation
353 	 * with a X25519 prefix on it */
354 
355 	ec = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf),
356 		(int)ldns_rdf_size(b64rdf));
357 	ldns_rdf_deep_free(b64rdf);
358 	if(!ec) return NULL;
359 	if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X25519) {
360 		/* wrong group, bad asn conversion */
361                 EC_KEY_free(ec);
362 		return NULL;
363 	}
364 
365         evp_key = EVP_PKEY_new();
366         if(!evp_key) {
367                 EC_KEY_free(ec);
368                 return NULL;
369         }
370         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
371 		EVP_PKEY_free(evp_key);
372                 EC_KEY_free(ec);
373                 return NULL;
374 	}
375         return evp_key;
376 }
377 #endif
378 
379 #ifdef USE_ED448
380 /** turn private key buffer into EC_KEY structure */
381 static EC_KEY*
382 ldns_ed448_priv_raw(uint8_t* pkey, int plen)
383 {
384 	const unsigned char* pp;
385 	uint8_t buf[256];
386 	int buflen = 0;
387 	uint8_t pre[] = {0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x39};
388 	int pre_len = 7;
389 	uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
390 		0x01, 0xda, 0x47, 0x0f, 0x02};
391 	int post_len = 13;
392 	int i;
393 	/* ASN looks like this for ED25519
394 	 * And for ED448, the parameters are ...02 instead of ...01
395 	 * For ED25519 it was:
396 	 * 30320201010420 <32byteskey>
397 	 * andparameters a00b06092b06010401da470f01
398 	 * (noparameters, preamble is 30250201010420).
399 	 * the key is reversed (little endian).
400 	 *
401 	 * For ED448 the key is 57 bytes, and that changes lengths.
402 	 * 304b0201010439 <57bytekey> a00b06092b06010401da470f02
403 	 */
404 	buflen = pre_len + plen + post_len;
405 	if((size_t)buflen > sizeof(buf))
406 		return NULL;
407 	memmove(buf, pre, pre_len);
408 	/* reverse the pkey into the buf */
409 	for(i=0; i<plen; i++)
410 		buf[pre_len+i] = pkey[plen-1-i];
411 	memmove(buf+pre_len+plen, post, post_len);
412 	pp = buf;
413 	return d2i_ECPrivateKey(NULL, &pp, buflen);
414 }
415 
416 /** read ED448 private key */
417 static EVP_PKEY*
418 ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr)
419 {
420 	char token[16384];
421         ldns_rdf* b64rdf = NULL;
422         EVP_PKEY* evp_key;
423         EC_KEY* ec;
424 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
425 		sizeof(token), line_nr) == -1)
426 		return NULL;
427 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
428 		return NULL;
429 
430 	/* convert private key into ASN notation and then convert that */
431 	ec = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf),
432 		(int)ldns_rdf_size(b64rdf));
433 	ldns_rdf_deep_free(b64rdf);
434 	if(!ec) return NULL;
435 	if(EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)) != NID_X448) {
436 		/* wrong group, bad asn conversion */
437                 EC_KEY_free(ec);
438 		return NULL;
439 	}
440 
441         evp_key = EVP_PKEY_new();
442         if(!evp_key) {
443                 EC_KEY_free(ec);
444                 return NULL;
445         }
446         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
447 		EVP_PKEY_free(evp_key);
448                 EC_KEY_free(ec);
449                 return NULL;
450 	}
451 	return evp_key;
452 }
453 #endif
454 
455 ldns_status
456 ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
457 {
458 	ldns_key *k;
459 	char *d;
460 	ldns_signing_algorithm alg;
461 	ldns_rr *key_rr;
462 #ifdef HAVE_SSL
463 	RSA *rsa;
464 #ifdef USE_DSA
465 	DSA *dsa;
466 #endif
467 	unsigned char *hmac;
468 	size_t hmac_size;
469 #endif /* HAVE_SSL */
470 
471 	k = ldns_key_new();
472 
473 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
474 	if (!k || !d) {
475                 ldns_key_free(k);
476                 LDNS_FREE(d);
477 		return LDNS_STATUS_MEM_ERR;
478 	}
479 
480 	alg = 0;
481 
482 	/* the file is highly structured. Do this in sequence */
483 	/* RSA:
484 	 * Private-key-format: v1.x.
485  	 * Algorithm: 1 (RSA)
486 
487 	 */
488 	/* get the key format version number */
489 	if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
490 				LDNS_MAX_LINELEN, line_nr) == -1) {
491 		/* no version information */
492                 ldns_key_free(k);
493                 LDNS_FREE(d);
494 		return LDNS_STATUS_SYNTAX_ERR;
495 	}
496 	if (strncmp(d, "v1.", 3) != 0) {
497                 ldns_key_free(k);
498                 LDNS_FREE(d);
499 		return LDNS_STATUS_SYNTAX_VERSION_ERR;
500 	}
501 
502 	/* get the algorithm type, our file function strip ( ) so there are
503 	 * not in the return string! */
504 	if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
505 				LDNS_MAX_LINELEN, line_nr) == -1) {
506 		/* no alg information */
507                 ldns_key_free(k);
508                 LDNS_FREE(d);
509 		return LDNS_STATUS_SYNTAX_ALG_ERR;
510 	}
511 
512 	if (strncmp(d, "1 RSA", 2) == 0) {
513 		alg = LDNS_SIGN_RSAMD5;
514 	}
515 	if (strncmp(d, "2 DH", 2) == 0) {
516 		alg = (ldns_signing_algorithm)LDNS_DH;
517 	}
518 	if (strncmp(d, "3 DSA", 2) == 0) {
519 #ifdef USE_DSA
520 		alg = LDNS_SIGN_DSA;
521 #else
522 # ifdef STDERR_MSGS
523 		fprintf(stderr, "Warning: DSA not compiled into this ");
524 		fprintf(stderr, "version of ldns\n");
525 # endif
526 #endif
527 	}
528 	if (strncmp(d, "4 ECC", 2) == 0) {
529 		alg = (ldns_signing_algorithm)LDNS_ECC;
530 	}
531 	if (strncmp(d, "5 RSASHA1", 2) == 0) {
532 		alg = LDNS_SIGN_RSASHA1;
533 	}
534 	if (strncmp(d, "6 DSA", 2) == 0) {
535 #ifdef USE_DSA
536 		alg = LDNS_SIGN_DSA_NSEC3;
537 #else
538 # ifdef STDERR_MSGS
539 		fprintf(stderr, "Warning: DSA not compiled into this ");
540 		fprintf(stderr, "version of ldns\n");
541 # endif
542 #endif
543 	}
544 	if (strncmp(d, "7 RSASHA1", 2) == 0) {
545 		alg = LDNS_SIGN_RSASHA1_NSEC3;
546 	}
547 
548 	if (strncmp(d, "8 RSASHA256", 2) == 0) {
549 #ifdef USE_SHA2
550 		alg = LDNS_SIGN_RSASHA256;
551 #else
552 # ifdef STDERR_MSGS
553 		fprintf(stderr, "Warning: SHA256 not compiled into this ");
554 		fprintf(stderr, "version of ldns\n");
555 # endif
556 #endif
557 	}
558 	if (strncmp(d, "10 RSASHA512", 3) == 0) {
559 #ifdef USE_SHA2
560 		alg = LDNS_SIGN_RSASHA512;
561 #else
562 # ifdef STDERR_MSGS
563 		fprintf(stderr, "Warning: SHA512 not compiled into this ");
564 		fprintf(stderr, "version of ldns\n");
565 # endif
566 #endif
567 	}
568 	if (strncmp(d, "12 ECC-GOST", 3) == 0) {
569 #ifdef USE_GOST
570 		alg = LDNS_SIGN_ECC_GOST;
571 #else
572 # ifdef STDERR_MSGS
573 		fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
574 		fprintf(stderr, "version of ldns, use --enable-gost\n");
575 # endif
576 #endif
577 	}
578 	if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
579 #ifdef USE_ECDSA
580                 alg = LDNS_SIGN_ECDSAP256SHA256;
581 #else
582 # ifdef STDERR_MSGS
583 		fprintf(stderr, "Warning: ECDSA not compiled into this ");
584 		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
585 # endif
586 #endif
587         }
588 	if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
589 #ifdef USE_ECDSA
590                 alg = LDNS_SIGN_ECDSAP384SHA384;
591 #else
592 # ifdef STDERR_MSGS
593 		fprintf(stderr, "Warning: ECDSA not compiled into this ");
594 		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
595 # endif
596 #endif
597         }
598 	if (strncmp(d, "15 ED25519", 3) == 0) {
599 #ifdef USE_ED25519
600                 alg = LDNS_SIGN_ED25519;
601 #else
602 # ifdef STDERR_MSGS
603 		fprintf(stderr, "Warning: ED25519 not compiled into this ");
604 		fprintf(stderr, "version of ldns, use --enable-ed25519\n");
605 # endif
606 #endif
607         }
608 	if (strncmp(d, "16 ED448", 3) == 0) {
609 #ifdef USE_ED448
610                 alg = LDNS_SIGN_ED448;
611 #else
612 # ifdef STDERR_MSGS
613 		fprintf(stderr, "Warning: ED448 not compiled into this ");
614 		fprintf(stderr, "version of ldns, use --enable-ed448\n");
615 # endif
616 #endif
617         }
618 	if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
619 		alg = LDNS_SIGN_HMACMD5;
620 	}
621 	if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
622 		alg = LDNS_SIGN_HMACSHA1;
623 	}
624 	if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
625 		alg = LDNS_SIGN_HMACSHA256;
626 	}
627 	/* For compatibility with dnssec-keygen */
628 	if (strncmp(d, "161 ", 4) == 0) {
629 		alg = LDNS_SIGN_HMACSHA1;
630 	}
631 	if (strncmp(d, "162 HMAC-SHA224", 4) == 0) {
632 		alg = LDNS_SIGN_HMACSHA224;
633 	}
634 	/* For compatibility with dnssec-keygen */
635 	if (strncmp(d, "163 ", 4) == 0) {
636 		alg = LDNS_SIGN_HMACSHA256;
637 	}
638 	if (strncmp(d, "164 HMAC-SHA384", 4) == 0) {
639 		alg = LDNS_SIGN_HMACSHA384;
640 	}
641 	if (strncmp(d, "165 HMAC-SHA512", 4) == 0) {
642 		alg = LDNS_SIGN_HMACSHA512;
643 	}
644 	LDNS_FREE(d);
645 
646 	switch(alg) {
647 		case LDNS_SIGN_RSAMD5:
648 		case LDNS_SIGN_RSASHA1:
649 		case LDNS_SIGN_RSASHA1_NSEC3:
650 #ifdef USE_SHA2
651 		case LDNS_SIGN_RSASHA256:
652 		case LDNS_SIGN_RSASHA512:
653 #endif
654 			ldns_key_set_algorithm(k, alg);
655 #ifdef HAVE_SSL
656 			rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
657 			if (!rsa) {
658 				ldns_key_free(k);
659 				return LDNS_STATUS_ERR;
660 			}
661 			ldns_key_assign_rsa_key(k, rsa);
662 #endif /* HAVE_SSL */
663 			break;
664 #ifdef USE_DSA
665 		case LDNS_SIGN_DSA:
666 		case LDNS_SIGN_DSA_NSEC3:
667 			ldns_key_set_algorithm(k, alg);
668 #ifdef HAVE_SSL
669 			dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
670 			if (!dsa) {
671 				ldns_key_free(k);
672 				return LDNS_STATUS_ERR;
673 			}
674 			ldns_key_assign_dsa_key(k, dsa);
675 #endif /* HAVE_SSL */
676 			break;
677 #endif /* USE_DSA */
678 		case LDNS_SIGN_HMACMD5:
679 		case LDNS_SIGN_HMACSHA1:
680 		case LDNS_SIGN_HMACSHA224:
681 		case LDNS_SIGN_HMACSHA256:
682 		case LDNS_SIGN_HMACSHA384:
683 		case LDNS_SIGN_HMACSHA512:
684 			ldns_key_set_algorithm(k, alg);
685 #ifdef HAVE_SSL
686 			hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
687 			if (!hmac) {
688 				ldns_key_free(k);
689 				return LDNS_STATUS_ERR;
690 			}
691 			ldns_key_set_hmac_size(k, hmac_size);
692 			ldns_key_set_hmac_key(k, hmac);
693 #endif /* HAVE_SSL */
694 			break;
695 		case LDNS_SIGN_ECC_GOST:
696 			ldns_key_set_algorithm(k, alg);
697 #if defined(HAVE_SSL) && defined(USE_GOST)
698                         if(!ldns_key_EVP_load_gost_id()) {
699 				ldns_key_free(k);
700                                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
701                         }
702 			ldns_key_set_evp_key(k,
703 				ldns_key_new_frm_fp_gost_l(fp, line_nr));
704 #ifndef S_SPLINT_S
705 			if(!k->_key.key) {
706 				ldns_key_free(k);
707 				return LDNS_STATUS_ERR;
708 			}
709 #endif /* splint */
710 #endif
711 			break;
712 #ifdef USE_ECDSA
713                case LDNS_SIGN_ECDSAP256SHA256:
714                case LDNS_SIGN_ECDSAP384SHA384:
715                         ldns_key_set_algorithm(k, alg);
716                         ldns_key_set_evp_key(k,
717                                 ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
718 #ifndef S_SPLINT_S
719 			if(!k->_key.key) {
720 				ldns_key_free(k);
721 				return LDNS_STATUS_ERR;
722 			}
723 #endif /* splint */
724 			break;
725 #endif
726 #ifdef USE_ED25519
727 		case LDNS_SIGN_ED25519:
728                         ldns_key_set_algorithm(k, alg);
729                         ldns_key_set_evp_key(k,
730                                 ldns_key_new_frm_fp_ed25519_l(fp, line_nr));
731 #ifndef S_SPLINT_S
732 			if(!k->_key.key) {
733 				ldns_key_free(k);
734 				return LDNS_STATUS_ERR;
735 			}
736 #endif /* splint */
737 			break;
738 #endif
739 #ifdef USE_ED448
740 		case LDNS_SIGN_ED448:
741                         ldns_key_set_algorithm(k, alg);
742                         ldns_key_set_evp_key(k,
743                                 ldns_key_new_frm_fp_ed448_l(fp, line_nr));
744 #ifndef S_SPLINT_S
745 			if(!k->_key.key) {
746 				ldns_key_free(k);
747 				return LDNS_STATUS_ERR;
748 			}
749 #endif /* splint */
750 			break;
751 #endif
752 		default:
753 			ldns_key_free(k);
754 			return LDNS_STATUS_SYNTAX_ALG_ERR;
755 	}
756 	key_rr = ldns_key2rr(k);
757 	ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
758 	ldns_rr_free(key_rr);
759 
760 	if (key) {
761 		*key = k;
762 		return LDNS_STATUS_OK;
763 	}
764 	ldns_key_free(k);
765 	return LDNS_STATUS_ERR;
766 }
767 
768 #ifdef HAVE_SSL
769 RSA *
770 ldns_key_new_frm_fp_rsa(FILE *f)
771 {
772 	return ldns_key_new_frm_fp_rsa_l(f, NULL);
773 }
774 
775 RSA *
776 ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
777 {
778 	/* we parse
779  	 * Modulus:
780  	 * PublicExponent:
781  	 * PrivateExponent:
782  	 * Prime1:
783  	 * Prime2:
784  	 * Exponent1:
785  	 * Exponent2:
786  	 * Coefficient:
787 	 *
788 	 * man 3 RSA:
789 	 *
790 	 * struct
791          *     {
792          *     BIGNUM *n;              // public modulus
793          *     BIGNUM *e;              // public exponent
794          *     BIGNUM *d;              // private exponent
795          *     BIGNUM *p;              // secret prime factor
796          *     BIGNUM *q;              // secret prime factor
797          *     BIGNUM *dmp1;           // d mod (p-1)
798          *     BIGNUM *dmq1;           // d mod (q-1)
799          *     BIGNUM *iqmp;           // q^-1 mod p
800          *     // ...
801 	 *
802 	 */
803 	char *b;
804 	RSA *rsa;
805 	uint8_t *buf;
806 	int i;
807 	BIGNUM *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL,
808 		*dmp1=NULL, *dmq1=NULL, *iqmp=NULL;
809 
810 	b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
811 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
812 	rsa = RSA_new();
813 	if (!b || !rsa || !buf) {
814                 goto error;
815 	}
816 
817 	/* I could use functions again, but that seems an overkill,
818 	 * allthough this also looks tedious
819 	 */
820 
821 	/* Modules, rsa->n */
822 	if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
823 		goto error;
824 	}
825 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
826 #ifndef S_SPLINT_S
827 	n = BN_bin2bn((const char unsigned*)buf, i, NULL);
828 	if (!n) {
829 		goto error;
830 	}
831 
832 	/* PublicExponent, rsa->e */
833 	if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
834 		goto error;
835 	}
836 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
837 	e = BN_bin2bn((const char unsigned*)buf, i, NULL);
838 	if (!e) {
839 		goto error;
840 	}
841 
842 	/* PrivateExponent, rsa->d */
843 	if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
844 		goto error;
845 	}
846 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
847 	d = BN_bin2bn((const char unsigned*)buf, i, NULL);
848 	if (!d) {
849 		goto error;
850 	}
851 
852 	/* Prime1, rsa->p */
853 	if (ldns_fget_keyword_data_l(f, "Prime1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
854 		goto error;
855 	}
856 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
857 	p = BN_bin2bn((const char unsigned*)buf, i, NULL);
858 	if (!p) {
859 		goto error;
860 	}
861 
862 	/* Prime2, rsa->q */
863 	if (ldns_fget_keyword_data_l(f, "Prime2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
864 		goto error;
865 	}
866 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
867 	q = BN_bin2bn((const char unsigned*)buf, i, NULL);
868 	if (!q) {
869 		goto error;
870 	}
871 
872 	/* Exponent1, rsa->dmp1 */
873 	if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
874 		goto error;
875 	}
876 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
877 	dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
878 	if (!dmp1) {
879 		goto error;
880 	}
881 
882 	/* Exponent2, rsa->dmq1 */
883 	if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
884 		goto error;
885 	}
886 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
887 	dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
888 	if (!dmq1) {
889 		goto error;
890 	}
891 
892 	/* Coefficient, rsa->iqmp */
893 	if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
894 		goto error;
895 	}
896 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
897 	iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
898 	if (!iqmp) {
899 		goto error;
900 	}
901 #endif /* splint */
902 
903 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
904 # ifndef S_SPLINT_S
905 	rsa->n = n;
906 	rsa->e = e;
907 	rsa->d = d;
908 	rsa->p = p;
909 	rsa->q = q;
910 	rsa->dmp1 = dmp1;
911 	rsa->dmq1 = dmq1;
912 	rsa->iqmp = iqmp;
913 # endif
914 #else
915 	if(!RSA_set0_key(rsa, n, e, d))
916 		goto error;
917 	n = NULL;
918 	e = NULL;
919 	d = NULL;
920 	if(!RSA_set0_factors(rsa, p, q))
921 		goto error;
922 	p = NULL;
923 	q = NULL;
924 	if(!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
925 		goto error;
926 #endif
927 
928 	LDNS_FREE(buf);
929 	LDNS_FREE(b);
930 	return rsa;
931 
932 error:
933 	RSA_free(rsa);
934 	LDNS_FREE(b);
935 	LDNS_FREE(buf);
936 	BN_free(n);
937 	BN_free(e);
938 	BN_free(d);
939 	BN_free(p);
940 	BN_free(q);
941 	BN_free(dmp1);
942 	BN_free(dmq1);
943 	BN_free(iqmp);
944 	return NULL;
945 }
946 
947 DSA *
948 ldns_key_new_frm_fp_dsa(FILE *f)
949 {
950 	return ldns_key_new_frm_fp_dsa_l(f, NULL);
951 }
952 
953 DSA *
954 ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
955 {
956 	int i;
957 	char *d;
958 	DSA *dsa;
959 	uint8_t *buf;
960 	BIGNUM *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL;
961 
962 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
963 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
964 	dsa = DSA_new();
965 	if (!d || !dsa || !buf) {
966                 goto error;
967 	}
968 
969 	/* the line parser removes the () from the input... */
970 
971 	/* Prime, dsa->p */
972 	if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
973 		goto error;
974 	}
975 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
976 #ifndef S_SPLINT_S
977 	p = BN_bin2bn((const char unsigned*)buf, i, NULL);
978 	if (!p) {
979 		goto error;
980 	}
981 
982 	/* Subprime, dsa->q */
983 	if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
984 		goto error;
985 	}
986 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
987 	q = BN_bin2bn((const char unsigned*)buf, i, NULL);
988 	if (!q) {
989 		goto error;
990 	}
991 
992 	/* Base, dsa->g */
993 	if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
994 		goto error;
995 	}
996 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
997 	g = BN_bin2bn((const char unsigned*)buf, i, NULL);
998 	if (!g) {
999 		goto error;
1000 	}
1001 
1002 	/* Private key, dsa->priv_key */
1003 	if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
1004 		goto error;
1005 	}
1006 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
1007 	priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
1008 	if (!priv_key) {
1009 		goto error;
1010 	}
1011 
1012 	/* Public key, dsa->priv_key */
1013 	if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
1014 		goto error;
1015 	}
1016 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
1017 	pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
1018 	if (!pub_key) {
1019 		goto error;
1020 	}
1021 #endif /* splint */
1022 
1023 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
1024 # ifndef S_SPLINT_S
1025 	dsa->p = p;
1026 	dsa->q = q;
1027 	dsa->g = g;
1028 	dsa->priv_key = priv_key;
1029 	dsa->pub_key = pub_key;
1030 # endif
1031 #else
1032 	if(!DSA_set0_pqg(dsa, p, q, g))
1033 		goto error;
1034 	p = NULL;
1035 	q = NULL;
1036 	g = NULL;
1037 	if(!DSA_set0_key(dsa, pub_key, priv_key))
1038 		goto error;
1039 #endif
1040 
1041 	LDNS_FREE(buf);
1042 	LDNS_FREE(d);
1043 
1044 	return dsa;
1045 
1046 error:
1047 	LDNS_FREE(d);
1048 	LDNS_FREE(buf);
1049         DSA_free(dsa);
1050 	BN_free(p);
1051 	BN_free(q);
1052 	BN_free(g);
1053 	BN_free(priv_key);
1054 	BN_free(pub_key);
1055 	return NULL;
1056 }
1057 
1058 unsigned char *
1059 ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
1060 {
1061 	return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
1062 }
1063 
1064 unsigned char *
1065 ldns_key_new_frm_fp_hmac_l( FILE *f
1066 			  , ATTR_UNUSED(int *line_nr)
1067 			  , size_t *hmac_size
1068 			  )
1069 {
1070 	size_t i, bufsz;
1071 	char d[LDNS_MAX_LINELEN];
1072 	unsigned char *buf = NULL;
1073 
1074 	if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
1075 		goto error;
1076 	}
1077 	bufsz = ldns_b64_ntop_calculate_size(strlen(d));
1078 	buf = LDNS_XMALLOC(unsigned char, bufsz);
1079 	i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
1080 
1081 	*hmac_size = i;
1082 	return buf;
1083 
1084 	error:
1085 	LDNS_FREE(buf);
1086 	*hmac_size = 0;
1087 	return NULL;
1088 }
1089 #endif /* HAVE_SSL */
1090 
1091 #ifdef USE_GOST
1092 static EVP_PKEY*
1093 ldns_gen_gost_key(void)
1094 {
1095 	EVP_PKEY_CTX* ctx;
1096 	EVP_PKEY* p = NULL;
1097 	int gost_id = ldns_key_EVP_load_gost_id();
1098 	if(!gost_id)
1099 		return NULL;
1100 	ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
1101 	if(!ctx) {
1102 		/* the id should be available now */
1103 		return NULL;
1104 	}
1105 	if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
1106 		/* cannot set paramset */
1107 		EVP_PKEY_CTX_free(ctx);
1108 		return NULL;
1109 	}
1110 
1111 	if(EVP_PKEY_keygen_init(ctx) <= 0) {
1112 		EVP_PKEY_CTX_free(ctx);
1113 		return NULL;
1114 	}
1115 	if(EVP_PKEY_keygen(ctx, &p) <= 0) {
1116 		EVP_PKEY_free(p);
1117 		EVP_PKEY_CTX_free(ctx);
1118 		return NULL;
1119 	}
1120 	EVP_PKEY_CTX_free(ctx);
1121 	return p;
1122 }
1123 #endif
1124 
1125 ldns_key *
1126 ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
1127 {
1128 	ldns_key *k;
1129 #ifdef HAVE_SSL
1130 #ifdef USE_DSA
1131 	DSA *d;
1132 #endif /* USE_DSA */
1133 #  ifdef USE_ECDSA
1134         EC_KEY *ec = NULL;
1135 #  endif
1136 #  ifdef HAVE_EVP_PKEY_KEYGEN
1137 	EVP_PKEY_CTX *ctx;
1138 #  else
1139 	RSA *r;
1140 #  endif
1141 #else
1142 	int i;
1143 	uint16_t offset = 0;
1144 #endif
1145 	unsigned char *hmac;
1146 
1147 	k = ldns_key_new();
1148 	if (!k) {
1149 		return NULL;
1150 	}
1151 	switch(alg) {
1152 		case LDNS_SIGN_RSAMD5:
1153 		case LDNS_SIGN_RSASHA1:
1154 		case LDNS_SIGN_RSASHA1_NSEC3:
1155 		case LDNS_SIGN_RSASHA256:
1156 		case LDNS_SIGN_RSASHA512:
1157 #ifdef HAVE_SSL
1158 #ifdef HAVE_EVP_PKEY_KEYGEN
1159 			ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
1160 			if(!ctx) {
1161 				ldns_key_free(k);
1162 				return NULL;
1163 			}
1164 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1165 				ldns_key_free(k);
1166 				EVP_PKEY_CTX_free(ctx);
1167 				return NULL;
1168 			}
1169 			if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) <= 0) {
1170 				ldns_key_free(k);
1171 				EVP_PKEY_CTX_free(ctx);
1172 				return NULL;
1173 			}
1174 #ifndef S_SPLINT_S
1175 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1176 				ldns_key_free(k);
1177 				EVP_PKEY_CTX_free(ctx);
1178 				return NULL;
1179 			}
1180 #endif
1181 			EVP_PKEY_CTX_free(ctx);
1182 #else /* HAVE_EVP_PKEY_KEYGEN */
1183 			r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
1184                         if(!r) {
1185 				ldns_key_free(k);
1186 				return NULL;
1187 			}
1188 			if (RSA_check_key(r) != 1) {
1189 				ldns_key_free(k);
1190 				return NULL;
1191 			}
1192 			ldns_key_set_rsa_key(k, r);
1193 			RSA_free(r);
1194 #endif /* HAVE_EVP_PKEY_KEYGEN */
1195 #endif /* HAVE_SSL */
1196 			break;
1197 		case LDNS_SIGN_DSA:
1198 		case LDNS_SIGN_DSA_NSEC3:
1199 #ifdef USE_DSA
1200 #ifdef HAVE_SSL
1201 # if OPENSSL_VERSION_NUMBER < 0x00908000L
1202 			d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
1203 			if (!d) {
1204 				ldns_key_free(k);
1205 				return NULL;
1206 			}
1207 
1208 # else
1209 			if (! (d = DSA_new())) {
1210 				ldns_key_free(k);
1211 				return NULL;
1212 			}
1213 			if (! DSA_generate_parameters_ex(d, (int)size, NULL, 0, NULL, NULL, NULL)) {
1214 				DSA_free(d);
1215 				ldns_key_free(k);
1216 				return NULL;
1217 			}
1218 # endif
1219 			if (DSA_generate_key(d) != 1) {
1220 				ldns_key_free(k);
1221 				return NULL;
1222 			}
1223 			ldns_key_set_dsa_key(k, d);
1224 			DSA_free(d);
1225 #endif /* HAVE_SSL */
1226 #endif /* USE_DSA */
1227 			break;
1228 		case LDNS_SIGN_HMACMD5:
1229 		case LDNS_SIGN_HMACSHA1:
1230 		case LDNS_SIGN_HMACSHA224:
1231 		case LDNS_SIGN_HMACSHA256:
1232 		case LDNS_SIGN_HMACSHA384:
1233 		case LDNS_SIGN_HMACSHA512:
1234 #ifdef HAVE_SSL
1235 #ifndef S_SPLINT_S
1236 			k->_key.key = NULL;
1237 #endif /* splint */
1238 #endif /* HAVE_SSL */
1239 			size = size / 8;
1240 			ldns_key_set_hmac_size(k, size);
1241 
1242 			hmac = LDNS_XMALLOC(unsigned char, size);
1243                         if(!hmac) {
1244 				ldns_key_free(k);
1245 				return NULL;
1246                         }
1247 #ifdef HAVE_SSL
1248 			if (RAND_bytes(hmac, (int) size) != 1) {
1249 				LDNS_FREE(hmac);
1250 				ldns_key_free(k);
1251 				return NULL;
1252 			}
1253 #else
1254 			while (offset + sizeof(i) < size) {
1255 			  i = random();
1256 			  memcpy(&hmac[offset], &i, sizeof(i));
1257 			  offset += sizeof(i);
1258 			}
1259 			if (offset < size) {
1260 			  i = random();
1261 			  memcpy(&hmac[offset], &i, size - offset);
1262 			}
1263 #endif /* HAVE_SSL */
1264 			ldns_key_set_hmac_key(k, hmac);
1265 
1266 			ldns_key_set_flags(k, 0);
1267 			break;
1268 		case LDNS_SIGN_ECC_GOST:
1269 #if defined(HAVE_SSL) && defined(USE_GOST)
1270 			ldns_key_set_evp_key(k, ldns_gen_gost_key());
1271 #ifndef S_SPLINT_S
1272                         if(!k->_key.key) {
1273                                 ldns_key_free(k);
1274                                 return NULL;
1275                         }
1276 #endif /* splint */
1277 #else
1278 			ldns_key_free(k);
1279 			return NULL;
1280 #endif /* HAVE_SSL and USE_GOST */
1281                         break;
1282                 case LDNS_SIGN_ECDSAP256SHA256:
1283                 case LDNS_SIGN_ECDSAP384SHA384:
1284 #ifdef USE_ECDSA
1285                         if(alg == LDNS_SIGN_ECDSAP256SHA256)
1286                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
1287                         else if(alg == LDNS_SIGN_ECDSAP384SHA384)
1288                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
1289                         if(!ec) {
1290                                 ldns_key_free(k);
1291                                 return NULL;
1292                         }
1293                         if(!EC_KEY_generate_key(ec)) {
1294                                 ldns_key_free(k);
1295                                 EC_KEY_free(ec);
1296                                 return NULL;
1297                         }
1298 #ifndef S_SPLINT_S
1299                         k->_key.key = EVP_PKEY_new();
1300                         if(!k->_key.key) {
1301                                 ldns_key_free(k);
1302                                 EC_KEY_free(ec);
1303                                 return NULL;
1304                         }
1305                         if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
1306                                 ldns_key_free(k);
1307                                 EC_KEY_free(ec);
1308                                 return NULL;
1309 			}
1310 #endif /* splint */
1311 #else
1312 			ldns_key_free(k);
1313 			return NULL;
1314 #endif /* ECDSA */
1315 			break;
1316 #ifdef USE_ED25519
1317 		case LDNS_SIGN_ED25519:
1318 #ifdef HAVE_EVP_PKEY_KEYGEN
1319 			ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
1320 			if(!ctx) {
1321 				ldns_key_free(k);
1322 				return NULL;
1323 			}
1324 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1325 				ldns_key_free(k);
1326 				EVP_PKEY_CTX_free(ctx);
1327 				return NULL;
1328 			}
1329 			if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx,
1330 				NID_X25519) <= 0) {
1331 				ldns_key_free(k);
1332 				EVP_PKEY_CTX_free(ctx);
1333 				return NULL;
1334 			}
1335 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1336 				ldns_key_free(k);
1337 				EVP_PKEY_CTX_free(ctx);
1338 				return NULL;
1339 			}
1340 			EVP_PKEY_CTX_free(ctx);
1341 #endif
1342 			break;
1343 #endif /* ED25519 */
1344 #ifdef USE_ED448
1345 		case LDNS_SIGN_ED448:
1346 #ifdef HAVE_EVP_PKEY_KEYGEN
1347 			ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
1348 			if(!ctx) {
1349 				ldns_key_free(k);
1350 				return NULL;
1351 			}
1352 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1353 				ldns_key_free(k);
1354 				EVP_PKEY_CTX_free(ctx);
1355 				return NULL;
1356 			}
1357 			if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx,
1358 				NID_X448) <= 0) {
1359 				ldns_key_free(k);
1360 				EVP_PKEY_CTX_free(ctx);
1361 				return NULL;
1362 			}
1363 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1364 				ldns_key_free(k);
1365 				EVP_PKEY_CTX_free(ctx);
1366 				return NULL;
1367 			}
1368 			EVP_PKEY_CTX_free(ctx);
1369 #endif
1370 			break;
1371 #endif /* ED448 */
1372 	}
1373 	ldns_key_set_algorithm(k, alg);
1374 	return k;
1375 }
1376 
1377 void
1378 ldns_key_print(FILE *output, const ldns_key *k)
1379 {
1380 	char *str = ldns_key2str(k);
1381 	if (str) {
1382                 fprintf(output, "%s", str);
1383         } else {
1384                 fprintf(output, "Unable to convert private key to string\n");
1385         }
1386         LDNS_FREE(str);
1387 }
1388 
1389 
1390 void
1391 ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
1392 {
1393 	k->_alg = l;
1394 }
1395 
1396 void
1397 ldns_key_set_flags(ldns_key *k, uint16_t f)
1398 {
1399 	k->_extra.dnssec.flags = f;
1400 }
1401 
1402 #ifdef HAVE_SSL
1403 #ifndef S_SPLINT_S
1404 void
1405 ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
1406 {
1407 	k->_key.key = e;
1408 }
1409 
1410 void
1411 ldns_key_set_rsa_key(ldns_key *k, RSA *r)
1412 {
1413 	EVP_PKEY *key = EVP_PKEY_new();
1414 	EVP_PKEY_set1_RSA(key, r);
1415 	k->_key.key = key;
1416 }
1417 
1418 void
1419 ldns_key_set_dsa_key(ldns_key *k, DSA *d)
1420 {
1421 #ifdef USE_DSA
1422 	EVP_PKEY *key = EVP_PKEY_new();
1423 	EVP_PKEY_set1_DSA(key, d);
1424 	k->_key.key  = key;
1425 #else
1426 	(void)k; (void)d;
1427 #endif
1428 }
1429 
1430 void
1431 ldns_key_assign_rsa_key(ldns_key *k, RSA *r)
1432 {
1433 	EVP_PKEY *key = EVP_PKEY_new();
1434 	EVP_PKEY_assign_RSA(key, r);
1435 	k->_key.key = key;
1436 }
1437 
1438 void
1439 ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
1440 {
1441 #ifdef USE_DSA
1442 	EVP_PKEY *key = EVP_PKEY_new();
1443 	EVP_PKEY_assign_DSA(key, d);
1444 	k->_key.key  = key;
1445 #else
1446 	(void)k; (void)d;
1447 #endif
1448 }
1449 #endif /* splint */
1450 #endif /* HAVE_SSL */
1451 
1452 void
1453 ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
1454 {
1455 	k->_key.hmac.key = hmac;
1456 }
1457 
1458 void
1459 ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
1460 {
1461 	k->_key.hmac.size = hmac_size;
1462 }
1463 
1464 void
1465 ldns_key_set_external_key(ldns_key *k, void *external_key)
1466 {
1467 	k->_key.external_key = external_key;
1468 }
1469 
1470 void
1471 ldns_key_set_origttl(ldns_key *k, uint32_t t)
1472 {
1473 	k->_extra.dnssec.orig_ttl = t;
1474 }
1475 
1476 void
1477 ldns_key_set_inception(ldns_key *k, uint32_t i)
1478 {
1479 	k->_extra.dnssec.inception = i;
1480 }
1481 
1482 void
1483 ldns_key_set_expiration(ldns_key *k, uint32_t e)
1484 {
1485 	k->_extra.dnssec.expiration = e;
1486 }
1487 
1488 void
1489 ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
1490 {
1491 	k->_pubkey_owner = r;
1492 }
1493 
1494 void
1495 ldns_key_set_keytag(ldns_key *k, uint16_t tag)
1496 {
1497 	k->_extra.dnssec.keytag = tag;
1498 }
1499 
1500 /* read */
1501 size_t
1502 ldns_key_list_key_count(const ldns_key_list *key_list)
1503 {
1504 	        return key_list->_key_count;
1505 }
1506 
1507 ldns_key *
1508 ldns_key_list_key(const ldns_key_list *key, size_t nr)
1509 {
1510 	if (nr < ldns_key_list_key_count(key)) {
1511 		return key->_keys[nr];
1512 	} else {
1513 		return NULL;
1514 	}
1515 }
1516 
1517 ldns_signing_algorithm
1518 ldns_key_algorithm(const ldns_key *k)
1519 {
1520 	return k->_alg;
1521 }
1522 
1523 void
1524 ldns_key_set_use(ldns_key *k, bool v)
1525 {
1526 	if (k) {
1527 		k->_use = v;
1528 	}
1529 }
1530 
1531 bool
1532 ldns_key_use(const ldns_key *k)
1533 {
1534 	if (k) {
1535 		return k->_use;
1536 	}
1537 	return false;
1538 }
1539 
1540 #ifdef HAVE_SSL
1541 #ifndef S_SPLINT_S
1542 EVP_PKEY *
1543 ldns_key_evp_key(const ldns_key *k)
1544 {
1545 	return k->_key.key;
1546 }
1547 
1548 RSA *
1549 ldns_key_rsa_key(const ldns_key *k)
1550 {
1551 	if (k->_key.key) {
1552 		return EVP_PKEY_get1_RSA(k->_key.key);
1553 	} else {
1554 		return NULL;
1555 	}
1556 }
1557 
1558 DSA *
1559 ldns_key_dsa_key(const ldns_key *k)
1560 {
1561 #ifdef USE_DSA
1562 	if (k->_key.key) {
1563 		return EVP_PKEY_get1_DSA(k->_key.key);
1564 	} else {
1565 		return NULL;
1566 	}
1567 #else
1568 	(void)k;
1569 	return NULL;
1570 #endif
1571 }
1572 #endif /* splint */
1573 #endif /* HAVE_SSL */
1574 
1575 unsigned char *
1576 ldns_key_hmac_key(const ldns_key *k)
1577 {
1578 	if (k->_key.hmac.key) {
1579 		return k->_key.hmac.key;
1580 	} else {
1581 		return NULL;
1582 	}
1583 }
1584 
1585 size_t
1586 ldns_key_hmac_size(const ldns_key *k)
1587 {
1588 	if (k->_key.hmac.size) {
1589 		return k->_key.hmac.size;
1590 	} else {
1591 		return 0;
1592 	}
1593 }
1594 
1595 void *
1596 ldns_key_external_key(const ldns_key *k)
1597 {
1598 	return k->_key.external_key;
1599 }
1600 
1601 uint32_t
1602 ldns_key_origttl(const ldns_key *k)
1603 {
1604 	return k->_extra.dnssec.orig_ttl;
1605 }
1606 
1607 uint16_t
1608 ldns_key_flags(const ldns_key *k)
1609 {
1610 	return k->_extra.dnssec.flags;
1611 }
1612 
1613 uint32_t
1614 ldns_key_inception(const ldns_key *k)
1615 {
1616 	return k->_extra.dnssec.inception;
1617 }
1618 
1619 uint32_t
1620 ldns_key_expiration(const ldns_key *k)
1621 {
1622 	return k->_extra.dnssec.expiration;
1623 }
1624 
1625 uint16_t
1626 ldns_key_keytag(const ldns_key *k)
1627 {
1628 	return k->_extra.dnssec.keytag;
1629 }
1630 
1631 ldns_rdf *
1632 ldns_key_pubkey_owner(const ldns_key *k)
1633 {
1634 	return k->_pubkey_owner;
1635 }
1636 
1637 /* write */
1638 void
1639 ldns_key_list_set_use(ldns_key_list *keys, bool v)
1640 {
1641 	size_t i;
1642 
1643 	for (i = 0; i < ldns_key_list_key_count(keys); i++) {
1644 		ldns_key_set_use(ldns_key_list_key(keys, i), v);
1645 	}
1646 }
1647 
1648 void
1649 ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
1650 {
1651 	        key->_key_count = count;
1652 }
1653 
1654 bool
1655 ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
1656 {
1657         size_t key_count;
1658         ldns_key **keys;
1659 
1660         key_count = ldns_key_list_key_count(key_list);
1661 
1662         /* grow the array */
1663         keys = LDNS_XREALLOC(
1664                 key_list->_keys, ldns_key *, key_count + 1);
1665         if (!keys) {
1666                 return false;
1667         }
1668 
1669         /* add the new member */
1670         key_list->_keys = keys;
1671         key_list->_keys[key_count] = key;
1672 
1673         ldns_key_list_set_key_count(key_list, key_count + 1);
1674         return true;
1675 }
1676 
1677 ldns_key *
1678 ldns_key_list_pop_key(ldns_key_list *key_list)
1679 {
1680         size_t key_count;
1681         ldns_key** a;
1682         ldns_key *pop;
1683 
1684 	if (!key_list) {
1685 		return NULL;
1686 	}
1687 
1688         key_count = ldns_key_list_key_count(key_list);
1689         if (key_count == 0) {
1690                 return NULL;
1691         }
1692 
1693         pop = ldns_key_list_key(key_list, key_count);
1694 
1695         /* shrink the array */
1696         a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
1697         if(a) {
1698                 key_list->_keys = a;
1699         }
1700 
1701         ldns_key_list_set_key_count(key_list, key_count - 1);
1702 
1703         return pop;
1704 }
1705 
1706 #ifdef HAVE_SSL
1707 #ifndef S_SPLINT_S
1708 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
1709 static bool
1710 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
1711 {
1712 	int i,j;
1713 	const BIGNUM *n=NULL, *e=NULL;
1714 
1715 	if (!k) {
1716 		return false;
1717 	}
1718 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
1719 	n = k->n;
1720 	e = k->e;
1721 #else
1722 	RSA_get0_key(k, &n, &e, NULL);
1723 #endif
1724 
1725 	if (BN_num_bytes(e) <= 256) {
1726 		/* normally only this path is executed (small factors are
1727 		 * more common
1728 		 */
1729 		data[0] = (unsigned char) BN_num_bytes(e);
1730 		i = BN_bn2bin(e, data + 1);
1731 		j = BN_bn2bin(n, data + i + 1);
1732 		*size = (uint16_t) i + j;
1733 	} else if (BN_num_bytes(e) <= 65536) {
1734 		data[0] = 0;
1735 		/* BN_bn2bin does bigendian, _uint16 also */
1736 		ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(e));
1737 
1738 		BN_bn2bin(e, data + 3);
1739 		BN_bn2bin(n, data + 4 + BN_num_bytes(e));
1740 		*size = (uint16_t) BN_num_bytes(n) + 6;
1741 	} else {
1742 		return false;
1743 	}
1744 	return true;
1745 }
1746 
1747 #ifdef USE_DSA
1748 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
1749 static bool
1750 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
1751 {
1752 	uint8_t T;
1753 	const BIGNUM *p, *q, *g;
1754 	const BIGNUM *pub_key, *priv_key;
1755 
1756 	if (!k) {
1757 		return false;
1758 	}
1759 
1760 	/* See RFC2536 */
1761 # ifdef HAVE_DSA_GET0_PQG
1762 	DSA_get0_pqg(k, &p, &q, &g);
1763 # else
1764 	p = k->p; q = k->q; g = k->g;
1765 # endif
1766 # ifdef HAVE_DSA_GET0_KEY
1767 	DSA_get0_key(k, &pub_key, &priv_key);
1768 # else
1769 	pub_key = k->pub_key; priv_key = k->priv_key;
1770 # endif
1771 	(void)priv_key;
1772 	*size = (uint16_t)BN_num_bytes(p);
1773 	T = (*size - 64) / 8;
1774 
1775 	if (T > 8) {
1776 #ifdef STDERR_MSGS
1777 		fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
1778 		fprintf(stderr, " not implemented\n");
1779 #endif
1780 		return false;
1781 	}
1782 
1783 	/* size = 64 + (T * 8); */
1784 	memset(data, 0, 21 + *size * 3);
1785 	data[0] = (unsigned char)T;
1786 	BN_bn2bin(q, data + 1 ); 		/* 20 octects */
1787 	BN_bn2bin(p, data + 21 ); 		/* offset octects */
1788 	BN_bn2bin(g, data + 21 + *size * 2 - BN_num_bytes(g));
1789 	BN_bn2bin(pub_key,data + 21 + *size * 3 - BN_num_bytes(pub_key));
1790 	*size = 21 + *size * 3;
1791 	return true;
1792 }
1793 #endif /* USE_DSA */
1794 
1795 #ifdef USE_GOST
1796 static bool
1797 ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
1798 {
1799 	int i;
1800 	unsigned char* pp = NULL;
1801 	if(i2d_PUBKEY(k, &pp) != 37 + 64) {
1802 		/* expect 37 byte(ASN header) and 64 byte(X and Y) */
1803 		free(pp);
1804 		return false;
1805 	}
1806 	/* omit ASN header */
1807 	for(i=0; i<64; i++)
1808 		data[i] = pp[i+37];
1809 	free(pp);
1810 	*size = 64;
1811 	return true;
1812 }
1813 #endif /* USE_GOST */
1814 #endif /* splint */
1815 #endif /* HAVE_SSL */
1816 
1817 ldns_rr *
1818 ldns_key2rr(const ldns_key *k)
1819 {
1820 	/* this function will convert a the keydata contained in
1821 	 * rsa/dsa pointers to a DNSKEY rr. It will fill in as
1822 	 * much as it can, but it does not know about key-flags
1823 	 * for instance
1824 	 */
1825 	ldns_rr *pubkey;
1826 	ldns_rdf *keybin;
1827 	unsigned char *bin = NULL;
1828 	uint16_t size = 0;
1829 #ifdef HAVE_SSL
1830 	RSA *rsa = NULL;
1831 #ifdef USE_DSA
1832 	DSA *dsa = NULL;
1833 #endif /* USE_DSA */
1834 #endif /* HAVE_SSL */
1835 #ifdef USE_ECDSA
1836         EC_KEY* ec;
1837 #endif
1838 	int internal_data = 0;
1839 
1840 	if (!k) {
1841 		return NULL;
1842 	}
1843 	pubkey = ldns_rr_new();
1844 
1845 	switch (ldns_key_algorithm(k)) {
1846 	case LDNS_SIGN_HMACMD5:
1847 	case LDNS_SIGN_HMACSHA1:
1848 	case LDNS_SIGN_HMACSHA224:
1849 	case LDNS_SIGN_HMACSHA256:
1850 	case LDNS_SIGN_HMACSHA384:
1851 	case LDNS_SIGN_HMACSHA512:
1852 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
1853         	break;
1854 	default:
1855 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
1856 		break;
1857         }
1858 	/* zero-th rdf - flags */
1859 	ldns_rr_push_rdf(pubkey,
1860 			ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
1861 				ldns_key_flags(k)));
1862 	/* first - proto */
1863 	ldns_rr_push_rdf(pubkey,
1864 			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
1865 
1866 	if (ldns_key_pubkey_owner(k)) {
1867 		ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
1868 	}
1869 
1870 	/* third - da algorithm */
1871 	switch(ldns_key_algorithm(k)) {
1872 		case LDNS_SIGN_RSAMD5:
1873 		case LDNS_SIGN_RSASHA1:
1874 		case LDNS_SIGN_RSASHA1_NSEC3:
1875 		case LDNS_SIGN_RSASHA256:
1876 		case LDNS_SIGN_RSASHA512:
1877 			ldns_rr_push_rdf(pubkey,
1878 						  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1879 #ifdef HAVE_SSL
1880 			rsa =  ldns_key_rsa_key(k);
1881 			if (rsa) {
1882 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1883 				if (!bin) {
1884                                         ldns_rr_free(pubkey);
1885 					return NULL;
1886 				}
1887 				if (!ldns_key_rsa2bin(bin, rsa, &size)) {
1888 		                        LDNS_FREE(bin);
1889                                         ldns_rr_free(pubkey);
1890 					return NULL;
1891 				}
1892 				RSA_free(rsa);
1893 				internal_data = 1;
1894 			}
1895 #endif
1896 			size++;
1897 			break;
1898 		case LDNS_SIGN_DSA:
1899 			ldns_rr_push_rdf(pubkey,
1900 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
1901 #ifdef USE_DSA
1902 #ifdef HAVE_SSL
1903 			dsa = ldns_key_dsa_key(k);
1904 			if (dsa) {
1905 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1906 				if (!bin) {
1907                                         ldns_rr_free(pubkey);
1908 					return NULL;
1909 				}
1910 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1911 		                        LDNS_FREE(bin);
1912                                         ldns_rr_free(pubkey);
1913 					return NULL;
1914 				}
1915 				DSA_free(dsa);
1916 				internal_data = 1;
1917 			}
1918 #endif /* HAVE_SSL */
1919 #endif /* USE_DSA */
1920 			break;
1921 		case LDNS_SIGN_DSA_NSEC3:
1922 			ldns_rr_push_rdf(pubkey,
1923 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
1924 #ifdef USE_DSA
1925 #ifdef HAVE_SSL
1926 			dsa = ldns_key_dsa_key(k);
1927 			if (dsa) {
1928 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1929 				if (!bin) {
1930                                         ldns_rr_free(pubkey);
1931 					return NULL;
1932 				}
1933 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1934 		                        LDNS_FREE(bin);
1935                                         ldns_rr_free(pubkey);
1936 					return NULL;
1937 				}
1938 				DSA_free(dsa);
1939 				internal_data = 1;
1940 			}
1941 #endif /* HAVE_SSL */
1942 #endif /* USE_DSA */
1943 			break;
1944 		case LDNS_SIGN_ECC_GOST:
1945 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
1946 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1947 #if defined(HAVE_SSL) && defined(USE_GOST)
1948 			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1949 			if (!bin) {
1950                                 ldns_rr_free(pubkey);
1951 				return NULL;
1952                         }
1953 #ifndef S_SPLINT_S
1954 			if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
1955 		                LDNS_FREE(bin);
1956                                 ldns_rr_free(pubkey);
1957 				return NULL;
1958 			}
1959 #endif /* splint */
1960 			internal_data = 1;
1961 #else
1962                         ldns_rr_free(pubkey);
1963 			return NULL;
1964 #endif /* HAVE_SSL and USE_GOST */
1965 			break;
1966                 case LDNS_SIGN_ECDSAP256SHA256:
1967                 case LDNS_SIGN_ECDSAP384SHA384:
1968 #ifdef USE_ECDSA
1969 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
1970 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1971                         bin = NULL;
1972 #ifndef S_SPLINT_S
1973                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
1974 #endif
1975                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
1976                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
1977                         if(!i2o_ECPublicKey(ec, &bin)) {
1978                                 EC_KEY_free(ec);
1979                                 ldns_rr_free(pubkey);
1980                                 return NULL;
1981                         }
1982 			if(size > 1) {
1983 				/* move back one byte to shave off the 0x02
1984 				 * 'uncompressed' indicator that openssl made
1985 				 * Actually its 0x04 (from implementation).
1986 				 */
1987 				assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
1988 				size -= 1;
1989 				memmove(bin, bin+1, size);
1990 			}
1991                         /* down the reference count for ec, its still assigned
1992                          * to the pkey */
1993                         EC_KEY_free(ec);
1994 			internal_data = 1;
1995 #else
1996                         ldns_rr_free(pubkey);
1997 			return NULL;
1998 #endif /* ECDSA */
1999                         break;
2000 #ifdef USE_ED25519
2001                 case LDNS_SIGN_ED25519:
2002 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
2003 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
2004                         bin = NULL;
2005                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2006                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
2007                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
2008                         if(!i2o_ECPublicKey(ec, &bin)) {
2009                                 EC_KEY_free(ec);
2010                                 ldns_rr_free(pubkey);
2011                                 return NULL;
2012                         }
2013                         /* down the reference count for ec, its still assigned
2014                          * to the pkey */
2015                         EC_KEY_free(ec);
2016 			internal_data = 1;
2017 			break;
2018 #endif
2019 #ifdef USE_ED448
2020                 case LDNS_SIGN_ED448:
2021 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
2022 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
2023                         bin = NULL;
2024                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
2025                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
2026                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
2027                         if(!i2o_ECPublicKey(ec, &bin)) {
2028                                 EC_KEY_free(ec);
2029                                 ldns_rr_free(pubkey);
2030                                 return NULL;
2031                         }
2032                         /* down the reference count for ec, its still assigned
2033                          * to the pkey */
2034                         EC_KEY_free(ec);
2035 			internal_data = 1;
2036 			break;
2037 #endif
2038 		case LDNS_SIGN_HMACMD5:
2039 		case LDNS_SIGN_HMACSHA1:
2040 		case LDNS_SIGN_HMACSHA224:
2041 		case LDNS_SIGN_HMACSHA256:
2042 		case LDNS_SIGN_HMACSHA384:
2043 		case LDNS_SIGN_HMACSHA512:
2044 			bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
2045 			if (!bin) {
2046                                 ldns_rr_free(pubkey);
2047 				return NULL;
2048 			}
2049 			ldns_rr_push_rdf(pubkey,
2050 			                 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
2051 			                 ldns_key_algorithm(k)));
2052 			size = ldns_key_hmac_size(k);
2053 			memcpy(bin, ldns_key_hmac_key(k), size);
2054 			internal_data = 1;
2055 			break;
2056 	}
2057 	/* fourth the key bin material */
2058 	if (internal_data) {
2059 		keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
2060 		LDNS_FREE(bin);
2061 		ldns_rr_push_rdf(pubkey, keybin);
2062 	}
2063 	return pubkey;
2064 }
2065 
2066 void
2067 ldns_key_free(ldns_key *key)
2068 {
2069 	LDNS_FREE(key);
2070 }
2071 
2072 void
2073 ldns_key_deep_free(ldns_key *key)
2074 {
2075 	unsigned char* hmac;
2076 	if (ldns_key_pubkey_owner(key)) {
2077 		ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
2078 	}
2079 #ifdef HAVE_SSL
2080 	if (ldns_key_evp_key(key)) {
2081 		EVP_PKEY_free(ldns_key_evp_key(key));
2082 	}
2083 #endif /* HAVE_SSL */
2084 	if (ldns_key_hmac_key(key)) {
2085 		hmac = ldns_key_hmac_key(key);
2086 		LDNS_FREE(hmac);
2087 	}
2088 	LDNS_FREE(key);
2089 }
2090 
2091 void
2092 ldns_key_list_free(ldns_key_list *key_list)
2093 {
2094 	size_t i;
2095 	for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
2096 		ldns_key_deep_free(ldns_key_list_key(key_list, i));
2097 	}
2098 	LDNS_FREE(key_list->_keys);
2099 	LDNS_FREE(key_list);
2100 }
2101 
2102 ldns_rr *
2103 ldns_read_anchor_file(const char *filename)
2104 {
2105 	FILE *fp;
2106 	/*char line[LDNS_MAX_PACKETLEN];*/
2107 	char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
2108 	int c;
2109 	size_t i = 0;
2110 	ldns_rr *r;
2111 	ldns_status status;
2112         if(!line) {
2113                 return NULL;
2114         }
2115 
2116 	fp = fopen(filename, "r");
2117 	if (!fp) {
2118 #ifdef STDERR_MSGS
2119 		fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
2120 #endif
2121 		LDNS_FREE(line);
2122 		return NULL;
2123 	}
2124 
2125 	while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
2126 		line[i] = c;
2127 		i++;
2128 	}
2129 	line[i] = '\0';
2130 
2131 	fclose(fp);
2132 
2133 	if (i <= 0) {
2134 #ifdef STDERR_MSGS
2135 		fprintf(stderr, "nothing read from %s", filename);
2136 #endif
2137 		LDNS_FREE(line);
2138 		return NULL;
2139 	} else {
2140 		status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
2141 		if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
2142 			LDNS_FREE(line);
2143 			return r;
2144 		} else {
2145 #ifdef STDERR_MSGS
2146 			fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
2147 #endif
2148 			LDNS_FREE(line);
2149 			return NULL;
2150 		}
2151 	}
2152 }
2153 
2154 char *
2155 ldns_key_get_file_base_name(const ldns_key *key)
2156 {
2157 	ldns_buffer *buffer;
2158 	char *file_base_name;
2159 
2160 	buffer = ldns_buffer_new(255);
2161 	ldns_buffer_printf(buffer, "K");
2162 	(void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
2163 	ldns_buffer_printf(buffer,
2164 	                   "+%03u+%05u",
2165 			   ldns_key_algorithm(key),
2166 			   ldns_key_keytag(key));
2167 	file_base_name = ldns_buffer_export(buffer);
2168 	ldns_buffer_free(buffer);
2169 	return file_base_name;
2170 }
2171 
2172 int ldns_key_algo_supported(int algo)
2173 {
2174 	ldns_lookup_table *lt = ldns_signing_algorithms;
2175 	while(lt->name) {
2176 		if(lt->id == algo)
2177 			return 1;
2178 		lt++;
2179 	}
2180 	return 0;
2181 }
2182 
2183 ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
2184 {
2185         /* list of (signing algorithm id, alias_name) */
2186         ldns_lookup_table aliases[] = {
2187                 /* from bind dnssec-keygen */
2188                 {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
2189                 {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
2190                 {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
2191                 /* old ldns usage, now RFC names */
2192 #ifdef USE_DSA
2193                 {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
2194 #endif
2195                 {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
2196 #ifdef USE_GOST
2197                 {LDNS_SIGN_ECC_GOST, "GOST"},
2198 #endif
2199                 /* compat with possible output */
2200                 {LDNS_DH, "DH"},
2201                 {LDNS_ECC, "ECC"},
2202                 {LDNS_INDIRECT, "INDIRECT"},
2203                 {LDNS_PRIVATEDNS, "PRIVATEDNS"},
2204                 {LDNS_PRIVATEOID, "PRIVATEOID"},
2205                 {0, NULL}};
2206         ldns_lookup_table* lt = ldns_signing_algorithms;
2207 	ldns_signing_algorithm a;
2208 	char *endptr;
2209 
2210         while(lt->name) {
2211                 if(strcasecmp(lt->name, name) == 0)
2212                         return lt->id;
2213                 lt++;
2214         }
2215         lt = aliases;
2216         while(lt->name) {
2217                 if(strcasecmp(lt->name, name) == 0)
2218                         return lt->id;
2219                 lt++;
2220         }
2221 	a = strtol(name, &endptr, 10);
2222 	if (*name && !*endptr)
2223 		return a;
2224 
2225         return 0;
2226 }
2227