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