1 /* $NetBSD: keygen.c,v 1.6 2014/12/10 04:37:51 christos Exp $ */
4 * Copyright (C) 2009, 2012-2014 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: keygen.c,v 1.4 2009/11/12 14:02:38 marka Exp */
28 #include <isc/base64.h>
29 #include <isc/buffer.h>
30 #include <isc/entropy.h>
32 #include <isc/keyboard.h>
34 #include <isc/result.h>
35 #include <isc/string.h>
37 #include <dns/keyvalues.h>
41 #include <confgen/os.h>
47 * Convert algorithm type to string.
50 alg_totext(dns_secalg_t alg
) {
54 case DST_ALG_HMACSHA1
:
56 case DST_ALG_HMACSHA224
:
58 case DST_ALG_HMACSHA256
:
60 case DST_ALG_HMACSHA384
:
62 case DST_ALG_HMACSHA512
:
70 * Convert string to algorithm type.
73 alg_fromtext(const char *name
) {
75 if (strncasecmp(p
, "hmac-", 5) == 0)
78 if (strcasecmp(p
, "md5") == 0)
79 return DST_ALG_HMACMD5
;
80 if (strcasecmp(p
, "sha1") == 0)
81 return DST_ALG_HMACSHA1
;
82 if (strcasecmp(p
, "sha224") == 0)
83 return DST_ALG_HMACSHA224
;
84 if (strcasecmp(p
, "sha256") == 0)
85 return DST_ALG_HMACSHA256
;
86 if (strcasecmp(p
, "sha384") == 0)
87 return DST_ALG_HMACSHA384
;
88 if (strcasecmp(p
, "sha512") == 0)
89 return DST_ALG_HMACSHA512
;
90 return DST_ALG_UNKNOWN
;
94 * Return default keysize for a given algorithm type.
97 alg_bits(dns_secalg_t alg
) {
101 case DST_ALG_HMACSHA1
:
103 case DST_ALG_HMACSHA224
:
105 case DST_ALG_HMACSHA256
:
107 case DST_ALG_HMACSHA384
:
109 case DST_ALG_HMACSHA512
:
117 * Generate a key of size 'keysize' using entropy source 'randomfile',
118 * and place it in 'key_txtbuffer'
121 generate_key(isc_mem_t
*mctx
, const char *randomfile
, dns_secalg_t alg
,
122 int keysize
, isc_buffer_t
*key_txtbuffer
) {
123 isc_result_t result
= ISC_R_SUCCESS
;
124 isc_entropysource_t
*entropy_source
= NULL
;
125 int open_keyboard
= ISC_ENTROPY_KEYBOARDMAYBE
;
126 int entropy_flags
= 0;
127 isc_entropy_t
*ectx
= NULL
;
128 isc_buffer_t key_rawbuffer
;
129 isc_region_t key_rawregion
;
130 char key_rawsecret
[64];
131 dst_key_t
*key
= NULL
;
134 case DST_ALG_HMACMD5
:
135 case DST_ALG_HMACSHA1
:
136 case DST_ALG_HMACSHA224
:
137 case DST_ALG_HMACSHA256
:
138 if (keysize
< 1 || keysize
> 512)
139 fatal("keysize %d out of range (must be 1-512)\n",
142 case DST_ALG_HMACSHA384
:
143 case DST_ALG_HMACSHA512
:
144 if (keysize
< 1 || keysize
> 1024)
145 fatal("keysize %d out of range (must be 1-1024)\n",
149 fatal("unsupported algorithm %d\n", alg
);
153 DO("create entropy context", isc_entropy_create(mctx
, &ectx
));
155 if (randomfile
!= NULL
&& strcmp(randomfile
, "keyboard") == 0) {
157 open_keyboard
= ISC_ENTROPY_KEYBOARDYES
;
159 DO("start entropy source", isc_entropy_usebestsource(ectx
,
164 entropy_flags
= ISC_ENTROPY_BLOCKING
| ISC_ENTROPY_GOODONLY
;
166 DO("initialize dst library", dst_lib_init(mctx
, ectx
, entropy_flags
));
168 DO("generate key", dst_key_generate(dns_rootname
, alg
,
171 dns_rdataclass_in
, mctx
, &key
));
173 isc_buffer_init(&key_rawbuffer
, &key_rawsecret
, sizeof(key_rawsecret
));
175 DO("dump key to buffer", dst_key_tobuffer(key
, &key_rawbuffer
));
177 isc_buffer_usedregion(&key_rawbuffer
, &key_rawregion
);
179 DO("bsse64 encode secret", isc_base64_totext(&key_rawregion
, -1, "",
183 * Shut down the entropy source now so the "stop typing" message
184 * does not muck with the output.
186 if (entropy_source
!= NULL
)
187 isc_entropy_destroysource(&entropy_source
);
192 isc_entropy_detach(&ectx
);
197 * Write a key file to 'keyfile'. If 'user' is non-NULL,
198 * make that user the owner of the file. The key will have
199 * the name 'keyname' and the secret in the buffer 'secret'.
202 write_key_file(const char *keyfile
, const char *user
,
203 const char *keyname
, isc_buffer_t
*secret
,
206 const char *algname
= alg_totext(alg
);
209 DO("create keyfile", isc_file_safecreate(keyfile
, &fd
));
212 if (set_user(fd
, user
) == -1)
213 fatal("unable to set file owner\n");
216 fprintf(fd
, "key \"%s\" {\n\talgorithm %s;\n"
217 "\tsecret \"%.*s\";\n};\n",
219 (int)isc_buffer_usedlength(secret
),
220 (char *)isc_buffer_base(secret
));
223 fatal("write to %s failed\n", keyfile
);
225 fatal("fclose(%s) failed\n", keyfile
);
226 fprintf(stderr
, "wrote key file \"%s\"\n", keyfile
);