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