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);
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 
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 # ifdef STDERR_MSGS
372  fprintf(stderr, "Warning: SHA256 not compiled into this ");
373  fprintf(stderr, "version of ldns\n");
374 # endif
375 #endif
376  }
377  if (strncmp(d, "10 RSASHA512", 3) == 0) {
378 #ifdef USE_SHA2
379  alg = LDNS_SIGN_RSASHA512;
380 #else
381 # ifdef STDERR_MSGS
382  fprintf(stderr, "Warning: SHA512 not compiled into this ");
383  fprintf(stderr, "version of ldns\n");
384 # endif
385 #endif
386  }
387  if (strncmp(d, "12 ECC-GOST", 3) == 0) {
388 #ifdef USE_GOST
389  alg = LDNS_SIGN_ECC_GOST;
390 #else
391 # ifdef STDERR_MSGS
392  fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
393  fprintf(stderr, "version of ldns, use --enable-gost\n");
394 # endif
395 #endif
396  }
397  if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
398 #ifdef USE_ECDSA
400 #else
401 # ifdef STDERR_MSGS
402  fprintf(stderr, "Warning: ECDSA not compiled into this ");
403  fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
404 # endif
405 #endif
406  }
407  if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
408 #ifdef USE_ECDSA
410 #else
411 # ifdef STDERR_MSGS
412  fprintf(stderr, "Warning: ECDSA not compiled into this ");
413  fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
414 # endif
415 #endif
416  }
417  if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
418  alg = LDNS_SIGN_HMACMD5;
419  }
420  if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
421  alg = LDNS_SIGN_HMACSHA1;
422  }
423  if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
424  alg = LDNS_SIGN_HMACSHA256;
425  }
426 
427  LDNS_FREE(d);
428 
429  switch(alg) {
430  case LDNS_SIGN_RSAMD5:
431  case LDNS_SIGN_RSASHA1:
433 #ifdef USE_SHA2
434  case LDNS_SIGN_RSASHA256:
435  case LDNS_SIGN_RSASHA512:
436 #endif
437  ldns_key_set_algorithm(k, alg);
438 #ifdef HAVE_SSL
439  rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
440  if (!rsa) {
441  ldns_key_free(k);
442  return LDNS_STATUS_ERR;
443  }
444  ldns_key_assign_rsa_key(k, rsa);
445 #endif /* HAVE_SSL */
446  break;
447  case LDNS_SIGN_DSA:
448  case LDNS_SIGN_DSA_NSEC3:
449  ldns_key_set_algorithm(k, alg);
450 #ifdef HAVE_SSL
451  dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
452  if (!dsa) {
453  ldns_key_free(k);
454  return LDNS_STATUS_ERR;
455  }
456  ldns_key_assign_dsa_key(k, dsa);
457 #endif /* HAVE_SSL */
458  break;
459  case LDNS_SIGN_HMACMD5:
460  case LDNS_SIGN_HMACSHA1:
462  ldns_key_set_algorithm(k, alg);
463 #ifdef HAVE_SSL
464  hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
465  if (!hmac) {
466  ldns_key_free(k);
467  return LDNS_STATUS_ERR;
468  }
469  ldns_key_set_hmac_size(k, hmac_size);
470  ldns_key_set_hmac_key(k, hmac);
471 #endif /* HAVE_SSL */
472  break;
473  case LDNS_SIGN_ECC_GOST:
474  ldns_key_set_algorithm(k, alg);
475 #if defined(HAVE_SSL) && defined(USE_GOST)
477  ldns_key_free(k);
479  }
481  ldns_key_new_frm_fp_gost_l(fp, line_nr));
482 #ifndef S_SPLINT_S
483  if(!k->_key.key) {
484  ldns_key_free(k);
485  return LDNS_STATUS_ERR;
486  }
487 #endif /* splint */
488 #endif
489  break;
490 #ifdef USE_ECDSA
493  ldns_key_set_algorithm(k, alg);
495  ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
496 #ifndef S_SPLINT_S
497  if(!k->_key.key) {
498  ldns_key_free(k);
499  return LDNS_STATUS_ERR;
500  }
501 #endif /* splint */
502  break;
503 #endif
504  default:
505  ldns_key_free(k);
507  }
508  key_rr = ldns_key2rr(k);
510  ldns_rr_free(key_rr);
511 
512  if (key) {
513  *key = k;
514  return LDNS_STATUS_OK;
515  }
516  ldns_key_free(k);
517  return LDNS_STATUS_ERR;
518 }
519 
520 #ifdef HAVE_SSL
521 RSA *
523 {
524  return ldns_key_new_frm_fp_rsa_l(f, NULL);
525 }
526 
527 RSA *
528 ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
529 {
530  /* we parse
531  * Modulus:
532  * PublicExponent:
533  * PrivateExponent:
534  * Prime1:
535  * Prime2:
536  * Exponent1:
537  * Exponent2:
538  * Coefficient:
539  *
540  * man 3 RSA:
541  *
542  * struct
543  * {
544  * BIGNUM *n; // public modulus
545  * BIGNUM *e; // public exponent
546  * BIGNUM *d; // private exponent
547  * BIGNUM *p; // secret prime factor
548  * BIGNUM *q; // secret prime factor
549  * BIGNUM *dmp1; // d mod (p-1)
550  * BIGNUM *dmq1; // d mod (q-1)
551  * BIGNUM *iqmp; // q^-1 mod p
552  * // ...
553  *
554  */
555  char *d;
556  RSA *rsa;
557  uint8_t *buf;
558  int i;
559 
560  d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
561  buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
562  rsa = RSA_new();
563  if (!d || !rsa || !buf) {
564  goto error;
565  }
566 
567  /* I could use functions again, but that seems an overkill,
568  * allthough this also looks tedious
569  */
570 
571  /* Modules, rsa->n */
572  if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
573  goto error;
574  }
575  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
576 #ifndef S_SPLINT_S
577  rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
578  if (!rsa->n) {
579  goto error;
580  }
581 
582  /* PublicExponent, rsa->e */
583  if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
584  goto error;
585  }
586  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
587  rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
588  if (!rsa->e) {
589  goto error;
590  }
591 
592  /* PrivateExponent, rsa->d */
593  if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
594  goto error;
595  }
596  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
597  rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
598  if (!rsa->d) {
599  goto error;
600  }
601 
602  /* Prime1, rsa->p */
603  if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
604  goto error;
605  }
606  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
607  rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
608  if (!rsa->p) {
609  goto error;
610  }
611 
612  /* Prime2, rsa->q */
613  if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
614  goto error;
615  }
616  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
617  rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
618  if (!rsa->q) {
619  goto error;
620  }
621 
622  /* Exponent1, rsa->dmp1 */
623  if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
624  goto error;
625  }
626  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
627  rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
628  if (!rsa->dmp1) {
629  goto error;
630  }
631 
632  /* Exponent2, rsa->dmq1 */
633  if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
634  goto error;
635  }
636  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
637  rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
638  if (!rsa->dmq1) {
639  goto error;
640  }
641 
642  /* Coefficient, rsa->iqmp */
643  if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
644  goto error;
645  }
646  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
647  rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
648  if (!rsa->iqmp) {
649  goto error;
650  }
651 #endif /* splint */
652 
653  LDNS_FREE(buf);
654  LDNS_FREE(d);
655  return rsa;
656 
657 error:
658  RSA_free(rsa);
659  LDNS_FREE(d);
660  LDNS_FREE(buf);
661  return NULL;
662 }
663 
664 DSA *
666 {
667  return ldns_key_new_frm_fp_dsa_l(f, NULL);
668 }
669 
670 DSA *
671 ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
672 {
673  int i;
674  char *d;
675  DSA *dsa;
676  uint8_t *buf;
677 
678  d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
679  buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
680  dsa = DSA_new();
681  if (!d || !dsa || !buf) {
682  goto error;
683  }
684 
685  /* the line parser removes the () from the input... */
686 
687  /* Prime, dsa->p */
688  if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
689  goto error;
690  }
691  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
692 #ifndef S_SPLINT_S
693  dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
694  if (!dsa->p) {
695  goto error;
696  }
697 
698  /* Subprime, dsa->q */
699  if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
700  goto error;
701  }
702  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
703  dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
704  if (!dsa->q) {
705  goto error;
706  }
707 
708  /* Base, dsa->g */
709  if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
710  goto error;
711  }
712  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
713  dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
714  if (!dsa->g) {
715  goto error;
716  }
717 
718  /* Private key, dsa->priv_key */
719  if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
720  goto error;
721  }
722  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
723  dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
724  if (!dsa->priv_key) {
725  goto error;
726  }
727 
728  /* Public key, dsa->priv_key */
729  if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
730  goto error;
731  }
732  i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
733  dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
734  if (!dsa->pub_key) {
735  goto error;
736  }
737 #endif /* splint */
738 
739  LDNS_FREE(buf);
740  LDNS_FREE(d);
741 
742  return dsa;
743 
744 error:
745  LDNS_FREE(d);
746  LDNS_FREE(buf);
747  DSA_free(dsa);
748  return NULL;
749 }
750 
751 unsigned char *
752 ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
753 {
754  return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
755 }
756 
757 unsigned char *
759  , ATTR_UNUSED(int *line_nr)
760  , size_t *hmac_size
761  )
762 {
763  size_t i, bufsz;
764  char d[LDNS_MAX_LINELEN];
765  unsigned char *buf = NULL;
766 
767  if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
768  goto error;
769  }
770  bufsz = ldns_b64_ntop_calculate_size(strlen(d));
771  buf = LDNS_XMALLOC(unsigned char, bufsz);
772  i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
773 
774  *hmac_size = i;
775  return buf;
776 
777  error:
778  LDNS_FREE(buf);
779  *hmac_size = 0;
780  return NULL;
781 }
782 #endif /* HAVE_SSL */
783 
784 #ifdef USE_GOST
785 static EVP_PKEY*
786 ldns_gen_gost_key(void)
787 {
788  EVP_PKEY_CTX* ctx;
789  EVP_PKEY* p = NULL;
790  int gost_id = ldns_key_EVP_load_gost_id();
791  if(!gost_id)
792  return NULL;
793  ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
794  if(!ctx) {
795  /* the id should be available now */
796  return NULL;
797  }
798  if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
799  /* cannot set paramset */
800  EVP_PKEY_CTX_free(ctx);
801  return NULL;
802  }
803 
804  if(EVP_PKEY_keygen_init(ctx) <= 0) {
805  EVP_PKEY_CTX_free(ctx);
806  return NULL;
807  }
808  if(EVP_PKEY_keygen(ctx, &p) <= 0) {
809  EVP_PKEY_free(p);
810  EVP_PKEY_CTX_free(ctx);
811  return NULL;
812  }
813  EVP_PKEY_CTX_free(ctx);
814  return p;
815 }
816 #endif
817 
818 ldns_key *
820 {
821  ldns_key *k;
822 #ifdef HAVE_SSL
823  DSA *d;
824  RSA *r;
825 # ifdef USE_ECDSA
826  EC_KEY *ec = NULL;
827 # endif
828 #else
829  int i;
830  uint16_t offset = 0;
831 #endif
832  unsigned char *hmac;
833 
834  k = ldns_key_new();
835  if (!k) {
836  return NULL;
837  }
838  switch(alg) {
839  case LDNS_SIGN_RSAMD5:
840  case LDNS_SIGN_RSASHA1:
842  case LDNS_SIGN_RSASHA256:
843  case LDNS_SIGN_RSASHA512:
844 #ifdef HAVE_SSL
845  r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
846  if(!r) {
847  ldns_key_free(k);
848  return NULL;
849  }
850  if (RSA_check_key(r) != 1) {
851  ldns_key_free(k);
852  return NULL;
853  }
854  ldns_key_set_rsa_key(k, r);
855  RSA_free(r);
856 #endif /* HAVE_SSL */
857  break;
858  case LDNS_SIGN_DSA:
859  case LDNS_SIGN_DSA_NSEC3:
860 #ifdef HAVE_SSL
861  d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
862  if (!d) {
863  ldns_key_free(k);
864  return NULL;
865  }
866  if (DSA_generate_key(d) != 1) {
867  ldns_key_free(k);
868  return NULL;
869  }
870  ldns_key_set_dsa_key(k, d);
871  DSA_free(d);
872 #endif /* HAVE_SSL */
873  break;
874  case LDNS_SIGN_HMACMD5:
875  case LDNS_SIGN_HMACSHA1:
877 #ifdef HAVE_SSL
878 #ifndef S_SPLINT_S
879  k->_key.key = NULL;
880 #endif /* splint */
881 #endif /* HAVE_SSL */
882  size = size / 8;
883  ldns_key_set_hmac_size(k, size);
884 
885  hmac = LDNS_XMALLOC(unsigned char, size);
886  if(!hmac) {
887  ldns_key_free(k);
888  return NULL;
889  }
890 #ifdef HAVE_SSL
891  if (RAND_bytes(hmac, (int) size) != 1) {
892  LDNS_FREE(hmac);
893  ldns_key_free(k);
894  return NULL;
895  }
896 #else
897  while (offset + sizeof(i) < size) {
898  i = random();
899  memcpy(&hmac[offset], &i, sizeof(i));
900  offset += sizeof(i);
901  }
902  if (offset < size) {
903  i = random();
904  memcpy(&hmac[offset], &i, size - offset);
905  }
906 #endif /* HAVE_SSL */
907  ldns_key_set_hmac_key(k, hmac);
908 
909  ldns_key_set_flags(k, 0);
910  break;
911  case LDNS_SIGN_ECC_GOST:
912 #if defined(HAVE_SSL) && defined(USE_GOST)
913  ldns_key_set_evp_key(k, ldns_gen_gost_key());
914 #ifndef S_SPLINT_S
915  if(!k->_key.key) {
916  ldns_key_free(k);
917  return NULL;
918  }
919 #endif /* splint */
920 #else
921  ldns_key_free(k);
922  return NULL;
923 #endif /* HAVE_SSL and USE_GOST */
924  break;
927 #ifdef USE_ECDSA
928  if(alg == LDNS_SIGN_ECDSAP256SHA256)
929  ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
930  else if(alg == LDNS_SIGN_ECDSAP384SHA384)
931  ec = EC_KEY_new_by_curve_name(NID_secp384r1);
932  if(!ec) {
933  ldns_key_free(k);
934  return NULL;
935  }
936  if(!EC_KEY_generate_key(ec)) {
937  ldns_key_free(k);
938  EC_KEY_free(ec);
939  return NULL;
940  }
941 #ifndef S_SPLINT_S
942  k->_key.key = EVP_PKEY_new();
943  if(!k->_key.key) {
944  ldns_key_free(k);
945  EC_KEY_free(ec);
946  return NULL;
947  }
948  if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
949  ldns_key_free(k);
950  EC_KEY_free(ec);
951  return NULL;
952  }
953 #endif /* splint */
954 #else
955  ldns_key_free(k);
956  return NULL;
957 #endif /* ECDSA */
958  break;
959  }
960  ldns_key_set_algorithm(k, alg);
961  return k;
962 }
963 
964 void
965 ldns_key_print(FILE *output, const ldns_key *k)
966 {
967  char *str = ldns_key2str(k);
968  if (str) {
969  fprintf(output, "%s", str);
970  } else {
971  fprintf(output, "Unable to convert private key to string\n");
972  }
973  LDNS_FREE(str);
974 }
975 
976 
977 void
979 {
980  k->_alg = l;
981 }
982 
983 void
985 {
986  k->_extra.dnssec.flags = f;
987 }
988 
989 #ifdef HAVE_SSL
990 #ifndef S_SPLINT_S
991 void
993 {
994  k->_key.key = e;
995 }
996 
997 void
999 {
1000  EVP_PKEY *key = EVP_PKEY_new();
1001  EVP_PKEY_set1_RSA(key, r);
1002  k->_key.key = key;
1003 }
1004 
1005 void
1007 {
1008  EVP_PKEY *key = EVP_PKEY_new();
1009  EVP_PKEY_set1_DSA(key, d);
1010  k->_key.key = key;
1011 }
1012 
1013 void
1015 {
1016  EVP_PKEY *key = EVP_PKEY_new();
1017  EVP_PKEY_assign_RSA(key, r);
1018  k->_key.key = key;
1019 }
1020 
1021 void
1023 {
1024  EVP_PKEY *key = EVP_PKEY_new();
1025  EVP_PKEY_assign_DSA(key, d);
1026  k->_key.key = key;
1027 }
1028 #endif /* splint */
1029 #endif /* HAVE_SSL */
1030 
1031 void
1032 ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
1033 {
1034  k->_key.hmac.key = hmac;
1035 }
1036 
1037 void
1038 ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
1039 {
1040  k->_key.hmac.size = hmac_size;
1041 }
1042 
1043 void
1044 ldns_key_set_external_key(ldns_key *k, void *external_key)
1045 {
1046  k->_key.external_key = external_key;
1047 }
1048 
1049 void
1051 {
1052  k->_extra.dnssec.orig_ttl = t;
1053 }
1054 
1055 void
1057 {
1058  k->_extra.dnssec.inception = i;
1059 }
1060 
1061 void
1063 {
1064  k->_extra.dnssec.expiration = e;
1065 }
1066 
1067 void
1069 {
1070  k->_pubkey_owner = r;
1071 }
1072 
1073 void
1075 {
1076  k->_extra.dnssec.keytag = tag;
1077 }
1078 
1079 /* read */
1080 size_t
1082 {
1083  return key_list->_key_count;
1084 }
1085 
1086 ldns_key *
1087 ldns_key_list_key(const ldns_key_list *key, size_t nr)
1088 {
1089  if (nr < ldns_key_list_key_count(key)) {
1090  return key->_keys[nr];
1091  } else {
1092  return NULL;
1093  }
1094 }
1095 
1098 {
1099  return k->_alg;
1100 }
1101 
1102 void
1104 {
1105  if (k) {
1106  k->_use = v;
1107  }
1108 }
1109 
1110 bool
1112 {
1113  if (k) {
1114  return k->_use;
1115  }
1116  return false;
1117 }
1118 
1119 #ifdef HAVE_SSL
1120 #ifndef S_SPLINT_S
1121 EVP_PKEY *
1123 {
1124  return k->_key.key;
1125 }
1126 
1127 RSA *
1129 {
1130  if (k->_key.key) {
1131  return EVP_PKEY_get1_RSA(k->_key.key);
1132  } else {
1133  return NULL;
1134  }
1135 }
1136 
1137 DSA *
1139 {
1140  if (k->_key.key) {
1141  return EVP_PKEY_get1_DSA(k->_key.key);
1142  } else {
1143  return NULL;
1144  }
1145 }
1146 #endif /* splint */
1147 #endif /* HAVE_SSL */
1148 
1149 unsigned char *
1151 {
1152  if (k->_key.hmac.key) {
1153  return k->_key.hmac.key;
1154  } else {
1155  return NULL;
1156  }
1157 }
1158 
1159 size_t
1161 {
1162  if (k->_key.hmac.size) {
1163  return k->_key.hmac.size;
1164  } else {
1165  return 0;
1166  }
1167 }
1168 
1169 void *
1171 {
1172  return k->_key.external_key;
1173 }
1174 
1175 uint32_t
1177 {
1178  return k->_extra.dnssec.orig_ttl;
1179 }
1180 
1181 uint16_t
1183 {
1184  return k->_extra.dnssec.flags;
1185 }
1186 
1187 uint32_t
1189 {
1190  return k->_extra.dnssec.inception;
1191 }
1192 
1193 uint32_t
1195 {
1196  return k->_extra.dnssec.expiration;
1197 }
1198 
1199 uint16_t
1201 {
1202  return k->_extra.dnssec.keytag;
1203 }
1204 
1205 ldns_rdf *
1207 {
1208  return k->_pubkey_owner;
1209 }
1210 
1211 /* write */
1212 void
1214 {
1215  size_t i;
1216 
1217  for (i = 0; i < ldns_key_list_key_count(keys); i++) {
1218  ldns_key_set_use(ldns_key_list_key(keys, i), v);
1219  }
1220 }
1221 
1222 void
1224 {
1225  key->_key_count = count;
1226 }
1227 
1228 bool
1230 {
1231  size_t key_count;
1232  ldns_key **keys;
1233 
1234  key_count = ldns_key_list_key_count(key_list);
1235 
1236  /* grow the array */
1237  keys = LDNS_XREALLOC(
1238  key_list->_keys, ldns_key *, key_count + 1);
1239  if (!keys) {
1240  return false;
1241  }
1242 
1243  /* add the new member */
1244  key_list->_keys = keys;
1245  key_list->_keys[key_count] = key;
1246 
1247  ldns_key_list_set_key_count(key_list, key_count + 1);
1248  return true;
1249 }
1250 
1251 ldns_key *
1253 {
1254  size_t key_count;
1255  ldns_key** a;
1256  ldns_key *pop;
1257 
1258  if (!key_list) {
1259  return NULL;
1260  }
1261 
1262  key_count = ldns_key_list_key_count(key_list);
1263  if (key_count == 0) {
1264  return NULL;
1265  }
1266 
1267  pop = ldns_key_list_key(key_list, key_count);
1268 
1269  /* shrink the array */
1270  a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
1271  if(a) {
1272  key_list->_keys = a;
1273  }
1274 
1275  ldns_key_list_set_key_count(key_list, key_count - 1);
1276 
1277  return pop;
1278 }
1279 
1280 #ifdef HAVE_SSL
1281 #ifndef S_SPLINT_S
1282 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
1283 static bool
1284 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
1285 {
1286  int i,j;
1287 
1288  if (!k) {
1289  return false;
1290  }
1291 
1292  if (BN_num_bytes(k->e) <= 256) {
1293  /* normally only this path is executed (small factors are
1294  * more common
1295  */
1296  data[0] = (unsigned char) BN_num_bytes(k->e);
1297  i = BN_bn2bin(k->e, data + 1);
1298  j = BN_bn2bin(k->n, data + i + 1);
1299  *size = (uint16_t) i + j;
1300  } else if (BN_num_bytes(k->e) <= 65536) {
1301  data[0] = 0;
1302  /* BN_bn2bin does bigendian, _uint16 also */
1303  ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e));
1304 
1305  BN_bn2bin(k->e, data + 3);
1306  BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
1307  *size = (uint16_t) BN_num_bytes(k->n) + 6;
1308  } else {
1309  return false;
1310  }
1311  return true;
1312 }
1313 
1314 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
1315 static bool
1316 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
1317 {
1318  uint8_t T;
1319 
1320  if (!k) {
1321  return false;
1322  }
1323 
1324  /* See RFC2536 */
1325  *size = (uint16_t)BN_num_bytes(k->p);
1326  T = (*size - 64) / 8;
1327 
1328  if (T > 8) {
1329 #ifdef STDERR_MSGS
1330  fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
1331  fprintf(stderr, " not implemented\n");
1332 #endif
1333  return false;
1334  }
1335 
1336  /* size = 64 + (T * 8); */
1337  memset(data, 0, 21 + *size * 3);
1338  data[0] = (unsigned char)T;
1339  BN_bn2bin(k->q, data + 1 ); /* 20 octects */
1340  BN_bn2bin(k->p, data + 21 ); /* offset octects */
1341  BN_bn2bin(k->g, data + 21 + *size * 2 - BN_num_bytes(k->g));
1342  BN_bn2bin(k->pub_key,data + 21 + *size * 3 - BN_num_bytes(k->pub_key));
1343  *size = 21 + *size * 3;
1344  return true;
1345 }
1346 
1347 #ifdef USE_GOST
1348 static bool
1349 ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
1350 {
1351  int i;
1352  unsigned char* pp = NULL;
1353  if(i2d_PUBKEY(k, &pp) != 37 + 64) {
1354  /* expect 37 byte(ASN header) and 64 byte(X and Y) */
1355  CRYPTO_free(pp);
1356  return false;
1357  }
1358  /* omit ASN header */
1359  for(i=0; i<64; i++)
1360  data[i] = pp[i+37];
1361  CRYPTO_free(pp);
1362  *size = 64;
1363  return true;
1364 }
1365 #endif /* USE_GOST */
1366 #endif /* splint */
1367 #endif /* HAVE_SSL */
1368 
1369 ldns_rr *
1371 {
1372  /* this function will convert a the keydata contained in
1373  * rsa/dsa pointers to a DNSKEY rr. It will fill in as
1374  * much as it can, but it does not know about key-flags
1375  * for instance
1376  */
1377  ldns_rr *pubkey;
1378  ldns_rdf *keybin;
1379  unsigned char *bin = NULL;
1380  uint16_t size = 0;
1381 #ifdef HAVE_SSL
1382  RSA *rsa = NULL;
1383  DSA *dsa = NULL;
1384 #endif /* HAVE_SSL */
1385 #ifdef USE_ECDSA
1386  EC_KEY* ec;
1387 #endif
1388  int internal_data = 0;
1389 
1390  if (!k) {
1391  return NULL;
1392  }
1393  pubkey = ldns_rr_new();
1394 
1395  switch (ldns_key_algorithm(k)) {
1396  case LDNS_SIGN_HMACMD5:
1397  case LDNS_SIGN_HMACSHA1:
1398  case LDNS_SIGN_HMACSHA256:
1400  break;
1401  default:
1403  break;
1404  }
1405  /* zero-th rdf - flags */
1406  ldns_rr_push_rdf(pubkey,
1408  ldns_key_flags(k)));
1409  /* first - proto */
1410  ldns_rr_push_rdf(pubkey,
1412 
1413  if (ldns_key_pubkey_owner(k)) {
1415  }
1416 
1417  /* third - da algorithm */
1418  switch(ldns_key_algorithm(k)) {
1419  case LDNS_SIGN_RSAMD5:
1420  case LDNS_SIGN_RSASHA1:
1422  case LDNS_SIGN_RSASHA256:
1423  case LDNS_SIGN_RSASHA512:
1424  ldns_rr_push_rdf(pubkey,
1426 #ifdef HAVE_SSL
1427  rsa = ldns_key_rsa_key(k);
1428  if (rsa) {
1429  bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1430  if (!bin) {
1431  ldns_rr_free(pubkey);
1432  return NULL;
1433  }
1434  if (!ldns_key_rsa2bin(bin, rsa, &size)) {
1435  LDNS_FREE(bin);
1436  ldns_rr_free(pubkey);
1437  return NULL;
1438  }
1439  RSA_free(rsa);
1440  internal_data = 1;
1441  }
1442 #endif
1443  size++;
1444  break;
1445  case LDNS_SIGN_DSA:
1446  ldns_rr_push_rdf(pubkey,
1448 #ifdef HAVE_SSL
1449  dsa = ldns_key_dsa_key(k);
1450  if (dsa) {
1451  bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1452  if (!bin) {
1453  ldns_rr_free(pubkey);
1454  return NULL;
1455  }
1456  if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1457  LDNS_FREE(bin);
1458  ldns_rr_free(pubkey);
1459  return NULL;
1460  }
1461  DSA_free(dsa);
1462  internal_data = 1;
1463  }
1464 #endif /* HAVE_SSL */
1465  break;
1466  case LDNS_SIGN_DSA_NSEC3:
1467  ldns_rr_push_rdf(pubkey,
1469 #ifdef HAVE_SSL
1470  dsa = ldns_key_dsa_key(k);
1471  if (dsa) {
1472  bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1473  if (!bin) {
1474  ldns_rr_free(pubkey);
1475  return NULL;
1476  }
1477  if (!ldns_key_dsa2bin(bin, dsa, &size)) {
1478  LDNS_FREE(bin);
1479  ldns_rr_free(pubkey);
1480  return NULL;
1481  }
1482  DSA_free(dsa);
1483  internal_data = 1;
1484  }
1485 #endif /* HAVE_SSL */
1486  break;
1487  case LDNS_SIGN_ECC_GOST:
1490 #if defined(HAVE_SSL) && defined(USE_GOST)
1491  bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1492  if (!bin) {
1493  ldns_rr_free(pubkey);
1494  return NULL;
1495  }
1496 #ifndef S_SPLINT_S
1497  if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
1498  LDNS_FREE(bin);
1499  ldns_rr_free(pubkey);
1500  return NULL;
1501  }
1502 #endif /* splint */
1503  internal_data = 1;
1504 #else
1505  ldns_rr_free(pubkey);
1506  return NULL;
1507 #endif /* HAVE_SSL and USE_GOST */
1508  break;
1511 #ifdef USE_ECDSA
1514  bin = NULL;
1515 #ifndef S_SPLINT_S
1516  ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
1517 #endif
1518  EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
1519  size = (uint16_t)i2o_ECPublicKey(ec, NULL);
1520  if(!i2o_ECPublicKey(ec, &bin)) {
1521  EC_KEY_free(ec);
1522  ldns_rr_free(pubkey);
1523  return NULL;
1524  }
1525  if(size > 1) {
1526  /* move back one byte to shave off the 0x02
1527  * 'uncompressed' indicator that openssl made
1528  * Actually its 0x04 (from implementation).
1529  */
1530  assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
1531  size -= 1;
1532  memmove(bin, bin+1, size);
1533  }
1534  /* down the reference count for ec, its still assigned
1535  * to the pkey */
1536  EC_KEY_free(ec);
1537  internal_data = 1;
1538 #else
1539  ldns_rr_free(pubkey);
1540  return NULL;
1541 #endif /* ECDSA */
1542  break;
1543  case LDNS_SIGN_HMACMD5:
1544  case LDNS_SIGN_HMACSHA1:
1545  case LDNS_SIGN_HMACSHA256:
1546  bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
1547  if (!bin) {
1548  ldns_rr_free(pubkey);
1549  return NULL;
1550  }
1551  ldns_rr_push_rdf(pubkey,
1553  ldns_key_algorithm(k)));
1554  size = ldns_key_hmac_size(k);
1555  memcpy(bin, ldns_key_hmac_key(k), size);
1556  internal_data = 1;
1557  break;
1558  }
1559  /* fourth the key bin material */
1560  if (internal_data) {
1561  keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
1562  LDNS_FREE(bin);
1563  ldns_rr_push_rdf(pubkey, keybin);
1564  }
1565  return pubkey;
1566 }
1567 
1568 void
1570 {
1571  LDNS_FREE(key);
1572 }
1573 
1574 void
1576 {
1577  unsigned char* hmac;
1578  if (ldns_key_pubkey_owner(key)) {
1580  }
1581 #ifdef HAVE_SSL
1582  if (ldns_key_evp_key(key)) {
1583  EVP_PKEY_free(ldns_key_evp_key(key));
1584  }
1585 #endif /* HAVE_SSL */
1586  if (ldns_key_hmac_key(key)) {
1587  hmac = ldns_key_hmac_key(key);
1588  LDNS_FREE(hmac);
1589  }
1590  LDNS_FREE(key);
1591 }
1592 
1593 void
1595 {
1596  size_t i;
1597  for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1598  ldns_key_deep_free(ldns_key_list_key(key_list, i));
1599  }
1600  LDNS_FREE(key_list->_keys);
1601  LDNS_FREE(key_list);
1602 }
1603 
1604 ldns_rr *
1605 ldns_read_anchor_file(const char *filename)
1606 {
1607  FILE *fp;
1608  /*char line[LDNS_MAX_PACKETLEN];*/
1609  char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
1610  int c;
1611  size_t i = 0;
1612  ldns_rr *r;
1613  ldns_status status;
1614  if(!line) {
1615  return NULL;
1616  }
1617 
1618  fp = fopen(filename, "r");
1619  if (!fp) {
1620 #ifdef STDERR_MSGS
1621  fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
1622 #endif
1623  LDNS_FREE(line);
1624  return NULL;
1625  }
1626 
1627  while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
1628  line[i] = c;
1629  i++;
1630  }
1631  line[i] = '\0';
1632 
1633  fclose(fp);
1634 
1635  if (i <= 0) {
1636 #ifdef STDERR_MSGS
1637  fprintf(stderr, "nothing read from %s", filename);
1638 #endif
1639  LDNS_FREE(line);
1640  return NULL;
1641  } else {
1642  status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
1644  LDNS_FREE(line);
1645  return r;
1646  } else {
1647 #ifdef STDERR_MSGS
1648  fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
1649 #endif
1650  LDNS_FREE(line);
1651  return NULL;
1652  }
1653  }
1654 }
1655 
1656 char *
1658 {
1659  ldns_buffer *buffer;
1660  char *file_base_name;
1661 
1662  buffer = ldns_buffer_new(255);
1663  ldns_buffer_printf(buffer, "K");
1665  ldns_buffer_printf(buffer,
1666  "+%03u+%05u",
1667  ldns_key_algorithm(key),
1668  ldns_key_keytag(key));
1669  file_base_name = ldns_buffer_export(buffer);
1670  ldns_buffer_free(buffer);
1671  return file_base_name;
1672 }
1673 
1675 {
1677  while(lt->name) {
1678  if(lt->id == algo)
1679  return 1;
1680  lt++;
1681  }
1682  return 0;
1683 }
1684 
1686 {
1687  /* list of (signing algorithm id, alias_name) */
1688  ldns_lookup_table aliases[] = {
1689  /* from bind dnssec-keygen */
1690  {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
1691  {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
1692  {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
1693  /* old ldns usage, now RFC names */
1694  {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
1695  {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
1696 #ifdef USE_GOST
1697  {LDNS_SIGN_ECC_GOST, "GOST"},
1698 #endif
1699  /* compat with possible output */
1700  {LDNS_DH, "DH"},
1701  {LDNS_ECC, "ECC"},
1702  {LDNS_INDIRECT, "INDIRECT"},
1703  {LDNS_PRIVATEDNS, "PRIVATEDNS"},
1704  {LDNS_PRIVATEOID, "PRIVATEOID"},
1705  {0, NULL}};
1707  while(lt->name) {
1708  if(strcasecmp(lt->name, name) == 0)
1709  return lt->id;
1710  lt++;
1711  }
1712  lt = aliases;
1713  while(lt->name) {
1714  if(strcasecmp(lt->name, name) == 0)
1715  return lt->id;
1716  lt++;
1717  }
1718  if(atoi(name) != 0)
1719  return atoi(name);
1720  return 0;
1721 }
void ldns_key_set_external_key(ldns_key *k, void *external_key)
Set the key id data.
Definition: keys.c:1044
implementation of buffers to ease operations
Definition: buffer.h:50
DSA * ldns_key_new_frm_fp_dsa_l(FILE *f, int *line_nr __attribute__((unused)))
Definition: keys.c:671
void ldns_key_set_origttl(ldns_key *k, uint32_t t)
Set the key&#39;s original ttl.
Definition: keys.c:1050
DSA * ldns_key_new_frm_fp_dsa(FILE *f)
frm_fp helper function.
Definition: keys.c:665
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:1087
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:1022
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:1206
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:1685
void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type)
sets the type in the rr.
Definition: rr.c:792
ldns_key * ldns_key_list_pop_key(ldns_key_list *key_list)
pops the last rr from a keylist
Definition: keys.c:1252
b64 string
Definition: rdata.h:68
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:978
void ldns_key_set_use(ldns_key *k, bool v)
Definition: keys.c:1103
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:984
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:1176
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:1138
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:1569
void ldns_key_set_rsa_key(ldns_key *k, RSA *r)
Set the key&#39;s rsa data.
Definition: keys.c:998
#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:752
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:1068
#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:1213
Resource Record.
Definition: rr.h:299
size_t ldns_key_hmac_size(const ldns_key *k)
return the hmac key size
Definition: keys.c:1160
unsigned char * ldns_key_new_frm_fp_hmac_l(FILE *f, int *line_nr __attribute__((unused)), size_t *hmac_size)
Definition: keys.c:758
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_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:649
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:1038
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:1674
16 bits
Definition: rdata.h:54
ldns_rr * ldns_read_anchor_file(const char *filename)
Instantiates a DNSKEY or DS RR from file.
Definition: keys.c:1605
#define ATTR_UNUSED(x)
Definition: common.h:67
a key algorithm
Definition: rdata.h:80
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:1062
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
#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:1111
Same as rr_list, but now for keys.
Definition: keys.h:157
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:528
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:320
void ldns_key_list_free(ldns_key_list *key_list)
Frees a key list structure.
Definition: keys.c:1594
RSA * ldns_key_rsa_key(const ldns_key *k)
returns the (openssl) RSA struct contained in the key
Definition: keys.c:1128
void ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
Set the key&#39;s evp key.
Definition: keys.c:992
RFC4034, RFC3658.
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:1229
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:522
void * ldns_key_external_key(const ldns_key *k)
return the key id key data
Definition: keys.c:1170
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition: rr.c:768
uint32_t ldns_key_inception(const ldns_key *k)
return the key&#39;s inception date
Definition: keys.c:1188
void ldns_key_print(FILE *output, const ldns_key *k)
print a private key to the file ouput
Definition: keys.c:965
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:907
unsigned char * ldns_key_hmac_key(const ldns_key *k)
return the hmac key data
Definition: keys.c:1150
const char * name
Definition: util.h:158
enum ldns_enum_status ldns_status
Definition: error.h:131
EVP_PKEY * ldns_key_evp_key(const ldns_key *k)
returns the (openssl) EVP struct contained in the key
Definition: keys.c:1122
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:1056
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:1097
uint32_t ldns_key_expiration(const ldns_key *k)
return the key&#39;s expiration date
Definition: keys.c:1194
ldns_signing_algorithm _alg
Definition: keys.h:108
void ldns_key_set_keytag(ldns_key *k, uint16_t tag)
Set the key&#39;s key tag.
Definition: keys.c:1074
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:821
ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
convert the string with the b64 data into wireformat
Definition: str2host.c:582
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:1370
#define LDNS_MAX_LINELEN
Definition: parse.h:23
Resource record data field.
Definition: rdata.h:166
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:1081
#define LDNS_DNSSEC_KEYPROTO
Definition: dnssec.h:42
8 bits
Definition: rdata.h:52
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:1014
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:1575
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
Definition: keys.c:1200
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:1657
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition: error.c:150
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:1006
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
Definition: keys.c:1182
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:2437
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:1223
ldns_lookup_table ldns_signing_algorithms[]
Definition: keys.c:23
ldns_key_list * ldns_key_list_new(void)
Creates a new empty key list.
Definition: keys.c:47
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:819
ldns_key * ldns_key_new(void)
Creates a new empty key structure.
Definition: keys.c:60
void ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
Set the key&#39;s hmac data.
Definition: keys.c:1032
enum ldns_enum_algorithm ldns_algorithm
Definition: keys.h:62