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