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