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
23ldns_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
57ldns_key_list *
58ldns_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
70ldns_key *
71ldns_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
96ldns_status
97ldns_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
103ldns_status
104ldns_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 */
129ENGINE* ldns_gost_engine = NULL;
130
131int
132ldns_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
180void 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 */
190static EVP_PKEY*
191ldns_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 */
223static int
224ldns_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 */
249static EVP_PKEY*
250ldns_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 */
303static EC_KEY*
304ldns_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 */
334static EVP_PKEY*
335ldns_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 */
379static EC_KEY*
380ldns_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 */
415static EVP_PKEY*
416ldns_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
453ldns_status
454ldns_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
767RSA *
768ldns_key_new_frm_fp_rsa(FILE *f)
769{
770	return ldns_key_new_frm_fp_rsa_l(f, NULL);
771}
772
773RSA *
774ldns_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
930error:
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
945DSA *
946ldns_key_new_frm_fp_dsa(FILE *f)
947{
948	return ldns_key_new_frm_fp_dsa_l(f, NULL);
949}
950
951DSA *
952ldns_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
1044error:
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
1056unsigned char *
1057ldns_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
1062unsigned char *
1063ldns_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
1090static EVP_PKEY*
1091ldns_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
1123ldns_key *
1124ldns_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
1375void
1376ldns_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
1388void
1389ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
1390{
1391	k->_alg = l;
1392}
1393
1394void
1395ldns_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
1402void
1403ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
1404{
1405	k->_key.key = e;
1406}
1407
1408void
1409ldns_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
1416void
1417ldns_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
1428void
1429ldns_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
1436void
1437ldns_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
1450void
1451ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
1452{
1453	k->_key.hmac.key = hmac;
1454}
1455
1456void
1457ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
1458{
1459	k->_key.hmac.size = hmac_size;
1460}
1461
1462void
1463ldns_key_set_external_key(ldns_key *k, void *external_key)
1464{
1465	k->_key.external_key = external_key;
1466}
1467
1468void
1469ldns_key_set_origttl(ldns_key *k, uint32_t t)
1470{
1471	k->_extra.dnssec.orig_ttl = t;
1472}
1473
1474void
1475ldns_key_set_inception(ldns_key *k, uint32_t i)
1476{
1477	k->_extra.dnssec.inception = i;
1478}
1479
1480void
1481ldns_key_set_expiration(ldns_key *k, uint32_t e)
1482{
1483	k->_extra.dnssec.expiration = e;
1484}
1485
1486void
1487ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
1488{
1489	k->_pubkey_owner = r;
1490}
1491
1492void
1493ldns_key_set_keytag(ldns_key *k, uint16_t tag)
1494{
1495	k->_extra.dnssec.keytag = tag;
1496}
1497
1498/* read */
1499size_t
1500ldns_key_list_key_count(const ldns_key_list *key_list)
1501{
1502	        return key_list->_key_count;
1503}
1504
1505ldns_key *
1506ldns_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
1515ldns_signing_algorithm
1516ldns_key_algorithm(const ldns_key *k)
1517{
1518	return k->_alg;
1519}
1520
1521void
1522ldns_key_set_use(ldns_key *k, bool v)
1523{
1524	if (k) {
1525		k->_use = v;
1526	}
1527}
1528
1529bool
1530ldns_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
1540EVP_PKEY *
1541ldns_key_evp_key(const ldns_key *k)
1542{
1543	return k->_key.key;
1544}
1545
1546RSA *
1547ldns_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
1556DSA *
1557ldns_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
1573unsigned char *
1574ldns_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
1583size_t
1584ldns_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
1593void *
1594ldns_key_external_key(const ldns_key *k)
1595{
1596	return k->_key.external_key;
1597}
1598
1599uint32_t
1600ldns_key_origttl(const ldns_key *k)
1601{
1602	return k->_extra.dnssec.orig_ttl;
1603}
1604
1605uint16_t
1606ldns_key_flags(const ldns_key *k)
1607{
1608	return k->_extra.dnssec.flags;
1609}
1610
1611uint32_t
1612ldns_key_inception(const ldns_key *k)
1613{
1614	return k->_extra.dnssec.inception;
1615}
1616
1617uint32_t
1618ldns_key_expiration(const ldns_key *k)
1619{
1620	return k->_extra.dnssec.expiration;
1621}
1622
1623uint16_t
1624ldns_key_keytag(const ldns_key *k)
1625{
1626	return k->_extra.dnssec.keytag;
1627}
1628
1629ldns_rdf *
1630ldns_key_pubkey_owner(const ldns_key *k)
1631{
1632	return k->_pubkey_owner;
1633}
1634
1635/* write */
1636void
1637ldns_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
1646void
1647ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
1648{
1649	        key->_key_count = count;
1650}
1651
1652bool
1653ldns_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
1675ldns_key *
1676ldns_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) */
1707static bool
1708ldns_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) */
1747static bool
1748ldns_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
1794static bool
1795ldns_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
1815ldns_rr *
1816ldns_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
2064void
2065ldns_key_free(ldns_key *key)
2066{
2067	LDNS_FREE(key);
2068}
2069
2070void
2071ldns_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
2089void
2090ldns_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
2100ldns_rr *
2101ldns_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
2152char *
2153ldns_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
2170int 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
2181ldns_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