xref: /dragonfly/contrib/ldns/keys.c (revision fcf53d9b)
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         { LDNS_SIGN_DSA, "DSA" },
39         { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
40         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
41         { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
42         { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
43         { 0, NULL }
44 };
45 
46 ldns_key_list *
47 ldns_key_list_new()
48 {
49 	ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
50 	if (!key_list) {
51 		return NULL;
52 	} else {
53 		key_list->_key_count = 0;
54 		key_list->_keys = NULL;
55 		return key_list;
56 	}
57 }
58 
59 ldns_key *
60 ldns_key_new()
61 {
62 	ldns_key *newkey;
63 
64 	newkey = LDNS_MALLOC(ldns_key);
65 	if (!newkey) {
66 		return NULL;
67 	} else {
68 		/* some defaults - not sure wether to do this */
69 		ldns_key_set_use(newkey, true);
70 		ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
71 		ldns_key_set_origttl(newkey, 0);
72 		ldns_key_set_keytag(newkey, 0);
73 		ldns_key_set_inception(newkey, 0);
74 		ldns_key_set_expiration(newkey, 0);
75 		ldns_key_set_pubkey_owner(newkey, NULL);
76 #ifdef HAVE_SSL
77 		ldns_key_set_evp_key(newkey, NULL);
78 #endif /* HAVE_SSL */
79 		ldns_key_set_hmac_key(newkey, NULL);
80 		ldns_key_set_external_key(newkey, NULL);
81 		return newkey;
82 	}
83 }
84 
85 ldns_status
86 ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
87 {
88 	return ldns_key_new_frm_fp_l(k, fp, NULL);
89 }
90 
91 #ifdef HAVE_SSL
92 ldns_status
93 ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
94 {
95 	ldns_key *k;
96 
97 	k = ldns_key_new();
98 	k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
99 	ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
100 	if (!k->_key.key) {
101 		return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
102 	} else {
103 		*key = k;
104 		return LDNS_STATUS_OK;
105 	}
106 }
107 #endif
108 
109 #ifdef USE_GOST
110 /** store GOST engine reference loaded into OpenSSL library */
111 ENGINE* ldns_gost_engine = NULL;
112 
113 int
114 ldns_key_EVP_load_gost_id(void)
115 {
116 	static int gost_id = 0;
117 	const EVP_PKEY_ASN1_METHOD* meth;
118 	ENGINE* e;
119 
120 	if(gost_id) return gost_id;
121 
122 	/* see if configuration loaded gost implementation from other engine*/
123 	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
124 	if(meth) {
125 		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
126 		return gost_id;
127 	}
128 
129 	/* see if engine can be loaded already */
130 	e = ENGINE_by_id("gost");
131 	if(!e) {
132 		/* load it ourself, in case statically linked */
133 		ENGINE_load_builtin_engines();
134 		ENGINE_load_dynamic();
135 		e = ENGINE_by_id("gost");
136 	}
137 	if(!e) {
138 		/* no gost engine in openssl */
139 		return 0;
140 	}
141 	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
142 		ENGINE_finish(e);
143 		ENGINE_free(e);
144 		return 0;
145 	}
146 
147 	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
148 	if(!meth) {
149 		/* algo not found */
150 		ENGINE_finish(e);
151 		ENGINE_free(e);
152 		return 0;
153 	}
154         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
155          * on some platforms this frees up the meth and unloads gost stuff */
156         ldns_gost_engine = e;
157 
158 	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
159 	return gost_id;
160 }
161 
162 void ldns_key_EVP_unload_gost(void)
163 {
164         if(ldns_gost_engine) {
165                 ENGINE_finish(ldns_gost_engine);
166                 ENGINE_free(ldns_gost_engine);
167                 ldns_gost_engine = NULL;
168         }
169 }
170 
171 /** read GOST private key */
172 static EVP_PKEY*
173 ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
174 {
175 	char token[16384];
176 	const unsigned char* pp;
177 	int gost_id;
178 	EVP_PKEY* pkey;
179 	ldns_rdf* b64rdf = NULL;
180 
181 	gost_id = ldns_key_EVP_load_gost_id();
182 	if(!gost_id)
183 		return NULL;
184 
185 	if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n",
186 		sizeof(token), line_nr) == -1)
187 		return NULL;
188 	while(strlen(token) < 96) {
189 		/* read more b64 from the file, b64 split on multiple lines */
190 		if(ldns_fget_token_l(fp, token+strlen(token), "\n",
191 			sizeof(token)-strlen(token), line_nr) == -1)
192 			return NULL;
193 	}
194 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
195 		return NULL;
196 	pp = (unsigned char*)ldns_rdf_data(b64rdf);
197 	pkey = d2i_PrivateKey(gost_id, NULL, &pp, ldns_rdf_size(b64rdf));
198 	ldns_rdf_deep_free(b64rdf);
199 	return pkey;
200 }
201 #endif
202 
203 #ifdef USE_ECDSA
204 /** calculate public key from private key */
205 static int
206 ldns_EC_KEY_calc_public(EC_KEY* ec)
207 {
208         EC_POINT* pub_key;
209         const EC_GROUP* group;
210         group = EC_KEY_get0_group(ec);
211         pub_key = EC_POINT_new(group);
212         if(!pub_key) return 0;
213         if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
214                 EC_POINT_free(pub_key);
215                 return 0;
216         }
217         if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
218                 NULL, NULL, NULL)) {
219                 EC_POINT_free(pub_key);
220                 return 0;
221         }
222         if(EC_KEY_set_public_key(ec, pub_key) == 0) {
223                 EC_POINT_free(pub_key);
224                 return 0;
225         }
226         EC_POINT_free(pub_key);
227         return 1;
228 }
229 
230 /** read ECDSA private key */
231 static EVP_PKEY*
232 ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
233 {
234 	char token[16384];
235         ldns_rdf* b64rdf = NULL;
236         unsigned char* pp;
237         BIGNUM* bn;
238         EVP_PKEY* evp_key;
239         EC_KEY* ec;
240 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
241 		sizeof(token), line_nr) == -1)
242 		return NULL;
243 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
244 		return NULL;
245         pp = (unsigned char*)ldns_rdf_data(b64rdf);
246 
247         if(alg == LDNS_ECDSAP256SHA256)
248                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
249         else if(alg == LDNS_ECDSAP384SHA384)
250                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
251         else    ec = NULL;
252         if(!ec) {
253 	        ldns_rdf_deep_free(b64rdf);
254                 return NULL;
255         }
256 	bn = BN_bin2bn(pp, ldns_rdf_size(b64rdf), NULL);
257 	ldns_rdf_deep_free(b64rdf);
258         if(!bn) {
259                 EC_KEY_free(ec);
260                 return NULL;
261         }
262         EC_KEY_set_private_key(ec, bn);
263         BN_free(bn);
264         if(!ldns_EC_KEY_calc_public(ec)) {
265                 EC_KEY_free(ec);
266                 return NULL;
267         }
268 
269         evp_key = EVP_PKEY_new();
270         if(!evp_key) {
271                 EC_KEY_free(ec);
272                 return NULL;
273         }
274         EVP_PKEY_assign_EC_KEY(evp_key, ec);
275 
276         return evp_key;
277 }
278 #endif
279 
280 ldns_status
281 ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
282 {
283 	ldns_key *k;
284 	char *d;
285 	ldns_signing_algorithm alg;
286 	ldns_rr *key_rr;
287 #ifdef HAVE_SSL
288 	RSA *rsa;
289 	DSA *dsa;
290 	unsigned char *hmac;
291 	size_t hmac_size;
292 #endif /* HAVE_SSL */
293 
294 	k = ldns_key_new();
295 
296 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
297 	if (!k || !d) {
298 		return LDNS_STATUS_MEM_ERR;
299 	}
300 
301 	alg = 0;
302 
303 	/* the file is highly structured. Do this in sequence */
304 	/* RSA:
305 	 * Private-key-format: v1.2
306  	 * Algorithm: 1 (RSA)
307 
308 	 */
309 	/* get the key format version number */
310 	if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
311 				LDNS_MAX_LINELEN, line_nr) == -1) {
312 		/* no version information */
313 		return LDNS_STATUS_SYNTAX_ERR;
314 	}
315 	if (strncmp(d, "v1.2", strlen(d)) != 0) {
316 		return LDNS_STATUS_SYNTAX_VERSION_ERR;
317 	}
318 
319 	/* get the algorithm type, our file function strip ( ) so there are
320 	 * not in the return string! */
321 	if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
322 				LDNS_MAX_LINELEN, line_nr) == -1) {
323 		/* no alg information */
324 		return LDNS_STATUS_SYNTAX_ALG_ERR;
325 	}
326 
327 	if (strncmp(d, "1 RSA", 2) == 0) {
328 		alg = LDNS_SIGN_RSAMD5;
329 	}
330 	if (strncmp(d, "2 DH", 2) == 0) {
331 		alg = (ldns_signing_algorithm)LDNS_DH;
332 	}
333 	if (strncmp(d, "3 DSA", 2) == 0) {
334 		alg = LDNS_SIGN_DSA;
335 	}
336 	if (strncmp(d, "4 ECC", 2) == 0) {
337 		alg = (ldns_signing_algorithm)LDNS_ECC;
338 	}
339 	if (strncmp(d, "5 RSASHA1", 2) == 0) {
340 		alg = LDNS_SIGN_RSASHA1;
341 	}
342 	if (strncmp(d, "6 DSA", 2) == 0) {
343 		alg = LDNS_SIGN_DSA_NSEC3;
344 	}
345 	if (strncmp(d, "7 RSASHA1", 2) == 0) {
346 		alg = LDNS_SIGN_RSASHA1_NSEC3;
347 	}
348 
349 	if (strncmp(d, "8 RSASHA256", 2) == 0) {
350 #ifdef USE_SHA2
351 		alg = LDNS_SIGN_RSASHA256;
352 #else
353 		fprintf(stderr, "Warning: SHA256 not compiled into this ");
354 		fprintf(stderr, "version of ldns\n");
355 #endif
356 	}
357 	if (strncmp(d, "10 RSASHA512", 3) == 0) {
358 #ifdef USE_SHA2
359 		alg = LDNS_SIGN_RSASHA512;
360 #else
361 		fprintf(stderr, "Warning: SHA512 not compiled into this ");
362 		fprintf(stderr, "version of ldns\n");
363 #endif
364 	}
365 	if (strncmp(d, "12 ECC-GOST", 3) == 0) {
366 #ifdef USE_GOST
367 		alg = LDNS_SIGN_ECC_GOST;
368 #else
369 		fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
370 		fprintf(stderr, "version of ldns, use --enable-gost\n");
371 #endif
372 	}
373 #ifdef USE_ECDSA
374 	if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
375                 alg = LDNS_ECDSAP256SHA256;
376         }
377 	if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
378                 alg = LDNS_ECDSAP384SHA384;
379         }
380 #endif
381 	if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
382 		alg = LDNS_SIGN_HMACMD5;
383 	}
384 	if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
385 		alg = LDNS_SIGN_HMACSHA1;
386 	}
387 	if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
388 		alg = LDNS_SIGN_HMACSHA256;
389 	}
390 
391 	LDNS_FREE(d);
392 
393 	switch(alg) {
394 		case LDNS_SIGN_RSAMD5:
395 		case LDNS_SIGN_RSASHA1:
396 		case LDNS_RSASHA1_NSEC3:
397 #ifdef USE_SHA2
398 		case LDNS_SIGN_RSASHA256:
399 		case LDNS_SIGN_RSASHA512:
400 #endif
401 			ldns_key_set_algorithm(k, alg);
402 #ifdef HAVE_SSL
403 			rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
404 			if (!rsa) {
405 				ldns_key_free(k);
406 				return LDNS_STATUS_ERR;
407 			}
408 			ldns_key_set_rsa_key(k, rsa);
409 			RSA_free(rsa);
410 #endif /* HAVE_SSL */
411 			break;
412 		case LDNS_SIGN_DSA:
413 		case LDNS_DSA_NSEC3:
414 			ldns_key_set_algorithm(k, alg);
415 #ifdef HAVE_SSL
416 			dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
417 			if (!dsa) {
418 				ldns_key_free(k);
419 				return LDNS_STATUS_ERR;
420 			}
421 			ldns_key_set_dsa_key(k, dsa);
422 			DSA_free(dsa);
423 #endif /* HAVE_SSL */
424 			break;
425 		case LDNS_SIGN_HMACMD5:
426 		case LDNS_SIGN_HMACSHA1:
427 		case LDNS_SIGN_HMACSHA256:
428 			ldns_key_set_algorithm(k, alg);
429 #ifdef HAVE_SSL
430 			hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
431 			if (!hmac) {
432 				ldns_key_free(k);
433 				return LDNS_STATUS_ERR;
434 			}
435 			ldns_key_set_hmac_size(k, hmac_size);
436 			ldns_key_set_hmac_key(k, hmac);
437 #endif /* HAVE_SSL */
438 			break;
439 		case LDNS_SIGN_ECC_GOST:
440 			ldns_key_set_algorithm(k, alg);
441 #if defined(HAVE_SSL) && defined(USE_GOST)
442                         if(!ldns_key_EVP_load_gost_id()) {
443 				ldns_key_free(k);
444                                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
445                         }
446 			ldns_key_set_evp_key(k,
447 				ldns_key_new_frm_fp_gost_l(fp, line_nr));
448 			if(!k->_key.key) {
449 				ldns_key_free(k);
450 				return LDNS_STATUS_ERR;
451 			}
452 #endif
453 			break;
454 #ifdef USE_ECDSA
455                case LDNS_SIGN_ECDSAP256SHA256:
456                case LDNS_SIGN_ECDSAP384SHA384:
457                         ldns_key_set_algorithm(k, alg);
458                         ldns_key_set_evp_key(k,
459                                 ldns_key_new_frm_fp_ecdsa_l(fp, alg, line_nr));
460 			if(!k->_key.key) {
461 				ldns_key_free(k);
462 				return LDNS_STATUS_ERR;
463 			}
464 			break;
465 #endif
466 		case 0:
467 		default:
468 			return LDNS_STATUS_SYNTAX_ALG_ERR;
469 	}
470 	key_rr = ldns_key2rr(k);
471 	ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
472 	ldns_rr_free(key_rr);
473 
474 	if (key) {
475 		*key = k;
476 		return LDNS_STATUS_OK;
477 	}
478 	return LDNS_STATUS_ERR;
479 }
480 
481 #ifdef HAVE_SSL
482 RSA *
483 ldns_key_new_frm_fp_rsa(FILE *f)
484 {
485 	return ldns_key_new_frm_fp_rsa_l(f, NULL);
486 }
487 
488 RSA *
489 ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
490 {
491 	/* we parse
492  	 * Modulus:
493  	 * PublicExponent:
494  	 * PrivateExponent:
495  	 * Prime1:
496  	 * Prime2:
497  	 * Exponent1:
498  	 * Exponent2:
499  	 * Coefficient:
500 	 *
501 	 * man 3 RSA:
502 	 *
503 	 * struct
504          *     {
505          *     BIGNUM *n;              // public modulus
506          *     BIGNUM *e;              // public exponent
507          *     BIGNUM *d;              // private exponent
508          *     BIGNUM *p;              // secret prime factor
509          *     BIGNUM *q;              // secret prime factor
510          *     BIGNUM *dmp1;           // d mod (p-1)
511          *     BIGNUM *dmq1;           // d mod (q-1)
512          *     BIGNUM *iqmp;           // q^-1 mod p
513          *     // ...
514 	 *
515 	 */
516 	char *d;
517 	RSA *rsa;
518 	uint8_t *buf;
519 	int i;
520 
521 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
522 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
523 	rsa = RSA_new();
524 	if (!d || !rsa || !buf) {
525 		return NULL;
526 	}
527 
528 	/* I could use functions again, but that seems an overkill,
529 	 * allthough this also looks tedious
530 	 */
531 
532 	/* Modules, rsa->n */
533 	if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
534 		goto error;
535 	}
536 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
537 	rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
538 	if (!rsa->n) {
539 		goto error;
540 	}
541 
542 	/* PublicExponent, rsa->e */
543 	if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
544 		goto error;
545 	}
546 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
547 	rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
548 	if (!rsa->e) {
549 		goto error;
550 	}
551 
552 	/* PrivateExponent, rsa->d */
553 	if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
554 		goto error;
555 	}
556 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
557 	rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
558 	if (!rsa->d) {
559 		goto error;
560 	}
561 
562 	/* Prime1, rsa->p */
563 	if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
564 		goto error;
565 	}
566 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
567 	rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
568 	if (!rsa->p) {
569 		goto error;
570 	}
571 
572 	/* Prime2, rsa->q */
573 	if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
574 		goto error;
575 	}
576 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
577 	rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
578 	if (!rsa->q) {
579 		goto error;
580 	}
581 
582 	/* Exponent1, rsa->dmp1 */
583 	if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
584 		goto error;
585 	}
586 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
587 	rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
588 	if (!rsa->dmp1) {
589 		goto error;
590 	}
591 
592 	/* Exponent2, rsa->dmq1 */
593 	if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
594 		goto error;
595 	}
596 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
597 	rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
598 	if (!rsa->dmq1) {
599 		goto error;
600 	}
601 
602 	/* Coefficient, rsa->iqmp */
603 	if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
604 		goto error;
605 	}
606 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
607 	rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
608 	if (!rsa->iqmp) {
609 		goto error;
610 	}
611 
612 	LDNS_FREE(buf);
613 	LDNS_FREE(d);
614 	return rsa;
615 
616 error:
617 	RSA_free(rsa);
618 	LDNS_FREE(d);
619 	LDNS_FREE(buf);
620 	return NULL;
621 }
622 
623 DSA *
624 ldns_key_new_frm_fp_dsa(FILE *f)
625 {
626 	return ldns_key_new_frm_fp_dsa_l(f, NULL);
627 }
628 
629 DSA *
630 ldns_key_new_frm_fp_dsa_l(FILE *f, int *line_nr)
631 {
632 	int i;
633 	char *d;
634 	DSA *dsa;
635 	uint8_t *buf;
636 
637 	line_nr = line_nr;
638 
639 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
640 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
641 	dsa = DSA_new();
642 	if (!d || !dsa) {
643 		return NULL;
644 	}
645 
646 	/* the line parser removes the () from the input... */
647 
648 	/* Prime, dsa->p */
649 	if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
650 		goto error;
651 	}
652 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
653 	dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
654 	if (!dsa->p) {
655 		goto error;
656 	}
657 
658 	/* Subprime, dsa->q */
659 	if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
660 		goto error;
661 	}
662 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
663 	dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
664 	if (!dsa->q) {
665 		goto error;
666 	}
667 
668 	/* Base, dsa->g */
669 	if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
670 		goto error;
671 	}
672 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
673 	dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
674 	if (!dsa->g) {
675 		goto error;
676 	}
677 
678 	/* Private key, dsa->priv_key */
679 	if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
680 		goto error;
681 	}
682 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
683 	dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
684 	if (!dsa->priv_key) {
685 		goto error;
686 	}
687 
688 	/* Public key, dsa->priv_key */
689 	if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
690 		goto error;
691 	}
692 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
693 	dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
694 	if (!dsa->pub_key) {
695 		goto error;
696 	}
697 
698 	LDNS_FREE(buf);
699 	LDNS_FREE(d);
700 
701 	return dsa;
702 
703 error:
704 	LDNS_FREE(d);
705 	LDNS_FREE(buf);
706 	return NULL;
707 }
708 
709 unsigned char *
710 ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
711 {
712 	return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
713 }
714 
715 unsigned char *
716 ldns_key_new_frm_fp_hmac_l(FILE *f, int *line_nr, size_t *hmac_size)
717 {
718 	size_t i;
719 	char *d;
720 	unsigned char *buf;
721 
722 	line_nr = line_nr;
723 
724 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
725 	buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN);
726 
727 	if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
728 		goto error;
729 	}
730 	i = (size_t) ldns_b64_pton((const char*)d,
731 	                           buf,
732 	                           ldns_b64_ntop_calculate_size(strlen(d)));
733 
734 	*hmac_size = i;
735 	return buf;
736 
737 	error:
738 	LDNS_FREE(d);
739 	LDNS_FREE(buf);
740 	*hmac_size = 0;
741 	return NULL;
742 }
743 #endif /* HAVE_SSL */
744 
745 #ifdef USE_GOST
746 static EVP_PKEY*
747 ldns_gen_gost_key(void)
748 {
749 	EVP_PKEY_CTX* ctx;
750 	EVP_PKEY* p = NULL;
751 	int gost_id = ldns_key_EVP_load_gost_id();
752 	if(!gost_id)
753 		return NULL;
754 	ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
755 	if(!ctx) {
756 		/* the id should be available now */
757 		return NULL;
758 	}
759 	if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
760 		/* cannot set paramset */
761 		EVP_PKEY_CTX_free(ctx);
762 		return NULL;
763 	}
764 
765 	if(EVP_PKEY_keygen_init(ctx) <= 0) {
766 		EVP_PKEY_CTX_free(ctx);
767 		return NULL;
768 	}
769 	if(EVP_PKEY_keygen(ctx, &p) <= 0) {
770 		EVP_PKEY_free(p);
771 		EVP_PKEY_CTX_free(ctx);
772 		return NULL;
773 	}
774 	EVP_PKEY_CTX_free(ctx);
775 	return p;
776 }
777 #endif
778 
779 ldns_key *
780 ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
781 {
782 	ldns_key *k;
783 #ifdef HAVE_SSL
784 	DSA *d;
785 	RSA *r;
786 #  ifdef USE_ECDSA
787         EC_KEY *ec = NULL;
788 #  endif
789 #else
790 	int i;
791 	uint16_t offset = 0;
792 #endif
793 	unsigned char *hmac;
794 
795 	k = ldns_key_new();
796 	if (!k) {
797 		return NULL;
798 	}
799 	switch(alg) {
800 		case LDNS_SIGN_RSAMD5:
801 		case LDNS_SIGN_RSASHA1:
802 		case LDNS_SIGN_RSASHA1_NSEC3:
803 		case LDNS_SIGN_RSASHA256:
804 		case LDNS_SIGN_RSASHA512:
805 #ifdef HAVE_SSL
806 			r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
807 			if (RSA_check_key(r) != 1) {
808 				return NULL;
809 			}
810 
811 			ldns_key_set_rsa_key(k, r);
812 #endif /* HAVE_SSL */
813 			break;
814 		case LDNS_SIGN_DSA:
815 		case LDNS_SIGN_DSA_NSEC3:
816 #ifdef HAVE_SSL
817 			d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
818 			if (!d) {
819 				return NULL;
820 			}
821 			if (DSA_generate_key(d) != 1) {
822 				return NULL;
823 			}
824 			ldns_key_set_dsa_key(k, d);
825 #endif /* HAVE_SSL */
826 			break;
827 		case LDNS_SIGN_HMACMD5:
828 		case LDNS_SIGN_HMACSHA1:
829 		case LDNS_SIGN_HMACSHA256:
830 #ifdef HAVE_SSL
831 			k->_key.key = NULL;
832 #endif /* HAVE_SSL */
833 			size = size / 8;
834 			ldns_key_set_hmac_size(k, size);
835 
836 			hmac = LDNS_XMALLOC(unsigned char, size);
837 #ifdef HAVE_SSL
838 			if (RAND_bytes(hmac, (int) size) != 1) {
839 				LDNS_FREE(hmac);
840 				ldns_key_free(k);
841 				return NULL;
842 			}
843 #else
844 			while (offset + sizeof(i) < size) {
845 			  i = random();
846 			  memcpy(&hmac[offset], &i, sizeof(i));
847 			  offset += sizeof(i);
848 			}
849 			if (offset < size) {
850 			  i = random();
851 			  memcpy(&hmac[offset], &i, size - offset);
852 			}
853 #endif /* HAVE_SSL */
854 			ldns_key_set_hmac_key(k, hmac);
855 
856 			ldns_key_set_flags(k, 0);
857 			break;
858 		case LDNS_SIGN_ECC_GOST:
859 #if defined(HAVE_SSL) && defined(USE_GOST)
860 			ldns_key_set_evp_key(k, ldns_gen_gost_key());
861 #endif /* HAVE_SSL and USE_GOST */
862                         break;
863 #ifdef USE_ECDSA
864                 case LDNS_ECDSAP256SHA256:
865                 case LDNS_ECDSAP384SHA384:
866                         if(alg == LDNS_ECDSAP256SHA256)
867                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
868                         else if(alg == LDNS_ECDSAP384SHA384)
869                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
870                         if(!ec) return NULL;
871                         if(!EC_KEY_generate_key(ec)) {
872                                 EC_KEY_free(ec);
873                                 return NULL;
874                         }
875                         k->_key.key = EVP_PKEY_new();
876                         if(!k->_key.key) {
877                                 EC_KEY_free(ec);
878                                 return NULL;
879                         }
880                         EVP_PKEY_assign_EC_KEY(k->_key.key, ec);
881 			break;
882 #endif
883 	}
884 	ldns_key_set_algorithm(k, alg);
885 	return k;
886 }
887 
888 void
889 ldns_key_print(FILE *output, const ldns_key *k)
890 {
891 	char *str = ldns_key2str(k);
892 	if (str) {
893                 fprintf(output, "%s", str);
894         } else {
895                 fprintf(output, "Unable to convert private key to string\n");
896         }
897         LDNS_FREE(str);
898 }
899 
900 
901 void
902 ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
903 {
904 	k->_alg = l;
905 }
906 
907 void
908 ldns_key_set_flags(ldns_key *k, uint16_t f)
909 {
910 	k->_extra.dnssec.flags = f;
911 }
912 
913 #ifdef HAVE_SSL
914 void
915 ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
916 {
917 	k->_key.key = e;
918 }
919 
920 void
921 ldns_key_set_rsa_key(ldns_key *k, RSA *r)
922 {
923 	EVP_PKEY *key = EVP_PKEY_new();
924 	EVP_PKEY_set1_RSA(key, r);
925 	k->_key.key = key;
926 }
927 
928 void
929 ldns_key_set_dsa_key(ldns_key *k, DSA *d)
930 {
931 	EVP_PKEY *key = EVP_PKEY_new();
932 	EVP_PKEY_set1_DSA(key, d);
933 	k->_key.key  = key;
934 }
935 #endif /* HAVE_SSL */
936 
937 void
938 ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
939 {
940 	k->_key.hmac.key = hmac;
941 }
942 
943 void
944 ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
945 {
946 	k->_key.hmac.size = hmac_size;
947 }
948 
949 void
950 ldns_key_set_external_key(ldns_key *k, void *external_key)
951 {
952 	k->_key.external_key = external_key;
953 }
954 
955 void
956 ldns_key_set_origttl(ldns_key *k, uint32_t t)
957 {
958 	k->_extra.dnssec.orig_ttl = t;
959 }
960 
961 void
962 ldns_key_set_inception(ldns_key *k, uint32_t i)
963 {
964 	k->_extra.dnssec.inception = i;
965 }
966 
967 void
968 ldns_key_set_expiration(ldns_key *k, uint32_t e)
969 {
970 	k->_extra.dnssec.expiration = e;
971 }
972 
973 void
974 ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
975 {
976 	k->_pubkey_owner = r;
977 }
978 
979 void
980 ldns_key_set_keytag(ldns_key *k, uint16_t tag)
981 {
982 	k->_extra.dnssec.keytag = tag;
983 }
984 
985 /* read */
986 size_t
987 ldns_key_list_key_count(const ldns_key_list *key_list)
988 {
989 	        return key_list->_key_count;
990 }
991 
992 ldns_key *
993 ldns_key_list_key(const ldns_key_list *key, size_t nr)
994 {
995 	if (nr < ldns_key_list_key_count(key)) {
996 		return key->_keys[nr];
997 	} else {
998 		return NULL;
999 	}
1000 }
1001 
1002 ldns_signing_algorithm
1003 ldns_key_algorithm(const ldns_key *k)
1004 {
1005 	return k->_alg;
1006 }
1007 
1008 void
1009 ldns_key_set_use(ldns_key *k, bool v)
1010 {
1011 	if (k) {
1012 		k->_use = v;
1013 	}
1014 }
1015 
1016 bool
1017 ldns_key_use(const ldns_key *k)
1018 {
1019 	if (k) {
1020 		return k->_use;
1021 	}
1022 	return false;
1023 }
1024 
1025 #ifdef HAVE_SSL
1026 EVP_PKEY *
1027 ldns_key_evp_key(const ldns_key *k)
1028 {
1029 	return k->_key.key;
1030 }
1031 
1032 RSA *
1033 ldns_key_rsa_key(const ldns_key *k)
1034 {
1035 	if (k->_key.key) {
1036 		return EVP_PKEY_get1_RSA(k->_key.key);
1037 	} else {
1038 		return NULL;
1039 	}
1040 }
1041 
1042 DSA *
1043 ldns_key_dsa_key(const ldns_key *k)
1044 {
1045 	if (k->_key.key) {
1046 		return EVP_PKEY_get1_DSA(k->_key.key);
1047 	} else {
1048 		return NULL;
1049 	}
1050 }
1051 #endif /* HAVE_SSL */
1052 
1053 unsigned char *
1054 ldns_key_hmac_key(const ldns_key *k)
1055 {
1056 	if (k->_key.hmac.key) {
1057 		return k->_key.hmac.key;
1058 	} else {
1059 		return NULL;
1060 	}
1061 }
1062 
1063 size_t
1064 ldns_key_hmac_size(const ldns_key *k)
1065 {
1066 	if (k->_key.hmac.size) {
1067 		return k->_key.hmac.size;
1068 	} else {
1069 		return 0;
1070 	}
1071 }
1072 
1073 void *
1074 ldns_key_external_key(const ldns_key *k)
1075 {
1076 	return k->_key.external_key;
1077 }
1078 
1079 uint32_t
1080 ldns_key_origttl(const ldns_key *k)
1081 {
1082 	return k->_extra.dnssec.orig_ttl;
1083 }
1084 
1085 uint16_t
1086 ldns_key_flags(const ldns_key *k)
1087 {
1088 	return k->_extra.dnssec.flags;
1089 }
1090 
1091 uint32_t
1092 ldns_key_inception(const ldns_key *k)
1093 {
1094 	return k->_extra.dnssec.inception;
1095 }
1096 
1097 uint32_t
1098 ldns_key_expiration(const ldns_key *k)
1099 {
1100 	return k->_extra.dnssec.expiration;
1101 }
1102 
1103 uint16_t
1104 ldns_key_keytag(const ldns_key *k)
1105 {
1106 	return k->_extra.dnssec.keytag;
1107 }
1108 
1109 ldns_rdf *
1110 ldns_key_pubkey_owner(const ldns_key *k)
1111 {
1112 	return k->_pubkey_owner;
1113 }
1114 
1115 /* write */
1116 void
1117 ldns_key_list_set_use(ldns_key_list *keys, bool v)
1118 {
1119 	size_t i;
1120 
1121 	for (i = 0; i < ldns_key_list_key_count(keys); i++) {
1122 		ldns_key_set_use(ldns_key_list_key(keys, i), v);
1123 	}
1124 }
1125 
1126 void
1127 ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
1128 {
1129 	        key->_key_count = count;
1130 }
1131 
1132 bool
1133 ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
1134 {
1135         size_t key_count;
1136         ldns_key **keys;
1137 
1138         key_count = ldns_key_list_key_count(key_list);
1139 
1140         /* grow the array */
1141         keys = LDNS_XREALLOC(
1142                 key_list->_keys, ldns_key *, key_count + 1);
1143         if (!keys) {
1144                 return false;
1145         }
1146 
1147         /* add the new member */
1148         key_list->_keys = keys;
1149         key_list->_keys[key_count] = key;
1150 
1151         ldns_key_list_set_key_count(key_list, key_count + 1);
1152         return true;
1153 }
1154 
1155 ldns_key *
1156 ldns_key_list_pop_key(ldns_key_list *key_list)
1157 {
1158         size_t key_count;
1159         ldns_key *pop;
1160 
1161 	if (!key_list) {
1162 		return NULL;
1163 	}
1164 
1165         key_count = ldns_key_list_key_count(key_list);
1166         if (key_count == 0) {
1167                 return NULL;
1168         }
1169 
1170         pop = ldns_key_list_key(key_list, key_count);
1171 
1172         /* shrink the array */
1173         key_list->_keys = LDNS_XREALLOC(
1174                 key_list->_keys, ldns_key *, key_count - 1);
1175 
1176         ldns_key_list_set_key_count(key_list, key_count - 1);
1177 
1178         return pop;
1179 }
1180 
1181 #ifdef HAVE_SSL
1182 static bool
1183 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
1184 {
1185 	int i,j;
1186 
1187 	if (!k) {
1188 		return false;
1189 	}
1190 
1191 	if (BN_num_bytes(k->e) <= 256) {
1192 		/* normally only this path is executed (small factors are
1193 		 * more common
1194 		 */
1195 		data[0] = (unsigned char) BN_num_bytes(k->e);
1196 		i = BN_bn2bin(k->e, data + 1);
1197 		j = BN_bn2bin(k->n, data + i + 1);
1198 		*size = (uint16_t) i + j;
1199 	} else if (BN_num_bytes(k->e) <= 65536) {
1200 		data[0] = 0;
1201 		/* BN_bn2bin does bigendian, _uint16 also */
1202 		ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e));
1203 
1204 		BN_bn2bin(k->e, data + 3);
1205 		BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
1206 		*size = (uint16_t) BN_num_bytes(k->n) + 6;
1207 	} else {
1208 		return false;
1209 	}
1210 	return true;
1211 }
1212 
1213 static bool
1214 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
1215 {
1216 	uint8_t T;
1217 
1218 	if (!k) {
1219 		return false;
1220 	}
1221 
1222 	/* See RFC2536 */
1223 	*size = (uint16_t)BN_num_bytes(k->g);
1224 	T = (*size - 64) / 8;
1225 	memcpy(data, &T, 1);
1226 
1227 	if (T > 8) {
1228 		fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
1229 		fprintf(stderr, " not implemented\n");
1230 		return false;
1231 	}
1232 
1233 	/* size = 64 + (T * 8); */
1234 	data[0] = (unsigned char)T;
1235 	BN_bn2bin(k->q, data + 1 ); 		/* 20 octects */
1236 	BN_bn2bin(k->p, data + 21 ); 		/* offset octects */
1237 	BN_bn2bin(k->g, data + 21 + *size); 	/* offset octets */
1238 	BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */
1239 	*size = 21 + (*size * 3);
1240 	return true;
1241 }
1242 
1243 #ifdef USE_GOST
1244 static bool
1245 ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
1246 {
1247 	int i;
1248 	unsigned char* pp = NULL;
1249 	if(i2d_PUBKEY(k, &pp) != 37 + 64) {
1250 		/* expect 37 byte(ASN header) and 64 byte(X and Y) */
1251 		CRYPTO_free(pp);
1252 		return false;
1253 	}
1254 	/* omit ASN header */
1255 	for(i=0; i<64; i++)
1256 		data[i] = pp[i+37];
1257 	CRYPTO_free(pp);
1258 	*size = 64;
1259 	return true;
1260 }
1261 #endif /* USE_GOST */
1262 #endif /* HAVE_SSL */
1263 
1264 ldns_rr *
1265 ldns_key2rr(const ldns_key *k)
1266 {
1267 	/* this function will convert a the keydata contained in
1268 	 * rsa/dsa pointers to a DNSKEY rr. It will fill in as
1269 	 * much as it can, but it does not know about key-flags
1270 	 * for instance
1271 	 */
1272 	ldns_rr *pubkey;
1273 	ldns_rdf *keybin;
1274 	unsigned char *bin = NULL;
1275 	uint16_t size = 0;
1276 #ifdef HAVE_SSL
1277 	RSA *rsa = NULL;
1278 	DSA *dsa = NULL;
1279 #endif /* HAVE_SSL */
1280 #ifdef USE_ECDSA
1281         EC_KEY* ec;
1282 #endif
1283 	int internal_data = 0;
1284 
1285 	pubkey = ldns_rr_new();
1286 	if (!k) {
1287 		return NULL;
1288 	}
1289 
1290 	switch (ldns_key_algorithm(k)) {
1291 	case LDNS_SIGN_HMACMD5:
1292 	case LDNS_SIGN_HMACSHA1:
1293 	case LDNS_SIGN_HMACSHA256:
1294 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
1295         	break;
1296 	default:
1297 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
1298 		break;
1299         }
1300 	/* zero-th rdf - flags */
1301 	ldns_rr_push_rdf(pubkey,
1302 			ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
1303 				ldns_key_flags(k)));
1304 	/* first - proto */
1305 	ldns_rr_push_rdf(pubkey,
1306 			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
1307 
1308 	if (ldns_key_pubkey_owner(k)) {
1309 		ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
1310 	}
1311 
1312 	/* third - da algorithm */
1313 	switch(ldns_key_algorithm(k)) {
1314 		case LDNS_RSAMD5:
1315 		case LDNS_RSASHA1:
1316 		case LDNS_RSASHA1_NSEC3:
1317 		case LDNS_RSASHA256:
1318 		case LDNS_RSASHA512:
1319 			ldns_rr_push_rdf(pubkey,
1320 						  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1321 #ifdef HAVE_SSL
1322 			rsa =  ldns_key_rsa_key(k);
1323 			if (rsa) {
1324 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1325 				if (!bin) {
1326 					return NULL;
1327 				}
1328 				if (!ldns_key_rsa2bin(bin, rsa, &size)) {
1329 					return NULL;
1330 				}
1331 				RSA_free(rsa);
1332 				internal_data = 1;
1333 			}
1334 #endif
1335 			size++;
1336 			break;
1337 		case LDNS_SIGN_DSA:
1338 			ldns_rr_push_rdf(pubkey,
1339 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
1340 #ifdef HAVE_SSL
1341 			dsa = ldns_key_dsa_key(k);
1342 			if (dsa) {
1343 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1344 				if (!bin) {
1345 					return NULL;
1346 				}
1347 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1348 					return NULL;
1349 				}
1350 				DSA_free(dsa);
1351 				internal_data = 1;
1352 			}
1353 #endif /* HAVE_SSL */
1354 			break;
1355 		case LDNS_DSA_NSEC3:
1356 			ldns_rr_push_rdf(pubkey,
1357 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
1358 #ifdef HAVE_SSL
1359 			dsa = ldns_key_dsa_key(k);
1360 			if (dsa) {
1361 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1362 				if (!bin) {
1363 					return NULL;
1364 				}
1365 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1366 					return NULL;
1367 				}
1368 				DSA_free(dsa);
1369 				internal_data = 1;
1370 			}
1371 #endif /* HAVE_SSL */
1372 			break;
1373 		case LDNS_SIGN_ECC_GOST:
1374 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
1375 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1376 #if defined(HAVE_SSL) && defined(USE_GOST)
1377 			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1378 			if (!bin)
1379 				return NULL;
1380 			if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
1381 				return NULL;
1382 			}
1383 			internal_data = 1;
1384 #endif /* HAVE_SSL and USE_GOST */
1385 			break;
1386 #ifdef USE_ECDSA
1387                 case LDNS_SIGN_ECDSAP256SHA256:
1388                 case LDNS_SIGN_ECDSAP384SHA384:
1389 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
1390 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1391                         bin = NULL;
1392                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
1393                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
1394                         size = i2o_ECPublicKey(ec, NULL);
1395                         if(!i2o_ECPublicKey(ec, &bin))
1396                                 return NULL;
1397 			if(size > 1) {
1398 				/* move back one byte to shave off the 0x02
1399 				 * 'uncompressed' indicator that openssl made
1400 				 * Actually its 0x04 (from implementation).
1401 				 */
1402 				assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
1403 				size -= 1;
1404 				memmove(bin, bin+1, size);
1405 			}
1406                         /* down the reference count for ec, its still assigned
1407                          * to the pkey */
1408                         EC_KEY_free(ec);
1409 			internal_data = 1;
1410                         break;
1411 #endif
1412 		case LDNS_SIGN_HMACMD5:
1413 		case LDNS_SIGN_HMACSHA1:
1414 		case LDNS_SIGN_HMACSHA256:
1415 			bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
1416 			if (!bin) {
1417 				return NULL;
1418 			}
1419 			ldns_rr_push_rdf(pubkey,
1420 			                 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
1421 			                 ldns_key_algorithm(k)));
1422 			size = ldns_key_hmac_size(k);
1423 			memcpy(bin, ldns_key_hmac_key(k), size);
1424 			internal_data = 1;
1425 			break;
1426 	}
1427 	/* fourth the key bin material */
1428 	if (internal_data) {
1429 		keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
1430 		LDNS_FREE(bin);
1431 		ldns_rr_push_rdf(pubkey, keybin);
1432 	}
1433 	return pubkey;
1434 }
1435 
1436 void
1437 ldns_key_free(ldns_key *key)
1438 {
1439 	LDNS_FREE(key);
1440 }
1441 
1442 void
1443 ldns_key_deep_free(ldns_key *key)
1444 {
1445 	if (ldns_key_pubkey_owner(key)) {
1446 		ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
1447 	}
1448 #ifdef HAVE_SSL
1449 	if (ldns_key_evp_key(key)) {
1450 		EVP_PKEY_free(ldns_key_evp_key(key));
1451 	}
1452 #endif /* HAVE_SSL */
1453 	if (ldns_key_hmac_key(key)) {
1454 		free(ldns_key_hmac_key(key));
1455 	}
1456 	LDNS_FREE(key);
1457 }
1458 
1459 void
1460 ldns_key_list_free(ldns_key_list *key_list)
1461 {
1462 	size_t i;
1463 	for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1464 		ldns_key_deep_free(ldns_key_list_key(key_list, i));
1465 	}
1466 	LDNS_FREE(key_list->_keys);
1467 	LDNS_FREE(key_list);
1468 }
1469 
1470 ldns_rr *
1471 ldns_read_anchor_file(const char *filename)
1472 {
1473 	FILE *fp;
1474 	/*char line[LDNS_MAX_PACKETLEN];*/
1475 	char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
1476 	int c;
1477 	size_t i = 0;
1478 	ldns_rr *r;
1479 	ldns_status status;
1480 
1481 	fp = fopen(filename, "r");
1482 	if (!fp) {
1483 		fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
1484 		LDNS_FREE(line);
1485 		return NULL;
1486 	}
1487 
1488 	while ((c = fgetc(fp)) && i < LDNS_MAX_PACKETLEN && c != EOF) {
1489 		line[i] = c;
1490 		i++;
1491 	}
1492 	line[i] = '\0';
1493 
1494 	fclose(fp);
1495 
1496 	if (i <= 0) {
1497 		fprintf(stderr, "nothing read from %s", filename);
1498 		LDNS_FREE(line);
1499 		return NULL;
1500 	} else {
1501 		status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
1502 		if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
1503 			LDNS_FREE(line);
1504 			return r;
1505 		} else {
1506 			fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
1507 			LDNS_FREE(line);
1508 			return NULL;
1509 		}
1510 	}
1511 }
1512 
1513 char *
1514 ldns_key_get_file_base_name(ldns_key *key)
1515 {
1516 	ldns_buffer *buffer;
1517 	char *file_base_name;
1518 
1519 	buffer = ldns_buffer_new(255);
1520 	ldns_buffer_printf(buffer, "K");
1521 	(void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
1522 	ldns_buffer_printf(buffer,
1523 	                   "+%03u+%05u",
1524 			   ldns_key_algorithm(key),
1525 			   ldns_key_keytag(key));
1526 	file_base_name = strdup(ldns_buffer_export(buffer));
1527 	ldns_buffer_free(buffer);
1528 	return file_base_name;
1529 }
1530 
1531 int ldns_key_algo_supported(int algo)
1532 {
1533 	ldns_lookup_table *lt = ldns_signing_algorithms;
1534 	while(lt->name) {
1535 		if(lt->id == algo)
1536 			return 1;
1537 		lt++;
1538 	}
1539 	return 0;
1540 }
1541 
1542 ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
1543 {
1544         /* list of (signing algorithm id, alias_name) */
1545         ldns_lookup_table aliases[] = {
1546                 /* from bind dnssec-keygen */
1547                 {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
1548                 {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
1549                 {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
1550                 /* old ldns usage, now RFC names */
1551                 {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
1552                 {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
1553 #ifdef USE_GOST
1554                 {LDNS_SIGN_ECC_GOST, "GOST"},
1555 #endif
1556                 /* compat with possible output */
1557                 {LDNS_DH, "DH"},
1558                 {LDNS_ECC, "ECC"},
1559                 {LDNS_INDIRECT, "INDIRECT"},
1560                 {LDNS_PRIVATEDNS, "PRIVATEDNS"},
1561                 {LDNS_PRIVATEOID, "PRIVATEOID"},
1562                 {0, NULL}};
1563         ldns_lookup_table* lt = ldns_signing_algorithms;
1564         while(lt->name) {
1565                 if(strcasecmp(lt->name, name) == 0)
1566                         return lt->id;
1567                 lt++;
1568         }
1569         lt = aliases;
1570         while(lt->name) {
1571                 if(strcasecmp(lt->name, name) == 0)
1572                         return lt->id;
1573                 lt++;
1574         }
1575         if(atoi(name) != 0)
1576                 return atoi(name);
1577         return 0;
1578 }
1579