Update repub branch u/fanf2/patch to rebasing branch u/fanf2/rebasing revision v9_13_...
[ipreg/bind9.git] / bin / dnssec / dnssec-settime.c
CommitLineData
553ead32 1/*
843d3896 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
553ead32 3 *
0c27b3fe
MA
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/.
843d3896
OS
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
553ead32
EH
10 */
11
553ead32
EH
12/*! \file */
13
cb6a185c 14#include <inttypes.h>
994e6569 15#include <stdbool.h>
553ead32
EH
16#include <stdlib.h>
17#include <unistd.h>
9edd523c 18#include <errno.h>
553ead32
EH
19#include <time.h>
20
21#include <isc/buffer.h>
22#include <isc/commandline.h>
747abb49 23#include <isc/file.h>
553ead32
EH
24#include <isc/hash.h>
25#include <isc/mem.h>
26#include <isc/print.h>
27#include <isc/string.h>
28#include <isc/util.h>
29
30#include <dns/keyvalues.h>
31#include <dns/result.h>
c514f38c 32#include <dns/log.h>
553ead32
EH
33
34#include <dst/dst.h>
35
c3b8130f 36#if USE_PKCS11
acbb301e
EH
37#include <pk11/result.h>
38#endif
39
553ead32
EH
40#include "dnssectool.h"
41
42const char *program = "dnssec-settime";
43int verbose;
44
45static isc_mem_t *mctx = NULL;
46
debd489a
FD
47ISC_PLATFORM_NORETURN_PRE static void
48usage(void) ISC_PLATFORM_NORETURN_POST;
49
553ead32
EH
50static void
51usage(void) {
52 fprintf(stderr, "Usage:\n");
53 fprintf(stderr, " %s [options] keyfile\n\n", program);
54 fprintf(stderr, "Version: %s\n", VERSION);
eab9975b 55 fprintf(stderr, "General options:\n");
c3b8130f 56#if USE_PKCS11
ba751492
EH
57 fprintf(stderr, " -E engine: specify PKCS#11 provider "
58 "(default: %s)\n", PK11_LIB_LOCATION);
59#elif defined(USE_PKCS11)
b1fbf2a4 60 fprintf(stderr, " -E engine: specify OpenSSL engine "
ba751492 61 "(default \"pkcs11\")\n");
8b78c993 62#else
b1fbf2a4 63 fprintf(stderr, " -E engine: specify OpenSSL engine\n");
8b78c993 64#endif
553ead32
EH
65 fprintf(stderr, " -f: force update of old-style "
66 "keys\n");
67 fprintf(stderr, " -K directory: set key file location\n");
61bcc232 68 fprintf(stderr, " -L ttl: set default key TTL\n");
eab9975b 69 fprintf(stderr, " -v level: set level of verbosity\n");
42782931 70 fprintf(stderr, " -V: print version information\n");
eab9975b 71 fprintf(stderr, " -h: help\n");
553ead32 72 fprintf(stderr, "Timing options:\n");
eab9975b
EH
73 fprintf(stderr, " -P date/[+-]offset/none: set/unset key "
74 "publication date\n");
e939674d
MA
75 fprintf(stderr, " -P sync date/[+-]offset/none: set/unset "
76 "CDS and CDNSKEY publication date\n");
8ebf67b7 77 fprintf(stderr, " -A date/[+-]offset/none: set/unset key "
eab9975b 78 "activation date\n");
8ebf67b7 79 fprintf(stderr, " -R date/[+-]offset/none: set/unset key "
eab9975b 80 "revocation date\n");
8ebf67b7 81 fprintf(stderr, " -I date/[+-]offset/none: set/unset key "
b843f577 82 "inactivation date\n");
8ebf67b7 83 fprintf(stderr, " -D date/[+-]offset/none: set/unset key "
eab9975b 84 "deletion date\n");
e939674d
MA
85 fprintf(stderr, " -D sync date/[+-]offset/none: set/unset "
86 "CDS and CDNSKEY deletion date\n");
5201b96d
MK
87 fprintf(stderr, " -S <key>: generate a successor to an existing "
88 "key\n");
89 fprintf(stderr, " -i <interval>: prepublication interval for "
90 "successor key "
91 "(default: 30 days)\n");
eab9975b 92 fprintf(stderr, "Printing options:\n");
e939674d
MA
93 fprintf(stderr, " -p C/P/Psync/A/R/I/D/Dsync/all: print a "
94 "particular time value or values\n");
eab9975b
EH
95 fprintf(stderr, " -u: print times in unix epoch "
96 "format\n");
553ead32
EH
97 fprintf(stderr, "Output:\n");
98 fprintf(stderr, " K<name>+<alg>+<new id>.key, "
99 "K<name>+<alg>+<new id>.private\n");
100
101 exit (-1);
102}
103
104static void
994e6569 105printtime(dst_key_t *key, int type, const char *tag, bool epoch,
eab9975b
EH
106 FILE *stream)
107{
553ead32 108 isc_result_t result;
eab9975b
EH
109 const char *output = NULL;
110 isc_stdtime_t when;
553ead32 111
eab9975b
EH
112 if (tag != NULL)
113 fprintf(stream, "%s: ", tag);
553ead32 114
eab9975b
EH
115 result = dst_key_gettime(key, type, &when);
116 if (result == ISC_R_NOTFOUND) {
117 fprintf(stream, "UNSET\n");
118 } else if (epoch) {
119 fprintf(stream, "%d\n", (int) when);
120 } else {
af669cb4
MA
121 time_t timet = when;
122 output = ctime(&timet);
eab9975b
EH
123 fprintf(stream, "%s", output);
124 }
553ead32
EH
125}
126
127int
128main(int argc, char **argv) {
c6f4972c 129 isc_result_t result;
c6f4972c 130 const char *engine = NULL;
5b1c7ef3
MA
131 const char *filename = NULL;
132 char *directory = NULL;
c6f4972c
MA
133 char newname[1024];
134 char keystr[DST_KEY_FORMATSIZE];
135 char *endp, *p;
136 int ch;
c6f4972c
MA
137 const char *predecessor = NULL;
138 dst_key_t *prevkey = NULL;
139 dst_key_t *key = NULL;
140 isc_buffer_t buf;
141 dns_name_t *name = NULL;
142 dns_secalg_t alg = 0;
143 unsigned int size = 0;
cb6a185c 144 uint16_t flags = 0;
c6f4972c 145 int prepub = -1;
61bcc232 146 dns_ttl_t ttl = 0;
eab9975b 147 isc_stdtime_t now;
b843f577 148 isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0;
c8803902 149 isc_stdtime_t prevact = 0, previnact = 0, prevdel = 0;
994e6569
OS
150 bool setpub = false, setact = false;
151 bool setrev = false, setinact = false;
152 bool setdel = false, setttl = false;
153 bool unsetpub = false, unsetact = false;
154 bool unsetrev = false, unsetinact = false;
155 bool unsetdel = false;
156 bool printcreate = false, printpub = false;
157 bool printact = false, printrev = false;
158 bool printinact = false, printdel = false;
159 bool force = false;
160 bool epoch = false;
161 bool changed = false;
c514f38c 162 isc_log_t *log = NULL;
e939674d 163 isc_stdtime_t syncadd = 0, syncdel = 0;
994e6569
OS
164 bool unsetsyncadd = false, setsyncadd = false;
165 bool unsetsyncdel = false, setsyncdel = false;
166 bool printsyncadd = false, printsyncdel = false;
553ead32
EH
167
168 if (argc == 1)
169 usage();
170
171 result = isc_mem_create(0, 0, &mctx);
172 if (result != ISC_R_SUCCESS)
173 fatal("Out of memory");
174
11463c0a 175 setup_logging(mctx, &log);
c514f38c 176
c3b8130f 177#if USE_PKCS11
acbb301e
EH
178 pk11_result_register();
179#endif
553ead32
EH
180 dns_result_register();
181
994e6569 182 isc_commandline_errprint = false;
553ead32
EH
183
184 isc_stdtime_get(&now);
185
42782931 186#define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:V"
c6f4972c 187 while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
553ead32 188 switch (ch) {
8b78c993
FD
189 case 'E':
190 engine = isc_commandline_argument;
191 break;
2847ddea 192 case 'f':
994e6569 193 force = true;
553ead32 194 break;
eab9975b
EH
195 case 'p':
196 p = isc_commandline_argument;
197 if (!strcasecmp(p, "all")) {
994e6569
OS
198 printcreate = true;
199 printpub = true;
200 printact = true;
201 printrev = true;
202 printinact = true;
203 printdel = true;
204 printsyncadd = true;
205 printsyncdel = true;
eab9975b
EH
206 break;
207 }
208
209 do {
210 switch (*p++) {
211 case 'C':
994e6569 212 printcreate = true;
eab9975b
EH
213 break;
214 case 'P':
f8432e3f
MA
215 if (!strncmp(p, "sync", 4)) {
216 p += 4;
994e6569 217 printsyncadd = true;
e939674d
MA
218 break;
219 }
994e6569 220 printpub = true;
eab9975b
EH
221 break;
222 case 'A':
994e6569 223 printact = true;
eab9975b
EH
224 break;
225 case 'R':
994e6569 226 printrev = true;
eab9975b 227 break;
b843f577 228 case 'I':
994e6569 229 printinact = true;
eab9975b
EH
230 break;
231 case 'D':
f8432e3f
MA
232 if (!strncmp(p, "sync", 4)) {
233 p += 4;
994e6569 234 printsyncdel = true;
e939674d
MA
235 break;
236 }
994e6569 237 printdel = true;
eab9975b
EH
238 break;
239 case ' ':
240 break;
241 default:
242 usage();
243 break;
244 }
245 } while (*p != '\0');
246 break;
247 case 'u':
994e6569 248 epoch = true;
eab9975b 249 break;
2847ddea
TJ
250 case 'K':
251 /*
252 * We don't have to copy it here, but do it to
253 * simplify cleanup later
254 */
255 directory = isc_mem_strdup(mctx,
256 isc_commandline_argument);
257 if (directory == NULL) {
8d0a1ede 258 fatal("Failed to allocate memory for "
2847ddea
TJ
259 "directory");
260 }
553ead32 261 break;
61bcc232 262 case 'L':
a165a17a 263 ttl = strtottl(isc_commandline_argument);
994e6569 264 setttl = true;
61bcc232 265 break;
2847ddea 266 case 'v':
553ead32
EH
267 verbose = strtol(isc_commandline_argument, &endp, 0);
268 if (*endp != '\0')
269 fatal("-v must be followed by a number");
270 break;
2847ddea 271 case 'P':
e939674d
MA
272 /* -Psync ? */
273 if (isoptarg("sync", argv, usage)) {
274 if (unsetsyncadd || setsyncadd)
275 fatal("-P sync specified more than "
276 "once");
277
994e6569 278 changed = true;
e939674d
MA
279 syncadd = strtotime(isc_commandline_argument,
280 now, now, &setsyncadd);
281 unsetsyncadd = !setsyncadd;
282 break;
283 }
284 (void)isoptarg("dnskey", argv, usage);
d7201de0
AU
285 if (setpub || unsetpub)
286 fatal("-P specified more than once");
eab9975b 287
994e6569 288 changed = true;
a165a17a
EH
289 pub = strtotime(isc_commandline_argument,
290 now, now, &setpub);
291 unsetpub = !setpub;
553ead32 292 break;
2847ddea 293 case 'A':
d7201de0
AU
294 if (setact || unsetact)
295 fatal("-A specified more than once");
eab9975b 296
994e6569 297 changed = true;
a165a17a
EH
298 act = strtotime(isc_commandline_argument,
299 now, now, &setact);
300 unsetact = !setact;
553ead32 301 break;
2847ddea 302 case 'R':
d7201de0
AU
303 if (setrev || unsetrev)
304 fatal("-R specified more than once");
eab9975b 305
994e6569 306 changed = true;
a165a17a
EH
307 rev = strtotime(isc_commandline_argument,
308 now, now, &setrev);
309 unsetrev = !setrev;
553ead32 310 break;
b843f577
EH
311 case 'I':
312 if (setinact || unsetinact)
313 fatal("-I specified more than once");
eab9975b 314
994e6569 315 changed = true;
a165a17a
EH
316 inact = strtotime(isc_commandline_argument,
317 now, now, &setinact);
318 unsetinact = !setinact;
553ead32 319 break;
2847ddea 320 case 'D':
e939674d
MA
321 /* -Dsync ? */
322 if (isoptarg("sync", argv, usage)) {
323 if (unsetsyncdel || setsyncdel)
324 fatal("-D sync specified more than "
325 "once");
326
994e6569 327 changed = true;
e939674d
MA
328 syncdel = strtotime(isc_commandline_argument,
329 now, now, &setsyncdel);
330 unsetsyncdel = !setsyncdel;
331 break;
332 }
333 /* -Ddnskey ? */
334 (void)isoptarg("dnskey", argv, usage);
d7201de0
AU
335 if (setdel || unsetdel)
336 fatal("-D specified more than once");
eab9975b 337
994e6569 338 changed = true;
a165a17a
EH
339 del = strtotime(isc_commandline_argument,
340 now, now, &setdel);
341 unsetdel = !setdel;
553ead32 342 break;
c6f4972c
MA
343 case 'S':
344 predecessor = isc_commandline_argument;
345 break;
346 case 'i':
347 prepub = strtottl(isc_commandline_argument);
348 break;
2847ddea 349 case '?':
553ead32
EH
350 if (isc_commandline_option != '?')
351 fprintf(stderr, "%s: invalid argument -%c\n",
352 program, isc_commandline_option);
cdacec1d 353 /* FALLTHROUGH */
2847ddea 354 case 'h':
42782931 355 /* Does not return. */
553ead32
EH
356 usage();
357
42782931
MS
358 case 'V':
359 /* Does not return. */
360 version(program);
361
2847ddea 362 default:
553ead32
EH
363 fprintf(stderr, "%s: unhandled option -%c\n",
364 program, isc_commandline_option);
365 exit(1);
366 }
367 }
368
369 if (argc < isc_commandline_index + 1 ||
370 argv[isc_commandline_index] == NULL)
371 fatal("The key file name was not specified");
372 if (argc > isc_commandline_index + 1)
373 fatal("Extraneous arguments");
374
3a4f820d 375 result = dst_lib_init(mctx, engine);
553ead32 376 if (result != ISC_R_SUCCESS)
8b78c993
FD
377 fatal("Could not initialize dst: %s",
378 isc_result_totext(result));
553ead32 379
c6f4972c 380 if (predecessor != NULL) {
c6f4972c
MA
381 int major, minor;
382
383 if (prepub == -1)
384 prepub = (30 * 86400);
385
386 if (setpub || unsetpub)
387 fatal("-S and -P cannot be used together");
388 if (setact || unsetact)
389 fatal("-S and -A cannot be used together");
390
391 result = dst_key_fromnamedfile(predecessor, directory,
f428e385 392 DST_TYPE_PUBLIC |
c6f4972c
MA
393 DST_TYPE_PRIVATE,
394 mctx, &prevkey);
395 if (result != ISC_R_SUCCESS)
396 fatal("Invalid keyfile %s: %s",
397 filename, isc_result_totext(result));
0c91911b 398 if (!dst_key_isprivate(prevkey) && !dst_key_isexternal(prevkey))
c6f4972c
MA
399 fatal("%s is not a private key", filename);
400
401 name = dst_key_name(prevkey);
402 alg = dst_key_alg(prevkey);
403 size = dst_key_size(prevkey);
404 flags = dst_key_flags(prevkey);
405
406 dst_key_format(prevkey, keystr, sizeof(keystr));
407 dst_key_getprivateformat(prevkey, &major, &minor);
408 if (major != DST_MAJOR_VERSION || minor < DST_MINOR_VERSION)
409 fatal("Predecessor has incompatible format "
410 "version %d.%d\n\t", major, minor);
411
c8803902 412 result = dst_key_gettime(prevkey, DST_TIME_ACTIVATE, &prevact);
c6f4972c
MA
413 if (result != ISC_R_SUCCESS)
414 fatal("Predecessor has no activation date. "
415 "You must set one before\n\t"
416 "generating a successor.");
417
c8803902
CB
418 result = dst_key_gettime(prevkey, DST_TIME_INACTIVE,
419 &previnact);
c6f4972c
MA
420 if (result != ISC_R_SUCCESS)
421 fatal("Predecessor has no inactivation date. "
422 "You must set one before\n\t"
423 "generating a successor.");
5ac5300f 424
5201b96d
MK
425 pub = previnact - prepub;
426 act = previnact;
427
428 if ((previnact - prepub) < now && prepub != 0)
429 fatal("Time until predecessor inactivation is\n\t"
430 "shorter than the prepublication interval. "
431 "Either change\n\t"
432 "predecessor inactivation date, or use the -i "
433 "option to set\n\t"
434 "a shorter prepublication interval.");
c6f4972c 435
c8803902 436 result = dst_key_gettime(prevkey, DST_TIME_DELETE, &prevdel);
c6f4972c 437 if (result != ISC_R_SUCCESS)
c8803902 438 fprintf(stderr, "%s: warning: Predecessor has no "
c6f4972c
MA
439 "removal date;\n\t"
440 "it will remain in the zone "
441 "indefinitely after rollover.\n",
442 program);
c8803902
CB
443 else if (prevdel < previnact)
444 fprintf(stderr, "%s: warning: Predecessor is "
445 "scheduled to be deleted\n\t"
446 "before it is scheduled to be "
447 "inactive.\n", program);
c6f4972c 448
994e6569 449 changed = setpub = setact = true;
c6f4972c
MA
450 } else {
451 if (prepub < 0)
452 prepub = 0;
453
454 if (prepub > 0) {
455 if (setpub && setact && (act - prepub) < pub)
456 fatal("Activation and publication dates "
457 "are closer together than the\n\t"
458 "prepublication interval.");
459
460 if (setpub && !setact) {
994e6569 461 setact = true;
c6f4972c
MA
462 act = pub + prepub;
463 } else if (setact && !setpub) {
994e6569 464 setpub = true;
c6f4972c
MA
465 pub = act - prepub;
466 }
467
468 if ((act - prepub) < now)
469 fatal("Time until activation is shorter "
470 "than the\n\tprepublication interval.");
471 }
472 }
473
474 if (directory != NULL) {
475 filename = argv[isc_commandline_index];
476 } else {
477 result = isc_file_splitpath(mctx, argv[isc_commandline_index],
478 &directory, &filename);
479 if (result != ISC_R_SUCCESS)
480 fatal("cannot process filename %s: %s",
481 argv[isc_commandline_index],
482 isc_result_totext(result));
483 }
484
553ead32
EH
485 result = dst_key_fromnamedfile(filename, directory,
486 DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
487 mctx, &key);
488 if (result != ISC_R_SUCCESS)
489 fatal("Invalid keyfile %s: %s",
490 filename, isc_result_totext(result));
491
0c91911b 492 if (!dst_key_isprivate(key) && !dst_key_isexternal(key))
553ead32
EH
493 fatal("%s is not a private key", filename);
494
77b8f88f 495 dst_key_format(key, keystr, sizeof(keystr));
553ead32 496
c6f4972c
MA
497 if (predecessor != NULL) {
498 if (!dns_name_equal(name, dst_key_name(key)))
499 fatal("Key name mismatch");
500 if (alg != dst_key_alg(key))
501 fatal("Key algorithm mismatch");
502 if (size != dst_key_size(key))
503 fatal("Key size mismatch");
504 if (flags != dst_key_flags(key))
505 fatal("Key flags mismatch");
506 }
507
c8803902
CB
508 prevdel = previnact = 0;
509 if ((setdel && setinact && del < inact) ||
510 (dst_key_gettime(key, DST_TIME_INACTIVE,
511 &previnact) == ISC_R_SUCCESS &&
f6096b95 512 setdel && !setinact && !unsetinact && del < previnact) ||
c8803902
CB
513 (dst_key_gettime(key, DST_TIME_DELETE,
514 &prevdel) == ISC_R_SUCCESS &&
f6096b95
EH
515 setinact && !setdel && !unsetdel && prevdel < inact) ||
516 (!setdel && !unsetdel && !setinact && !unsetinact &&
33036556 517 prevdel != 0 && prevdel < previnact))
c8803902
CB
518 fprintf(stderr, "%s: warning: Key is scheduled to "
519 "be deleted before it is\n\t"
520 "scheduled to be inactive.\n",
521 program);
522
c0214996
EH
523 if (force)
524 set_keyversion(key);
525 else
526 check_keyversion(key, keystr);
553ead32
EH
527
528 if (verbose > 2)
529 fprintf(stderr, "%s: %s\n", program, keystr);
530
eab9975b
EH
531 /*
532 * Set time values.
533 */
534 if (setpub)
535 dst_key_settime(key, DST_TIME_PUBLISH, pub);
536 else if (unsetpub)
537 dst_key_unsettime(key, DST_TIME_PUBLISH);
538
539 if (setact)
540 dst_key_settime(key, DST_TIME_ACTIVATE, act);
541 else if (unsetact)
542 dst_key_unsettime(key, DST_TIME_ACTIVATE);
543
544 if (setrev) {
b843f577 545 if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
d7201de0 546 fprintf(stderr, "%s: warning: Key %s is already "
eab9975b
EH
547 "revoked; changing the revocation date "
548 "will not affect this.\n",
549 program, keystr);
53c22b8e
EH
550 if ((dst_key_flags(key) & DNS_KEYFLAG_KSK) == 0)
551 fprintf(stderr, "%s: warning: Key %s is not flagged as "
552 "a KSK, but -R was used. Revoking a "
553 "ZSK is legal, but undefined.\n",
554 program, keystr);
eab9975b
EH
555 dst_key_settime(key, DST_TIME_REVOKE, rev);
556 } else if (unsetrev) {
d7201de0
AU
557 if ((dst_key_flags(key) & DNS_KEYFLAG_REVOKE) != 0)
558 fprintf(stderr, "%s: warning: Key %s is already "
eab9975b
EH
559 "revoked; removing the revocation date "
560 "will not affect this.\n",
561 program, keystr);
562 dst_key_unsettime(key, DST_TIME_REVOKE);
d7201de0 563 }
eab9975b 564
b843f577
EH
565 if (setinact)
566 dst_key_settime(key, DST_TIME_INACTIVE, inact);
567 else if (unsetinact)
568 dst_key_unsettime(key, DST_TIME_INACTIVE);
eab9975b
EH
569
570 if (setdel)
571 dst_key_settime(key, DST_TIME_DELETE, del);
572 else if (unsetdel)
573 dst_key_unsettime(key, DST_TIME_DELETE);
574
e939674d
MA
575 if (setsyncadd)
576 dst_key_settime(key, DST_TIME_SYNCPUBLISH, syncadd);
577 else if (unsetsyncadd)
578 dst_key_unsettime(key, DST_TIME_SYNCPUBLISH);
579
580 if (setsyncdel)
581 dst_key_settime(key, DST_TIME_SYNCDELETE, syncdel);
582 else if (unsetsyncdel)
583 dst_key_unsettime(key, DST_TIME_SYNCDELETE);
584
61bcc232
EH
585 if (setttl)
586 dst_key_setttl(key, ttl);
587
10a759ce
EH
588 /*
589 * No metadata changes were made but we're forcing an upgrade
590 * to the new format anyway: use "-P now -A now" as the default
591 */
592 if (force && !changed) {
593 dst_key_settime(key, DST_TIME_PUBLISH, now);
594 dst_key_settime(key, DST_TIME_ACTIVATE, now);
994e6569 595 changed = true;
10a759ce
EH
596 }
597
598 if (!changed && setttl)
994e6569 599 changed = true;
10a759ce 600
eab9975b
EH
601 /*
602 * Print out time values, if -p was used.
603 */
604 if (printcreate)
605 printtime(key, DST_TIME_CREATED, "Created", epoch, stdout);
606
607 if (printpub)
608 printtime(key, DST_TIME_PUBLISH, "Publish", epoch, stdout);
609
610 if (printact)
611 printtime(key, DST_TIME_ACTIVATE, "Activate", epoch, stdout);
612
613 if (printrev)
614 printtime(key, DST_TIME_REVOKE, "Revoke", epoch, stdout);
615
b843f577
EH
616 if (printinact)
617 printtime(key, DST_TIME_INACTIVE, "Inactive", epoch, stdout);
eab9975b
EH
618
619 if (printdel)
620 printtime(key, DST_TIME_DELETE, "Delete", epoch, stdout);
621
e939674d
MA
622 if (printsyncadd)
623 printtime(key, DST_TIME_SYNCPUBLISH, "SYNC Publish",
624 epoch, stdout);
625
626 if (printsyncdel)
627 printtime(key, DST_TIME_SYNCDELETE, "SYNC Delete",
628 epoch, stdout);
629
eab9975b 630 if (changed) {
553ead32 631 isc_buffer_init(&buf, newname, sizeof(newname));
2847ddea
TJ
632 result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory,
633 &buf);
634 if (result != ISC_R_SUCCESS) {
635 fatal("Failed to build public key filename: %s",
636 isc_result_totext(result));
637 }
553ead32
EH
638
639 result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE,
640 directory);
641 if (result != ISC_R_SUCCESS) {
77b8f88f 642 dst_key_format(key, keystr, sizeof(keystr));
553ead32
EH
643 fatal("Failed to write key %s: %s", keystr,
644 isc_result_totext(result));
645 }
646
647 printf("%s\n", newname);
648
649 isc_buffer_clear(&buf);
2847ddea
TJ
650 result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory,
651 &buf);
652 if (result != ISC_R_SUCCESS) {
653 fatal("Failed to build private key filename: %s",
654 isc_result_totext(result));
655 }
553ead32
EH
656 printf("%s\n", newname);
657 }
658
bc8f8249
MA
659 if (prevkey != NULL)
660 dst_key_free(&prevkey);
553ead32 661 dst_key_free(&key);
586e65ea 662 dst_lib_destroy();
553ead32
EH
663 if (verbose > 10)
664 isc_mem_stats(mctx, stdout);
c514f38c 665 cleanup_logging(&log);
2847ddea 666 isc_mem_free(mctx, directory);
553ead32
EH
667 isc_mem_destroy(&mctx);
668
669 return (0);
670}