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