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