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