ldns-signzone.c

Go to the documentation of this file.
00001 /*
00002  * ldns-signzone signs a zone file
00003  * 
00004  * (c) NLnet Labs, 2005
00005  * See the file LICENSE for the license
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 #include <openssl/conf.h>
00020 #include <openssl/engine.h>
00021 
00022 
00023 #define MAX_FILENAME_LEN 250
00024 int verbosity = 0;
00025 
00026 #ifdef HAVE_SSL
00027 #include <openssl/err.h>
00028 #endif
00029 
00030 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, "  -e <date>\texpiration date\n");
00035         fprintf(fp, "  -f <file>\toutput zone to file (default <name>.signed)\n");
00036         fprintf(fp, "  -i <date>\tinception date\n");
00037         fprintf(fp, "  -l\t\tLeave old DNSSEC RRSIGS and NSEC records intact\n");
00038         fprintf(fp, "  -o <domain>\torigin for the zone\n");
00039         fprintf(fp, "  -v\t\tprint version and exit\n");
00040         fprintf(fp, "  -E <name>\tuse <name> as the crypto engine for signing\n");
00041         fprintf(fp, "           \tThis can have a lot of extra options, see -E help for more info\n");
00042         fprintf(fp, "  -k <id>,<int>\tuse key id with algorithm int from engine\n");
00043         fprintf(fp, "  -K <id>,<int>\tuse key id with algorithm int from engine as KSK\n");
00044         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");
00045         fprintf(fp, "  -n\t\tuse NSEC3 instead of NSEC.\n");
00046         fprintf(fp, "\t\tIf you use NSEC3, you can specify the following extra options:\n");
00047         fprintf(fp, "\t\t-a [algorithm] hashing algorithm\n");
00048         fprintf(fp, "\t\t-t [number] number of hash iterations\n");
00049         fprintf(fp, "\t\t-s [string] salt\n");
00050         fprintf(fp, "\n");
00051         fprintf(fp, "  keys must be specified by their base name: K<name>+<alg>+<id>\n");
00052         fprintf(fp, "  if the public part of the key is not present in the zone, \n");
00053         fprintf(fp, "  both a .key and .private file must be present\n");
00054         fprintf(fp, "  A date can be a timestamp (seconds since the epoch), or of\n  the form <YYYYMMdd[hhmmss]>\n");
00055 }
00056 
00057 void
00058 usage_openssl(FILE *fp, const char *prog) {
00059         fprintf(fp, "Special commands for openssl engines:\n");
00060         fprintf(fp, "-c <file>\tOpenSSL config file\n");
00061 }
00062 
00063 void check_tm(struct tm tm)
00064 {
00065         if (tm.tm_year < 70) {
00066                 fprintf(stderr, "You cannot specify dates before 1970\n");
00067                 exit(EXIT_FAILURE);
00068         }
00069         if (tm.tm_mon < 0 || tm.tm_mon > 11) {
00070                 fprintf(stderr, "The month must be in the range 1 to 12\n");
00071                 exit(EXIT_FAILURE);
00072         }
00073         if (tm.tm_mday < 1 || tm.tm_mday > 31) {
00074                 fprintf(stderr, "The day must be in the range 1 to 31\n");
00075                 exit(EXIT_FAILURE);
00076         }
00077         
00078         if (tm.tm_hour < 0 || tm.tm_hour > 23) {
00079                 fprintf(stderr, "The hour must be in the range 0-23\n");
00080                 exit(EXIT_FAILURE);
00081         }
00082 
00083         if (tm.tm_min < 0 || tm.tm_min > 59) {
00084                 fprintf(stderr, "The minute must be in the range 0-59\n");
00085                 exit(EXIT_FAILURE);
00086         }
00087 
00088         if (tm.tm_sec < 0 || tm.tm_sec > 59) {
00089                 fprintf(stderr, "The second must be in the range 0-59\n");
00090                 exit(EXIT_FAILURE);
00091         }
00092 
00093 }
00094 
00095 void
00096 strip_dnssec_records(ldns_zone *zone)
00097 {
00098         ldns_rr_list *new_list;
00099         ldns_rr *cur_rr;
00100         
00101         new_list = ldns_rr_list_new();
00102         
00103         while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(zone)))) {
00104                 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG ||
00105                     ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC
00106                    ) {
00107                         
00108                         ldns_rr_free(cur_rr);
00109                 } else {
00110                         ldns_rr_list_push_rr(new_list, cur_rr);
00111                 }
00112         }
00113         ldns_rr_list_free(ldns_zone_rrs(zone));
00114         ldns_zone_set_rrs(zone, new_list);
00115 }
00116 
00117 int
00118 main(int argc, char *argv[])
00119 {
00120         const char *zonefile_name;
00121         FILE *zonefile = NULL;
00122         uint32_t default_ttl = LDNS_DEFAULT_TTL;
00123         int line_nr = 0;
00124         int c;
00125         int argi;
00126         ENGINE *engine = NULL;
00127 
00128         ldns_zone *orig_zone;
00129         ldns_rr_list *orig_rrs = NULL;
00130         ldns_rr *orig_soa = NULL;
00131         ldns_dnssec_zone *signed_zone;
00132 
00133         const char *keyfile_name_base;
00134         char *keyfile_name;
00135         FILE *keyfile = NULL;
00136         ldns_key *key = NULL;
00137         ldns_rr *pubkey, *pubkey_gen;
00138         ldns_key_list *keys;
00139         size_t key_i;
00140         ldns_status s;
00141         size_t i;
00142         ldns_rr_list *added_rrs;
00143 
00144         bool leave_old_dnssec_data = false;
00145 
00146         char *outputfile_name = NULL;
00147         FILE *outputfile;
00148         
00149         /* tmp vars for engine keys */
00150         char *eng_key_l;
00151         size_t eng_key_id_len;
00152         char *eng_key_id;
00153         int eng_key_algo;
00154         
00155         bool use_nsec3 = false;
00156         
00157         uint8_t nsec3_algorithm = 1;
00158         /*uint8_t nsec3_flags = 0;*/
00159         size_t nsec3_iterations_cmd = 1;
00160         uint16_t nsec3_iterations = 1;
00161         uint8_t nsec3_salt_length = 0;
00162         uint8_t *nsec3_salt = NULL;
00163         
00164         /* we need to know the origin before reading ksk's,
00165          * so keep an array of filenames until we know it
00166          */
00167         struct tm tm;
00168         uint32_t inception;
00169         uint32_t expiration;
00170         ldns_rdf *origin = NULL;
00171         uint32_t ttl = 0;
00172         ldns_rr_class class = LDNS_RR_CLASS_IN; 
00173         
00174         char *prog = strdup(argv[0]);
00175         ldns_status result;
00176         
00177         inception = 0;
00178         expiration = 0;
00179         
00180         keys = ldns_key_list_new();
00181 
00182         OPENSSL_config(NULL);
00183 
00184         while ((c = getopt(argc, argv, "a:e:f:i:k:lno:s:t:v:E:K:")) != -1) {
00185                 switch (c) {
00186                 case 'a':
00187                         nsec3_algorithm = (uint8_t) atoi(optarg);
00188                         break;
00189                 case 'e':
00190                         /* try to parse YYYYMMDD first,
00191                          * if that doesn't work, it
00192                          * should be a timestamp (seconds since epoch)
00193                          */
00194                         memset(&tm, 0, sizeof(tm));
00195 
00196                         if (strlen(optarg) == 8 &&
00197                             sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
00198                             ) {
00199                                 tm.tm_year -= 1900;
00200                                 tm.tm_mon--;
00201                                 check_tm(tm);
00202                                 expiration = (uint32_t) mktime_from_utc(&tm);
00203                         } else if (strlen(optarg) == 14 &&
00204                                          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)
00205                                          ) {
00206                                 tm.tm_year -= 1900;
00207                                 tm.tm_mon--;
00208                                 check_tm(tm);
00209                                 expiration = (uint32_t) mktime_from_utc(&tm);
00210                         } else {
00211                                 expiration = (uint32_t) atol(optarg);
00212                         }
00213                         break;
00214                 case 'f':
00215                         outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
00216                         strncpy(outputfile_name, optarg, MAX_FILENAME_LEN);
00217                         break;
00218                 case 'i':
00219                         memset(&tm, 0, sizeof(tm));
00220 
00221                         if (strlen(optarg) == 8 &&
00222                             sscanf(optarg, "%4d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday)
00223                             ) {
00224                                 tm.tm_year -= 1900;
00225                                 tm.tm_mon--;
00226                                 check_tm(tm);
00227                                 inception = (uint32_t) mktime_from_utc(&tm);
00228                         } else if (strlen(optarg) == 14 &&
00229                                          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)
00230                                          ) {
00231                                 tm.tm_year -= 1900;
00232                                 tm.tm_mon--;
00233                                 check_tm(tm);
00234                                 inception = (uint32_t) mktime_from_utc(&tm);
00235                         } else {
00236                                 inception = (uint32_t) atol(optarg);
00237                         }
00238                         break;
00239                 case 'l':
00240                         leave_old_dnssec_data = true;
00241                         break;
00242                 case 'n':
00243                         use_nsec3 = true;
00244                         break;
00245                 case 'o':
00246                         if (ldns_str2rdf_dname(&origin, optarg) != LDNS_STATUS_OK) {
00247                                 fprintf(stderr, "Bad origin, not a correct domain name\n");
00248                                 usage(stderr, prog);
00249                                 exit(EXIT_FAILURE);
00250                         }
00251                         
00252                         break;
00253                 case 'v':
00254                         printf("zone signer version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
00255                         exit(EXIT_SUCCESS);
00256                         break;
00257                 case 'E':
00258                         if (strncmp("help", optarg, 5) == 0) {
00259                                 printf("help\n");
00260                                 exit(EXIT_SUCCESS);
00261                         }
00262                         ENGINE_load_openssl();
00263                         ENGINE_load_builtin_engines();
00264                         ENGINE_load_dynamic();
00265                         ENGINE_load_cryptodev();
00266                         engine = ENGINE_by_id(optarg);
00267                         if (!engine) {
00268                                 printf("No such engine: %s\n", optarg);
00269                                 engine = ENGINE_get_first();
00270                                 printf("Available engines:\n");
00271                                 while (engine) {
00272                                         printf("%s\n", ENGINE_get_id(engine));
00273                                         engine = ENGINE_get_next(engine);
00274                                 }
00275                                 exit(EXIT_FAILURE);
00276                         } else {
00277                                 if (!ENGINE_init(engine)) {
00278                                         printf("The engine couldn't initialize\n");
00279                                         exit(EXIT_FAILURE);
00280                                 }
00281                                 ENGINE_set_default_RSA(engine);
00282                                 ENGINE_set_default_DSA(engine);
00283                                 ENGINE_set_default(engine, 0);
00284                         }
00285                         break;
00286                 case 'k':
00287                         eng_key_l = index(optarg, ',');
00288                         if (eng_key_l && strlen(eng_key_l) > 1) {
00289                                 if (eng_key_l > optarg) {
00290                                         eng_key_id_len = (size_t) (eng_key_l - optarg);
00291                                         eng_key_id = malloc(eng_key_id_len + 1);
00292                                         memcpy(eng_key_id, optarg, eng_key_id_len);
00293                                         eng_key_id[eng_key_id_len] = '\0';
00294                                 } else {
00295                                         /* no id given, use default from engine */
00296                                         eng_key_id = NULL;
00297                                 }
00298                                 
00299                                 eng_key_algo = atoi(eng_key_l + 1);
00300 
00301                                 printf("Engine key id: %s, algo %d\n", eng_key_id, eng_key_algo);
00302                                 
00303                                 if (expiration != 0) {
00304                                         ldns_key_set_expiration(key, expiration);
00305                                 }
00306                                 if (inception != 0) {
00307                                         ldns_key_set_inception(key, inception);
00308                                 }
00309 
00310                                 s = ldns_key_new_frm_engine(&key, engine, eng_key_id, eng_key_algo);
00311                                 if (s == LDNS_STATUS_OK) {
00312                                         /* must be dnssec key */
00313                                         switch (ldns_key_algorithm(key)) {
00314                                         case LDNS_SIGN_RSAMD5:
00315                                         case LDNS_SIGN_RSASHA1:
00316                                         case LDNS_SIGN_RSASHA1_NSEC3:
00317                                         case LDNS_SIGN_RSASHA256:
00318                                         case LDNS_SIGN_RSASHA256_NSEC3:
00319                                         case LDNS_SIGN_RSASHA512:
00320                                         case LDNS_SIGN_RSASHA512_NSEC3:
00321                                         case LDNS_SIGN_DSA:
00322                                         case LDNS_SIGN_DSA_NSEC3:
00323                                                 ldns_key_list_push_key(keys, key);
00324                                                 /*printf("Added key at %p:\n", key);*/
00325                                                 /*ldns_key_print(stdout, key);*/
00326                                                 break;
00327                                         default:
00328                                                 fprintf(stderr, "Warning, key not suitable for signing, ignoring key with algorithm %u\n", ldns_key_algorithm(key));
00329                                                 break;
00330                                         }
00331                                 } else {
00332                                         printf("Error reading key '%s' from engine: %s\n", eng_key_id, ldns_get_errorstr_by_id(s));
00333                                         printf("The available key id's are:\n");
00334                                         printf("TODO\n");
00335                                         exit(EXIT_FAILURE);
00336                                 }
00337                                 
00338                                 if (eng_key_id) {
00339                                         free(eng_key_id);
00340                                 }
00341                         } else {
00342                                 printf("Error: bad engine key specification (should be: -k <id>,<algorithm>)).\n");
00343                                 exit(EXIT_FAILURE);
00344                         }
00345                         
00346                         break;
00347                 case 'K':
00348                         printf("Not implemented yet\n");
00349                         exit(EXIT_FAILURE);
00350                         break;
00351                 case 's':
00352                         if (strlen(optarg) % 2 != 0) {
00353                                 fprintf(stderr, "Salt value is not valid hex data, not a multiple of 2 characters\n");
00354                                 exit(EXIT_FAILURE);
00355                         }
00356                         nsec3_salt_length = (uint8_t) strlen(optarg) / 2;
00357                         nsec3_salt = LDNS_XMALLOC(uint8_t, nsec3_salt_length);
00358                         for (c = 0; c < (int) strlen(optarg); c += 2) {
00359                                 if (isxdigit(optarg[c]) && isxdigit(optarg[c+1])) {
00360                                         nsec3_salt[c/2] = (uint8_t) ldns_hexdigit_to_int(optarg[c]) * 16 +
00361                                                 ldns_hexdigit_to_int(optarg[c+1]);
00362                                 } else {
00363                                         fprintf(stderr, "Salt value is not valid hex data.\n");
00364                                         exit(EXIT_FAILURE);
00365                                 }
00366                         }
00367 
00368                         break;
00369                 case 't':
00370                         nsec3_iterations_cmd = (size_t) atol(optarg);
00371                         if (nsec3_iterations_cmd > LDNS_NSEC3_MAX_ITERATIONS) {
00372                                 fprintf(stderr, "Iterations count can not exceed %u, quitting\n", LDNS_NSEC3_MAX_ITERATIONS);
00373                                 exit(EXIT_FAILURE);
00374                         }
00375                         nsec3_iterations = (uint16_t) nsec3_iterations_cmd;
00376                         break;
00377                 default:
00378                         usage(stderr, prog);
00379                         exit(EXIT_SUCCESS);
00380                 }
00381         }
00382         
00383         argc -= optind;
00384         argv += optind;
00385 
00386         if (argc < 1) {
00387                 printf("Error: not enough arguments\n");
00388                 usage(stdout, prog);
00389                 exit(EXIT_FAILURE);
00390         } else {
00391                 zonefile_name = argv[0];
00392         }
00393 
00394         /* read zonefile first to find origin if not specified */
00395         
00396         zonefile = fopen(zonefile_name, "r");
00397         
00398         printf("[XX] Reading zone file\n");
00399         if (!zonefile) {
00400                 fprintf(stderr, "Error: unable to read %s (%s)\n", zonefile_name, strerror(errno));
00401                 exit(EXIT_FAILURE);
00402         } else {
00403                 s = ldns_zone_new_frm_fp_l(&orig_zone, zonefile, origin, ttl, class, &line_nr);
00404                 if (s != LDNS_STATUS_OK) {
00405                         fprintf(stderr, "Zone not read, error: %s at %s line %d\n", 
00406                                    ldns_get_errorstr_by_id(s), 
00407                                    zonefile_name, line_nr);
00408                         exit(EXIT_FAILURE);
00409                 } else {
00410                         orig_soa = ldns_zone_soa(orig_zone);
00411                         if (!orig_soa) {
00412                                 fprintf(stderr, "Error reading zonefile: missing SOA record\n");
00413                                 exit(EXIT_FAILURE);
00414                         }
00415                         orig_rrs = ldns_zone_rrs(orig_zone);
00416                         if (!orig_rrs) {
00417                                 fprintf(stderr, "Error reading zonefile: no resource records\n");
00418                                 exit(EXIT_FAILURE);
00419                         }
00420                 }
00421                 fclose(zonefile);
00422         }
00423 
00424         if (!origin) {
00425                 origin = ldns_rr_owner(orig_soa);
00426         }
00427         
00428         /* read the ZSKs */
00429         argi = 1;
00430         while (argi < argc) {
00431                 keyfile_name_base = argv[argi];
00432                 keyfile_name = LDNS_XMALLOC(char, strlen(keyfile_name_base) + 9);
00433                 snprintf(keyfile_name,
00434                             strlen(keyfile_name_base) + 9,
00435                             "%s.private",
00436                             keyfile_name_base);
00437                 keyfile = fopen(keyfile_name, "r");
00438                 line_nr = 0;
00439                 if (!keyfile) {
00440                         fprintf(stderr,
00441                                    "Error: unable to read %s: %s\n",
00442                                    keyfile_name,
00443                                    strerror(errno));
00444                 } else {
00445                         s = ldns_key_new_frm_fp_l(&key, keyfile, &line_nr);
00446                         fclose(keyfile);
00447                         if (s == LDNS_STATUS_OK) {
00448                                 /* set times in key? they will end up
00449                                    in the rrsigs
00450                                 */
00451                                 if (expiration != 0) {
00452                                         ldns_key_set_expiration(key, expiration);
00453                                 }
00454                                 if (inception != 0) {
00455                                         ldns_key_set_inception(key, inception);
00456                                 }
00457 
00458                                 LDNS_FREE(keyfile_name);
00459                                 
00460                                 /* find the public key in the zone, or in a
00461                                  * seperate file
00462                                  * we 'generate' one anyway, 
00463                                  * then match that to any present in the zone,
00464                                  * if it matches, we drop our own. If not,
00465                                  * we try to see if there is a .key file present.
00466                                  * If not, we use our own generated one, with
00467                                  * some default values */
00468                                 
00469                                 pubkey_gen = ldns_key2rr(key);
00470 
00471                                 if (verbosity >= 2) {
00472                                         fprintf(stderr,
00473                                                    "Looking for key with keytag %u or %u\n",
00474                                                    (unsigned int) ldns_calc_keytag(pubkey_gen),
00475                                                    (unsigned int) ldns_calc_keytag(pubkey_gen)+1
00476                                                    );
00477                                 }
00478                                 for (key_i = 0;
00479                                         key_i < ldns_rr_list_rr_count(orig_rrs);
00480                                         key_i++) {
00481                                         pubkey = ldns_rr_list_rr(orig_rrs, key_i);
00482                                         if (ldns_rr_get_type(pubkey) == LDNS_RR_TYPE_DNSKEY &&
00483                                             (ldns_calc_keytag(pubkey)
00484                                                 ==
00485                                                 ldns_calc_keytag(pubkey_gen) ||
00486                                              /* KSK has gen-keytag + 1 */
00487                                              ldns_calc_keytag(pubkey)
00488                                                 ==
00489                                                 ldns_calc_keytag(pubkey_gen) + 1) 
00490                                             ) {
00491                                                 /* found it, drop our own */
00492                                                 if (verbosity >= 2) {
00493                                                         fprintf(stderr, "Found it in the zone!\n");
00494                                                 }
00495                                                 goto found;
00496                                         }
00497                                 }
00498                                 /* it was not in the zone, try to read a .key file */
00499                                 keyfile_name = LDNS_XMALLOC(char,
00500                                                                            strlen(keyfile_name_base) + 5);
00501                                 snprintf(keyfile_name,
00502                                             strlen(keyfile_name_base) + 5,
00503                                             "%s.key",
00504                                             keyfile_name_base);
00505                                 if (verbosity >= 2) {
00506                                         fprintf(stderr, "Trying to read %s\n", keyfile_name);
00507                                 }
00508                                 keyfile = fopen(keyfile_name, "r");
00509                                 line_nr = 0;
00510                                 if (keyfile) {
00511                                         if (ldns_rr_new_frm_fp_l(&pubkey,
00512                                                                                 keyfile,
00513                                                                                 &default_ttl,
00514                                                                                 NULL,
00515                                                                                 NULL,
00516                                                                                 &line_nr) ==
00517                                             LDNS_STATUS_OK) {
00518                                                 ldns_key_set_pubkey_owner(key, ldns_rdf_clone(ldns_rr_owner(pubkey)));
00519                                                 ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
00520                                                 ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
00521                                         }
00522                                         ldns_zone_push_rr(orig_zone, ldns_rr_clone(pubkey));
00523                                         ldns_rr_free(pubkey);
00524                                         fclose(keyfile);
00525                                         goto found;
00526                                 }
00527                                 
00528                                 /* okay, so reading .key didn't work either,
00529                                    just use our generated one */
00530                                 if (verbosity >= 2) {
00531                                         fprintf(stderr, "Not in zone, no .key file, generating DNSKEY from .private\n");
00532                                 }
00533                                 ldns_zone_push_rr(orig_zone, pubkey_gen);
00534                                 
00535                                 
00536                         found:
00537                                 ldns_rr_free(pubkey_gen);
00538                                 switch (ldns_key_algorithm(key)) {
00539                                 case LDNS_SIGN_RSAMD5:
00540                                 case LDNS_SIGN_RSASHA1:
00541                                 case LDNS_SIGN_RSASHA1_NSEC3:
00542                                 case LDNS_SIGN_RSASHA256:
00543                                 case LDNS_SIGN_RSASHA256_NSEC3:
00544                                 case LDNS_SIGN_RSASHA512:
00545                                 case LDNS_SIGN_RSASHA512_NSEC3:
00546                                 case LDNS_SIGN_DSA:
00547                                 case LDNS_SIGN_DSA_NSEC3:
00548                                         ldns_key_list_push_key(keys, key);
00549                                         /*printf("Added key at %p:\n", key);*/
00550                                         /*ldns_key_print(stdout, key);*/
00551                                         break;
00552                                 default:
00553                                         fprintf(stderr, "Warning, key not suitable for signing, ignoring key from %s with algorithm %u\n", keyfile_name, ldns_key_algorithm(key));
00554                                         break;
00555                                 }
00556                                 LDNS_FREE(keyfile_name);
00557                         } else {
00558                                 fprintf(stderr, "Error reading key from %s at line %d\n", argv[argi], line_nr);
00559                         }
00560                 }
00561 
00562                 argi++;
00563         }
00564         
00565         if (ldns_key_list_key_count(keys) < 1) {
00566                 fprintf(stderr, "Error: no keys to sign with. Aborting.\n\n");
00567                 usage(stderr, prog);
00568                 exit(EXIT_FAILURE);
00569         }
00570 
00571         /* walk through the keys, and add pubkeys to the orig zone */
00572         for (key_i = 0; key_i < ldns_key_list_key_count(keys); key_i++) {
00573                 key = ldns_key_list_key(keys, key_i);
00574                 if (!ldns_key_pubkey_owner(key)) {
00575                         ldns_key_set_pubkey_owner(key, ldns_rdf_clone(origin));
00576                         pubkey = ldns_key2rr(key);
00577                         ldns_key_set_flags(key, ldns_rdf2native_int16(ldns_rr_rdf(pubkey, 0)));
00578                         ldns_key_set_keytag(key, ldns_calc_keytag(pubkey));
00579                         /*ldns_zone_push_rr(orig_zone, pubkey);*/
00580                         printf("Derived DNSKEY RR:\n");
00581                         ldns_rr_print(stdout, pubkey);
00582                 }
00583         }
00584 
00585         printf("[XX] convert to dnssec zone\n");
00586         signed_zone = ldns_dnssec_zone_new();
00587         if (ldns_dnssec_zone_add_rr(signed_zone, ldns_zone_soa(orig_zone)) !=
00588             LDNS_STATUS_OK) {
00589                 fprintf(stderr, "Error adding SOA to dnssec zone, skipping record\n");
00590         }
00591 
00592         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(orig_zone)); i++) {
00593                 if (ldns_dnssec_zone_add_rr(signed_zone, 
00594                                                            ldns_rr_list_rr(ldns_zone_rrs(orig_zone), 
00595                                                                                     i)) !=
00596                     LDNS_STATUS_OK) {
00597                         fprintf(stderr, "Error adding RR to dnssec zone");
00598                         fprintf(stderr, ", skipping record:\n");
00599                         ldns_rr_print(stderr, 
00600                                             ldns_rr_list_rr(ldns_zone_rrs(orig_zone), i));
00601                 }
00602         }
00603 
00604         /* list to store newly created rrs, so we can free them later */
00605         added_rrs = ldns_rr_list_new();
00606 
00607         if (use_nsec3) {
00608                 result = ldns_dnssec_zone_sign_nsec3(signed_zone,
00609                                                                           added_rrs,
00610                                                                           keys,
00611                                                                           ldns_dnssec_default_replace_signatures,
00612                                                                           NULL,
00613                                                                           nsec3_algorithm,
00614                                                                           0,
00615                                                                           nsec3_iterations,
00616                                                                           nsec3_salt_length,
00617                                                                           nsec3_salt);
00618         } else {
00619                 result = ldns_dnssec_zone_sign(signed_zone,
00620                                                   added_rrs,
00621                                                   keys,
00622                                                   ldns_dnssec_default_replace_signatures,
00623                                                   NULL);
00624         }
00625         if (result != LDNS_STATUS_OK) {
00626                 fprintf(stderr, "Error signing zone: %s\n",
00627                            ldns_get_errorstr_by_id(result));
00628         }
00629         
00630         if (!outputfile_name) {
00631                 outputfile_name = LDNS_XMALLOC(char, MAX_FILENAME_LEN);
00632                 snprintf(outputfile_name, MAX_FILENAME_LEN, "%s.signed", zonefile_name);
00633         }
00634 
00635         if (signed_zone) {
00636                 outputfile = fopen(outputfile_name, "w");
00637                 if (!outputfile) {
00638                         fprintf(stderr, "Unable to open %s for writing: %s\n", outputfile_name, strerror(errno));
00639                 } else {
00640                         ldns_dnssec_zone_print(outputfile, signed_zone);
00641                         fclose(outputfile);
00642                 }
00643 /*
00644                 ldns_zone_deep_free(signed_zone); 
00645 */
00646         } else {
00647                 fprintf(stderr, "Error signing zone.\n");
00648 
00649 #ifdef HAVE_SSL
00650                 if (ERR_peek_error()) {
00651                         ERR_load_crypto_strings();
00652                         ERR_print_errors_fp(stderr);
00653                         ERR_free_strings();
00654                 }
00655 #endif
00656                 exit(EXIT_FAILURE);
00657         }
00658         
00659         ldns_dnssec_zone_free(signed_zone);
00660         ldns_key_list_free(keys);
00661         ldns_zone_deep_free(orig_zone);
00662         ldns_rr_list_deep_free(added_rrs);
00663         
00664         LDNS_FREE(outputfile_name);
00665         
00666         CRYPTO_cleanup_all_ex_data();
00667 
00668         free(prog);
00669         exit(EXIT_SUCCESS);
00670 }

Generated on Fri Sep 19 13:35:25 2008 for ldns by  doxygen 1.5.5