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