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