File Coverage

src/ldns/keys.c
Criterion Covered Total %
statement 16 805 1.9
branch 7 336 2.0
condition n/a
subroutine n/a
pod n/a
total 23 1141 2.0


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