4 * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
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.
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.
19 /* Id: dnssec-settime.c,v 1.19 2009/10/27 18:56:49 each Exp */
31 #include <isc/buffer.h>
32 #include <isc/commandline.h>
33 #include <isc/entropy.h>
37 #include <isc/print.h>
38 #include <isc/string.h>
41 #include <dns/keyvalues.h>
42 #include <dns/result.h>
46 #include "dnssectool.h"
48 const char *program
= "dnssec-settime";
51 static isc_mem_t
*mctx
= NULL
;
53 ISC_PLATFORM_NORETURN_PRE
static void
54 usage(void) ISC_PLATFORM_NORETURN_POST
;
58 fprintf(stderr
, "Usage:\n");
59 fprintf(stderr
, " %s [options] keyfile\n\n", program
);
60 fprintf(stderr
, "Version: %s\n", VERSION
);
61 fprintf(stderr
, "General options:\n");
63 fprintf(stderr
, "\t\tname of an OpenSSL engine to use "
64 "(default is \"pkcs11\")\n");
66 fprintf(stderr
, "\t\tname of an OpenSSL engine to use\n");
68 fprintf(stderr
, " -f: force update of old-style "
70 fprintf(stderr
, " -K directory: set key file location\n");
71 fprintf(stderr
, " -v level: set level of verbosity\n");
72 fprintf(stderr
, " -h: help\n");
73 fprintf(stderr
, "Timing options:\n");
74 fprintf(stderr
, " -P date/[+-]offset/none: set/unset key "
75 "publication date\n");
76 fprintf(stderr
, " -A date/[+-]offset/none: set key "
78 fprintf(stderr
, " -R date/[+-]offset/none: set key "
80 fprintf(stderr
, " -I date/[+-]offset/none: set key "
81 "inactivation date\n");
82 fprintf(stderr
, " -D date/[+-]offset/none: set key "
84 fprintf(stderr
, "Printing options:\n");
85 fprintf(stderr
, " -p C/P/A/R/U/D/all: print a particular time "
88 fprintf(stderr
, " -u: print times in unix epoch "
90 fprintf(stderr
, "Output:\n");
91 fprintf(stderr
, " K<name>+<alg>+<new id>.key, "
92 "K<name>+<alg>+<new id>.private\n");
98 printtime(dst_key_t
*key
, int type
, const char *tag
, isc_boolean_t epoch
,
102 const char *output
= NULL
;
106 fprintf(stream
, "%s: ", tag
);
108 result
= dst_key_gettime(key
, type
, &when
);
109 if (result
== ISC_R_NOTFOUND
) {
110 fprintf(stream
, "UNSET\n");
112 fprintf(stream
, "%d\n", (int) when
);
115 output
= ctime(&time
);
116 fprintf(stream
, "%s", output
);
121 main(int argc
, char **argv
) {
124 const char *engine
= "pkcs11";
126 const char *engine
= NULL
;
128 char *filename
= NULL
, *directory
= NULL
;
130 char keystr
[DST_KEY_FORMATSIZE
];
133 isc_entropy_t
*ectx
= NULL
;
134 dst_key_t
*key
= NULL
;
137 isc_stdtime_t pub
= 0, act
= 0, rev
= 0, inact
= 0, del
= 0;
138 isc_boolean_t setpub
= ISC_FALSE
, setact
= ISC_FALSE
;
139 isc_boolean_t setrev
= ISC_FALSE
, setinact
= ISC_FALSE
;
140 isc_boolean_t setdel
= ISC_FALSE
;
141 isc_boolean_t unsetpub
= ISC_FALSE
, unsetact
= ISC_FALSE
;
142 isc_boolean_t unsetrev
= ISC_FALSE
, unsetinact
= ISC_FALSE
;
143 isc_boolean_t unsetdel
= ISC_FALSE
;
144 isc_boolean_t printcreate
= ISC_FALSE
, printpub
= ISC_FALSE
;
145 isc_boolean_t printact
= ISC_FALSE
, printrev
= ISC_FALSE
;
146 isc_boolean_t printinact
= ISC_FALSE
, printdel
= ISC_FALSE
;
147 isc_boolean_t force
= ISC_FALSE
;
148 isc_boolean_t epoch
= ISC_FALSE
;
149 isc_boolean_t changed
= ISC_FALSE
;
154 result
= isc_mem_create(0, 0, &mctx
);
155 if (result
!= ISC_R_SUCCESS
)
156 fatal("Out of memory");
158 dns_result_register();
160 isc_commandline_errprint
= ISC_FALSE
;
162 isc_stdtime_get(&now
);
164 while ((ch
= isc_commandline_parse(argc
, argv
,
165 "E:fK:uhp:v:P:A:R:I:D:")) != -1) {
168 engine
= isc_commandline_argument
;
174 p
= isc_commandline_argument
;
175 if (!strcasecmp(p
, "all")) {
176 printcreate
= ISC_TRUE
;
180 printinact
= ISC_TRUE
;
188 printcreate
= ISC_TRUE
;
200 printinact
= ISC_TRUE
;
211 } while (*p
!= '\0');
218 * We don't have to copy it here, but do it to
219 * simplify cleanup later
221 directory
= isc_mem_strdup(mctx
,
222 isc_commandline_argument
);
223 if (directory
== NULL
) {
224 fatal("Failed to allocate memory for "
229 verbose
= strtol(isc_commandline_argument
, &endp
, 0);
231 fatal("-v must be followed by a number");
234 if (setpub
|| unsetpub
)
235 fatal("-P specified more than once");
238 if (!strcasecmp(isc_commandline_argument
, "none")) {
242 pub
= strtotime(isc_commandline_argument
,
247 if (setact
|| unsetact
)
248 fatal("-A specified more than once");
251 if (!strcasecmp(isc_commandline_argument
, "none")) {
255 act
= strtotime(isc_commandline_argument
,
260 if (setrev
|| unsetrev
)
261 fatal("-R specified more than once");
264 if (!strcasecmp(isc_commandline_argument
, "none")) {
268 rev
= strtotime(isc_commandline_argument
,
273 if (setinact
|| unsetinact
)
274 fatal("-I specified more than once");
277 if (!strcasecmp(isc_commandline_argument
, "none")) {
278 unsetinact
= ISC_TRUE
;
281 inact
= strtotime(isc_commandline_argument
,
286 if (setdel
|| unsetdel
)
287 fatal("-D specified more than once");
290 if (!strcasecmp(isc_commandline_argument
, "none")) {
294 del
= strtotime(isc_commandline_argument
,
299 if (isc_commandline_option
!= '?')
300 fprintf(stderr
, "%s: invalid argument -%c\n",
301 program
, isc_commandline_option
);
307 fprintf(stderr
, "%s: unhandled option -%c\n",
308 program
, isc_commandline_option
);
313 if (argc
< isc_commandline_index
+ 1 ||
314 argv
[isc_commandline_index
] == NULL
)
315 fatal("The key file name was not specified");
316 if (argc
> isc_commandline_index
+ 1)
317 fatal("Extraneous arguments");
319 if (directory
!= NULL
) {
320 filename
= argv
[isc_commandline_index
];
322 result
= isc_file_splitpath(mctx
, argv
[isc_commandline_index
],
323 &directory
, &filename
);
324 if (result
!= ISC_R_SUCCESS
)
325 fatal("cannot process filename %s: %s",
326 argv
[isc_commandline_index
],
327 isc_result_totext(result
));
331 setup_entropy(mctx
, NULL
, &ectx
);
332 result
= isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
);
333 if (result
!= ISC_R_SUCCESS
)
334 fatal("Could not initialize hash");
335 result
= dst_lib_init2(mctx
, ectx
, engine
,
336 ISC_ENTROPY_BLOCKING
| ISC_ENTROPY_GOODONLY
);
337 if (result
!= ISC_R_SUCCESS
)
338 fatal("Could not initialize dst: %s",
339 isc_result_totext(result
));
340 isc_entropy_stopcallbacksources(ectx
);
342 result
= dst_key_fromnamedfile(filename
, directory
,
343 DST_TYPE_PUBLIC
| DST_TYPE_PRIVATE
,
345 if (result
!= ISC_R_SUCCESS
)
346 fatal("Invalid keyfile %s: %s",
347 filename
, isc_result_totext(result
));
349 if (!dst_key_isprivate(key
))
350 fatal("%s is not a private key", filename
);
352 dst_key_format(key
, keystr
, sizeof(keystr
));
357 check_keyversion(key
, keystr
);
360 fprintf(stderr
, "%s: %s\n", program
, keystr
);
366 dst_key_settime(key
, DST_TIME_PUBLISH
, pub
);
368 dst_key_unsettime(key
, DST_TIME_PUBLISH
);
371 dst_key_settime(key
, DST_TIME_ACTIVATE
, act
);
373 dst_key_unsettime(key
, DST_TIME_ACTIVATE
);
376 if ((dst_key_flags(key
) & DNS_KEYFLAG_REVOKE
) != 0)
377 fprintf(stderr
, "%s: warning: Key %s is already "
378 "revoked; changing the revocation date "
379 "will not affect this.\n",
381 if ((dst_key_flags(key
) & DNS_KEYFLAG_KSK
) == 0)
382 fprintf(stderr
, "%s: warning: Key %s is not flagged as "
383 "a KSK, but -R was used. Revoking a "
384 "ZSK is legal, but undefined.\n",
386 dst_key_settime(key
, DST_TIME_REVOKE
, rev
);
387 } else if (unsetrev
) {
388 if ((dst_key_flags(key
) & DNS_KEYFLAG_REVOKE
) != 0)
389 fprintf(stderr
, "%s: warning: Key %s is already "
390 "revoked; removing the revocation date "
391 "will not affect this.\n",
393 dst_key_unsettime(key
, DST_TIME_REVOKE
);
397 dst_key_settime(key
, DST_TIME_INACTIVE
, inact
);
399 dst_key_unsettime(key
, DST_TIME_INACTIVE
);
402 dst_key_settime(key
, DST_TIME_DELETE
, del
);
404 dst_key_unsettime(key
, DST_TIME_DELETE
);
407 * Print out time values, if -p was used.
410 printtime(key
, DST_TIME_CREATED
, "Created", epoch
, stdout
);
413 printtime(key
, DST_TIME_PUBLISH
, "Publish", epoch
, stdout
);
416 printtime(key
, DST_TIME_ACTIVATE
, "Activate", epoch
, stdout
);
419 printtime(key
, DST_TIME_REVOKE
, "Revoke", epoch
, stdout
);
422 printtime(key
, DST_TIME_INACTIVE
, "Inactive", epoch
, stdout
);
425 printtime(key
, DST_TIME_DELETE
, "Delete", epoch
, stdout
);
428 isc_buffer_init(&buf
, newname
, sizeof(newname
));
429 result
= dst_key_buildfilename(key
, DST_TYPE_PUBLIC
, directory
,
431 if (result
!= ISC_R_SUCCESS
) {
432 fatal("Failed to build public key filename: %s",
433 isc_result_totext(result
));
436 result
= dst_key_tofile(key
, DST_TYPE_PUBLIC
|DST_TYPE_PRIVATE
,
438 if (result
!= ISC_R_SUCCESS
) {
439 dst_key_format(key
, keystr
, sizeof(keystr
));
440 fatal("Failed to write key %s: %s", keystr
,
441 isc_result_totext(result
));
444 printf("%s\n", newname
);
446 isc_buffer_clear(&buf
);
447 result
= dst_key_buildfilename(key
, DST_TYPE_PRIVATE
, directory
,
449 if (result
!= ISC_R_SUCCESS
) {
450 fatal("Failed to build private key filename: %s",
451 isc_result_totext(result
));
453 printf("%s\n", newname
);
459 cleanup_entropy(&ectx
);
461 isc_mem_stats(mctx
, stdout
);
462 isc_mem_free(mctx
, directory
);
463 isc_mem_destroy(&mctx
);