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