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