00001
00002
00003
00004
00005
00006
00007
00008 #include "config.h"
00009 #include <stdlib.h>
00010 #include <unistd.h>
00011
00012 #include <errno.h>
00013
00014 #include <time.h>
00015
00016 #include <ldns/ldns.h>
00017 #include <ldns/keys.h>
00018
00019 #ifdef HAVE_SSL
00020 #include <openssl/conf.h>
00021 #include <openssl/engine.h>
00022 #endif
00023
00024 #define MAX_FILENAME_LEN 250
00025 int verbosity = 1;
00026
00027 #ifdef HAVE_SSL
00028 #include <openssl/err.h>
00029
00030 static void
00031 usage(FILE *fp, const char *prog) {
00032 fprintf(fp, "%s [OPTIONS] zonefile key [key [key]]\n", prog);
00033 fprintf(fp, " signs the zone with the given key(s)\n");
00034 fprintf(fp, " -b\t\tuse layout in signed zone and print comments DNSSEC records\n");
00035 fprintf(fp, " -d\t\tused keys are not added to the zone\n");
00036 fprintf(fp, " -e <date>\texpiration date\n");
00037 fprintf(fp, " -f <file>\toutput zone to file (default <name>.signed)\n");
00038 fprintf(fp, " -i <date>\tinception date\n");
00039 fprintf(fp, " -l\t\tLeave old DNSSEC RRSIGS and NSEC(3) records intact\n");
00040 fprintf(fp, " -o <domain>\torigin for the zone\n");
00041 fprintf(fp, " -v\t\tprint version and exit\n");
00042 fprintf(fp, " -A\t\tsign DNSKEY with all keys instead of minimal\n");
00043 fprintf(fp, " -E <name>\tuse <name> as the crypto engine for signing\n");
00044 fprintf(fp, " \tThis can have a lot of extra options, see the manual page for more info\n");
00045 fprintf(fp, " -k <id>,<int>\tuse key id with algorithm int from engine\n");
00046 fprintf(fp, " -K <id>,<int>\tuse key id with algorithm int from engine as KSK\n");
00047 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");
00048 fprintf(fp, " -n\t\tuse NSEC3 instead of NSEC.\n");
00049 fprintf(fp, "\t\tIf you use NSEC3, you can specify the following extra options:\n");
00050 fprintf(fp, "\t\t-a [algorithm] hashing algorithm\n");
00051 fprintf(fp, "\t\t-t [number] number of hash iterations\n");
00052 fprintf(fp, "\t\t-s [string] salt\n");
00053 fprintf(fp, "\t\t-p set the opt-out flag on all nsec3 rrs\n");
00054 fprintf(fp, "\n");
00055 fprintf(fp, " keys must be specified by their base name (usually K<name>+<alg>+<id>),\n");
00056 fprintf(fp, " i.e. WITHOUT the .private extension.\n");
00057 fprintf(fp, " If the public part of the key is not present in the zone, the DNSKEY RR\n");
00058 fprintf(fp, " will be read from the file called <base name>.key. If that does not exist,\n");
00059 fprintf(fp, " a default DNSKEY will be generated from the private key and added to the zone.\n");
00060 fprintf(fp, " A date can be a timestamp (seconds since the epoch), or of\n the form <YYYYMMdd[hhmmss]>\n");
00061 }
00062
00063 void
00064 usage_openssl(FILE *fp, const char *prog) {
00065 fprintf(fp, "Special commands for openssl engines:\n");
00066 fprintf(fp, "-c <file>\tOpenSSL config file\n");
00067 }
00068
00069 static void check_tm(struct tm tm)
00070 {
00071 if (tm.tm_year < 70) {
00072 fprintf(stderr, "You cannot specify dates before 1970\n");
00073 exit(EXIT_FAILURE);
00074 }
00075 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
00076 fprintf(stderr, "The month must be in the range 1 to 12\n");
00077 exit(EXIT_FAILURE);
00078 }
00079 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
00080 fprintf(stderr, "The day must be in the range 1 to 31\n");
00081 exit(EXIT_FAILURE);
00082 }
00083
00084 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
00085 fprintf(stderr, "The hour must be in the range 0-23\n");
00086 exit(EXIT_FAILURE);
00087 }
00088
00089 if (tm.tm_min < 0 || tm.tm_min > 59) {
00090 fprintf(stderr, "The minute must be in the range 0-59\n");
00091 exit(EXIT_FAILURE);
00092 }
00093
00094 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
00095 fprintf(stderr, "The second must be in the range 0-59\n");
00096 exit(EXIT_FAILURE);
00097 }
00098
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 static void
00109 equalize_ttls(ldns_rr *rr1, ldns_rr *rr2, uint32_t default_ttl)
00110 {
00111 uint32_t ttl1, ttl2;
00112
00113 ttl1 = ldns_rr_ttl(rr1);
00114 ttl2 = ldns_rr_ttl(rr2);
00115
00116 if (ttl1 != ttl2) {
00117 if (ttl1 == default_ttl) {
00118 ldns_rr_set_ttl(rr1, ttl2);
00119 } else if (ttl2 == default_ttl) {
00120 ldns_rr_set_ttl(rr2, ttl1);
00121 } else {
00122 ldns_rr_set_ttl(rr2, ttl1);
00123 fprintf(stderr,
00124 "warning: changing non-default TTL %u to %u\n",
00125 (unsigned int) ttl2, (unsigned int) ttl1);
00126 }
00127 }
00128 }
00129
00130 static void
00131 equalize_ttls_rr_list(ldns_rr_list *rr_list, ldns_rr *rr, uint32_t default_ttl)
00132 {
00133 size_t i;
00134 ldns_rr *cur_rr;
00135
00136 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00137 cur_rr = ldns_rr_list_rr(rr_list, i);
00138 if (ldns_rr_compare_no_rdata(cur_rr, rr) == 0) {
00139 equalize_ttls(cur_rr, rr, default_ttl);
00140 }
00141 }
00142 }
00143
00144 static ldns_rr *
00145 find_key_in_zone(ldns_rr *pubkey_gen, ldns_zone *zone) {
00146 size_t key_i;
00147 ldns_rr *pubkey;
00148
00149 for (key_i = 0;
00150 key_i < ldns_rr_list_rr_count(ldns_zone_rrs(zone));
00151 key_i++) {
00152 pubkey = ldns_rr_list_rr(ldns_zone_rrs(zone), key_i);
00153 if (ldns_rr_get_type(pubkey) == LDNS_RR_TYPE_DNSKEY &&
00154 (ldns_calc_keytag(pubkey)
00155 ==
00156 ldns_calc_keytag(pubkey_gen) ||
00157
00158 ldns_calc_keytag(pubkey)
00159 ==
00160 ldns_calc_keytag(pubkey_gen) + 1)
00161 ) {
00162 if (verbosity >= 2) {
00163 fprintf(stderr, "Found it in the zone!\n");
00164 }
00165 return pubkey;
00166 }
00167 }
00168 return NULL;
00169 }
00170
00171 static ldns_rr *
00172 find_key_in_file(const char *keyfile_name_base, ldns_key *key, uint32_t zone_ttl)
00173 {
00174 char *keyfile_name;
00175 FILE *keyfile;
00176 int line_nr;
00177 uint32_t default_ttl = zone_ttl;
00178
00179 ldns_rr *pubkey = NULL;
00180 keyfile_name = LDNS_XMALLOC(char,
00181 strlen(keyfile_name_base) + 5);
00182 snprintf(keyfile_name,
00183 strlen(keyfile_name_base) + 5,
00184 "%s.key",
00185 keyfile_name_base);
00186 if (verbosity >= 2) {
00187 fprintf(stderr, "Trying to read %s\n", keyfile_name);
00188 }
00189 keyfile = fopen(keyfile_name, "r");
00190 line_nr = 0;
00191 if (keyfile) {
00192 if (ldns_rr_new_frm_fp_l(&pubkey,
00193 keyfile,
00194 &default_ttl,
00195 NULL,
00196 NULL,
00197 &line_nr) ==
00198 LDNS_STATUS_OK) {
00199 if (verbosity >= 2) {
00200 printf("Key found in file: %s\n", keyfile_name);
00201 }
00202 }
00203 fclose(keyfile);
00204 }
00205 LDNS_FREE(keyfile_name);
00206 return pubkey;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 static ldns_status
00219 find_or_create_pubkey(const char *keyfile_name_base, ldns_key *key, ldns_zone *orig_zone, bool add_keys, uint32_t default_ttl) {
00220 ldns_rr *pubkey_gen, *pubkey;
00221 int key_in_zone;
00222
00223 if (default_ttl == LDNS_DEFAULT_TTL) {
00224 default_ttl = ldns_rr_ttl(ldns_zone_soa(orig_zone));
00225 }
00226
00227 if (!ldns_key_pubkey_owner(key)) {
00228 ldns_key_set_pubkey_owner(key, ldns_rdf_clone(ldns_rr_owner(ldns_zone_soa(orig_zone))));
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 pubkey_gen = ldns_key2rr(key);
00245 ldns_rr_set_ttl(pubkey_gen, default_ttl);
00246
00247 if (verbosity >= 2) {
00248 fprintf(stderr,
00249 "Looking for key with keytag %u or %u\n",
00250 (unsigned int) ldns_calc_keytag(pubkey_gen),
00251 (unsigned int) ldns_calc_keytag(pubkey_gen)+1
00252 );
00253 }
00254
00255 pubkey = find_key_in_zone(pubkey_gen, orig_zone);
00256 key_in_zone = 1;
00257 if (!pubkey) {
00258 key_in_zone = 0;
00259
00260 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
00261 if (!pubkey && !(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
00262
00263 ldns_key_set_keytag(key, ldns_key_keytag(key) + 1);
00264 pubkey = find_key_in_file(keyfile_name_base, key, default_ttl);
00265 if (!pubkey) {
00266
00267 ldns_key_set_keytag(key, ldns_key_keytag(key) - 1);
00268 }
00269 }
00270 if(pubkey && ldns_dname_compare(ldns_rr_owner(pubkey), ldns_rr_owner(ldns_zone_soa(orig_zone))) != 0) {
00271 fprintf(stderr, "Error %s.key has wrong name: %s\n",
00272 keyfile_name_base, ldns_rdf2str(ldns_rr_owner(pubkey)));
00273 exit(EXIT_FAILURE);
00274 }
00275 }
00276
00277 if (!pubkey) {
00278
00279
00280 pubkey = pubkey_gen;
00281 if (verbosity >= 2) {
00282 fprintf(stderr, "Not in zone, no .key file, generating ZSK DNSKEY from private key data\n");
00283 }
00284 } else {
00285 ldns_rr_free(pubkey_gen);
00286 }
00287 ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
00288 ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
00289
00290 if (add_keys && !key_in_zone) {
00291 equalize_ttls_rr_list(ldns_zone_rrs(orig_zone), pubkey, default_ttl);
00292 ldns_zone_push_rr(orig_zone, pubkey);
00293 }
00294 return LDNS_STATUS_OK;
00295 }
00296
00297 void
00298 strip_dnssec_records(ldns_zone *zone)
00299 {
00300 ldns_rr_list *new_list;
00301 ldns_rr *cur_rr;
00302
00303 new_list = ldns_rr_list_new();
00304
00305 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(zone)))) {
00306 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG ||
00307 ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC ||
00308 ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC3
00309 ) {
00310
00311 ldns_rr_free(cur_rr);
00312 } else {
00313 ldns_rr_list_push_rr(new_list, cur_rr);
00314 }
00315 }
00316 ldns_rr_list_free(ldns_zone_rrs(zone));
00317 ldns_zone_set_rrs(zone, new_list);
00318 }
00319
00320 int
00321 main(int argc, char *argv[])
00322 {
00323 const char *zonefile_name;
00324 FILE *zonefile = NULL;
00325 int line_nr = 0;
00326 int c;
00327 int argi;
00328 ENGINE *engine = NULL;
00329
00330 ldns_zone *orig_zone;
00331 ldns_rr_list *orig_rrs = NULL;
00332 ldns_rr *orig_soa = NULL;
00333 ldns_dnssec_zone *signed_zone;
00334
00335 char *keyfile_name_base;
00336 char *keyfile_name = NULL;
00337 FILE *keyfile = NULL;
00338 ldns_key *key = NULL;
00339 ldns_key_list *keys;
00340 ldns_status s;
00341 size_t i;
00342 ldns_rr_list *added_rrs;
00343 ldns_status status;
00344
00345 bool leave_old_dnssec_data = false;
00346
00347 char *outputfile_name = NULL;
00348 FILE *outputfile;
00349
00350
00351 char *eng_key_l;
00352 size_t eng_key_id_len;
00353 char *eng_key_id;
00354 int eng_key_algo;
00355
00356 bool use_nsec3 = false;
00357 int signflags = 0;
00358
00359
00360 bool add_keys = true;
00361 uint8_t nsec3_algorithm = 1;
00362 uint8_t nsec3_flags = 0;
00363 size_t nsec3_iterations_cmd = 1;
00364 uint16_t nsec3_iterations = 1;
00365 uint8_t nsec3_salt_length = 0;
00366 uint8_t *nsec3_salt = NULL;
00367
00368
00369
00370
00371 struct tm tm;
00372 uint32_t inception;
00373 uint32_t expiration;
00374 ldns_rdf *origin = NULL;
00375 uint32_t ttl = LDNS_DEFAULT_TTL;
00376 ldns_rr_class class = LDNS_RR_CLASS_IN;
00377
00378 char *prog = strdup(argv[0]);
00379 ldns_status result;
00380
00381 ldns_output_format fmt = { ldns_output_format_default->flags, NULL };
00382 ldns_rbtree_t **hashmap = NULL;
00383
00384
00385 inception = 0;
00386 expiration = 0;
00387
00388 keys = ldns_key_list_new();
00389
00390 OPENSSL_config(NULL);
00391
00392 while ((c = getopt(argc, argv, "a:bde:f:i:k:lno:ps:t:vAE:K:")) != -1) {
00393 switch (c) {
00394 case 'a':
00395 nsec3_algorithm = (uint8_t) atoi(optarg);
00396 if (nsec3_algorithm != 1) {
00397 fprintf(stderr, "Bad NSEC3 algorithm, only RSASHA1 allowed\n");
00398 exit(EXIT_FAILURE);
00399 }
00400 break;
00401 case 'b':
00402 fmt.flags |= LDNS_COMMENT_BUBBLEBABBLE;
00403 fmt.flags |= LDNS_COMMENT_FLAGS;
00404 fmt.flags |= LDNS_COMMENT_NSEC3_CHAIN;
00405 fmt.flags |= LDNS_COMMENT_LAYOUT;
00406 hashmap = (ldns_rbtree_t **)&fmt.data;
00407 break;
00408 case 'd':
00409 add_keys = false;
00410 break;
00411 case 'e':
00412
00413
00414
00415
00416 memset(&tm, 0, sizeof(tm));
00417
00418 if (strlen(optarg) == 8 &&
00419 sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
00420 ) {
00421 tm.tm_year -= 1900;
00422 tm.tm_mon--;
00423 check_tm(tm);
00424 expiration = (uint32_t) mktime_from_utc(&tm);
00425 } else if (strlen(optarg) == 14 &&
00426 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)
00427 ) {
00428 tm.tm_year -= 1900;
00429 tm.tm_mon--;
00430 check_tm(tm);
00431 expiration = (uint32_t) mktime_from_utc(&tm);
00432 } else {
00433 expiration = (uint32_t) atol(optarg);
00434 }
00435 break;
00436 case 'f':
00437 outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
00438 strncpy(outputfile_name, optarg, MAX_FILENAME_LEN);
00439 break;
00440 case 'i':
00441 memset(&tm, 0, sizeof(tm));
00442
00443 if (strlen(optarg) == 8 &&
00444 sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
00445 ) {
00446 tm.tm_year -= 1900;
00447 tm.tm_mon--;
00448 check_tm(tm);
00449 inception = (uint32_t) mktime_from_utc(&tm);
00450 } else if (strlen(optarg) == 14 &&
00451 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)
00452 ) {
00453 tm.tm_year -= 1900;
00454 tm.tm_mon--;
00455 check_tm(tm);
00456 inception = (uint32_t) mktime_from_utc(&tm);
00457 } else {
00458 inception = (uint32_t) atol(optarg);
00459 }
00460 break;
00461 case 'l':
00462 leave_old_dnssec_data = true;
00463 break;
00464 case 'n':
00465 use_nsec3 = true;
00466 break;
00467 case 'o':
00468 if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
00469 fprintf(stderr, "Bad origin, not a correct domain name\n");
00470 usage(stderr, prog);
00471 exit(EXIT_FAILURE);
00472 }
00473 break;
00474 case 'p':
00475 nsec3_flags = nsec3_flags | LDNS_NSEC3_VARS_OPTOUT_MASK;
00476 break;
00477 case 'v':
00478 printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
00479 exit(EXIT_SUCCESS);
00480 break;
00481 case 'A':
00482 signflags |= LDNS_SIGN_DNSKEY_WITH_ZSK;
00483 break;
00484 case 'E':
00485 ENGINE_load_builtin_engines();
00486 ENGINE_load_dynamic();
00487 ENGINE_load_cryptodev();
00488 engine = ENGINE_by_id(optarg);
00489 if (!engine) {
00490 printf("No such engine: %s\n", optarg);
00491 engine = ENGINE_get_first();
00492 printf("Available engines:\n");
00493 while (engine) {
00494 printf("%s\n", ENGINE_get_id(engine));
00495 engine = ENGINE_get_next(engine);
00496 }
00497 exit(EXIT_FAILURE);
00498 } else {
00499 if (!ENGINE_init(engine)) {
00500 printf("The engine couldn't initialize\n");
00501 exit(EXIT_FAILURE);
00502 }
00503 ENGINE_set_default_RSA(engine);
00504 ENGINE_set_default_DSA(engine);
00505 ENGINE_set_default(engine, 0);
00506 }
00507 break;
00508 case 'k':
00509 eng_key_l = strchr(optarg, ',');
00510 if (eng_key_l && strlen(eng_key_l) > 1) {
00511 if (eng_key_l > optarg) {
00512 eng_key_id_len = (size_t) (eng_key_l - optarg);
00513 eng_key_id = malloc(eng_key_id_len + 1);
00514 memcpy(eng_key_id, optarg, eng_key_id_len);
00515 eng_key_id[eng_key_id_len] = '\0';
00516 } else {
00517
00518 eng_key_id = NULL;
00519 }
00520
00521 eng_key_algo = atoi(eng_key_l + 1);
00522
00523 printf("Engine key id: %s, algo %d\n", eng_key_id, eng_key_algo);
00524
00525 if (expiration != 0) {
00526 ldns_key_set_expiration(key, expiration);
00527 }
00528 if (inception != 0) {
00529 ldns_key_set_inception(key, inception);
00530 }
00531
00532 s = ldns_key_new_frm_engine(&key, engine, eng_key_id, eng_key_algo);
00533 if (s == LDNS_STATUS_OK) {
00534
00535 switch (ldns_key_algorithm(key)) {
00536 case LDNS_SIGN_RSAMD5:
00537 case LDNS_SIGN_RSASHA1:
00538 case LDNS_SIGN_RSASHA1_NSEC3:
00539 case LDNS_SIGN_RSASHA256:
00540 case LDNS_SIGN_RSASHA512:
00541 case LDNS_SIGN_DSA:
00542 case LDNS_SIGN_DSA_NSEC3:
00543 case LDNS_SIGN_ECC_GOST:
00544 #ifdef USE_ECDSA
00545 case LDNS_SIGN_ECDSAP256SHA256:
00546 case LDNS_SIGN_ECDSAP384SHA384:
00547 #endif
00548 ldns_key_list_push_key(keys, key);
00549
00550
00551 break;
00552 default:
00553 fprintf(stderr, "Warning, key not suitable for signing, ignoring key with algorithm %u\n", ldns_key_algorithm(key));
00554 break;
00555 }
00556 } else {
00557 printf("Error reading key '%s' from engine: %s\n", eng_key_id, ldns_get_errorstr_by_id(s));
00558 #ifdef HAVE_SSL
00559 if (ERR_peek_error()) {
00560 ERR_load_crypto_strings();
00561 ERR_print_errors_fp(stderr);
00562 ERR_free_strings();
00563 }
00564 #endif
00565 exit(EXIT_FAILURE);
00566 }
00567
00568 if (eng_key_id) {
00569 free(eng_key_id);
00570 }
00571 } else {
00572 printf("Error: bad engine key specification (should be: -k <id>,<algorithm>)).\n");
00573 exit(EXIT_FAILURE);
00574 }
00575 break;
00576 case 'K':
00577 printf("Not implemented yet\n");
00578 exit(EXIT_FAILURE);
00579 break;
00580 case 's':
00581 if (strlen(optarg) % 2 != 0) {
00582 fprintf(stderr, "Salt value is not valid hex data, not a multiple of 2 characters\n");
00583 exit(EXIT_FAILURE);
00584 }
00585 nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
00586 nsec3_salt = LDNS_XMALLOC(uint8_t, nsec3_salt_length);
00587 for (c = 0; c < (int) strlen(optarg); c += 2) {
00588 if (isxdigit((int) optarg[c]) && isxdigit((int) optarg[c+1])) {
00589 nsec3_salt[c/2] = (uint8_t) ldns_hexdigit_to_int(optarg[c]) * 16 +
00590 ldns_hexdigit_to_int(optarg[c+1]);
00591 } else {
00592 fprintf(stderr, "Salt value is not valid hex data.\n");
00593 exit(EXIT_FAILURE);
00594 }
00595 }
00596
00597 break;
00598 case 't':
00599 nsec3_iterations_cmd = (size_t) atol(optarg);
00600 if (nsec3_iterations_cmd > LDNS_NSEC3_MAX_ITERATIONS) {
00601 fprintf(stderr, "Iterations count can not exceed %u, quitting\n", LDNS_NSEC3_MAX_ITERATIONS);
00602 exit(EXIT_FAILURE);
00603 }
00604 nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
00605 break;
00606 default:
00607 usage(stderr, prog);
00608 exit(EXIT_SUCCESS);
00609 }
00610 }
00611
00612 argc -= optind;
00613 argv += optind;
00614
00615 if (argc < 1) {
00616 printf("Error: not enough arguments\n");
00617 usage(stdout, prog);
00618 exit(EXIT_FAILURE);
00619 } else {
00620 zonefile_name = argv[0];
00621 }
00622
00623
00624
00625 if (strncmp(zonefile_name, "-", 2) == 0) {
00626 s = ldns_zone_new_frm_fp_l(&orig_zone,
00627 stdin,
00628 origin,
00629 ttl,
00630 class,
00631 &line_nr);
00632 if (s != LDNS_STATUS_OK) {
00633 fprintf(stderr, "Zone not read, error: %s at stdin line %d\n",
00634 ldns_get_errorstr_by_id(s),
00635 line_nr);
00636 exit(EXIT_FAILURE);
00637 } else {
00638 orig_soa = ldns_zone_soa(orig_zone);
00639 if (!orig_soa) {
00640 fprintf(stderr,
00641 "Error reading zonefile: missing SOA record\n");
00642 exit(EXIT_FAILURE);
00643 }
00644 orig_rrs = ldns_zone_rrs(orig_zone);
00645 if (!orig_rrs) {
00646 fprintf(stderr,
00647 "Error reading zonefile: no resource records\n");
00648 exit(EXIT_FAILURE);
00649 }
00650 }
00651 } else {
00652 zonefile = fopen(zonefile_name, "r");
00653
00654 if (!zonefile) {
00655 fprintf(stderr,
00656 "Error: unable to read %s (%s)\n",
00657 zonefile_name,
00658 strerror(errno));
00659 exit(EXIT_FAILURE);
00660 } else {
00661 s = ldns_zone_new_frm_fp_l(&orig_zone,
00662 zonefile,
00663 origin,
00664 ttl,
00665 class,
00666 &line_nr);
00667 if (s != LDNS_STATUS_OK) {
00668 fprintf(stderr, "Zone not read, error: %s at %s line %d\n",
00669 ldns_get_errorstr_by_id(s),
00670 zonefile_name, line_nr);
00671 exit(EXIT_FAILURE);
00672 } else {
00673 orig_soa = ldns_zone_soa(orig_zone);
00674 if (!orig_soa) {
00675 fprintf(stderr,
00676 "Error reading zonefile: missing SOA record\n");
00677 exit(EXIT_FAILURE);
00678 }
00679 orig_rrs = ldns_zone_rrs(orig_zone);
00680 if (!orig_rrs) {
00681 fprintf(stderr,
00682 "Error reading zonefile: no resource records\n");
00683 exit(EXIT_FAILURE);
00684 }
00685 }
00686 fclose(zonefile);
00687 }
00688 }
00689
00690 if (!origin) {
00691 origin = ldns_rr_owner(orig_soa);
00692 }
00693
00694
00695 argi = 1;
00696 while (argi < argc) {
00697 keyfile_name_base = argv[argi];
00698 keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
00699 snprintf(keyfile_name,
00700 strlen(keyfile_name_base) + 9,
00701 "%s.private",
00702 keyfile_name_base);
00703 keyfile = fopen(keyfile_name, "r");
00704 line_nr = 0;
00705 if (!keyfile) {
00706 fprintf(stderr,
00707 "Error: unable to read %s: %s\n",
00708 keyfile_name,
00709 strerror(errno));
00710 } else {
00711 s = ldns_key_new_frm_fp_l(&key, keyfile, &line_nr);
00712 fclose(keyfile);
00713 if (s == LDNS_STATUS_OK) {
00714
00715
00716
00717 if (expiration != 0) {
00718 ldns_key_set_expiration(key, expiration);
00719 }
00720 if (inception != 0) {
00721 ldns_key_set_inception(key, inception);
00722 }
00723
00724 LDNS_FREE(keyfile_name);
00725
00726 ldns_key_list_push_key(keys, key);
00727 } else {
00728 fprintf(stderr, "Error reading key from %s at line %d: %s\n", argv[argi], line_nr, ldns_get_errorstr_by_id(s));
00729 }
00730 }
00731
00732 if (key) {
00733 status = find_or_create_pubkey(keyfile_name_base,
00734 key, orig_zone,
00735 add_keys, ttl);
00736 }
00737 argi++;
00738 }
00739
00740 if (ldns_key_list_key_count(keys) < 1) {
00741 fprintf(stderr, "Error: no keys to sign with. Aborting.\n\n");
00742 usage(stderr, prog);
00743 exit(EXIT_FAILURE);
00744 }
00745
00746 signed_zone = ldns_dnssec_zone_new();
00747 if (ldns_dnssec_zone_add_rr(signed_zone, ldns_zone_soa(orig_zone)) !=
00748 LDNS_STATUS_OK) {
00749 fprintf(stderr,
00750 "Error adding SOA to dnssec zone, skipping record\n");
00751 }
00752
00753 for (i = 0;
00754 i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone));
00755 i++) {
00756 if (ldns_dnssec_zone_add_rr(signed_zone,
00757 ldns_rr_list_rr(ldns_zone_rrs(orig_zone),
00758 i)) !=
00759 LDNS_STATUS_OK) {
00760 fprintf(stderr,
00761 "Error adding RR to dnssec zone");
00762 fprintf(stderr, ", skipping record:\n");
00763 ldns_rr_print(stderr,
00764 ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i));
00765 }
00766 }
00767
00768
00769 added_rrs = ldns_rr_list_new();
00770
00771 if (use_nsec3) {
00772 result = ldns_dnssec_zone_sign_nsec3_flg_mkmap(signed_zone,
00773 added_rrs,
00774 keys,
00775 ldns_dnssec_default_replace_signatures,
00776 NULL,
00777 nsec3_algorithm,
00778 nsec3_flags,
00779 nsec3_iterations,
00780 nsec3_salt_length,
00781 nsec3_salt,
00782 signflags,
00783 hashmap);
00784 } else {
00785 result = ldns_dnssec_zone_sign_flg(signed_zone,
00786 added_rrs,
00787 keys,
00788 ldns_dnssec_default_replace_signatures,
00789 NULL,
00790 signflags);
00791 }
00792 if (result != LDNS_STATUS_OK) {
00793 fprintf(stderr, "Error signing zone: %s\n",
00794 ldns_get_errorstr_by_id(result));
00795 }
00796
00797 if (!outputfile_name) {
00798 outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
00799 snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
00800 }
00801
00802 if (signed_zone) {
00803 if (strncmp(outputfile_name, "-", 2) == 0) {
00804 ldns_dnssec_zone_print(stdout, signed_zone);
00805 } else {
00806 outputfile = fopen(outputfile_name, "w");
00807 if (!outputfile) {
00808 fprintf(stderr, "Unable to open %s for writing: %s\n",
00809 outputfile_name, strerror(errno));
00810 } else {
00811 ldns_dnssec_zone_print_fmt(
00812 outputfile, &fmt, signed_zone);
00813 fclose(outputfile);
00814 }
00815 }
00816 } else {
00817 fprintf(stderr, "Error signing zone.\n");
00818
00819 #ifdef HAVE_SSL
00820 if (ERR_peek_error()) {
00821 ERR_load_crypto_strings();
00822 ERR_print_errors_fp(stderr);
00823 ERR_free_strings();
00824 }
00825 #endif
00826 exit(EXIT_FAILURE);
00827 }
00828
00829 ldns_key_list_free(keys);
00830
00831
00832
00833
00834
00835 ldns_dnssec_zone_free(signed_zone);
00836 ldns_zone_deep_free(orig_zone);
00837 ldns_rr_list_deep_free(added_rrs);
00838
00839 LDNS_FREE(outputfile_name);
00840
00841 CRYPTO_cleanup_all_ex_data();
00842
00843 free(prog);
00844 exit(EXIT_SUCCESS);
00845 }
00846 #else
00847 int
00848 main(int argc, char **argv)
00849 {
00850 fprintf(stderr, "ldns-signzone needs OpenSSL support, which has not been compiled in\n");
00851 return 1;
00852 }
00853 #endif