ldns-signzone.c
Go to the documentation of this file.
1 /*
2  * ldns-signzone signs a zone file
3  *
4  * (c) NLnet Labs, 2005 - 2008
5  * See the file LICENSE for the license
6  */
7 
8 #include <stdio.h>
9 
10 #include "config.h"
11 
12 #ifdef HAVE_SSL
13 
14 #include <stdlib.h>
15 #include <unistd.h>
16 
17 #include <errno.h>
18 
19 #include <time.h>
20 
21 #include <ldns/ldns.h>
22 #include <ldns/keys.h>
23 
24 #include <openssl/conf.h>
25 #ifndef OPENSSL_NO_ENGINE
26 #include <openssl/engine.h>
27 #endif
28 #include <openssl/err.h>
29 
30 #define MAX_FILENAME_LEN 250
31 
32 char *prog;
33 int verbosity = 1;
34 
35 static void
36 usage(FILE *fp, const char *prog) {
37  fprintf(fp, "%s [OPTIONS] zonefile key [key [key]]\n", prog);
38  fprintf(fp, " signs the zone with the given key(s)\n");
39  fprintf(fp, " -b\t\tuse layout in signed zone and print comments DNSSEC records\n");
40  fprintf(fp, " -d\t\tused keys are not added to the zone\n");
41  fprintf(fp, " -e <date>\texpiration date\n");
42  fprintf(fp, " -f <file>\toutput zone to file (default <name>.signed)\n");
43  fprintf(fp, " -i <date>\tinception date\n");
44  fprintf(fp, " -o <domain>\torigin for the zone\n");
45  fprintf(fp, " -u\t\tset SOA serial to the number of seconds since 1-1-1970\n");
46  fprintf(fp, " -v\t\tprint version and exit\n");
47  fprintf(fp, " -z <[scheme:]hash>\tAdd ZONEMD resource record\n");
48  fprintf(fp, "\t\t<scheme> should be \"simple\" (or 1)\n");
49  fprintf(fp, "\t\t<hash> should be \"sha384\" or \"sha512\" (or 1 or 2)\n");
50  fprintf(fp, "\t\tthis option can be given more than once\n");
51  fprintf(fp, " -Z\t\tAllow ZONEMDs to be added without signing\n");
52  fprintf(fp, " -A\t\tsign DNSKEY with all keys instead of minimal\n");
53  fprintf(fp, " -U\t\tSign with every unique algorithm in the provided keys\n");
54 #ifndef OPENSSL_NO_ENGINE
55  fprintf(fp, " -E <name>\tuse <name> as the crypto engine for signing\n");
56  fprintf(fp, " \tThis can have a lot of extra options, see the manual page for more info\n");
57  fprintf(fp, " -k <algorithm>,<key>\tuse `key' with `algorithm' from engine as ZSK\n");
58  fprintf(fp, " -K <algorithm>,<key>\tuse `key' with `algorithm' from engine as KSK\n");
59 #endif
60  fprintf(fp, " -n\t\tuse NSEC3 instead of NSEC.\n");
61  fprintf(fp, "\t\tIf you use NSEC3, you can specify the following extra options:\n");
62  fprintf(fp, "\t\t-a [algorithm] hashing algorithm\n");
63  fprintf(fp, "\t\t-t [number] number of hash iterations\n");
64  fprintf(fp, "\t\t-s [string] salt\n");
65  fprintf(fp, "\t\t-p set the opt-out flag on all nsec3 rrs\n");
66  fprintf(fp, "\n");
67  fprintf(fp, " keys must be specified by their base name (usually K<name>+<alg>+<id>),\n");
68  fprintf(fp, " i.e. WITHOUT the .private extension.\n");
69  fprintf(fp, " If the public part of the key is not present in the zone, the DNSKEY RR\n");
70  fprintf(fp, " will be read from the file called <base name>.key. If that does not exist,\n");
71  fprintf(fp, " a default DNSKEY will be generated from the private key and added to the zone.\n");
72  fprintf(fp, " A date can be a timestamp (seconds since the epoch), or of\n the form <YYYYMMdd[hhmmss]>\n");
73 #ifndef OPENSSL_NO_ENGINE
74  fprintf(fp, " For -k or -K, the algorithm can be specified as an integer or a symbolic name:" );
75 
76 #define __LIST(x) fprintf ( fp, " %3d: %-15s", LDNS_SIGN_ ## x, # x )
77 
78  fprintf ( fp, "\n " );
79  __LIST ( RSAMD5 );
80 #ifdef USE_DSA
81  __LIST ( DSA );
82 #endif
83  __LIST ( RSASHA1 );
84  fprintf ( fp, "\n " );
85 #ifdef USE_DSA
86  __LIST ( DSA_NSEC3 );
87 #endif
88  __LIST ( RSASHA1_NSEC3 );
89  __LIST ( RSASHA256 );
90  fprintf ( fp, "\n " );
91  __LIST ( RSASHA512 );
92  __LIST ( ECC_GOST );
93  __LIST ( ECDSAP256SHA256 );
94  fprintf ( fp, "\n " );
95  __LIST ( ECDSAP384SHA384 );
96 
97 #ifdef USE_ED25519
98  __LIST ( ED25519 );
99 #endif
100 
101 #ifdef USE_ED448
102  __LIST ( ED448 );
103 #endif
104  fprintf ( fp, "\n" );
105 
106 #undef __LIST
107 #endif
108 }
109 
110 static void check_tm(struct tm tm)
111 {
112  if (tm.tm_year < 70) {
113  fprintf(stderr, "You cannot specify dates before 1970\n");
114  exit(EXIT_FAILURE);
115  }
116  if (tm.tm_mon < 0 || tm.tm_mon > 11) {
117  fprintf(stderr, "The month must be in the range 1 to 12\n");
118  exit(EXIT_FAILURE);
119  }
120  if (tm.tm_mday < 1 || tm.tm_mday > 31) {
121  fprintf(stderr, "The day must be in the range 1 to 31\n");
122  exit(EXIT_FAILURE);
123  }
124 
125  if (tm.tm_hour < 0 || tm.tm_hour > 23) {
126  fprintf(stderr, "The hour must be in the range 0-23\n");
127  exit(EXIT_FAILURE);
128  }
129 
130  if (tm.tm_min < 0 || tm.tm_min > 59) {
131  fprintf(stderr, "The minute must be in the range 0-59\n");
132  exit(EXIT_FAILURE);
133  }
134 
135  if (tm.tm_sec < 0 || tm.tm_sec > 59) {
136  fprintf(stderr, "The second must be in the range 0-59\n");
137  exit(EXIT_FAILURE);
138  }
139 
140 }
141 
142 /*
143  * if the ttls are different, make them equal
144  * if one of the ttls equals LDNS_DEFAULT_TTL, that one is changed
145  * otherwise, rr2 will get the ttl of rr1
146  *
147  * prints a warning if a non-default TTL is changed
148  */
149 static void
150 equalize_ttls(ldns_rr *rr1, ldns_rr *rr2, uint32_t default_ttl)
151 {
152  uint32_t ttl1, ttl2;
153 
154  ttl1 = ldns_rr_ttl(rr1);
155  ttl2 = ldns_rr_ttl(rr2);
156 
157  if (ttl1 != ttl2) {
158  if (ttl1 == default_ttl) {
159  ldns_rr_set_ttl(rr1, ttl2);
160  } else if (ttl2 == default_ttl) {
161  ldns_rr_set_ttl(rr2, ttl1);
162  } else {
163  ldns_rr_set_ttl(rr2, ttl1);
164  fprintf(stderr,
165  "warning: changing non-default TTL %u to %u\n",
166  (unsigned int) ttl2, (unsigned int) ttl1);
167  }
168  }
169 }
170 
171 static void
172 equalize_ttls_rr_list(ldns_rr_list *rr_list, ldns_rr *rr, uint32_t default_ttl)
173 {
174  size_t i;
175  ldns_rr *cur_rr;
176 
177  for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
178  cur_rr = ldns_rr_list_rr(rr_list, i);
179  if (ldns_rr_compare_no_rdata(cur_rr, rr) == 0) {
180  equalize_ttls(cur_rr, rr, default_ttl);
181  }
182  }
183 }
184 
185 static ldns_rr *
186 find_key_in_zone(ldns_rr *pubkey_gen, ldns_zone *zone) {
187  size_t key_i;
188  ldns_rr *pubkey;
189 
190  for (key_i = 0;
191  key_i < ldns_rr_list_rr_count(ldns_zone_rrs(zone));
192  key_i++) {
193  pubkey = ldns_rr_list_rr(ldns_zone_rrs(zone), key_i);
194  if (ldns_rr_get_type(pubkey) == LDNS_RR_TYPE_DNSKEY &&
195  (ldns_calc_keytag(pubkey)
196  ==
197  ldns_calc_keytag(pubkey_gen) ||
198  /* KSK has gen-keytag + 1 */
199  ldns_calc_keytag(pubkey)
200  ==
201  ldns_calc_keytag(pubkey_gen) + 1)
202  ) {
203  if (verbosity >= 2) {
204  fprintf(stderr, "Found it in the zone!\n");
205  }
206  return pubkey;
207  }
208  }
209  return NULL;
210 }
211 
212 static ldns_rr *
213 find_key_in_file(const char *keyfile_name_base, ldns_key* ATTR_UNUSED(key),
214  uint32_t zone_ttl)
215 {
216  char *keyfile_name;
217  FILE *keyfile;
218  int line_nr;
219  uint32_t default_ttl = zone_ttl;
220 
221  ldns_rr *pubkey = NULL;
222  keyfile_name = LDNS_XMALLOC(char,
223  strlen(keyfile_name_base) + 5);
224  snprintf(keyfile_name,
225  strlen(keyfile_name_base) + 5,
226  "%s.key",
227  keyfile_name_base);
228  if (verbosity >= 2) {
229  fprintf(stderr, "Trying to read %s\n", keyfile_name);
230  }
231  keyfile = fopen(keyfile_name, "r");
232  line_nr = 0;
233  if (keyfile) {
234  if (ldns_rr_new_frm_fp_l(&pubkey,
235  keyfile,
236  &default_ttl,
237  NULL,
238  NULL,
239  &line_nr) ==
240  LDNS_STATUS_OK) {
241  if (verbosity >= 2) {
242  printf("Key found in file: %s\n", keyfile_name);
243  }
244  }
245  fclose(keyfile);
246  }
247  LDNS_FREE(keyfile_name);
248  return pubkey;
249 }
250 
251 /* this function tries to find the specified keys either in the zone that
252  * has been read, or in a <basename>.key file. If the key is not found,
253  * a public key is generated, and it is assumed the key is a ZSK
254  *
255  * if add_keys is true; the DNSKEYs are added to the zone prior to signing
256  * if it is false, they are not added.
257  * Even if keys are not added, the function is still needed, to check
258  * whether keys of which we only have key data are KSKs or ZSKS
259  */
260 static void
261 find_or_create_pubkey(const char *keyfile_name_base, ldns_key *key, ldns_zone *orig_zone, bool add_keys, uint32_t default_ttl) {
262  ldns_rr *pubkey_gen, *pubkey;
263  int key_in_zone;
264 
265  if (default_ttl == LDNS_DEFAULT_TTL) {
266  default_ttl = ldns_rr_ttl(ldns_zone_soa(orig_zone));
267  }
268 
269  if (!ldns_key_pubkey_owner(key)) {
271  }
272 
273  /* find the public key in the zone, or in a
274  * separate file
275  * we 'generate' one anyway,
276  * then match that to any present in the zone,
277  * if it matches, we drop our own. If not,
278  * we try to see if there is a .key file present.
279  * If not, we use our own generated one, with
280  * some default values
281  *
282  * Even if -d (do-not-add-keys) is specified,
283  * we still need to do this, because we need
284  * to have any key flags that are set this way
285  */
286  pubkey_gen = ldns_key2rr(key);
287  ldns_rr_set_ttl(pubkey_gen, default_ttl);
288 
289  if (verbosity >= 2) {
290  fprintf(stderr,
291  "Looking for key with keytag %u or %u\n",
292  (unsigned int) ldns_calc_keytag(pubkey_gen),
293  (unsigned int) ldns_calc_keytag(pubkey_gen)+1
294  );
295  }
296 
297  pubkey = find_key_in_zone(pubkey_gen, orig_zone);
298  key_in_zone = 1;
299  if (!pubkey) {
300  key_in_zone = 0;
301  /* it was not in the zone, try to read a .key file */
302  pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
303  if (!pubkey && !(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
304  /* maybe it is a ksk? */
305  ldns_key_set_keytag(key, ldns_key_keytag(key) + 1);
306  pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
307  if (!pubkey) {
308  /* ok, no file, set back to ZSK */
309  ldns_key_set_keytag(key, ldns_key_keytag(key) - 1);
310  }
311  }
312  if(pubkey && ldns_dname_compare(ldns_rr_owner(pubkey), ldns_rr_owner(ldns_zone_soa(orig_zone))) != 0) {
313  fprintf(stderr, "Error %s.key has wrong name: %s\n",
314  keyfile_name_base, ldns_rdf2str(ldns_rr_owner(pubkey)));
315  exit(EXIT_FAILURE); /* leak rdf2str, but we exit */
316  }
317  }
318 
319  if (!pubkey) {
320  /* okay, no public key found,
321  just use our generated one */
322  pubkey = pubkey_gen;
323  if (verbosity >= 2) {
324  fprintf(stderr, "Not in zone, no .key file, generating ZSK DNSKEY from private key data\n");
325  }
326  } else {
327  ldns_rr_free(pubkey_gen);
328  }
331 
332  if (add_keys && !key_in_zone) {
333  equalize_ttls_rr_list(ldns_zone_rrs(orig_zone), pubkey, default_ttl);
334  ldns_zone_push_rr(orig_zone, pubkey);
335  }
336 }
337 
338 #ifndef OPENSSL_NO_ENGINE
339 /*
340  * For keys coming from the engine (-k or -K), parse algorithm specification.
341  */
342 static enum ldns_enum_signing_algorithm
343 parse_algspec ( const char * const p )
344 {
345  if ( p == NULL )
346  return 0;
347 
348  if ( isdigit ( (const unsigned char)*p ) ) {
349  const char *nptr = NULL;
350  const long id = strtol ( p, (char **) &nptr, 10 );
351  return id > 0 && nptr != NULL && *nptr == ',' ? id : 0;
352  }
353 
354 #define __MATCH(x) \
355  if ( !memcmp ( # x, p, sizeof ( # x ) - 1 ) \
356  && p [ sizeof ( # x ) - 1 ] == ',' ) { \
357  return LDNS_SIGN_ ## x; \
358  }
359 
360  __MATCH ( RSAMD5 );
361  __MATCH ( RSASHA1 );
362 #ifdef USE_DSA
363  __MATCH ( DSA );
364 #endif
365  __MATCH ( RSASHA1_NSEC3 );
366  __MATCH ( RSASHA256 );
367  __MATCH ( RSASHA512 );
368 #ifdef USE_DSA
369  __MATCH ( DSA_NSEC3 );
370 #endif
371  __MATCH ( ECC_GOST );
372  __MATCH ( ECDSAP256SHA256 );
373  __MATCH ( ECDSAP384SHA384 );
374 
375 #ifdef USE_ED25519
376  __MATCH ( ED25519 );
377 #endif
378 
379 #ifdef USE_ED448
380  __MATCH ( ED448 );
381 #endif
382 
383 #undef __MATCH
384 
385  return 0;
386 }
387 
388 /*
389  * For keys coming from the engine (-k or -K), parse key specification
390  * in the form of <algorithm>,<key-id>. No whitespace is allowed
391  * between <algorithm> and the comma, and between the comma and
392  * <key-id>. <key-id> format is specific to the engine at hand, i.e.
393  * it can be the old OpenSC syntax or a PKCS #11 URI as defined in RFC 7512
394  * and (partially) supported by OpenSC (as of 20180312).
395  */
396 static const char *
397 parse_keyspec ( const char * const p,
398  enum ldns_enum_signing_algorithm * const algorithm,
399  const char ** const id )
400 {
401  const char * const comma = strchr ( p, ',' );
402 
403  if ( comma == NULL || !(*algorithm = parse_algspec ( p )) )
404  return NULL;
405  return comma [ 1 ] ? *id = comma + 1 : NULL;
406 }
407 
408 /*
409  * Load a key from the engine.
410  */
411 static ldns_key *
412 load_key ( const char * const p, ENGINE * const e )
413 {
414  enum ldns_enum_signing_algorithm alg = 0;
415  const char *id = NULL;
416  ldns_status status = LDNS_STATUS_ERR;
417  ldns_key *key = NULL;
418 
419  /* Parse key specification. */
420  if ( parse_keyspec ( p, &alg, &id ) == NULL ) {
421  fprintf ( stderr,
422  "Failed to parse key specification `%s'.\n",
423  p );
424  usage ( stderr, prog );
425  exit ( EXIT_FAILURE );
426  }
427 
428  /* Validate that the algorithm can be used for signing. */
429  switch ( alg ) {
430  case LDNS_SIGN_RSAMD5:
431  case LDNS_SIGN_RSASHA1:
433  case LDNS_SIGN_RSASHA256:
434  case LDNS_SIGN_RSASHA512:
435 #ifdef USE_DSA
436  case LDNS_SIGN_DSA:
437  case LDNS_SIGN_DSA_NSEC3:
438 #endif
439  case LDNS_SIGN_ECC_GOST:
440 #ifdef USE_ECDSA
443 #endif
444  break;
445  default:
446  fprintf ( stderr,
447  "Algorithm %d cannot be used for signing.\n",
448  alg );
449  usage ( stderr, prog );
450  exit ( EXIT_FAILURE );
451  }
452 
453  printf ( "Engine key id: %s, algo %d\n", id, alg );
454 
455  /* Attempt to load the key from the engine. */
456  status = ldns_key_new_frm_engine (
457  &key, e, (char *) id, (ldns_algorithm)alg );
458  if ( status != LDNS_STATUS_OK ) {
459  ERR_print_errors_fp ( stderr );
460  exit ( EXIT_FAILURE );
461  }
462 
463  return key;
464 }
465 
466 /*
467  * For keys coming from the engine (-k or -K), set key parameters
468  * and determine whether the key is listed in the zone file.
469  */
470 static void
471 post_process_engine_key ( ldns_key_list * const keys,
472  ldns_key * const key,
473  ldns_zone * const zone,
474  const bool add_keys,
475  const uint32_t ttl,
476  const uint32_t inception,
477  const uint32_t expiration )
478 {
479  if ( key == NULL ) return;
480 
481  if ( expiration ) ldns_key_set_expiration ( key, expiration );
482 
483  if ( inception ) ldns_key_set_inception ( key, inception );
484 
485  ldns_key_list_push_key ( keys, key );
486  find_or_create_pubkey ( "", key, zone, add_keys, ttl );
487 }
488 
489 /*
490  * Initialize OpenSSL, for versions 1.1 and newer.
491  */
492 static ENGINE *
493 init_openssl_engine ( const char * const id )
494 {
495  ENGINE *e = NULL;
496 
497 #ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
498  ERR_load_crypto_strings();
499 #endif
500 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) || !defined(HAVE_OPENSSL_INIT_CRYPTO)
501  OpenSSL_add_all_algorithms();
502 #else
503  if ( !OPENSSL_init_crypto ( OPENSSL_INIT_LOAD_CONFIG, NULL ) ) {
504  fprintf ( stderr, "OPENSSL_init_crypto(3) failed.\n" );
505  ERR_print_errors_fp ( stderr );
506  exit ( EXIT_FAILURE );
507  }
508 #endif
509 
510  if ( (e = ENGINE_by_id ( id )) == NULL ) {
511  fprintf ( stderr, "ENGINE_by_id(3) failed.\n" );
512  ERR_print_errors_fp ( stderr );
513  exit ( EXIT_FAILURE );
514  }
515 
516  if ( !ENGINE_set_default_DSA ( e ) ) {
517  fprintf ( stderr, "ENGINE_set_default_DSA(3) failed.\n" );
518  ERR_print_errors_fp ( stderr );
519  exit ( EXIT_FAILURE );
520  }
521 
522  if ( !ENGINE_set_default_RSA ( e ) ) {
523  fprintf ( stderr, "ENGINE_set_default_RSA(3) failed.\n" );
524  ERR_print_errors_fp ( stderr );
525  exit ( EXIT_FAILURE );
526  }
527 
528  return e;
529 }
530 
531 /*
532  * De-initialize OpenSSL, for versions 1.1 and newer.
533  *
534  * All of that is not strictly necessary because the process exits
535  * anyway, however, when an engine is used, this is the only hope
536  * of letting the engine's driver know that the program terminates
537  * (for the fear that the driver's reference counting may go awry, etc.)
538  * Still, there is no guarantee that this function helps...
539  */
540 static void
541 shutdown_openssl ( ENGINE * const e )
542 {
543  if ( e != NULL ) {
544 #ifdef HAVE_ENGINE_FREE
545  ENGINE_free ( e );
546 #endif
547 #ifdef HAVE_ENGINE_CLEANUP
548  ENGINE_cleanup ();
549 #endif
550  }
551 
552 #ifdef HAVE_CONF_MODULES_UNLOAD
553  CONF_modules_unload ( 1 );
554 #endif
555 #ifdef HAVE_EVP_CLEANUP
556  EVP_cleanup ();
557 #endif
558 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
559  CRYPTO_cleanup_all_ex_data ();
560 #endif
561 #ifdef HAVE_ERR_FREE_STRINGS
562  ERR_free_strings ();
563 #endif
564 }
565 #endif
566 
567 int str2zonemd_signflag(const char *str, const char **reason)
568 {
569  char *colon;
570 
571  static const char *reasons[] = {
572  "Unknown <scheme>, should be \"simple\""
573  , "Syntax error in <hash>, should be \"sha384\" or \"sha512\""
574  , "Unknown <hash>, should be \"sha384\" or \"sha512\""
575  };
576 
577  if (!str)
578  return LDNS_STATUS_NULL;
579 
580  if ((colon = strchr(str, ':'))) {
581  if ((colon - str != 1 || str[0] != '1')
582  && (colon - str != 6 || strncasecmp(str, "simple", 6))) {
583  if (reason) *reason = reasons[0];
584  return 0;
585  }
586 
587  if (strchr(colon + 1, ':')) {
588  if (reason) *reason = reasons[1];
589  return 0;
590  }
591  return str2zonemd_signflag(colon + 1, reason);
592  }
593  if (!strcasecmp(str, "1") || !strcasecmp(str, "sha384"))
595  if (!strcasecmp(str, "2") || !strcasecmp(str, "sha512"))
597 
598  if (reason) *reason = reasons[2];
599  return 0;
600 }
601 
602 int
603 main(int argc, char *argv[])
604 {
605  const char *zonefile_name;
606  FILE *zonefile = NULL;
607  int line_nr = 0;
608  int c;
609  int argi;
610 #ifndef OPENSSL_NO_ENGINE
611  ENGINE *engine = NULL;
612 #endif
613  ldns_zone *orig_zone;
614  ldns_rr_list *orig_rrs = NULL;
615  ldns_rr *orig_soa = NULL;
616  ldns_dnssec_zone *signed_zone;
617 
618  char *keyfile_name_base;
619  char *keyfile_name = NULL;
620  FILE *keyfile = NULL;
621  ldns_key *key = NULL;
622 #ifndef OPENSSL_NO_ENGINE
623  ldns_key *eng_ksk = NULL; /* KSK specified with -K */
624  ldns_key *eng_zsk = NULL; /* ZSK specified with -k */
625 #endif
626  ldns_key_list *keys;
627  ldns_status s;
628  size_t i;
629  ldns_rr_list *added_rrs;
630 
631  char *outputfile_name = NULL;
632  FILE *outputfile;
633 
634  bool use_nsec3 = false;
635  int signflags = 0;
636  bool unixtime_serial = false;
637 
638  /* Add the given keys to the zone if they are not yet present */
639  bool add_keys = true;
640  uint8_t nsec3_algorithm = 1;
641  uint8_t nsec3_flags = 0;
642  size_t nsec3_iterations_cmd = 1;
643  uint16_t nsec3_iterations = 1;
644  uint8_t nsec3_salt_length = 0;
645  uint8_t *nsec3_salt = NULL;
646 
647  /* we need to know the origin before reading ksk's,
648  * so keep an array of filenames until we know it
649  */
650  struct tm tm;
651  uint32_t inception;
652  uint32_t expiration;
653  ldns_rdf *origin = NULL;
654  uint32_t ttl = LDNS_DEFAULT_TTL;
656 
657  ldns_status result;
658 
660  ldns_output_format* fmt = ldns_output_format_init(&fmt_st);
661 
662  /* For parson zone digest parameters */
663  int flag;
664  const char *reason = NULL;
665 
666  prog = strdup(argv[0]);
667  inception = 0;
668  expiration = 0;
669 
670  keys = ldns_key_list_new();
671 
672  while ((c = getopt(argc, argv, "a:bde:f:i:k:no:ps:t:uvz:ZAUE:K:")) != -1) {
673  switch (c) {
674  case 'a':
675  nsec3_algorithm = (uint8_t) atoi(optarg);
676  if (nsec3_algorithm != 1) {
677  fprintf(stderr, "Bad NSEC3 algorithm, only RSASHA1 allowed\n");
678  exit(EXIT_FAILURE);
679  }
680  break;
681  case 'b':
682  ldns_output_format_set(fmt, LDNS_COMMENT_FLAGS
686  break;
687  case 'd':
688  add_keys = false;
689  break;
690  case 'e':
691  /* try to parse YYYYMMDD first,
692  * if that doesn't work, it
693  * should be a timestamp (seconds since epoch)
694  */
695  memset(&tm, 0, sizeof(tm));
696 
697  if (strlen(optarg) == 8 &&
698  sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
699  ) {
700  tm.tm_year -= 1900;
701  tm.tm_mon--;
702  check_tm(tm);
703  expiration =
704  (uint32_t) ldns_mktime_from_utc(&tm);
705  } else if (strlen(optarg) == 14 &&
706  sscanf(optarg, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
707  ) {
708  tm.tm_year -= 1900;
709  tm.tm_mon--;
710  check_tm(tm);
711  expiration =
712  (uint32_t) ldns_mktime_from_utc(&tm);
713  } else {
714  expiration = (uint32_t) atol(optarg);
715  }
716  break;
717  case 'f':
718  outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN + 1);
719  strncpy(outputfile_name, optarg, MAX_FILENAME_LEN);
720  break;
721  case 'i':
722  memset(&tm, 0, sizeof(tm));
723 
724  if (strlen(optarg) == 8 &&
725  sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
726  ) {
727  tm.tm_year -= 1900;
728  tm.tm_mon--;
729  check_tm(tm);
730  inception =
731  (uint32_t) ldns_mktime_from_utc(&tm);
732  } else if (strlen(optarg) == 14 &&
733  sscanf(optarg, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec)
734  ) {
735  tm.tm_year -= 1900;
736  tm.tm_mon--;
737  check_tm(tm);
738  inception =
739  (uint32_t) ldns_mktime_from_utc(&tm);
740  } else {
741  inception = (uint32_t) atol(optarg);
742  }
743  break;
744  case 'n':
745  use_nsec3 = true;
746  break;
747  case 'o':
748  if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
749  fprintf(stderr, "Bad origin, not a correct domain name\n");
750  usage(stderr, prog);
751  exit(EXIT_FAILURE);
752  }
753  break;
754  case 'p':
755  nsec3_flags = nsec3_flags | LDNS_NSEC3_VARS_OPTOUT_MASK;
756  break;
757  case 'u':
758  unixtime_serial = true;
759  break;
760  case 'v':
761  printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
762  exit(EXIT_SUCCESS);
763  break;
764  case 'z':
765  flag = str2zonemd_signflag(optarg, &reason);
766  if (flag)
767  signflags |= flag;
768  else {
769  fprintf( stderr
770  , "%s\nwith zone digest parameters:"
771  " \"%s\"\n"
772  , reason, optarg);
773  exit(EXIT_FAILURE);
774  }
775  break;
776  case 'Z':
777  signflags |= LDNS_SIGN_NO_KEYS_NO_NSECS;
778  break;
779  case 'A':
780  signflags |= LDNS_SIGN_DNSKEY_WITH_ZSK;
781  break;
782  case 'E':
783 #ifndef OPENSSL_NO_ENGINE
784  engine = init_openssl_engine ( optarg );
785  break;
786 #else
787  /* fallthrough */
788 #endif
789  case 'k':
790 #ifndef OPENSSL_NO_ENGINE
791  eng_zsk = load_key ( optarg, engine );
792  break;
793 #else
794  /* fallthrough */
795 #endif
796  case 'K':
797 #ifndef OPENSSL_NO_ENGINE
798  eng_ksk = load_key ( optarg, engine );
799  /* I apologize for that, there is no API. */
800  eng_ksk -> _extra.dnssec.flags |= LDNS_KEY_SEP_KEY;
801 #else
802  fprintf(stderr, "%s compiled without engine support\n"
803  , prog);
804  exit(EXIT_FAILURE);
805 #endif
806  break;
807  case 'U':
808  signflags |= LDNS_SIGN_WITH_ALL_ALGORITHMS;
809  break;
810  case 's':
811  if (strlen(optarg) % 2 != 0) {
812  fprintf(stderr, "Salt value is not valid hex data, not a multiple of 2 characters\n");
813  exit(EXIT_FAILURE);
814  }
815  nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
816  nsec3_salt = LDNS_XMALLOC(uint8_t, nsec3_salt_length);
817  for (c = 0; c < (int) strlen(optarg); c += 2) {
818  if (isxdigit((int) optarg[c]) && isxdigit((int) optarg[c+1])) {
819  nsec3_salt[c/2] = (uint8_t) ldns_hexdigit_to_int(optarg[c]) * 16 +
820  ldns_hexdigit_to_int(optarg[c+1]);
821  } else {
822  fprintf(stderr, "Salt value is not valid hex data.\n");
823  exit(EXIT_FAILURE);
824  }
825  }
826 
827  break;
828  case 't':
829  nsec3_iterations_cmd = (size_t) atol(optarg);
830  if (nsec3_iterations_cmd > LDNS_NSEC3_MAX_ITERATIONS) {
831  fprintf(stderr, "Iterations count can not exceed %u, quitting\n", LDNS_NSEC3_MAX_ITERATIONS);
832  exit(EXIT_FAILURE);
833  }
834  nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
835  break;
836  default:
837  usage(stderr, prog);
838  exit(EXIT_SUCCESS);
839  }
840  }
841 
842  argc -= optind;
843  argv += optind;
844 
845  if (argc < 1) {
846  printf("Error: not enough arguments\n");
847  usage(stdout, prog);
848  exit(EXIT_FAILURE);
849  } else {
850  zonefile_name = argv[0];
851  }
852 
853  /* read zonefile first to find origin if not specified */
854 
855  if (strncmp(zonefile_name, "-", 2) == 0) {
856  s = ldns_zone_new_frm_fp_l(&orig_zone,
857  stdin,
858  origin,
859  ttl,
860  class,
861  &line_nr);
862  if (s != LDNS_STATUS_OK) {
863  fprintf(stderr, "Zone not read, error: %s at stdin line %d\n",
865  line_nr);
866  exit(EXIT_FAILURE);
867  } else {
868  orig_soa = ldns_zone_soa(orig_zone);
869  if (!orig_soa) {
870  fprintf(stderr,
871  "Error reading zonefile: missing SOA record\n");
872  exit(EXIT_FAILURE);
873  }
874  orig_rrs = ldns_zone_rrs(orig_zone);
875  if (!orig_rrs) {
876  fprintf(stderr,
877  "Error reading zonefile: no resource records\n");
878  exit(EXIT_FAILURE);
879  }
880  }
881  } else {
882  zonefile = fopen(zonefile_name, "r");
883 
884  if (!zonefile) {
885  fprintf(stderr,
886  "Error: unable to read %s (%s)\n",
887  zonefile_name,
888  strerror(errno));
889  exit(EXIT_FAILURE);
890  } else {
891  s = ldns_zone_new_frm_fp_l(&orig_zone,
892  zonefile,
893  origin,
894  ttl,
895  class,
896  &line_nr);
897  if (s != LDNS_STATUS_OK) {
898  fprintf(stderr, "Zone not read, error: %s at %s line %d\n",
900  zonefile_name, line_nr);
901  exit(EXIT_FAILURE);
902  } else {
903  orig_soa = ldns_zone_soa(orig_zone);
904  if (!orig_soa) {
905  fprintf(stderr,
906  "Error reading zonefile: missing SOA record\n");
907  exit(EXIT_FAILURE);
908  }
909  orig_rrs = ldns_zone_rrs(orig_zone);
910  if (!orig_rrs) {
911  fprintf(stderr,
912  "Error reading zonefile: no resource records\n");
913  exit(EXIT_FAILURE);
914  }
915  }
916  fclose(zonefile);
917  }
918  }
919 
920  /* read the ZSKs */
921  argi = 1;
922  while (argi < argc) {
923  keyfile_name_base = argv[argi];
924  keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
925  snprintf(keyfile_name,
926  strlen(keyfile_name_base) + 9,
927  "%s.private",
928  keyfile_name_base);
929  keyfile = fopen(keyfile_name, "r");
930  line_nr = 0;
931  if (!keyfile) {
932  fprintf(stderr,
933  "Error: unable to read %s: %s\n",
934  keyfile_name,
935  strerror(errno));
936  } else {
937  s = ldns_key_new_frm_fp_l(&key, keyfile, &line_nr);
938  fclose(keyfile);
939  if (s == LDNS_STATUS_OK) {
940  /* set times in key? they will end up
941  in the rrsigs
942  */
943  if (expiration != 0) {
944  ldns_key_set_expiration(key, expiration);
945  }
946  if (inception != 0) {
947  ldns_key_set_inception(key, inception);
948  }
949 
950  LDNS_FREE(keyfile_name);
951 
952  ldns_key_list_push_key(keys, key);
953  } else {
954  fprintf(stderr, "Error reading key from %s at line %d: %s\n", argv[argi], line_nr, ldns_get_errorstr_by_id(s));
955  }
956  }
957  /* and, if not unset by -p, find or create the corresponding DNSKEY record */
958  if (key) {
959  find_or_create_pubkey(keyfile_name_base, key,
960  orig_zone, add_keys, ttl);
961  }
962  argi++;
963  }
964 
965 #ifndef OPENSSL_NO_ENGINE
966  /*
967  * The user may have loaded a KSK and a ZSK from the engine.
968  * Since these keys carry no meta-information which is
969  * relevant to DNS (origin, TTL, etc), and because that
970  * information becomes known only after the command line
971  * and the zone file are parsed completely, the program
972  * needs to post-process these keys before they become usable.
973  */
974 
975  /* The engine's KSK. */
976  post_process_engine_key ( keys,
977  eng_ksk,
978  orig_zone,
979  add_keys,
980  ttl,
981  inception,
982  expiration );
983 
984  /* The engine's ZSK. */
985  post_process_engine_key ( keys,
986  eng_zsk,
987  orig_zone,
988  add_keys,
989  ttl,
990  inception,
991  expiration );
992 #endif
993  if (ldns_key_list_key_count(keys) < 1
994  && !(signflags & LDNS_SIGN_NO_KEYS_NO_NSECS)) {
995 
996  fprintf(stderr, "Error: no keys to sign with. Aborting.\n\n");
997  usage(stderr, prog);
998  exit(EXIT_FAILURE);
999  }
1000 
1001  signed_zone = ldns_dnssec_zone_new();
1002  if (unixtime_serial) {
1005  }
1006  if (ldns_dnssec_zone_add_rr(signed_zone, ldns_zone_soa(orig_zone)) !=
1007  LDNS_STATUS_OK) {
1008  fprintf(stderr,
1009  "Error adding SOA to dnssec zone, skipping record\n");
1010  }
1011 
1012  for (i = 0;
1013  i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone));
1014  i++) {
1015  if (ldns_dnssec_zone_add_rr(signed_zone,
1016  ldns_rr_list_rr(ldns_zone_rrs(orig_zone),
1017  i)) !=
1018  LDNS_STATUS_OK) {
1019  fprintf(stderr,
1020  "Error adding RR to dnssec zone");
1021  fprintf(stderr, ", skipping record:\n");
1022  ldns_rr_print(stderr,
1023  ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i));
1024  }
1025  }
1026  /* list to store newly created rrs, so we can free them later */
1027  added_rrs = ldns_rr_list_new();
1028 
1029  if (use_nsec3) {
1030  if (verbosity < 1)
1031  ; /* pass */
1032 
1033  else if (nsec3_iterations > 500)
1034  fprintf(stderr, "Warning! NSEC3 iterations larger than "
1035  "500 may cause validating resolvers to return "
1036  "SERVFAIL!\n"
1037  "See: https://datatracker.ietf.org/doc/html/"
1038  "draft-hardaker-dnsop-nsec3-guidance-03#section-4\n");
1039 
1040  else if (nsec3_iterations > 100)
1041  fprintf(stderr, "Warning! NSEC3 iterations larger than "
1042  "100 may cause validating resolvers to return "
1043  "insecure responses!\n"
1044  "See: https://datatracker.ietf.org/doc/html/"
1045  "draft-hardaker-dnsop-nsec3-guidance-03#section-4\n");
1046 
1047  result = ldns_dnssec_zone_sign_nsec3_flg_mkmap(signed_zone,
1048  added_rrs,
1049  keys,
1051  NULL,
1052  nsec3_algorithm,
1053  nsec3_flags,
1054  nsec3_iterations,
1055  nsec3_salt_length,
1056  nsec3_salt,
1057  signflags,
1058  &fmt_st.hashmap);
1059  } else {
1060  result = ldns_dnssec_zone_sign_flg(signed_zone,
1061  added_rrs,
1062  keys,
1064  NULL,
1065  signflags);
1066  }
1067  if (result != LDNS_STATUS_OK) {
1068  fprintf(stderr, "Error signing zone: %s\n",
1069  ldns_get_errorstr_by_id(result));
1070  }
1071 
1072  if (!outputfile_name) {
1073  outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
1074  snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
1075  }
1076 
1077  if (signed_zone) {
1078  if (strncmp(outputfile_name, "-", 2) == 0) {
1079  ldns_dnssec_zone_print(stdout, signed_zone);
1080  } else {
1081  outputfile = fopen(outputfile_name, "w");
1082  if (!outputfile) {
1083  fprintf(stderr, "Unable to open %s for writing: %s\n",
1084  outputfile_name, strerror(errno));
1085  } else {
1087  outputfile, fmt, signed_zone);
1088  fclose(outputfile);
1089  }
1090  }
1091  } else {
1092  fprintf(stderr, "Error signing zone.\n");
1093 
1094 #ifdef HAVE_SSL
1095  if (ERR_peek_error()) {
1096 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
1097 #ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
1098  ERR_load_crypto_strings();
1099 #endif
1100 #endif
1101  ERR_print_errors_fp(stderr);
1102 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
1103 #ifdef HAVE_ERR_FREE_STRINGS
1104  ERR_free_strings ();
1105 #endif
1106 #endif
1107  }
1108 #endif
1109  exit(EXIT_FAILURE);
1110  }
1111 
1112  ldns_key_list_free(keys);
1113  /* since the ldns_rr records are pointed to in both the ldns_zone
1114  * and the ldns_dnssec_zone, we can either deep_free the
1115  * dnssec_zone and 'shallow' free the original zone and added
1116  * records, or the other way around
1117  */
1118  ldns_dnssec_zone_free(signed_zone);
1119  ldns_zone_deep_free(orig_zone);
1120  ldns_rr_list_deep_free(added_rrs);
1121  ldns_rdf_deep_free(origin);
1122  LDNS_FREE(outputfile_name);
1123 
1124 #ifndef OPENSSL_NO_ENGINE
1125  shutdown_openssl ( engine );
1126 #else
1127 #if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
1128 #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
1129  CRYPTO_cleanup_all_ex_data ();
1130 #endif
1131 #endif
1132 #endif
1133 
1134  free(prog);
1135  exit(EXIT_SUCCESS);
1136 }
1137 
1138 #else /* !HAVE_SSL */
1139 int
1140 main(int argc __attribute__((unused)),
1141  char **argv __attribute__((unused)))
1142 {
1143  fprintf(stderr, "ldns-signzone needs OpenSSL support, which has not been compiled in\n");
1144  return 1;
1145 }
1146 #endif /* HAVE_SSL */
#define ATTR_UNUSED(x)
Definition: common.h:72
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf's according to the algorithm for ordering in RFC4034 Section 6.
Definition: dname.c:359
int ldns_dnssec_default_replace_signatures(ldns_rr *sig __attribute__((unused)), void *n __attribute__((unused)))
Definition: dnssec.c:1737
uint16_t ldns_calc_keytag(const ldns_rr *key)
calculates a keytag of a key for use in DNSSEC.
Definition: dnssec.c:277
#define LDNS_NSEC3_MAX_ITERATIONS
Definition: dnssec.h:87
ldns_status ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt, int signflags, ldns_rbtree_t **map)
signs the given zone with the given new zone, with NSEC3
Definition: dnssec_sign.c:1460
ldns_status ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone, ldns_rr_list *new_rrs, ldns_key_list *key_list, int(*func)(ldns_rr *, void *), void *arg, int flags)
signs the given zone with the given keys
Definition: dnssec_sign.c:1373
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384
Definition: dnssec_sign.h:18
#define LDNS_SIGN_DNSKEY_WITH_ZSK
dnssec_verify
Definition: dnssec_sign.h:15
#define LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512
Definition: dnssec_sign.h:19
#define LDNS_SIGN_WITH_ALL_ALGORITHMS
Definition: dnssec_sign.h:16
#define LDNS_SIGN_NO_KEYS_NO_NSECS
Definition: dnssec_sign.h:17
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:1085
void ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:1113
ldns_status ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr)
Adds the given RR to the zone.
Definition: dnssec_zone.c:1006
void ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
Frees the given zone structure, and its rbtree of dnssec_names Individual ldns_rr RRs within those na...
Definition: dnssec_zone.c:869
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition: dnssec_zone.c:570
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition: error.c:191
@ LDNS_STATUS_NULL
Definition: error.h:51
@ LDNS_STATUS_ERR
Definition: error.h:37
@ LDNS_STATUS_OK
Definition: error.h:26
enum ldns_enum_status ldns_status
Definition: error.h:146
void ldns_rr_print(FILE *output, const ldns_rr *rr)
Prints the data in the resource record to the given file stream (in presentation format)
Definition: host2str.c:3411
char * ldns_rdf2str(const ldns_rdf *rdf)
Converts the data in the rdata field to presentation format and returns that as a char *.
Definition: host2str.c:3268
#define LDNS_COMMENT_BUBBLEBABBLE
Provide bubblebabble representation for DS RR's as comment.
Definition: host2str.h:56
#define LDNS_COMMENT_FLAGS
Show when a NSEC3 RR has the optout flag set as comment.
Definition: host2str.h:58
#define LDNS_COMMENT_NSEC3_CHAIN
Show the unhashed owner and next owner names for NSEC3 RR's as comment.
Definition: host2str.h:60
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
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:417
void ldns_key_list_free(ldns_key_list *key_list)
Frees a key list structure.
Definition: keys.c:2073
bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
pushes a key to a keylist
Definition: keys.c:1600
void ldns_key_set_expiration(ldns_key *k, uint32_t e)
Set the key's expiration date (seconds after epoch)
Definition: keys.c:1428
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,...
Definition: keys.c:1803
void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
Set the key's pubkey owner.
Definition: keys.c:1434
ldns_key_list * ldns_key_list_new(void)
Creates a new empty key list.
Definition: keys.c:66
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
Definition: keys.c:1571
void ldns_key_set_keytag(ldns_key *k, uint16_t tag)
Set the key's key tag.
Definition: keys.c:1440
ldns_rdf * ldns_key_pubkey_owner(const ldns_key *k)
return the public key's owner
Definition: keys.c:1577
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:112
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
Definition: keys.c:1553
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:1447
void ldns_key_set_flags(ldns_key *k, uint16_t f)
Set the key's flags.
Definition: keys.c:1342
void ldns_key_set_inception(ldns_key *k, uint32_t i)
Set the key's inception date (seconds after epoch)
Definition: keys.c:1422
Addendum to dnssec.h, this module contains key and algorithm definitions and functions.
#define LDNS_KEY_SEP_KEY
Definition: keys.h:38
ldns_enum_signing_algorithm
Algorithms used in dns for signing.
Definition: keys.h:82
@ LDNS_SIGN_RSASHA1
Definition: keys.h:84
@ LDNS_SIGN_ECDSAP256SHA256
Definition: keys.h:95
@ LDNS_SIGN_DSA_NSEC3
Definition: keys.h:92
@ LDNS_SIGN_ECC_GOST
Definition: keys.h:94
@ LDNS_SIGN_RSASHA1_NSEC3
Definition: keys.h:88
@ LDNS_SIGN_ECDSAP384SHA384
Definition: keys.h:96
@ LDNS_SIGN_RSAMD5
Definition: keys.h:83
@ LDNS_SIGN_RSASHA512
Definition: keys.h:90
@ LDNS_SIGN_DSA
Definition: keys.h:86
@ LDNS_SIGN_RSASHA256
Definition: keys.h:89
enum ldns_enum_algorithm ldns_algorithm
Definition: keys.h:64
int main(int argc, char *argv[])
int verbosity
Definition: ldns-signzone.c:33
int str2zonemd_signflag(const char *str, const char **reason)
#define __LIST(x)
#define __MATCH(x)
char * prog
Definition: ldns-signzone.c:32
#define MAX_FILENAME_LEN
Definition: ldns-signzone.c:30
Including this file will include all ldns files, and define some lookup tables.
#define LDNS_DEFAULT_TTL
Definition: ldns.h:136
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition: rdata.c:84
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
#define LDNS_NSEC3_VARS_OPTOUT_MASK
Definition: rdata.h:40
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:990
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition: rr.c:931
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:919
ldns_status ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
creates a new rr from a file containing a string.
Definition: rr.c:796
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1020
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:81
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition: rr.c:957
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:943
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition: rr.c:816
int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs, up to the rdata.
Definition: rr.c:1559
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:1000
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:909
@ LDNS_RR_TYPE_DNSKEY
Definition: rr.h:172
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
@ LDNS_RR_CLASS_IN
the Internet
Definition: rr.h:47
uint32_t ldns_soa_serial_unixtime(uint32_t s, void *data)
Function to be used with ldns_rr_soa_increment_func or ldns_rr_soa_increment_func_int to set the soa ...
Definition: rr_functions.c:383
void ldns_rr_soa_increment_func_int(ldns_rr *soa, ldns_soa_serial_increment_func_t f, int data)
Increment the serial number of the given SOA with the given function using data as an argument for th...
Definition: rr_functions.c:426
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
Definition: str2host.c:311
Structure containing a dnssec zone.
Definition: dnssec_zone.h:91
Same as rr_list, but now for keys.
Definition: keys.h:173
General key structure, can contain all types of keys that are used in DNSSEC.
Definition: keys.h:122
struct ldns_struct_key::@1::@3 dnssec
Some values that influence generated signatures.
Output format struct with additional data for flags that use them.
Definition: host2str.h:103
Output format specifier.
Definition: host2str.h:89
Resource record data field.
Definition: rdata.h:197
List or Set of Resource Records.
Definition: rr.h:338
Resource Record.
Definition: rr.h:310
DNS Zone.
Definition: zone.h:43
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
Definition: util.c:88
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
Definition: util.c:194
const char * ldns_version(void)
Show the internal library version.
Definition: util.c:160
#define LDNS_FREE(ptr)
Definition: util.h:60
#define LDNS_VERSION
Definition: util.h:30
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone's content.
Definition: zone.c:35
void ldns_zone_deep_free(ldns_zone *zone)
Frees the allocated memory for the zone, the soa rr in it, and the rr_list structure in it,...
Definition: zone.c:376
bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
push an single rr to a zone structure.
Definition: zone.c:53
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, const ldns_rdf *origin, uint32_t default_ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: zone.c:198