1 /* $NetBSD: dnssec-keygen.c,v 1.1.1.3 2009/12/26 22:18:59 christos Exp $ */
4 * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright (C) 1999-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
12 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
14 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
17 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
21 * Permission to use, copy, modify, and/or distribute this software for any
22 * purpose with or without fee is hereby granted, provided that the above
23 * copyright notice and this permission notice appear in all copies.
25 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
26 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
28 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
31 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 /* Id: dnssec-keygen.c,v 1.108 2009/11/25 22:58:48 marka Exp */
44 #include <isc/buffer.h>
45 #include <isc/commandline.h>
46 #include <isc/entropy.h>
48 #include <isc/region.h>
49 #include <isc/string.h>
52 #include <dns/fixedname.h>
53 #include <dns/keyvalues.h>
56 #include <dns/rdataclass.h>
57 #include <dns/result.h>
58 #include <dns/secalg.h>
62 #include "dnssectool.h"
64 #define MAX_RSA 4096 /* should be long enough... */
66 const char *program
= "dnssec-keygen";
69 #define DEFAULT_ALGORITHM "RSASHA1"
70 #define DEFAULT_NSEC3_ALGORITHM "NSEC3RSASHA1"
73 dsa_size_ok(int size
) {
74 return (ISC_TF(size
>= 512 && size
<= 1024 && size
% 64 == 0));
77 ISC_PLATFORM_NORETURN_PRE
static void
78 usage(void) ISC_PLATFORM_NORETURN_POST
;
80 static void progress(int p
);
84 fprintf(stderr
, "Usage:\n");
85 fprintf(stderr
, " %s [options] name\n\n", program
);
86 fprintf(stderr
, "Version: %s\n", VERSION
);
87 fprintf(stderr
, " name: owner of the key\n");
88 fprintf(stderr
, "Options:\n");
89 fprintf(stderr
, " -K <directory>: write keys into directory\n");
90 fprintf(stderr
, " -a <algorithm>:\n");
91 fprintf(stderr
, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1"
93 fprintf(stderr
, " RSASHA256 | RSASHA512 |\n");
94 fprintf(stderr
, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | "
96 fprintf(stderr
, " HMAC-SHA384 | HMAC-SHA512\n");
97 fprintf(stderr
, " (default: RSASHA1, or "
98 "NSEC3RSASHA1 if using -3)\n");
99 fprintf(stderr
, " -3: use NSEC3-capable algorithm\n");
100 fprintf(stderr
, " -b <key size in bits>:\n");
101 fprintf(stderr
, " RSAMD5:\t[512..%d]\n", MAX_RSA
);
102 fprintf(stderr
, " RSASHA1:\t[512..%d]\n", MAX_RSA
);
103 fprintf(stderr
, " NSEC3RSASHA1:\t[512..%d]\n", MAX_RSA
);
104 fprintf(stderr
, " RSASHA256:\t[512..%d]\n", MAX_RSA
);
105 fprintf(stderr
, " RSASHA512:\t[1024..%d]\n", MAX_RSA
);
106 fprintf(stderr
, " DH:\t\t[128..4096]\n");
107 fprintf(stderr
, " DSA:\t\t[512..1024] and divisible by 64\n");
108 fprintf(stderr
, " NSEC3DSA:\t[512..1024] and divisible "
110 fprintf(stderr
, " HMAC-MD5:\t[1..512]\n");
111 fprintf(stderr
, " HMAC-SHA1:\t[1..160]\n");
112 fprintf(stderr
, " HMAC-SHA224:\t[1..224]\n");
113 fprintf(stderr
, " HMAC-SHA256:\t[1..256]\n");
114 fprintf(stderr
, " HMAC-SHA384:\t[1..384]\n");
115 fprintf(stderr
, " HMAC-SHA512:\t[1..512]\n");
116 fprintf(stderr
, " (if using the default algorithm, key size\n"
117 " defaults to 2048 for KSK, or 1024 for all "
119 fprintf(stderr
, " -n <nametype>: ZONE | HOST | ENTITY | "
121 fprintf(stderr
, " (DNSKEY generation defaults to ZONE)\n");
122 fprintf(stderr
, " -c <class>: (default: IN)\n");
123 fprintf(stderr
, " -d <digest bits> (0 => max, default)\n");
125 fprintf(stderr
, " -E <engine name> (default \"pkcs11\")\n");
127 fprintf(stderr
, " -E <engine name>\n");
129 fprintf(stderr
, " -e: use large exponent (RSAMD5/RSASHA1 only)\n");
130 fprintf(stderr
, " -f <keyflag>: KSK | REVOKE\n");
131 fprintf(stderr
, " -g <generator>: use specified generator "
133 fprintf(stderr
, " -p <protocol>: (default: 3 [dnssec])\n");
134 fprintf(stderr
, " -s <strength>: strength value this key signs DNS "
135 "records with (default: 0)\n");
136 fprintf(stderr
, " -T <rrtype>: DNSKEY | KEY (default: DNSKEY; "
137 "use KEY for SIG(0))\n");
138 fprintf(stderr
, " -t <type>: "
139 "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF "
140 "(default: AUTHCONF)\n");
141 fprintf(stderr
, " -r <randomdev>: a file containing random data\n");
143 fprintf(stderr
, " -h: print usage and exit\n");
144 fprintf(stderr
, " -m <memory debugging mode>:\n");
145 fprintf(stderr
, " usage | trace | record | size | mctx\n");
146 fprintf(stderr
, " -v <level>: set verbosity level (0 - 10)\n");
147 fprintf(stderr
, "Date options:\n");
148 fprintf(stderr
, " -P date/[+-]offset: set key publication date "
150 fprintf(stderr
, " -A date/[+-]offset: set key activation date "
152 fprintf(stderr
, " -R date/[+-]offset: set key revocation date\n");
153 fprintf(stderr
, " -I date/[+-]offset: set key inactivation date\n");
154 fprintf(stderr
, " -D date/[+-]offset: set key deletion date\n");
155 fprintf(stderr
, " -G: generate key only; do not set -P or -A\n");
156 fprintf(stderr
, " -C: generate a backward-compatible key, omitting "
158 fprintf(stderr
, "Output:\n");
159 fprintf(stderr
, " K<name>+<alg>+<id>.key, "
160 "K<name>+<alg>+<id>.private\n");
186 (void) putc(c
, stderr
);
187 (void) fflush(stderr
);
191 main(int argc
, char **argv
) {
192 char *algname
= NULL
, *nametype
= NULL
, *type
= NULL
;
193 char *classname
= NULL
;
195 dst_key_t
*key
= NULL
, *oldkey
;
196 dns_fixedname_t fname
;
198 isc_uint16_t flags
= 0, kskflag
= 0, revflag
= 0;
200 isc_boolean_t conflict
= ISC_FALSE
, null_key
= ISC_FALSE
;
201 isc_boolean_t oldstyle
= ISC_FALSE
;
202 isc_mem_t
*mctx
= NULL
;
203 int ch
, rsa_exp
= 0, generator
= 0, param
= 0;
204 int protocol
= -1, size
= -1, signatory
= 0;
208 const char *directory
= NULL
;
210 isc_log_t
*log
= NULL
;
211 isc_entropy_t
*ectx
= NULL
;
213 const char *engine
= "pkcs11";
215 const char *engine
= NULL
;
217 dns_rdataclass_t rdclass
;
218 int options
= DST_TYPE_PRIVATE
| DST_TYPE_PUBLIC
;
220 isc_boolean_t use_default
= ISC_FALSE
, use_nsec3
= ISC_FALSE
;
221 isc_stdtime_t publish
= 0, activate
= 0, revoke
= 0;
222 isc_stdtime_t inactive
= 0, delete = 0;
224 isc_boolean_t setpub
= ISC_FALSE
, setact
= ISC_FALSE
;
225 isc_boolean_t setrev
= ISC_FALSE
, setinact
= ISC_FALSE
;
226 isc_boolean_t setdel
= ISC_FALSE
;
227 isc_boolean_t unsetpub
= ISC_FALSE
, unsetact
= ISC_FALSE
;
228 isc_boolean_t unsetrev
= ISC_FALSE
, unsetinact
= ISC_FALSE
;
229 isc_boolean_t unsetdel
= ISC_FALSE
;
230 isc_boolean_t genonly
= ISC_FALSE
;
231 isc_boolean_t quiet
= ISC_FALSE
;
232 isc_boolean_t show_progress
= ISC_FALSE
;
238 dns_result_register();
240 isc_commandline_errprint
= ISC_FALSE
;
243 * Process memory debugging argument first.
245 #define CMDLINE_FLAGS "3a:b:Cc:d:E:eFf:g:K:km:n:p:qr:s:T:t:v:hGP:A:R:I:D:"
246 while ((ch
= isc_commandline_parse(argc
, argv
, CMDLINE_FLAGS
)) != -1) {
249 if (strcasecmp(isc_commandline_argument
, "record") == 0)
250 isc_mem_debugging
|= ISC_MEM_DEBUGRECORD
;
251 if (strcasecmp(isc_commandline_argument
, "trace") == 0)
252 isc_mem_debugging
|= ISC_MEM_DEBUGTRACE
;
253 if (strcasecmp(isc_commandline_argument
, "usage") == 0)
254 isc_mem_debugging
|= ISC_MEM_DEBUGUSAGE
;
255 if (strcasecmp(isc_commandline_argument
, "size") == 0)
256 isc_mem_debugging
|= ISC_MEM_DEBUGSIZE
;
257 if (strcasecmp(isc_commandline_argument
, "mctx") == 0)
258 isc_mem_debugging
|= ISC_MEM_DEBUGCTX
;
264 isc_commandline_reset
= ISC_TRUE
;
266 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
268 isc_stdtime_get(&now
);
270 while ((ch
= isc_commandline_parse(argc
, argv
, CMDLINE_FLAGS
)) != -1) {
273 use_nsec3
= ISC_TRUE
;
276 algname
= isc_commandline_argument
;
279 size
= strtol(isc_commandline_argument
, &endp
, 10);
280 if (*endp
!= '\0' || size
< 0)
281 fatal("-b requires a non-negative number");
287 classname
= isc_commandline_argument
;
290 dbits
= strtol(isc_commandline_argument
, &endp
, 10);
291 if (*endp
!= '\0' || dbits
< 0)
292 fatal("-d requires a non-negative number");
295 engine
= isc_commandline_argument
;
301 c
= (unsigned char)(isc_commandline_argument
[0]);
302 if (toupper(c
) == 'K')
303 kskflag
= DNS_KEYFLAG_KSK
;
304 else if (toupper(c
) == 'R')
305 revflag
= DNS_KEYFLAG_REVOKE
;
307 fatal("unknown flag '%s'",
308 isc_commandline_argument
);
311 generator
= strtol(isc_commandline_argument
,
313 if (*endp
!= '\0' || generator
<= 0)
314 fatal("-g requires a positive number");
317 directory
= isc_commandline_argument
;
318 ret
= try_dir(directory
);
319 if (ret
!= ISC_R_SUCCESS
)
320 fatal("cannot open directory %s: %s",
321 directory
, isc_result_totext(ret
));
324 fatal("The -k option has been deprecated.\n"
325 "To generate a key-signing key, use -f KSK.\n"
326 "To generate a key with TYPE=KEY, use -T KEY.\n");
329 nametype
= isc_commandline_argument
;
334 protocol
= strtol(isc_commandline_argument
, &endp
, 10);
335 if (*endp
!= '\0' || protocol
< 0 || protocol
> 255)
336 fatal("-p must be followed by a number "
343 setup_entropy(mctx
, isc_commandline_argument
, &ectx
);
346 signatory
= strtol(isc_commandline_argument
,
348 if (*endp
!= '\0' || signatory
< 0 || signatory
> 15)
349 fatal("-s must be followed by a number "
353 if (strcasecmp(isc_commandline_argument
, "KEY") == 0)
354 options
|= DST_TYPE_KEY
;
355 else if (strcasecmp(isc_commandline_argument
,
357 /* default behavior */
360 fatal("unknown type '%s'",
361 isc_commandline_argument
);
364 type
= isc_commandline_argument
;
368 verbose
= strtol(isc_commandline_argument
, &endp
, 0);
370 fatal("-v must be followed by a number");
373 /* already the default */
379 if (setpub
|| unsetpub
)
380 fatal("-P specified more than once");
382 if (strcasecmp(isc_commandline_argument
, "none")) {
384 publish
= strtotime(isc_commandline_argument
,
391 if (setact
|| unsetact
)
392 fatal("-A specified more than once");
394 if (strcasecmp(isc_commandline_argument
, "none")) {
396 activate
= strtotime(isc_commandline_argument
,
403 if (setrev
|| unsetrev
)
404 fatal("-R specified more than once");
406 if (strcasecmp(isc_commandline_argument
, "none")) {
408 revoke
= strtotime(isc_commandline_argument
,
415 if (setinact
|| unsetinact
)
416 fatal("-I specified more than once");
418 if (strcasecmp(isc_commandline_argument
, "none")) {
420 inactive
= strtotime(isc_commandline_argument
,
423 unsetinact
= ISC_TRUE
;
427 if (setdel
|| unsetdel
)
428 fatal("-D specified more than once");
430 if (strcasecmp(isc_commandline_argument
, "none")) {
432 delete = strtotime(isc_commandline_argument
,
439 /* Reserved for FIPS mode */
442 if (isc_commandline_option
!= '?')
443 fprintf(stderr
, "%s: invalid argument -%c\n",
444 program
, isc_commandline_option
);
450 fprintf(stderr
, "%s: unhandled option -%c\n",
451 program
, isc_commandline_option
);
460 setup_entropy(mctx
, NULL
, &ectx
);
461 ret
= dst_lib_init2(mctx
, ectx
, engine
,
462 ISC_ENTROPY_BLOCKING
| ISC_ENTROPY_GOODONLY
);
463 if (ret
!= ISC_R_SUCCESS
)
464 fatal("could not initialize dst: %s",
465 isc_result_totext(ret
));
467 setup_logging(verbose
, mctx
, &log
);
469 if (argc
< isc_commandline_index
+ 1)
470 fatal("the key name was not specified");
471 if (argc
> isc_commandline_index
+ 1)
472 fatal("extraneous arguments");
474 if (algname
== NULL
) {
475 use_default
= ISC_TRUE
;
477 algname
= strdup(DEFAULT_NSEC3_ALGORITHM
);
479 algname
= strdup(DEFAULT_ALGORITHM
);
481 fprintf(stderr
, "no algorithm specified; "
482 "defaulting to %s\n", algname
);
485 if (strcasecmp(algname
, "RSA") == 0) {
486 fprintf(stderr
, "The use of RSA (RSAMD5) is not recommended.\n"
487 "If you still wish to use RSA (RSAMD5) please "
488 "specify \"-a RSAMD5\"\n");
490 } else if (strcasecmp(algname
, "HMAC-MD5") == 0) {
491 options
|= DST_TYPE_KEY
;
492 alg
= DST_ALG_HMACMD5
;
493 } else if (strcasecmp(algname
, "HMAC-SHA1") == 0) {
494 options
|= DST_TYPE_KEY
;
495 alg
= DST_ALG_HMACSHA1
;
496 } else if (strcasecmp(algname
, "HMAC-SHA224") == 0) {
497 options
|= DST_TYPE_KEY
;
498 alg
= DST_ALG_HMACSHA224
;
499 } else if (strcasecmp(algname
, "HMAC-SHA256") == 0) {
500 options
|= DST_TYPE_KEY
;
501 alg
= DST_ALG_HMACSHA256
;
502 } else if (strcasecmp(algname
, "HMAC-SHA384") == 0) {
503 options
|= DST_TYPE_KEY
;
504 alg
= DST_ALG_HMACSHA384
;
505 } else if (strcasecmp(algname
, "HMAC-SHA512") == 0) {
506 options
|= DST_TYPE_KEY
;
507 alg
= DST_ALG_HMACSHA512
;
510 r
.length
= strlen(algname
);
511 ret
= dns_secalg_fromtext(&alg
, &r
);
512 if (ret
!= ISC_R_SUCCESS
)
513 fatal("unknown algorithm %s", algname
);
514 if (alg
== DST_ALG_DH
)
515 options
|= DST_TYPE_KEY
;
519 alg
!= DST_ALG_NSEC3DSA
&& alg
!= DST_ALG_NSEC3RSASHA1
&&
520 alg
!= DST_ALG_RSASHA256
&& alg
!= DST_ALG_RSASHA512
) {
521 fatal("%s is incompatible with NSEC3; "
522 "do not use the -3 option", algname
);
525 if (type
!= NULL
&& (options
& DST_TYPE_KEY
) != 0) {
526 if (strcasecmp(type
, "NOAUTH") == 0)
527 flags
|= DNS_KEYTYPE_NOAUTH
;
528 else if (strcasecmp(type
, "NOCONF") == 0)
529 flags
|= DNS_KEYTYPE_NOCONF
;
530 else if (strcasecmp(type
, "NOAUTHCONF") == 0) {
531 flags
|= (DNS_KEYTYPE_NOAUTH
| DNS_KEYTYPE_NOCONF
);
535 else if (strcasecmp(type
, "AUTHCONF") == 0)
538 fatal("invalid type %s", type
);
543 size
= ((kskflag
& DNS_KEYFLAG_KSK
) != 0) ? 2048 : 1024;
545 fprintf(stderr
, "key size not specified; "
546 "defaulting to %d\n", size
);
548 fatal("key size not specified (-b option)");
553 case DNS_KEYALG_RSAMD5
:
554 case DNS_KEYALG_RSASHA1
:
555 case DNS_KEYALG_NSEC3RSASHA1
:
556 case DNS_KEYALG_RSASHA256
:
557 if (size
!= 0 && (size
< 512 || size
> MAX_RSA
))
558 fatal("RSA key size %d out of range", size
);
560 case DNS_KEYALG_RSASHA512
:
561 if (size
!= 0 && (size
< 1024 || size
> MAX_RSA
))
562 fatal("RSA key size %d out of range", size
);
565 if (size
!= 0 && (size
< 128 || size
> 4096))
566 fatal("DH key size %d out of range", size
);
569 case DNS_KEYALG_NSEC3DSA
:
570 if (size
!= 0 && !dsa_size_ok(size
))
571 fatal("invalid DSS key size: %d", size
);
573 case DST_ALG_HMACMD5
:
574 if (size
< 1 || size
> 512)
575 fatal("HMAC-MD5 key size %d out of range", size
);
576 if (dbits
!= 0 && (dbits
< 80 || dbits
> 128))
577 fatal("HMAC-MD5 digest bits %d out of range", dbits
);
578 if ((dbits
% 8) != 0)
579 fatal("HMAC-MD5 digest bits %d not divisible by 8",
582 case DST_ALG_HMACSHA1
:
583 if (size
< 1 || size
> 160)
584 fatal("HMAC-SHA1 key size %d out of range", size
);
585 if (dbits
!= 0 && (dbits
< 80 || dbits
> 160))
586 fatal("HMAC-SHA1 digest bits %d out of range", dbits
);
587 if ((dbits
% 8) != 0)
588 fatal("HMAC-SHA1 digest bits %d not divisible by 8",
591 case DST_ALG_HMACSHA224
:
592 if (size
< 1 || size
> 224)
593 fatal("HMAC-SHA224 key size %d out of range", size
);
594 if (dbits
!= 0 && (dbits
< 112 || dbits
> 224))
595 fatal("HMAC-SHA224 digest bits %d out of range", dbits
);
596 if ((dbits
% 8) != 0)
597 fatal("HMAC-SHA224 digest bits %d not divisible by 8",
600 case DST_ALG_HMACSHA256
:
601 if (size
< 1 || size
> 256)
602 fatal("HMAC-SHA256 key size %d out of range", size
);
603 if (dbits
!= 0 && (dbits
< 128 || dbits
> 256))
604 fatal("HMAC-SHA256 digest bits %d out of range", dbits
);
605 if ((dbits
% 8) != 0)
606 fatal("HMAC-SHA256 digest bits %d not divisible by 8",
609 case DST_ALG_HMACSHA384
:
610 if (size
< 1 || size
> 384)
611 fatal("HMAC-384 key size %d out of range", size
);
612 if (dbits
!= 0 && (dbits
< 192 || dbits
> 384))
613 fatal("HMAC-SHA384 digest bits %d out of range", dbits
);
614 if ((dbits
% 8) != 0)
615 fatal("HMAC-SHA384 digest bits %d not divisible by 8",
618 case DST_ALG_HMACSHA512
:
619 if (size
< 1 || size
> 512)
620 fatal("HMAC-SHA512 key size %d out of range", size
);
621 if (dbits
!= 0 && (dbits
< 256 || dbits
> 512))
622 fatal("HMAC-SHA512 digest bits %d out of range", dbits
);
623 if ((dbits
% 8) != 0)
624 fatal("HMAC-SHA512 digest bits %d not divisible by 8",
629 if (!(alg
== DNS_KEYALG_RSAMD5
|| alg
== DNS_KEYALG_RSASHA1
||
630 alg
== DNS_KEYALG_NSEC3RSASHA1
|| alg
== DNS_KEYALG_RSASHA256
||
631 alg
== DNS_KEYALG_RSASHA512
) && rsa_exp
!= 0)
632 fatal("specified RSA exponent for a non-RSA key");
634 if (alg
!= DNS_KEYALG_DH
&& generator
!= 0)
635 fatal("specified DH generator for a non-DH key");
637 if (nametype
== NULL
) {
638 if ((options
& DST_TYPE_KEY
) != 0) /* KEY / HMAC */
639 fatal("no nametype specified");
640 flags
|= DNS_KEYOWNER_ZONE
; /* DNSKEY */
641 } else if (strcasecmp(nametype
, "zone") == 0)
642 flags
|= DNS_KEYOWNER_ZONE
;
643 else if ((options
& DST_TYPE_KEY
) != 0) { /* KEY / HMAC */
644 if (strcasecmp(nametype
, "host") == 0 ||
645 strcasecmp(nametype
, "entity") == 0)
646 flags
|= DNS_KEYOWNER_ENTITY
;
647 else if (strcasecmp(nametype
, "user") == 0)
648 flags
|= DNS_KEYOWNER_USER
;
650 fatal("invalid KEY nametype %s", nametype
);
651 } else if (strcasecmp(nametype
, "other") != 0) /* DNSKEY */
652 fatal("invalid DNSKEY nametype %s", nametype
);
654 rdclass
= strtoclass(classname
);
656 if (directory
== NULL
)
659 if ((options
& DST_TYPE_KEY
) != 0) /* KEY / HMAC */
661 else if ((flags
& DNS_KEYOWNER_ZONE
) != 0) { /* DNSKEY */
667 protocol
= DNS_KEYPROTO_DNSSEC
;
668 else if ((options
& DST_TYPE_KEY
) == 0 &&
669 protocol
!= DNS_KEYPROTO_DNSSEC
)
670 fatal("invalid DNSKEY protocol: %d", protocol
);
672 if ((flags
& DNS_KEYFLAG_TYPEMASK
) == DNS_KEYTYPE_NOKEY
) {
674 fatal("specified null key with non-zero size");
675 if ((flags
& DNS_KEYFLAG_SIGNATORYMASK
) != 0)
676 fatal("specified null key with signing authority");
679 if ((flags
& DNS_KEYFLAG_OWNERMASK
) == DNS_KEYOWNER_ZONE
&&
680 (alg
== DNS_KEYALG_DH
|| alg
== DST_ALG_HMACMD5
||
681 alg
== DST_ALG_HMACSHA1
|| alg
== DST_ALG_HMACSHA224
||
682 alg
== DST_ALG_HMACSHA256
|| alg
== DST_ALG_HMACSHA384
||
683 alg
== DST_ALG_HMACSHA512
))
684 fatal("a key with algorithm '%s' cannot be a zone key",
687 dns_fixedname_init(&fname
);
688 name
= dns_fixedname_name(&fname
);
689 isc_buffer_init(&buf
, argv
[isc_commandline_index
],
690 strlen(argv
[isc_commandline_index
]));
691 isc_buffer_add(&buf
, strlen(argv
[isc_commandline_index
]));
692 ret
= dns_name_fromtext(name
, &buf
, dns_rootname
, 0, NULL
);
693 if (ret
!= ISC_R_SUCCESS
)
694 fatal("invalid key name %s: %s", argv
[isc_commandline_index
],
695 isc_result_totext(ret
));
698 case DNS_KEYALG_RSAMD5
:
699 case DNS_KEYALG_RSASHA1
:
700 case DNS_KEYALG_NSEC3RSASHA1
:
701 case DNS_KEYALG_RSASHA256
:
702 case DNS_KEYALG_RSASHA512
:
704 show_progress
= ISC_TRUE
;
712 case DNS_KEYALG_NSEC3DSA
:
713 show_progress
= ISC_TRUE
;
716 case DST_ALG_HMACMD5
:
717 case DST_ALG_HMACSHA1
:
718 case DST_ALG_HMACSHA224
:
719 case DST_ALG_HMACSHA256
:
720 case DST_ALG_HMACSHA384
:
721 case DST_ALG_HMACSHA512
:
726 if ((flags
& DNS_KEYFLAG_TYPEMASK
) == DNS_KEYTYPE_NOKEY
)
729 isc_buffer_init(&buf
, filename
, sizeof(filename
) - 1);
732 conflict
= ISC_FALSE
;
735 if (!quiet
&& show_progress
) {
736 fprintf(stderr
, "Generating key pair.");
737 ret
= dst_key_generate2(name
, alg
, size
, param
, flags
,
738 protocol
, rdclass
, mctx
, &key
,
743 ret
= dst_key_generate2(name
, alg
, size
, param
, flags
,
744 protocol
, rdclass
, mctx
, &key
,
748 isc_entropy_stopcallbacksources(ectx
);
750 if (ret
!= ISC_R_SUCCESS
) {
751 char namestr
[DNS_NAME_FORMATSIZE
];
752 char algstr
[DNS_SECALG_FORMATSIZE
];
753 dns_name_format(name
, namestr
, sizeof(namestr
));
754 dns_secalg_format(alg
, algstr
, sizeof(algstr
));
755 fatal("failed to generate key %s/%s: %s\n",
756 namestr
, algstr
, isc_result_totext(ret
));
761 dst_key_setbits(key
, dbits
);
764 * Set key timing metadata (unless using -C)
766 * Publish and activation dates are set to "now" by default,
767 * but can be overridden. Creation date is always set to
771 dst_key_settime(key
, DST_TIME_CREATED
, now
);
773 if (genonly
&& (setpub
|| setact
))
774 fatal("cannot use -G together with "
778 dst_key_settime(key
, DST_TIME_PUBLISH
, publish
);
780 dst_key_settime(key
, DST_TIME_PUBLISH
,
782 else if (!genonly
&& !unsetpub
)
783 dst_key_settime(key
, DST_TIME_PUBLISH
, now
);
786 dst_key_settime(key
, DST_TIME_ACTIVATE
,
788 else if (!genonly
&& !unsetact
)
789 dst_key_settime(key
, DST_TIME_ACTIVATE
, now
);
793 fprintf(stderr
, "%s: warning: Key is "
794 "not flagged as a KSK, but -R "
795 "was used. Revoking a ZSK is "
796 "legal, but undefined.\n",
798 dst_key_settime(key
, DST_TIME_REVOKE
, revoke
);
802 dst_key_settime(key
, DST_TIME_INACTIVE
,
806 dst_key_settime(key
, DST_TIME_DELETE
, delete);
808 if (setpub
|| setact
|| setrev
|| setinact
||
809 setdel
|| unsetpub
|| unsetact
||
810 unsetrev
|| unsetinact
|| unsetdel
|| genonly
)
811 fatal("cannot use -C together with "
812 "-P, -A, -R, -I, -D, or -G options");
814 * Compatibility mode: Private-key-format
815 * should be set to 1.2.
817 dst_key_setprivateformat(key
, 1, 2);
821 * Try to read a key with the same name, alg and id from disk.
822 * If there is one we must continue generating a different
823 * key unless we were asked to generate a null key, in which
824 * case we return failure.
826 ret
= dst_key_fromfile(name
, dst_key_id(key
), alg
,
827 DST_TYPE_PRIVATE
, directory
,
829 /* do not overwrite an existing key */
830 if (ret
== ISC_R_SUCCESS
) {
831 dst_key_free(&oldkey
);
836 if (conflict
== ISC_TRUE
) {
838 isc_buffer_clear(&buf
);
839 dst_key_buildfilename(key
, 0, directory
, &buf
);
841 "%s: %s already exists, "
842 "generating a new key\n",
847 } while (conflict
== ISC_TRUE
);
850 fatal("cannot generate a null key when a key with id 0 "
853 ret
= dst_key_tofile(key
, options
, directory
);
854 if (ret
!= ISC_R_SUCCESS
) {
855 char keystr
[DST_KEY_FORMATSIZE
];
856 dst_key_format(key
, keystr
, sizeof(keystr
));
857 fatal("failed to write key %s: %s\n", keystr
,
858 isc_result_totext(ret
));
861 isc_buffer_clear(&buf
);
862 ret
= dst_key_buildfilename(key
, 0, NULL
, &buf
);
863 printf("%s\n", filename
);
866 cleanup_logging(&log
);
867 cleanup_entropy(&ectx
);
871 isc_mem_stats(mctx
, stdout
);
872 isc_mem_destroy(&mctx
);