"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/bin/dnssec/dnssec-keyfromlabel.c" (4 Sep 2020, 20780 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dnssec-keyfromlabel.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.2_vs_9.17.3.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file */
   13 
   14 #include <ctype.h>
   15 #include <inttypes.h>
   16 #include <stdbool.h>
   17 #include <stdlib.h>
   18 
   19 #include <isc/attributes.h>
   20 #include <isc/buffer.h>
   21 #include <isc/commandline.h>
   22 #include <isc/mem.h>
   23 #include <isc/print.h>
   24 #include <isc/region.h>
   25 #include <isc/string.h>
   26 #include <isc/util.h>
   27 
   28 #include <pk11/site.h>
   29 
   30 #include <dns/dnssec.h>
   31 #include <dns/fixedname.h>
   32 #include <dns/keyvalues.h>
   33 #include <dns/log.h>
   34 #include <dns/name.h>
   35 #include <dns/rdataclass.h>
   36 #include <dns/result.h>
   37 #include <dns/secalg.h>
   38 
   39 #include <dst/dst.h>
   40 
   41 #if USE_PKCS11
   42 #include <pk11/result.h>
   43 #endif /* if USE_PKCS11 */
   44 
   45 #include "dnssectool.h"
   46 
   47 #define MAX_RSA 4096 /* should be long enough... */
   48 
   49 const char *program = "dnssec-keyfromlabel";
   50 
   51 ISC_NORETURN static void
   52 usage(void);
   53 
   54 static void
   55 usage(void) {
   56     fprintf(stderr, "Usage:\n");
   57     fprintf(stderr, "    %s -l label [options] name\n\n", program);
   58     fprintf(stderr, "Version: %s\n", PACKAGE_VERSION);
   59     fprintf(stderr, "Required options:\n");
   60     fprintf(stderr, "    -l label: label of the key pair\n");
   61     fprintf(stderr, "    name: owner of the key\n");
   62     fprintf(stderr, "Other options:\n");
   63     fprintf(stderr, "    -a algorithm: \n"
   64             "        DH | RSASHA1 |\n"
   65             "        NSEC3RSASHA1 |\n"
   66             "        RSASHA256 | RSASHA512 |\n"
   67             "        ECDSAP256SHA256 | ECDSAP384SHA384 |\n"
   68             "        ED25519 | ED448\n");
   69     fprintf(stderr, "    -3: use NSEC3-capable algorithm\n");
   70     fprintf(stderr, "    -c class (default: IN)\n");
   71     fprintf(stderr, "    -E <engine>:\n");
   72 #if USE_PKCS11
   73     fprintf(stderr,
   74         "        path to PKCS#11 provider library "
   75         "(default is %s)\n",
   76         PK11_LIB_LOCATION);
   77 #else  /* if USE_PKCS11 */
   78     fprintf(stderr, "        name of an OpenSSL engine to use\n");
   79 #endif /* if USE_PKCS11 */
   80     fprintf(stderr, "    -f keyflag: KSK | REVOKE\n");
   81     fprintf(stderr, "    -K directory: directory in which to place "
   82             "key files\n");
   83     fprintf(stderr, "    -k: generate a TYPE=KEY key\n");
   84     fprintf(stderr, "    -L ttl: default key TTL\n");
   85     fprintf(stderr, "    -n nametype: ZONE | HOST | ENTITY | USER | "
   86             "OTHER\n");
   87     fprintf(stderr, "        (DNSKEY generation defaults to ZONE\n");
   88     fprintf(stderr, "    -p protocol: default: 3 [dnssec]\n");
   89     fprintf(stderr, "    -t type: "
   90             "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
   91             "(default: AUTHCONF)\n");
   92     fprintf(stderr, "    -y: permit keys that might collide\n");
   93     fprintf(stderr, "    -v verbose level\n");
   94     fprintf(stderr, "    -V: print version information\n");
   95     fprintf(stderr, "Date options:\n");
   96     fprintf(stderr, "    -P date/[+-]offset: set key publication date\n");
   97     fprintf(stderr, "    -P sync date/[+-]offset: set CDS and CDNSKEY "
   98             "publication date\n");
   99     fprintf(stderr, "    -A date/[+-]offset: set key activation date\n");
  100     fprintf(stderr, "    -R date/[+-]offset: set key revocation date\n");
  101     fprintf(stderr, "    -I date/[+-]offset: set key inactivation date\n");
  102     fprintf(stderr, "    -D date/[+-]offset: set key deletion date\n");
  103     fprintf(stderr, "    -D sync date/[+-]offset: set CDS and CDNSKEY "
  104             "deletion date\n");
  105     fprintf(stderr, "    -G: generate key only; do not set -P or -A\n");
  106     fprintf(stderr, "    -C: generate a backward-compatible key, omitting"
  107             " all dates\n");
  108     fprintf(stderr, "    -S <key>: generate a successor to an existing "
  109             "key\n");
  110     fprintf(stderr, "    -i <interval>: prepublication interval for "
  111             "successor key "
  112             "(default: 30 days)\n");
  113     fprintf(stderr, "Output:\n");
  114     fprintf(stderr, "     K<name>+<alg>+<id>.key, "
  115             "K<name>+<alg>+<id>.private\n");
  116 
  117     exit(-1);
  118 }
  119 
  120 int
  121 main(int argc, char **argv) {
  122     char *algname = NULL, *freeit = NULL;
  123     char *nametype = NULL, *type = NULL;
  124     const char *directory = NULL;
  125     const char *predecessor = NULL;
  126     dst_key_t *prevkey = NULL;
  127     const char *engine = NULL;
  128     char *classname = NULL;
  129     char *endp;
  130     dst_key_t *key = NULL;
  131     dns_fixedname_t fname;
  132     dns_name_t *name;
  133     uint16_t flags = 0, kskflag = 0, revflag = 0;
  134     dns_secalg_t alg;
  135     bool oldstyle = false;
  136     isc_mem_t *mctx = NULL;
  137     int ch;
  138     int protocol = -1, signatory = 0;
  139     isc_result_t ret;
  140     isc_textregion_t r;
  141     char filename[255];
  142     isc_buffer_t buf;
  143     isc_log_t *log = NULL;
  144     dns_rdataclass_t rdclass;
  145     int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC;
  146     char *label = NULL;
  147     dns_ttl_t ttl = 0;
  148     isc_stdtime_t publish = 0, activate = 0, revoke = 0;
  149     isc_stdtime_t inactive = 0, deltime = 0;
  150     isc_stdtime_t now;
  151     int prepub = -1;
  152     bool setpub = false, setact = false;
  153     bool setrev = false, setinact = false;
  154     bool setdel = false, setttl = false;
  155     bool unsetpub = false, unsetact = false;
  156     bool unsetrev = false, unsetinact = false;
  157     bool unsetdel = false;
  158     bool genonly = false;
  159     bool use_nsec3 = false;
  160     bool avoid_collisions = true;
  161     bool exact;
  162     unsigned char c;
  163     isc_stdtime_t syncadd = 0, syncdel = 0;
  164     bool unsetsyncadd = false, setsyncadd = false;
  165     bool unsetsyncdel = false, setsyncdel = false;
  166 
  167     if (argc == 1) {
  168         usage();
  169     }
  170 
  171     isc_mem_create(&mctx);
  172 
  173 #if USE_PKCS11
  174     pk11_result_register();
  175 #endif /* if USE_PKCS11 */
  176     dns_result_register();
  177 
  178     isc_commandline_errprint = false;
  179 
  180     isc_stdtime_get(&now);
  181 
  182 #define CMDLINE_FLAGS "3A:a:Cc:D:E:Ff:GhI:i:kK:L:l:n:P:p:R:S:t:v:Vy"
  183     while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
  184         switch (ch) {
  185         case '3':
  186             use_nsec3 = true;
  187             break;
  188         case 'a':
  189             algname = isc_commandline_argument;
  190             break;
  191         case 'C':
  192             oldstyle = true;
  193             break;
  194         case 'c':
  195             classname = isc_commandline_argument;
  196             break;
  197         case 'E':
  198             engine = isc_commandline_argument;
  199             break;
  200         case 'f':
  201             c = (unsigned char)(isc_commandline_argument[0]);
  202             if (toupper(c) == 'K') {
  203                 kskflag = DNS_KEYFLAG_KSK;
  204             } else if (toupper(c) == 'R') {
  205                 revflag = DNS_KEYFLAG_REVOKE;
  206             } else {
  207                 fatal("unknown flag '%s'",
  208                       isc_commandline_argument);
  209             }
  210             break;
  211         case 'K':
  212             directory = isc_commandline_argument;
  213             ret = try_dir(directory);
  214             if (ret != ISC_R_SUCCESS) {
  215                 fatal("cannot open directory %s: %s", directory,
  216                       isc_result_totext(ret));
  217             }
  218             break;
  219         case 'k':
  220             options |= DST_TYPE_KEY;
  221             break;
  222         case 'L':
  223             ttl = strtottl(isc_commandline_argument);
  224             setttl = true;
  225             break;
  226         case 'l':
  227             label = isc_mem_strdup(mctx, isc_commandline_argument);
  228             break;
  229         case 'n':
  230             nametype = isc_commandline_argument;
  231             break;
  232         case 'p':
  233             protocol = strtol(isc_commandline_argument, &endp, 10);
  234             if (*endp != '\0' || protocol < 0 || protocol > 255) {
  235                 fatal("-p must be followed by a number "
  236                       "[0..255]");
  237             }
  238             break;
  239         case 't':
  240             type = isc_commandline_argument;
  241             break;
  242         case 'v':
  243             verbose = strtol(isc_commandline_argument, &endp, 0);
  244             if (*endp != '\0') {
  245                 fatal("-v must be followed by a number");
  246             }
  247             break;
  248         case 'y':
  249             avoid_collisions = false;
  250             break;
  251         case 'G':
  252             genonly = true;
  253             break;
  254         case 'P':
  255             /* -Psync ? */
  256             if (isoptarg("sync", argv, usage)) {
  257                 if (unsetsyncadd || setsyncadd) {
  258                     fatal("-P sync specified more than "
  259                           "once");
  260                 }
  261 
  262                 syncadd = strtotime(isc_commandline_argument,
  263                             now, now, &setsyncadd);
  264                 unsetsyncadd = !setsyncadd;
  265                 break;
  266             }
  267             /* -Pdnskey ? */
  268             (void)isoptarg("dnskey", argv, usage);
  269             if (setpub || unsetpub) {
  270                 fatal("-P specified more than once");
  271             }
  272 
  273             publish = strtotime(isc_commandline_argument, now, now,
  274                         &setpub);
  275             unsetpub = !setpub;
  276             break;
  277         case 'A':
  278             if (setact || unsetact) {
  279                 fatal("-A specified more than once");
  280             }
  281 
  282             activate = strtotime(isc_commandline_argument, now, now,
  283                          &setact);
  284             unsetact = !setact;
  285             break;
  286         case 'R':
  287             if (setrev || unsetrev) {
  288                 fatal("-R specified more than once");
  289             }
  290 
  291             revoke = strtotime(isc_commandline_argument, now, now,
  292                        &setrev);
  293             unsetrev = !setrev;
  294             break;
  295         case 'I':
  296             if (setinact || unsetinact) {
  297                 fatal("-I specified more than once");
  298             }
  299 
  300             inactive = strtotime(isc_commandline_argument, now, now,
  301                          &setinact);
  302             unsetinact = !setinact;
  303             break;
  304         case 'D':
  305             /* -Dsync ? */
  306             if (isoptarg("sync", argv, usage)) {
  307                 if (unsetsyncdel || setsyncdel) {
  308                     fatal("-D sync specified more than "
  309                           "once");
  310                 }
  311 
  312                 syncdel = strtotime(isc_commandline_argument,
  313                             now, now, &setsyncdel);
  314                 unsetsyncdel = !setsyncdel;
  315                 break;
  316             }
  317             /* -Ddnskey ? */
  318             (void)isoptarg("dnskey", argv, usage);
  319             if (setdel || unsetdel) {
  320                 fatal("-D specified more than once");
  321             }
  322 
  323             deltime = strtotime(isc_commandline_argument, now, now,
  324                         &setdel);
  325             unsetdel = !setdel;
  326             break;
  327         case 'S':
  328             predecessor = isc_commandline_argument;
  329             break;
  330         case 'i':
  331             prepub = strtottl(isc_commandline_argument);
  332             break;
  333         case 'F':
  334         /* Reserved for FIPS mode */
  335         /* FALLTHROUGH */
  336         case '?':
  337             if (isc_commandline_option != '?') {
  338                 fprintf(stderr, "%s: invalid argument -%c\n",
  339                     program, isc_commandline_option);
  340             }
  341         /* FALLTHROUGH */
  342         case 'h':
  343             /* Does not return. */
  344             usage();
  345 
  346         case 'V':
  347             /* Does not return. */
  348             version(program);
  349 
  350         default:
  351             fprintf(stderr, "%s: unhandled option -%c\n", program,
  352                 isc_commandline_option);
  353             exit(1);
  354         }
  355     }
  356 
  357     ret = dst_lib_init(mctx, engine);
  358     if (ret != ISC_R_SUCCESS) {
  359         fatal("could not initialize dst: %s", isc_result_totext(ret));
  360     }
  361 
  362     setup_logging(mctx, &log);
  363 
  364     if (predecessor == NULL) {
  365         /* cppcheck-suppress nullPointerRedundantCheck */
  366         if (label == NULL) {
  367             fatal("the key label was not specified");
  368         }
  369         if (argc < isc_commandline_index + 1) {
  370             fatal("the key name was not specified");
  371         }
  372         if (argc > isc_commandline_index + 1) {
  373             fatal("extraneous arguments");
  374         }
  375 
  376         name = dns_fixedname_initname(&fname);
  377         isc_buffer_init(&buf, argv[isc_commandline_index],
  378                 strlen(argv[isc_commandline_index]));
  379         isc_buffer_add(&buf, strlen(argv[isc_commandline_index]));
  380         ret = dns_name_fromtext(name, &buf, dns_rootname, 0, NULL);
  381         if (ret != ISC_R_SUCCESS) {
  382             fatal("invalid key name %s: %s",
  383                   argv[isc_commandline_index],
  384                   isc_result_totext(ret));
  385         }
  386 
  387         /* cppcheck-suppress nullPointerRedundantCheck */
  388         if (strchr(label, ':') == NULL) {
  389             char *l;
  390             int len;
  391 
  392             len = strlen(label) + 8;
  393             l = isc_mem_allocate(mctx, len);
  394             snprintf(l, len, "pkcs11:%s", label);
  395             isc_mem_free(mctx, label);
  396             label = l;
  397         }
  398 
  399         /* cppcheck-suppress nullPointerRedundantCheck */
  400         if (algname == NULL) {
  401             fatal("no algorithm specified");
  402         }
  403 
  404         r.base = algname;
  405         /* cppcheck-suppress nullPointerRedundantCheck */
  406         r.length = strlen(algname);
  407         ret = dns_secalg_fromtext(&alg, &r);
  408         if (ret != ISC_R_SUCCESS) {
  409             fatal("unknown algorithm %s", algname);
  410         }
  411         if (alg == DST_ALG_DH) {
  412             options |= DST_TYPE_KEY;
  413         }
  414 
  415         if (use_nsec3) {
  416             switch (alg) {
  417             case DST_ALG_RSASHA1:
  418                 alg = DST_ALG_NSEC3RSASHA1;
  419                 break;
  420             case DST_ALG_NSEC3RSASHA1:
  421             case DST_ALG_RSASHA256:
  422             case DST_ALG_RSASHA512:
  423             case DST_ALG_ECDSA256:
  424             case DST_ALG_ECDSA384:
  425             case DST_ALG_ED25519:
  426             case DST_ALG_ED448:
  427                 break;
  428             default:
  429                 fatal("%s is incompatible with NSEC3; "
  430                       "do not use the -3 option",
  431                       algname);
  432             }
  433         }
  434 
  435         if (type != NULL && (options & DST_TYPE_KEY) != 0) {
  436             if (strcasecmp(type, "NOAUTH") == 0) {
  437                 flags |= DNS_KEYTYPE_NOAUTH;
  438             } else if (strcasecmp(type, "NOCONF") == 0) {
  439                 flags |= DNS_KEYTYPE_NOCONF;
  440             } else if (strcasecmp(type, "NOAUTHCONF") == 0) {
  441                 flags |= (DNS_KEYTYPE_NOAUTH |
  442                       DNS_KEYTYPE_NOCONF);
  443             } else if (strcasecmp(type, "AUTHCONF") == 0) {
  444                 /* nothing */
  445             } else {
  446                 fatal("invalid type %s", type);
  447             }
  448         }
  449 
  450         if (!oldstyle && prepub > 0) {
  451             if (setpub && setact && (activate - prepub) < publish) {
  452                 fatal("Activation and publication dates "
  453                       "are closer together than the\n\t"
  454                       "prepublication interval.");
  455             }
  456 
  457             if (!setpub && !setact) {
  458                 setpub = setact = true;
  459                 publish = now;
  460                 activate = now + prepub;
  461             } else if (setpub && !setact) {
  462                 setact = true;
  463                 activate = publish + prepub;
  464             } else if (setact && !setpub) {
  465                 setpub = true;
  466                 publish = activate - prepub;
  467             }
  468 
  469             if ((activate - prepub) < now) {
  470                 fatal("Time until activation is shorter "
  471                       "than the\n\tprepublication interval.");
  472             }
  473         }
  474     } else {
  475         char keystr[DST_KEY_FORMATSIZE];
  476         isc_stdtime_t when;
  477         int major, minor;
  478 
  479         if (prepub == -1) {
  480             prepub = (30 * 86400);
  481         }
  482 
  483         if (algname != NULL) {
  484             fatal("-S and -a cannot be used together");
  485         }
  486         if (nametype != NULL) {
  487             fatal("-S and -n cannot be used together");
  488         }
  489         if (type != NULL) {
  490             fatal("-S and -t cannot be used together");
  491         }
  492         if (setpub || unsetpub) {
  493             fatal("-S and -P cannot be used together");
  494         }
  495         if (setact || unsetact) {
  496             fatal("-S and -A cannot be used together");
  497         }
  498         if (use_nsec3) {
  499             fatal("-S and -3 cannot be used together");
  500         }
  501         if (oldstyle) {
  502             fatal("-S and -C cannot be used together");
  503         }
  504         if (genonly) {
  505             fatal("-S and -G cannot be used together");
  506         }
  507 
  508         ret = dst_key_fromnamedfile(predecessor, directory,
  509                         DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
  510                         mctx, &prevkey);
  511         if (ret != ISC_R_SUCCESS) {
  512             fatal("Invalid keyfile %s: %s", predecessor,
  513                   isc_result_totext(ret));
  514         }
  515         if (!dst_key_isprivate(prevkey)) {
  516             fatal("%s is not a private key", predecessor);
  517         }
  518 
  519         name = dst_key_name(prevkey);
  520         alg = dst_key_alg(prevkey);
  521         flags = dst_key_flags(prevkey);
  522 
  523         dst_key_format(prevkey, keystr, sizeof(keystr));
  524         dst_key_getprivateformat(prevkey, &major, &minor);
  525         if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION) {
  526             fatal("Key %s has incompatible format version %d.%d\n\t"
  527                   "It is not possible to generate a successor key.",
  528                   keystr, major, minor);
  529         }
  530 
  531         ret = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &when);
  532         if (ret != ISC_R_SUCCESS) {
  533             fatal("Key %s has no activation date.\n\t"
  534                   "You must use dnssec-settime -A to set one "
  535                   "before generating a successor.",
  536                   keystr);
  537         }
  538 
  539         ret = dst_key_gettime(prevkey, DST_TIME_INACTIVE, &activate);
  540         if (ret != ISC_R_SUCCESS) {
  541             fatal("Key %s has no inactivation date.\n\t"
  542                   "You must use dnssec-settime -I to set one "
  543                   "before generating a successor.",
  544                   keystr);
  545         }
  546 
  547         publish = activate - prepub;
  548         if (publish < now) {
  549             fatal("Key %s becomes inactive\n\t"
  550                   "sooner than the prepublication period "
  551                   "for the new key ends.\n\t"
  552                   "Either change the inactivation date with "
  553                   "dnssec-settime -I,\n\t"
  554                   "or use the -i option to set a shorter "
  555                   "prepublication interval.",
  556                   keystr);
  557         }
  558 
  559         ret = dst_key_gettime(prevkey, DST_TIME_DELETE, &when);
  560         if (ret != ISC_R_SUCCESS) {
  561             fprintf(stderr,
  562                 "%s: WARNING: Key %s has no removal "
  563                 "date;\n\t it will remain in the zone "
  564                 "indefinitely after rollover.\n\t "
  565                 "You can use dnssec-settime -D to "
  566                 "change this.\n",
  567                 program, keystr);
  568         }
  569 
  570         setpub = setact = true;
  571     }
  572 
  573     if (nametype == NULL) {
  574         if ((options & DST_TYPE_KEY) != 0) { /* KEY */
  575             fatal("no nametype specified");
  576         }
  577         flags |= DNS_KEYOWNER_ZONE; /* DNSKEY */
  578     } else if (strcasecmp(nametype, "zone") == 0) {
  579         flags |= DNS_KEYOWNER_ZONE;
  580     } else if ((options & DST_TYPE_KEY) != 0) { /* KEY */
  581         if (strcasecmp(nametype, "host") == 0 ||
  582             strcasecmp(nametype, "entity") == 0) {
  583             flags |= DNS_KEYOWNER_ENTITY;
  584         } else if (strcasecmp(nametype, "user") == 0) {
  585             flags |= DNS_KEYOWNER_USER;
  586         } else {
  587             fatal("invalid KEY nametype %s", nametype);
  588         }
  589     } else if (strcasecmp(nametype, "other") != 0) { /* DNSKEY */
  590         fatal("invalid DNSKEY nametype %s", nametype);
  591     }
  592 
  593     rdclass = strtoclass(classname);
  594 
  595     if (directory == NULL) {
  596         directory = ".";
  597     }
  598 
  599     if ((options & DST_TYPE_KEY) != 0) { /* KEY */
  600         flags |= signatory;
  601     } else if ((flags & DNS_KEYOWNER_ZONE) != 0) { /* DNSKEY */
  602         flags |= kskflag;
  603         flags |= revflag;
  604     }
  605 
  606     if (protocol == -1) {
  607         protocol = DNS_KEYPROTO_DNSSEC;
  608     } else if ((options & DST_TYPE_KEY) == 0 &&
  609            protocol != DNS_KEYPROTO_DNSSEC) {
  610         fatal("invalid DNSKEY protocol: %d", protocol);
  611     }
  612 
  613     if ((flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
  614         if ((flags & DNS_KEYFLAG_SIGNATORYMASK) != 0) {
  615             fatal("specified null key with signing authority");
  616         }
  617     }
  618 
  619     if ((flags & DNS_KEYFLAG_OWNERMASK) == DNS_KEYOWNER_ZONE &&
  620         alg == DNS_KEYALG_DH)
  621     {
  622         fatal("a key with algorithm '%s' cannot be a zone key",
  623               algname);
  624     }
  625 
  626     isc_buffer_init(&buf, filename, sizeof(filename) - 1);
  627 
  628     /* associate the key */
  629     ret = dst_key_fromlabel(name, alg, flags, protocol, rdclass,
  630 #if USE_PKCS11
  631                 "pkcs11",
  632 #else  /* if USE_PKCS11 */
  633                 engine,
  634 #endif /* if USE_PKCS11 */
  635                 label, NULL, mctx, &key);
  636 
  637     if (ret != ISC_R_SUCCESS) {
  638         char namestr[DNS_NAME_FORMATSIZE];
  639         char algstr[DNS_SECALG_FORMATSIZE];
  640         dns_name_format(name, namestr, sizeof(namestr));
  641         dns_secalg_format(alg, algstr, sizeof(algstr));
  642         fatal("failed to get key %s/%s: %s", namestr, algstr,
  643               isc_result_totext(ret));
  644         /* NOTREACHED */
  645         exit(-1);
  646     }
  647 
  648     /*
  649      * Set key timing metadata (unless using -C)
  650      *
  651      * Publish and activation dates are set to "now" by default, but
  652      * can be overridden.  Creation date is always set to "now".
  653      */
  654     if (!oldstyle) {
  655         dst_key_settime(key, DST_TIME_CREATED, now);
  656 
  657         if (genonly && (setpub || setact)) {
  658             fatal("cannot use -G together with -P or -A options");
  659         }
  660 
  661         if (setpub) {
  662             dst_key_settime(key, DST_TIME_PUBLISH, publish);
  663         } else if (setact) {
  664             dst_key_settime(key, DST_TIME_PUBLISH, activate);
  665         } else if (!genonly && !unsetpub) {
  666             dst_key_settime(key, DST_TIME_PUBLISH, now);
  667         }
  668 
  669         if (setact) {
  670             dst_key_settime(key, DST_TIME_ACTIVATE, activate);
  671         } else if (!genonly && !unsetact) {
  672             dst_key_settime(key, DST_TIME_ACTIVATE, now);
  673         }
  674 
  675         if (setrev) {
  676             if (kskflag == 0) {
  677                 fprintf(stderr,
  678                     "%s: warning: Key is "
  679                     "not flagged as a KSK, but -R "
  680                     "was used. Revoking a ZSK is "
  681                     "legal, but undefined.\n",
  682                     program);
  683             }
  684             dst_key_settime(key, DST_TIME_REVOKE, revoke);
  685         }
  686 
  687         if (setinact) {
  688             dst_key_settime(key, DST_TIME_INACTIVE, inactive);
  689         }
  690 
  691         if (setdel) {
  692             dst_key_settime(key, DST_TIME_DELETE, deltime);
  693         }
  694         if (setsyncadd) {
  695             dst_key_settime(key, DST_TIME_SYNCPUBLISH, syncadd);
  696         }
  697         if (setsyncdel) {
  698             dst_key_settime(key, DST_TIME_SYNCDELETE, syncdel);
  699         }
  700     } else {
  701         if (setpub || setact || setrev || setinact || setdel ||
  702             unsetpub || unsetact || unsetrev || unsetinact ||
  703             unsetdel || genonly || setsyncadd || setsyncdel)
  704         {
  705             fatal("cannot use -C together with "
  706                   "-P, -A, -R, -I, -D, or -G options");
  707         }
  708         /*
  709          * Compatibility mode: Private-key-format
  710          * should be set to 1.2.
  711          */
  712         dst_key_setprivateformat(key, 1, 2);
  713     }
  714 
  715     /* Set default key TTL */
  716     if (setttl) {
  717         dst_key_setttl(key, ttl);
  718     }
  719 
  720     /*
  721      * Do not overwrite an existing key.  Warn LOUDLY if there
  722      * is a risk of ID collision due to this key or another key
  723      * being revoked.
  724      */
  725     if (key_collision(key, name, directory, mctx, &exact)) {
  726         isc_buffer_clear(&buf);
  727         ret = dst_key_buildfilename(key, 0, directory, &buf);
  728         if (ret != ISC_R_SUCCESS) {
  729             fatal("dst_key_buildfilename returned: %s\n",
  730                   isc_result_totext(ret));
  731         }
  732         if (exact) {
  733             fatal("%s: %s already exists\n", program, filename);
  734         }
  735 
  736         if (avoid_collisions) {
  737             fatal("%s: %s could collide with another key upon "
  738                   "revokation\n",
  739                   program, filename);
  740         }
  741 
  742         fprintf(stderr,
  743             "%s: WARNING: Key %s could collide with "
  744             "another key upon revokation.  If you plan "
  745             "to revoke keys, destroy this key and "
  746             "generate a different one.\n",
  747             program, filename);
  748     }
  749 
  750     ret = dst_key_tofile(key, options, directory);
  751     if (ret != ISC_R_SUCCESS) {
  752         char keystr[DST_KEY_FORMATSIZE];
  753         dst_key_format(key, keystr, sizeof(keystr));
  754         fatal("failed to write key %s: %s\n", keystr,
  755               isc_result_totext(ret));
  756     }
  757 
  758     isc_buffer_clear(&buf);
  759     ret = dst_key_buildfilename(key, 0, NULL, &buf);
  760     if (ret != ISC_R_SUCCESS) {
  761         fatal("dst_key_buildfilename returned: %s\n",
  762               isc_result_totext(ret));
  763     }
  764     printf("%s\n", filename);
  765     dst_key_free(&key);
  766     if (prevkey != NULL) {
  767         dst_key_free(&prevkey);
  768     }
  769 
  770     cleanup_logging(&log);
  771     dst_lib_destroy();
  772     if (verbose > 10) {
  773         isc_mem_stats(mctx, stdout);
  774     }
  775     isc_mem_free(mctx, label);
  776     isc_mem_destroy(&mctx);
  777 
  778     if (freeit != NULL) {
  779         free(freeit);
  780     }
  781 
  782     return (0);
  783 }