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