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