ldns documentation

- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

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 "config.h"
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include <errno.h>
13
14 #include <time.h>
15
16 #include <ldns/ldns.h>
17 #include <ldns/keys.h>
18
19 #ifdef HAVE_SSL
20 #include <openssl/conf.h>
21 #include <openssl/engine.h>
22 #endif /* HAVE_SSL */
23
24 #define MAX_FILENAME_LEN 250
25 int verbosity = 1;
26
27 #ifdef HAVE_SSL
28 #include <openssl/err.h>
29
30 static void
31 usage(FILE *fp, const char *prog) {
32 fprintf(fp, "%s [OPTIONS] zonefile key [key [key]]\n", prog);
33 fprintf(fp, " signs the zone with the given key(s)\n");
34 fprintf(fp, " -b\t\tuse layout in signed zone and print comments DNSSEC records\n");
35 fprintf(fp, " -d\t\tused keys are not added to the zone\n");
36 fprintf(fp, " -e <date>\texpiration date\n");
37 fprintf(fp, " -f <file>\toutput zone to file (default <name>.signed)\n");
38 fprintf(fp, " -i <date>\tinception date\n");
39 fprintf(fp, " -o <domain>\torigin for the zone\n");
40 fprintf(fp, " -v\t\tprint version and exit\n");
41 fprintf(fp, " -A\t\tsign DNSKEY with all keys instead of minimal\n");
42 fprintf(fp, " -E <name>\tuse <name> as the crypto engine for signing\n");
43 fprintf(fp, " \tThis can have a lot of extra options, see the manual page for more info\n");
44 fprintf(fp, " -k <id>,<int>\tuse key id with algorithm int from engine\n");
45 fprintf(fp, " -K <id>,<int>\tuse key id with algorithm int from engine as KSK\n");
46 fprintf(fp, "\t\tif no key is given (but an external one is used through the engine support, it might be necessary to provide the right algorithm number.\n");
47 fprintf(fp, " -n\t\tuse NSEC3 instead of NSEC.\n");
48 fprintf(fp, "\t\tIf you use NSEC3, you can specify the following extra options:\n");
49 fprintf(fp, "\t\t-a [algorithm] hashing algorithm\n");
50 fprintf(fp, "\t\t-t [number] number of hash iterations\n");
51 fprintf(fp, "\t\t-s [string] salt\n");
52 fprintf(fp, "\t\t-p set the opt-out flag on all nsec3 rrs\n");
53 fprintf(fp, "\n");
54 fprintf(fp, " keys must be specified by their base name (usually K<name>+<alg>+<id>),\n");
55 fprintf(fp, " i.e. WITHOUT the .private extension.\n");
56 fprintf(fp, " If the public part of the key is not present in the zone, the DNSKEY RR\n");
57 fprintf(fp, " will be read from the file called <base name>.key. If that does not exist,\n");
58 fprintf(fp, " a default DNSKEY will be generated from the private key and added to the zone.\n");
59 fprintf(fp, " A date can be a timestamp (seconds since the epoch), or of\n the form <YYYYMMdd[hhmmss]>\n");
60 }
61
62 static void check_tm(struct tm tm)
63 {
64 if (tm.tm_year < 70) {
65 fprintf(stderr, "You cannot specify dates before 1970\n");
66 exit(EXIT_FAILURE);
67 }
68 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
69 fprintf(stderr, "The month must be in the range 1 to 12\n");
70 exit(EXIT_FAILURE);
71 }
72 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
73 fprintf(stderr, "The day must be in the range 1 to 31\n");
74 exit(EXIT_FAILURE);
75 }
76
77 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
78 fprintf(stderr, "The hour must be in the range 0-23\n");
79 exit(EXIT_FAILURE);
80 }
81
82 if (tm.tm_min < 0 || tm.tm_min > 59) {
83 fprintf(stderr, "The minute must be in the range 0-59\n");
84 exit(EXIT_FAILURE);
85 }
86
87 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
88 fprintf(stderr, "The second must be in the range 0-59\n");
89 exit(EXIT_FAILURE);
90 }
91
92 }
93
94 /*
95 * if the ttls are different, make them equal
96 * if one of the ttls equals LDNS_DEFAULT_TTL, that one is changed
97 * otherwise, rr2 will get the ttl of rr1
98 *
99 * prints a warning if a non-default TTL is changed
100 */
101 static void
102 equalize_ttls(ldns_rr *rr1, ldns_rr *rr2, uint32_t default_ttl)
103 {
104 uint32_t ttl1, ttl2;
105
106 ttl1 = ldns_rr_ttl(rr1);
107 ttl2 = ldns_rr_ttl(rr2);
108
109 if (ttl1 != ttl2) {
110 if (ttl1 == default_ttl) {
111 ldns_rr_set_ttl(rr1, ttl2);
112 } else if (ttl2 == default_ttl) {
113 ldns_rr_set_ttl(rr2, ttl1);
114 } else {
115 ldns_rr_set_ttl(rr2, ttl1);
116 fprintf(stderr,
117 "warning: changing non-default TTL %u to %u\n",
118 (unsigned int) ttl2, (unsigned int) ttl1);
119 }
120 }
121 }
122
123 static void
124 equalize_ttls_rr_list(ldns_rr_list *rr_list, ldns_rr *rr, uint32_t default_ttl)
125 {
126 size_t i;
127 ldns_rr *cur_rr;
128
129 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
130 cur_rr = ldns_rr_list_rr(rr_list, i);
131 if (ldns_rr_compare_no_rdata(cur_rr, rr) == 0) {
132 equalize_ttls(cur_rr, rr, default_ttl);
133 }
134 }
135 }
136
137 static ldns_rr *
138 find_key_in_zone(ldns_rr *pubkey_gen, ldns_zone *zone) {
139 size_t key_i;
140 ldns_rr *pubkey;
141
142 for (key_i = 0;
143 key_i < ldns_rr_list_rr_count(ldns_zone_rrs(zone));
144 key_i++) {
145 pubkey = ldns_rr_list_rr(ldns_zone_rrs(zone), key_i);
146 if (ldns_rr_get_type(pubkey) == LDNS_RR_TYPE_DNSKEY &&
147 (ldns_calc_keytag(pubkey)
148 ==
149 ldns_calc_keytag(pubkey_gen) ||
150 /* KSK has gen-keytag + 1 */
151 ldns_calc_keytag(pubkey)
152 ==
153 ldns_calc_keytag(pubkey_gen) + 1)
154 ) {
155 if (verbosity >= 2) {
156 fprintf(stderr, "Found it in the zone!\n");
157 }
158 return pubkey;
159 }
160 }
161 return NULL;
162 }
163
164 static ldns_rr *
165 find_key_in_file(const char *keyfile_name_base, ldns_key* ATTR_UNUSED(key),
166 uint32_t zone_ttl)
167 {
168 char *keyfile_name;
169 FILE *keyfile;
170 int line_nr;
171 uint32_t default_ttl = zone_ttl;
172
173 ldns_rr *pubkey = NULL;
174 keyfile_name = LDNS_XMALLOC(char,
175 strlen(keyfile_name_base) + 5);
176 snprintf(keyfile_name,
177 strlen(keyfile_name_base) + 5,
178 "%s.key",
179 keyfile_name_base);
180 if (verbosity >= 2) {
181 fprintf(stderr, "Trying to read %s\n", keyfile_name);
182 }
183 keyfile = fopen(keyfile_name, "r");
184 line_nr = 0;
185 if (keyfile) {
186 if (ldns_rr_new_frm_fp_l(&pubkey,
187 keyfile,
188 &default_ttl,
189 NULL,
190 NULL,
191 &line_nr) ==
192 LDNS_STATUS_OK) {
193 if (verbosity >= 2) {
194 printf("Key found in file: %s\n", keyfile_name);
195 }
196 }
197 fclose(keyfile);
198 }
199 LDNS_FREE(keyfile_name);
200 return pubkey;
201 }
202
203 /* this function tries to find the specified keys either in the zone that
204 * has been read, or in a <basename>.key file. If the key is not found,
205 * a public key is generated, and it is assumed the key is a ZSK
206 *
207 * if add_keys is true; the DNSKEYs are added to the zone prior to signing
208 * if it is false, they are not added.
209 * Even if keys are not added, the function is still needed, to check
210 * whether keys of which we only have key data are KSKs or ZSKS
211 */
212 static void
213 find_or_create_pubkey(const char *keyfile_name_base, ldns_key *key, ldns_zone *orig_zone, bool add_keys, uint32_t default_ttl) {
214 ldns_rr *pubkey_gen, *pubkey;
215 int key_in_zone;
216
217 if (default_ttl == LDNS_DEFAULT_TTL) {
218 default_ttl = ldns_rr_ttl(ldns_zone_soa(orig_zone));
219 }
220
221 if (!ldns_key_pubkey_owner(key)) {
222 ldns_key_set_pubkey_owner(key, ldns_rdf_clone(ldns_rr_owner(ldns_zone_soa(orig_zone))));
223 }
224
225 /* find the public key in the zone, or in a
226 * separate file
227 * we 'generate' one anyway,
228 * then match that to any present in the zone,
229 * if it matches, we drop our own. If not,
230 * we try to see if there is a .key file present.
231 * If not, we use our own generated one, with
232 * some default values
233 *
234 * Even if -d (do-not-add-keys) is specified,
235 * we still need to do this, because we need
236 * to have any key flags that are set this way
237 */
238 pubkey_gen = ldns_key2rr(key);
239 ldns_rr_set_ttl(pubkey_gen, default_ttl);
240
241 if (verbosity >= 2) {
242 fprintf(stderr,
243 "Looking for key with keytag %u or %u\n",
244 (unsigned int) ldns_calc_keytag(pubkey_gen),
245 (unsigned int) ldns_calc_keytag(pubkey_gen)+1
246 );
247 }
248
249 pubkey = find_key_in_zone(pubkey_gen, orig_zone);
250 key_in_zone = 1;
251 if (!pubkey) {
252 key_in_zone = 0;
253 /* it was not in the zone, try to read a .key file */
254 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
255 if (!pubkey && !(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
256 /* maybe it is a ksk? */
257 ldns_key_set_keytag(key, ldns_key_keytag(key) + 1);
258 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
259 if (!pubkey) {
260 /* ok, no file, set back to ZSK */
261 ldns_key_set_keytag(key, ldns_key_keytag(key) - 1);
262 }
263 }
264 if(pubkey && ldns_dname_compare(ldns_rr_owner(pubkey), ldns_rr_owner(ldns_zone_soa(orig_zone))) != 0) {
265 fprintf(stderr, "Error %s.key has wrong name: %s\n",
266 keyfile_name_base, ldns_rdf2str(ldns_rr_owner(pubkey)));
267 exit(EXIT_FAILURE); /* leak rdf2str, but we exit */
268 }
269 }
270
271 if (!pubkey) {
272 /* okay, no public key found,
273 just use our generated one */
274 pubkey = pubkey_gen;
275 if (verbosity >= 2) {
276 fprintf(stderr, "Not in zone, no .key file, generating ZSK DNSKEY from private key data\n");
277 }
278 } else {
279 ldns_rr_free(pubkey_gen);
280 }
281 ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
282 ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
283
284 if (add_keys && !key_in_zone) {
285 equalize_ttls_rr_list(ldns_zone_rrs(orig_zone), pubkey, default_ttl);
286 ldns_zone_push_rr(orig_zone, pubkey);
287 }
288 }
289
290 void
291 strip_dnssec_records(ldns_zone *zone)
292 {
293 ldns_rr_list *new_list;
294 ldns_rr *cur_rr;
295
296 new_list = ldns_rr_list_new();
297
298 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(zone)))) {
299 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG ||
300 ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC ||
301 ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC3
302 ) {
303
304 ldns_rr_free(cur_rr);
305 } else {
306 ldns_rr_list_push_rr(new_list, cur_rr);
307 }
308 }
309 ldns_rr_list_free(ldns_zone_rrs(zone));
310 ldns_zone_set_rrs(zone, new_list);
311 }
312
313 int
314 main(int argc, char *argv[])
315 {
316 const char *zonefile_name;
317 FILE *zonefile = NULL;
318 int line_nr = 0;
319 int c;
320 int argi;
321 ENGINE *engine = NULL;
322
323 ldns_zone *orig_zone;
324 ldns_rr_list *orig_rrs = NULL;
325 ldns_rr *orig_soa = NULL;
326 ldns_dnssec_zone *signed_zone;
327
328 char *keyfile_name_base;
329 char *keyfile_name = NULL;
330 FILE *keyfile = NULL;
331 ldns_key *key = NULL;
332 ldns_key_list *keys;
333 ldns_status s;
334 size_t i;
335 ldns_rr_list *added_rrs;
336
337 char *outputfile_name = NULL;
338 FILE *outputfile;
339
340 /* tmp vars for engine keys */
341 char *eng_key_l;
342 size_t eng_key_id_len;
343 char *eng_key_id;
344 int eng_key_algo;
345
346 bool use_nsec3 = false;
347 int signflags = 0;
348
349 /* Add the given keys to the zone if they are not yet present */
350 bool add_keys = true;
351 uint8_t nsec3_algorithm = 1;
352 uint8_t nsec3_flags = 0;
353 size_t nsec3_iterations_cmd = 1;
354 uint16_t nsec3_iterations = 1;
355 uint8_t nsec3_salt_length = 0;
356 uint8_t *nsec3_salt = NULL;
357
358 /* we need to know the origin before reading ksk's,
359 * so keep an array of filenames until we know it
360 */
361 struct tm tm;
362 uint32_t inception;
363 uint32_t expiration;
364 ldns_rdf *origin = NULL;
365 uint32_t ttl = LDNS_DEFAULT_TTL;
366 ldns_rr_class class = LDNS_RR_CLASS_IN;
367
368 char *prog = strdup(argv[0]);
369 ldns_status result;
370
371 ldns_output_format_storage fmt_st;
372 ldns_output_format* fmt = ldns_output_format_init(&fmt_st);
373
374 inception = 0;
375 expiration = 0;
376
377 keys = ldns_key_list_new();
378
379 OPENSSL_config(NULL);
380
381 while ((c = getopt(argc, argv, "a:bde:f:i:k:no:ps:t:vAE:K:")) != -1) {
382 switch (c) {
383 case 'a':
384 nsec3_algorithm = (uint8_t) atoi(optarg);
385 if (nsec3_algorithm != 1) {
386 fprintf(stderr, "Bad NSEC3 algorithm, only RSASHA1 allowed\n");
387 exit(EXIT_FAILURE);
388 }
389 break;
390 case 'b':
391 ldns_output_format_set(fmt, LDNS_COMMENT_FLAGS
392 | LDNS_COMMENT_LAYOUT
393 | LDNS_COMMENT_NSEC3_CHAIN
394 | LDNS_COMMENT_BUBBLEBABBLE);
395 break;
396 case 'd':
397 add_keys = false;
398 break;
399 case 'e':
400 /* try to parse YYYYMMDD first,
401 * if that doesn't work, it
402 * should be a timestamp (seconds since epoch)
403 */
404 memset(&tm, 0, sizeof(tm));
405
406 if (strlen(optarg) == 8 &&
407 sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
408 ) {
409 tm.tm_year -= 1900;
410 tm.tm_mon--;
411 check_tm(tm);
412 expiration =
413 (uint32_t) ldns_mktime_from_utc(&tm);
414 } else if (strlen(optarg) == 14 &&
415 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)
416 ) {
417 tm.tm_year -= 1900;
418 tm.tm_mon--;
419 check_tm(tm);
420 expiration =
421 (uint32_t) ldns_mktime_from_utc(&tm);
422 } else {
423 expiration = (uint32_t) atol(optarg);
424 }
425 break;
426 case 'f':
427 outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
428 strncpy(outputfile_name, optarg, MAX_FILENAME_LEN);
429 break;
430 case 'i':
431 memset(&tm, 0, sizeof(tm));
432
433 if (strlen(optarg) == 8 &&
434 sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
435 ) {
436 tm.tm_year -= 1900;
437 tm.tm_mon--;
438 check_tm(tm);
439 inception =
440 (uint32_t) ldns_mktime_from_utc(&tm);
441 } else if (strlen(optarg) == 14 &&
442 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)
443 ) {
444 tm.tm_year -= 1900;
445 tm.tm_mon--;
446 check_tm(tm);
447 inception =
448 (uint32_t) ldns_mktime_from_utc(&tm);
449 } else {
450 inception = (uint32_t) atol(optarg);
451 }
452 break;
453 case 'n':
454 use_nsec3 = true;
455 break;
456 case 'o':
457 if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
458 fprintf(stderr, "Bad origin, not a correct domain name\n");
459 usage(stderr, prog);
460 exit(EXIT_FAILURE);
461 }
462 break;
463 case 'p':
464 nsec3_flags = nsec3_flags | LDNS_NSEC3_VARS_OPTOUT_MASK;
465 break;
466 case 'v':
467 printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
468 exit(EXIT_SUCCESS);
469 break;
470 case 'A':
471 signflags |= LDNS_SIGN_DNSKEY_WITH_ZSK;
472 break;
473 case 'E':
474 ENGINE_load_builtin_engines();
475 ENGINE_load_dynamic();
476 ENGINE_load_cryptodev();
477 engine = ENGINE_by_id(optarg);
478 if (!engine) {
479 printf("No such engine: %s\n", optarg);
480 engine = ENGINE_get_first();
481 printf("Available engines:\n");
482 while (engine) {
483 printf("%s\n", ENGINE_get_id(engine));
484 engine = ENGINE_get_next(engine);
485 }
486 exit(EXIT_FAILURE);
487 } else {
488 if (!ENGINE_init(engine)) {
489 printf("The engine couldn't initialize\n");
490 exit(EXIT_FAILURE);
491 }
492 ENGINE_set_default_RSA(engine);
493 ENGINE_set_default_DSA(engine);
494 ENGINE_set_default(engine, 0);
495 }
496 break;
497 case 'k':
498 eng_key_l = strchr(optarg, ',');
499 if (eng_key_l && strlen(eng_key_l) > 1) {
500 if (eng_key_l > optarg) {
501 eng_key_id_len = (size_t) (eng_key_l - optarg);
502 eng_key_id = malloc(eng_key_id_len + 1);
503 memcpy(eng_key_id, optarg, eng_key_id_len);
504 eng_key_id[eng_key_id_len] = '\0';
505 } else {
506 /* no id given, use default from engine */
507 eng_key_id = NULL;
508 }
509
510 eng_key_algo = atoi(eng_key_l + 1);
511
512 printf("Engine key id: %s, algo %d\n", eng_key_id, eng_key_algo);
513
514 s = ldns_key_new_frm_engine(&key, engine, eng_key_id, eng_key_algo);
515 if (s == LDNS_STATUS_OK) {
516 /* must be dnssec key */
517 switch (ldns_key_algorithm(key)) {
518 case LDNS_SIGN_RSAMD5:
519 case LDNS_SIGN_RSASHA1:
520 case LDNS_SIGN_RSASHA1_NSEC3:
521 case LDNS_SIGN_RSASHA256:
522 case LDNS_SIGN_RSASHA512:
523 case LDNS_SIGN_DSA:
524 case LDNS_SIGN_DSA_NSEC3:
525 case LDNS_SIGN_ECC_GOST:
526 #ifdef USE_ECDSA
527 case LDNS_SIGN_ECDSAP256SHA256:
528 case LDNS_SIGN_ECDSAP384SHA384:
529 #endif
530 ldns_key_list_push_key(keys, key);
531 /*printf("Added key at %p:\n", key);*/
532 /*ldns_key_print(stdout, key);*/
533 break;
534 default:
535 fprintf(stderr, "Warning, key not suitable for signing, ignoring key with algorithm %u\n", ldns_key_algorithm(key));
536 break;
537 }
538 if (expiration != 0) {
539 ldns_key_set_expiration(key,
540 expiration);
541 }
542 if (inception != 0) {
543 ldns_key_set_inception(key,
544 inception);
545 }
546 } else {
547 printf("Error reading key '%s' from engine: %s\n", eng_key_id, ldns_get_errorstr_by_id(s));
548 #ifdef HAVE_SSL
549 if (ERR_peek_error()) {
550 ERR_load_crypto_strings();
551 ERR_print_errors_fp(stderr);
552 ERR_free_strings();
553 }
554 #endif
555 exit(EXIT_FAILURE);
556 }
557
558 if (eng_key_id) {
559 free(eng_key_id);
560 }
561 } else {
562 printf("Error: bad engine key specification (should be: -k <id>,<algorithm>)).\n");
563 exit(EXIT_FAILURE);
564 }
565 break;
566 case 'K':
567 printf("Not implemented yet\n");
568 exit(EXIT_FAILURE);
569 break;
570 case 's':
571 if (strlen(optarg) % 2 != 0) {
572 fprintf(stderr, "Salt value is not valid hex data, not a multiple of 2 characters\n");
573 exit(EXIT_FAILURE);
574 }
575 nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
576 nsec3_salt = LDNS_XMALLOC(uint8_t, nsec3_salt_length);
577 for (c = 0; c < (int) strlen(optarg); c += 2) {
578 if (isxdigit((int) optarg[c]) && isxdigit((int) optarg[c+1])) {
579 nsec3_salt[c/2] = (uint8_t) ldns_hexdigit_to_int(optarg[c]) * 16 +
580 ldns_hexdigit_to_int(optarg[c+1]);
581 } else {
582 fprintf(stderr, "Salt value is not valid hex data.\n");
583 exit(EXIT_FAILURE);
584 }
585 }
586
587 break;
588 case 't':
589 nsec3_iterations_cmd = (size_t) atol(optarg);
590 if (nsec3_iterations_cmd > LDNS_NSEC3_MAX_ITERATIONS) {
591 fprintf(stderr, "Iterations count can not exceed %u, quitting\n", LDNS_NSEC3_MAX_ITERATIONS);
592 exit(EXIT_FAILURE);
593 }
594 nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
595 break;
596 default:
597 usage(stderr, prog);
598 exit(EXIT_SUCCESS);
599 }
600 }
601
602 argc -= optind;
603 argv += optind;
604
605 if (argc < 1) {
606 printf("Error: not enough arguments\n");
607 usage(stdout, prog);
608 exit(EXIT_FAILURE);
609 } else {
610 zonefile_name = argv[0];
611 }
612
613 /* read zonefile first to find origin if not specified */
614
615 if (strncmp(zonefile_name, "-", 2) == 0) {
616 s = ldns_zone_new_frm_fp_l(&orig_zone,
617 stdin,
618 origin,
619 ttl,
620 class,
621 &line_nr);
622 if (s != LDNS_STATUS_OK) {
623 fprintf(stderr, "Zone not read, error: %s at stdin line %d\n",
624 ldns_get_errorstr_by_id(s),
625 line_nr);
626 exit(EXIT_FAILURE);
627 } else {
628 orig_soa = ldns_zone_soa(orig_zone);
629 if (!orig_soa) {
630 fprintf(stderr,
631 "Error reading zonefile: missing SOA record\n");
632 exit(EXIT_FAILURE);
633 }
634 orig_rrs = ldns_zone_rrs(orig_zone);
635 if (!orig_rrs) {
636 fprintf(stderr,
637 "Error reading zonefile: no resource records\n");
638 exit(EXIT_FAILURE);
639 }
640 }
641 } else {
642 zonefile = fopen(zonefile_name, "r");
643
644 if (!zonefile) {
645 fprintf(stderr,
646 "Error: unable to read %s (%s)\n",
647 zonefile_name,
648 strerror(errno));
649 exit(EXIT_FAILURE);
650 } else {
651 s = ldns_zone_new_frm_fp_l(&orig_zone,
652 zonefile,
653 origin,
654 ttl,
655 class,
656 &line_nr);
657 if (s != LDNS_STATUS_OK) {
658 fprintf(stderr, "Zone not read, error: %s at %s line %d\n",
659 ldns_get_errorstr_by_id(s),
660 zonefile_name, line_nr);
661 exit(EXIT_FAILURE);
662 } else {
663 orig_soa = ldns_zone_soa(orig_zone);
664 if (!orig_soa) {
665 fprintf(stderr,
666 "Error reading zonefile: missing SOA record\n");
667 exit(EXIT_FAILURE);
668 }
669 orig_rrs = ldns_zone_rrs(orig_zone);
670 if (!orig_rrs) {
671 fprintf(stderr,
672 "Error reading zonefile: no resource records\n");
673 exit(EXIT_FAILURE);
674 }
675 }
676 fclose(zonefile);
677 }
678 }
679
680 /* read the ZSKs */
681 argi = 1;
682 while (argi < argc) {
683 keyfile_name_base = argv[argi];
684 keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
685 snprintf(keyfile_name,
686 strlen(keyfile_name_base) + 9,
687 "%s.private",
688 keyfile_name_base);
689 keyfile = fopen(keyfile_name, "r");
690 line_nr = 0;
691 if (!keyfile) {
692 fprintf(stderr,
693 "Error: unable to read %s: %s\n",
694 keyfile_name,
695 strerror(errno));
696 } else {
697 s = ldns_key_new_frm_fp_l(&key, keyfile, &line_nr);
698 fclose(keyfile);
699 if (s == LDNS_STATUS_OK) {
700 /* set times in key? they will end up
701 in the rrsigs
702 */
703 if (expiration != 0) {
704 ldns_key_set_expiration(key, expiration);
705 }
706 if (inception != 0) {
707 ldns_key_set_inception(key, inception);
708 }
709
710 LDNS_FREE(keyfile_name);
711
712 ldns_key_list_push_key(keys, key);
713 } else {
714 fprintf(stderr, "Error reading key from %s at line %d: %s\n", argv[argi], line_nr, ldns_get_errorstr_by_id(s));
715 }
716 }
717 /* and, if not unset by -p, find or create the corresponding DNSKEY record */
718 if (key) {
719 find_or_create_pubkey(keyfile_name_base, key,
720 orig_zone, add_keys, ttl);
721 }
722 argi++;
723 }
724
725 if (ldns_key_list_key_count(keys) < 1) {
726 fprintf(stderr, "Error: no keys to sign with. Aborting.\n\n");
727 usage(stderr, prog);
728 exit(EXIT_FAILURE);
729 }
730
731 signed_zone = ldns_dnssec_zone_new();
732 if (ldns_dnssec_zone_add_rr(signed_zone, ldns_zone_soa(orig_zone)) !=
733 LDNS_STATUS_OK) {
734 fprintf(stderr,
735 "Error adding SOA to dnssec zone, skipping record\n");
736 }
737
738 for (i = 0;
739 i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone));
740 i++) {
741 if (ldns_dnssec_zone_add_rr(signed_zone,
742 ldns_rr_list_rr(ldns_zone_rrs(orig_zone),
743 i)) !=
744 LDNS_STATUS_OK) {
745 fprintf(stderr,
746 "Error adding RR to dnssec zone");
747 fprintf(stderr, ", skipping record:\n");
748 ldns_rr_print(stderr,
749 ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i));
750 }
751 }
752
753 /* list to store newly created rrs, so we can free them later */
754 added_rrs = ldns_rr_list_new();
755
756 if (use_nsec3) {
757 result = ldns_dnssec_zone_sign_nsec3_flg_mkmap(signed_zone,
758 added_rrs,
759 keys,
760 ldns_dnssec_default_replace_signatures,
761 NULL,
762 nsec3_algorithm,
763 nsec3_flags,
764 nsec3_iterations,
765 nsec3_salt_length,
766 nsec3_salt,
767 signflags,
768 &fmt_st.hashmap);
769 } else {
770 result = ldns_dnssec_zone_sign_flg(signed_zone,
771 added_rrs,
772 keys,
773 ldns_dnssec_default_replace_signatures,
774 NULL,
775 signflags);
776 }
777 if (result != LDNS_STATUS_OK) {
778 fprintf(stderr, "Error signing zone: %s\n",
779 ldns_get_errorstr_by_id(result));
780 }
781
782 if (!outputfile_name) {
783 outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
784 snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
785 }
786
787 if (signed_zone) {
788 if (strncmp(outputfile_name, "-", 2) == 0) {
789 ldns_dnssec_zone_print(stdout, signed_zone);
790 } else {
791 outputfile = fopen(outputfile_name, "w");
792 if (!outputfile) {
793 fprintf(stderr, "Unable to open %s for writing: %s\n",
794 outputfile_name, strerror(errno));
795 } else {
796 ldns_dnssec_zone_print_fmt(
797 outputfile, fmt, signed_zone);
798 fclose(outputfile);
799 }
800 }
801 } else {
802 fprintf(stderr, "Error signing zone.\n");
803
804 #ifdef HAVE_SSL
805 if (ERR_peek_error()) {
806 ERR_load_crypto_strings();
807 ERR_print_errors_fp(stderr);
808 ERR_free_strings();
809 }
810 #endif
811 exit(EXIT_FAILURE);
812 }
813
814 ldns_key_list_free(keys);
815 /* since the ldns_rr records are pointed to in both the ldns_zone
816 * and the ldns_dnssec_zone, we can either deep_free the
817 * dnssec_zone and 'shallow' free the original zone and added
818 * records, or the other way around
819 */
820 ldns_dnssec_zone_free(signed_zone);
821 ldns_zone_deep_free(orig_zone);
822 ldns_rr_list_deep_free(added_rrs);
823
824 LDNS_FREE(outputfile_name);
825
826 CRYPTO_cleanup_all_ex_data();
827
828 free(prog);
829 exit(EXIT_SUCCESS);
830 }
831 #else
832 int
833 main(int argc, char **argv)
834 {
835 fprintf(stderr, "ldns-signzone needs OpenSSL support, which has not been compiled in\n");
836 return 1;
837 }
838 #endif /* HAVE_SSL */
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:873
LDNS_SIGN_RSASHA256
Definition: keys.h:85
LDNS_SIGN_ECDSAP256SHA256
Definition: keys.h:89
ldns_zone_set_rrs
void ldns_zone_set_rrs(ldns_zone *z, ldns_rr_list *rrlist)
Set the zone&#39;s contents.
Definition: zone.c:41
ldns_zone_soa
ldns_rr * ldns_zone_soa(const ldns_zone *z)
Return the soa record of a zone.
Definition: zone.c:17
LDNS_SIGN_DSA_NSEC3
Definition: keys.h:87
ldns_struct_output_format_storage
Output format struct with additional data for flags that use them.
Definition: host2str.h:100
ldns_key_pubkey_owner
ldns_rdf * ldns_key_pubkey_owner(const ldns_key *k)
return the public key&#39;s owner
Definition: keys.c:1206
LDNS_COMMENT_BUBBLEBABBLE
#define LDNS_COMMENT_BUBBLEBABBLE
Provide bubblebabble representation for DS RR&#39;s as comment.
Definition: host2str.h:56
LDNS_DEFAULT_TTL
#define LDNS_DEFAULT_TTL
Definition: ldns.h:135
LDNS_RR_TYPE_RRSIG
DNSSEC.
Definition: rr.h:173
ldns_dname_compare
int ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
Compares the two dname rdf&#39;s according to the algorithm for ordering in RFC4034 Section 6...
Definition: dname.c:356
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
ldns_rr_list_push_rr
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1096
LDNS_SIGN_ECC_GOST
Definition: keys.h:88
ldns_struct_rr_list
List or Set of Resource Records.
Definition: rr.h:327
ldns_str2rdf_dname
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
Definition: str2host.c:311
ldns_struct_output_format
Output format specifier.
Definition: host2str.h:86
ldns_key_set_flags
void ldns_key_set_flags(ldns_key *k, uint16_t f)
Set the key&#39;s flags.
Definition: keys.c:984
ldns_mktime_from_utc
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
Definition: util.c:194
LDNS_STATUS_OK
Definition: error.h:26
LDNS_SIGN_DNSKEY_WITH_ZSK
#define LDNS_SIGN_DNSKEY_WITH_ZSK
dnssec_verify
Definition: dnssec_sign.h:15
strip_dnssec_records
void strip_dnssec_records(ldns_zone *zone)
Definition: ldns-signzone.c:291
ldns_zone_new_frm_fp_l
ldns_status ldns_zone_new_frm_fp_l(ldns_zone **z, FILE *fp, ldns_rdf *origin, uint32_t ttl, ldns_rr_class c __attribute__((unused)), int *line_nr)
Definition: zone.c:195
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
ldns_rr_list_deep_free
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:984
ldns_struct_zone
DNS Zone.
Definition: zone.h:42
LDNS_SIGN_RSASHA1
Definition: keys.h:82
config.h
ldns_rdf_clone
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
ldns_dnssec_zone_print_fmt
void ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:959
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:75
ldns_struct_dnssec_zone
Structure containing a dnssec zone.
Definition: dnssec_zone.h:91
ldns_key_set_pubkey_owner
void ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
Set the key&#39;s pubkey owner.
Definition: keys.c:1068
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:975
LDNS_RR_TYPE_DNSKEY
Definition: rr.h:175
ldns_struct_rr
Resource Record.
Definition: rr.h:299
ldns_key_new_frm_engine
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.h
Including this file will include all ldns files, and define some lookup tables.
ldns_dnssec_zone_sign_nsec3_flg_mkmap
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:1266
verbosity
int verbosity
Definition: ldns-signzone.c:25
ldns_struct_key
General key structure, can contain all types of keys that are used in DNSSEC.
Definition: keys.h:107
ldns_struct_output_format_storage::hashmap
ldns_rbtree_t * hashmap
Definition: host2str.h:102
ldns_rr_list_rr
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:954
ldns_version
const char * ldns_version(void)
Show the internal library version.
Definition: util.c:160
ldns_dnssec_zone_add_rr
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:880
LDNS_VERSION
#define LDNS_VERSION
Definition: util.h:30
ldns_zone_push_rr
bool ldns_zone_push_rr(ldns_zone *z, ldns_rr *rr)
push an single rr to a zone structure.
Definition: zone.c:54
ATTR_UNUSED
#define ATTR_UNUSED(x)
Definition: common.h:67
ldns_rr_list_pop_rr
ldns_rr * ldns_rr_list_pop_rr(ldns_rr_list *rr_list)
pops the last rr from an rrlist.
Definition: rr.c:1141
ldns_rdf2native_int16
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition: rdata.c:84
ldns_key_set_expiration
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
LDNS_NSEC3_VARS_OPTOUT_MASK
#define LDNS_NSEC3_VARS_OPTOUT_MASK
Definition: rdata.h:40
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:964
LDNS_RR_CLASS_IN
the Internet
Definition: rr.h:50
ldns_struct_key_list
Same as rr_list, but now for keys.
Definition: keys.h:157
ldns_key_new_frm_fp_l
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
ldns_calc_keytag
uint16_t ldns_calc_keytag(const ldns_rr *key)
calculates a keytag of a key for use in DNSSEC.
Definition: dnssec.c:271
main
int main(int argc, char *argv[])
Definition: ldns-signzone.c:314
MAX_FILENAME_LEN
#define MAX_FILENAME_LEN
Definition: ldns-signzone.c:24
ldns_key_list_free
void ldns_key_list_free(ldns_key_list *key_list)
Frees a key list structure.
Definition: keys.c:1594
LDNS_RR_TYPE_NSEC
Definition: rr.h:174
ldns_key_list_push_key
bool ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
pushes a key to a keylist
Definition: keys.c:1229
LDNS_KEY_SEP_KEY
#define LDNS_KEY_SEP_KEY
Definition: keys.h:38
LDNS_SIGN_RSASHA512
Definition: keys.h:86
ldns_zone_deep_free
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:313
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:907
LDNS_RR_TYPE_NSEC3
Definition: rr.h:179
ldns_rr_compare_no_rdata
int ldns_rr_compare_no_rdata(const ldns_rr *rr1, const ldns_rr *rr2)
compares two rrs, up to the rdata.
Definition: rr.c:1522
ldns_rr_set_ttl
void ldns_rr_set_ttl(ldns_rr *rr, uint32_t ttl)
sets the ttl in the rr structure.
Definition: rr.c:780
ldns_status
enum ldns_enum_status ldns_status
Definition: error.h:131
ldns_key_set_inception
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_SIGN_RSAMD5
Definition: keys.h:81
ldns_key_algorithm
ldns_signing_algorithm ldns_key_algorithm(const ldns_key *k)
return the signing alg of the key
Definition: keys.c:1097
ldns_dnssec_zone_free
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:749
ldns_rr_new_frm_fp_l
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:680
ldns_rr_print
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:2514
ldns_key_set_keytag
void ldns_key_set_keytag(ldns_key *k, uint16_t tag)
Set the key&#39;s key tag.
Definition: keys.c:1074
LDNS_SIGN_RSASHA1_NSEC3
Definition: keys.h:84
LDNS_SIGN_DSA
Definition: keys.h:83
keys.h
Addendum to dnssec.h, this module contains key and algorithm definitions and functions.
LDNS_COMMENT_FLAGS
#define LDNS_COMMENT_FLAGS
Show when a NSEC3 RR has the optout flag set as comment.
Definition: host2str.h:58
ldns_rdf2str
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:2371
ldns_zone_rrs
ldns_rr_list * ldns_zone_rrs(const ldns_zone *z)
Get a list of a zone&#39;s content.
Definition: zone.c:35
ldns_hexdigit_to_int
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
Definition: util.c:88
ldns_dnssec_zone_print
void ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone)
Prints the complete zone to the given file descriptor.
Definition: dnssec_zone.c:987
ldns_key2rr
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
ldns_struct_rdf
Resource record data field.
Definition: rdata.h:166
ldns_dnssec_zone_new
ldns_dnssec_zone * ldns_dnssec_zone_new(void)
Creates a new dnssec_zone structure.
Definition: dnssec_zone.c:569
ldns_key_list_key_count
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
LDNS_SIGN_ECDSAP384SHA384
Definition: keys.h:90
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:883
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr&#39;s in an rr_list.
Definition: rr.c:921
LDNS_COMMENT_NSEC3_CHAIN
#define LDNS_COMMENT_NSEC3_CHAIN
Show the unhashed owner and next owner names for NSEC3 RR&#39;s as comment.
Definition: host2str.h:60
LDNS_FREE
#define LDNS_FREE(ptr)
Definition: util.h:60
ldns_key_keytag
uint16_t ldns_key_keytag(const ldns_key *k)
return the keytag
Definition: keys.c:1200
LDNS_COMMENT_LAYOUT
#define LDNS_COMMENT_LAYOUT
Print mark up.
Definition: host2str.h:62
ldns_get_errorstr_by_id
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition: error.c:150
ldns_rr_ttl
uint32_t ldns_rr_ttl(const ldns_rr *rr)
returns the ttl of an rr structure.
Definition: rr.c:895
ldns_key_flags
uint16_t ldns_key_flags(const ldns_key *k)
return the flag of the key
Definition: keys.c:1182
ldns_dnssec_default_replace_signatures
int ldns_dnssec_default_replace_signatures(ldns_rr *sig __attribute__((unused)), void *n __attribute__((unused)))
Definition: dnssec.c:1698
ldns_key_list_new
ldns_key_list * ldns_key_list_new(void)
Creates a new empty key list.
Definition: keys.c:47
ldns_dnssec_zone_sign_flg
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:1211
LDNS_NSEC3_MAX_ITERATIONS
#define LDNS_NSEC3_MAX_ITERATIONS
Definition: dnssec.h:87