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