Mercurial > dropbear
comparison dropbearkey.c @ 846:b298bb438625 keyondemand
refactor key generation, make it generate as required.
Needs UI in server command line options
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 07 Nov 2013 00:18:52 +0800 |
parents | d4ce5269a439 |
children | f4bb964c8678 |
comparison
equal
deleted
inserted
replaced
845:774ad9b112ef | 846:b298bb438625 |
---|---|
55 #include "crypto_desc.h" | 55 #include "crypto_desc.h" |
56 #include "random.h" | 56 #include "random.h" |
57 | 57 |
58 static void printhelp(char * progname); | 58 static void printhelp(char * progname); |
59 | 59 |
60 #define RSA_DEFAULT_SIZE 2048 | 60 |
61 #define DSS_DEFAULT_SIZE 1024 | |
62 | |
63 static void buf_writefile(buffer * buf, const char * filename); | |
64 static void printpubkey(sign_key * key, int keytype); | 61 static void printpubkey(sign_key * key, int keytype); |
65 static void justprintpub(const char* filename); | 62 static int printpubfile(const char* filename); |
66 | 63 |
67 /* Print a help message */ | 64 /* Print a help message */ |
68 static void printhelp(char * progname) { | 65 static void printhelp(char * progname) { |
69 | 66 |
70 fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n" | 67 fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n" |
99 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n" | 96 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n" |
100 #ifdef DEBUG_TRACE | 97 #ifdef DEBUG_TRACE |
101 "-v verbose\n" | 98 "-v verbose\n" |
102 #endif | 99 #endif |
103 ,progname); | 100 ,progname); |
101 } | |
102 | |
103 /* fails fatally */ | |
104 static void check_signkey_bits(enum signkey_type type, int bits) | |
105 { | |
106 switch (type) { | |
107 #ifdef DROPBEAR_RSA | |
108 case DROPBEAR_SIGNKEY_RSA: | |
109 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { | |
110 dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a" | |
111 " multiple of 8\n"); | |
112 } | |
113 break; | |
114 #endif | |
115 #ifdef DROPEAR_DSS | |
116 case DROPBEAR_SIGNKEY_DSS: | |
117 if (bits != 1024) { | |
118 dropbear_exit("DSS keys have a fixed size of 1024 bits\n"); | |
119 exit(EXIT_FAILURE); | |
120 } | |
121 #endif | |
122 default: | |
123 (void)0; /* quiet, compiler. ecdsa handles checks itself */ | |
124 } | |
104 } | 125 } |
105 | 126 |
106 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) | 127 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) |
107 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) | 128 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) |
108 int dropbearkey_main(int argc, char ** argv) { | 129 int dropbearkey_main(int argc, char ** argv) { |
116 buffer *buf = NULL; | 137 buffer *buf = NULL; |
117 char * filename = NULL; | 138 char * filename = NULL; |
118 enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; | 139 enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; |
119 char * typetext = NULL; | 140 char * typetext = NULL; |
120 char * sizetext = NULL; | 141 char * sizetext = NULL; |
121 unsigned int bits; | 142 unsigned int bits = 0; |
122 int printpub = 0; | 143 int printpub = 0; |
123 | 144 |
124 crypto_init(); | 145 crypto_init(); |
125 seedrandom(); | 146 seedrandom(); |
126 | 147 |
172 printhelp(argv[0]); | 193 printhelp(argv[0]); |
173 exit(EXIT_FAILURE); | 194 exit(EXIT_FAILURE); |
174 } | 195 } |
175 | 196 |
176 if (printpub) { | 197 if (printpub) { |
177 justprintpub(filename); | 198 int ret = printpubfile(filename); |
178 /* Not reached */ | 199 exit(ret); |
179 } | 200 } |
180 | 201 |
181 /* check/parse args */ | 202 /* check/parse args */ |
182 if (!typetext) { | 203 if (!typetext) { |
183 fprintf(stderr, "Must specify key type\n"); | 204 fprintf(stderr, "Must specify key type\n"); |
214 if (sscanf(sizetext, "%u", &bits) != 1) { | 235 if (sscanf(sizetext, "%u", &bits) != 1) { |
215 fprintf(stderr, "Bits must be an integer\n"); | 236 fprintf(stderr, "Bits must be an integer\n"); |
216 exit(EXIT_FAILURE); | 237 exit(EXIT_FAILURE); |
217 } | 238 } |
218 | 239 |
219 // TODO: put RSA and DSS size checks into genrsa.c etc | 240 check_signkey_bits(keytype, bits);; |
220 switch (keytype) { | 241 } |
221 #ifdef DROPBEAR_RSA | 242 |
222 case DROPBEAR_SIGNKEY_RSA: | |
223 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { | |
224 fprintf(stderr, "Bits must satisfy 512 <= bits <= 4096, and be a" | |
225 " multiple of 8\n"); | |
226 exit(EXIT_FAILURE); | |
227 } | |
228 break; | |
229 #endif | |
230 #ifdef DROPEAR_DSS | |
231 case DROPBEAR_SIGNKEY_DSS: | |
232 if (bits != 1024) { | |
233 fprintf(stderr, "DSS keys have a fixed size of 1024 bits\n"); | |
234 exit(EXIT_FAILURE); | |
235 } | |
236 #endif | |
237 default: | |
238 (void)0; /* quiet, compiler. ecdsa handles checks itself */ | |
239 } | |
240 | |
241 } else { | |
242 /* default key size */ | |
243 | |
244 switch (keytype) { | |
245 #ifdef DROPBEAR_RSA | |
246 case DROPBEAR_SIGNKEY_RSA: | |
247 bits = RSA_DEFAULT_SIZE; | |
248 break; | |
249 #endif | |
250 #ifdef DROPBEAR_DSS | |
251 case DROPBEAR_SIGNKEY_DSS: | |
252 bits = DSS_DEFAULT_SIZE; | |
253 break; | |
254 #endif | |
255 #ifdef DROPBEAR_ECDSA | |
256 case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: | |
257 bits = ECDSA_DEFAULT_SIZE; | |
258 break; | |
259 #endif | |
260 default: | |
261 exit(EXIT_FAILURE); /* not reached */ | |
262 } | |
263 } | |
264 | |
265 | |
266 fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", bits, | |
267 typetext, filename); | |
268 | |
269 /* don't want the file readable by others */ | |
270 umask(077); | |
271 | |
272 /* now we can generate the key */ | |
273 key = new_sign_key(); | |
274 | |
275 fprintf(stderr, "Generating key, this may take a while...\n"); | 243 fprintf(stderr, "Generating key, this may take a while...\n"); |
276 switch(keytype) { | 244 if (signkey_generate(keytype, bits, filename) == DROPBEAR_FAILURE) |
277 #ifdef DROPBEAR_RSA | 245 { |
278 case DROPBEAR_SIGNKEY_RSA: | 246 dropbear_exit("Failed to generate key.\n"); |
279 key->rsakey = gen_rsa_priv_key(bits); | 247 } |
280 break; | 248 |
281 #endif | 249 printpubfile(filename); |
282 #ifdef DROPBEAR_DSS | |
283 case DROPBEAR_SIGNKEY_DSS: | |
284 key->dsskey = gen_dss_priv_key(bits); | |
285 break; | |
286 #endif | |
287 #ifdef DROPBEAR_ECDSA | |
288 case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: | |
289 { | |
290 ecc_key *ecckey = gen_ecdsa_priv_key(bits); | |
291 keytype = ecdsa_signkey_type(ecckey); | |
292 *signkey_key_ptr(key, keytype) = ecckey; | |
293 } | |
294 break; | |
295 #endif | |
296 default: | |
297 fprintf(stderr, "Internal error, bad key type\n"); | |
298 exit(EXIT_FAILURE); | |
299 } | |
300 | |
301 buf = buf_new(MAX_PRIVKEY_SIZE); | |
302 | |
303 buf_put_priv_key(buf, key, keytype); | |
304 buf_setpos(buf, 0); | |
305 buf_writefile(buf, filename); | |
306 | |
307 buf_burn(buf); | |
308 buf_free(buf); | |
309 | |
310 printpubkey(key, keytype); | |
311 | |
312 sign_key_free(key); | |
313 | 250 |
314 return EXIT_SUCCESS; | 251 return EXIT_SUCCESS; |
315 } | 252 } |
316 #endif | 253 #endif |
317 | 254 |
318 static void justprintpub(const char* filename) { | 255 static int printpubfile(const char* filename) { |
319 | 256 |
320 buffer *buf = NULL; | 257 buffer *buf = NULL; |
321 sign_key *key = NULL; | 258 sign_key *key = NULL; |
322 enum signkey_type keytype; | 259 enum signkey_type keytype; |
323 int ret; | 260 int ret; |
351 buf = NULL; | 288 buf = NULL; |
352 if (key) { | 289 if (key) { |
353 sign_key_free(key); | 290 sign_key_free(key); |
354 key = NULL; | 291 key = NULL; |
355 } | 292 } |
356 exit(err); | 293 return err; |
357 } | 294 } |
358 | 295 |
359 static void printpubkey(sign_key * key, int keytype) { | 296 static void printpubkey(sign_key * key, int keytype) { |
360 | 297 |
361 buffer * buf = NULL; | 298 buffer * buf = NULL; |
400 typestring, base64key, username, hostname, fp); | 337 typestring, base64key, username, hostname, fp); |
401 | 338 |
402 m_free(fp); | 339 m_free(fp); |
403 buf_free(buf); | 340 buf_free(buf); |
404 } | 341 } |
405 | |
406 /* Write a buffer to a file specified, failing if the file exists */ | |
407 static void buf_writefile(buffer * buf, const char * filename) { | |
408 | |
409 int fd; | |
410 int len; | |
411 | |
412 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); | |
413 if (fd < 0) { | |
414 fprintf(stderr, "Couldn't create new file %s\n", filename); | |
415 perror("Reason"); | |
416 buf_burn(buf); | |
417 exit(EXIT_FAILURE); | |
418 } | |
419 | |
420 /* write the file now */ | |
421 while (buf->pos != buf->len) { | |
422 len = write(fd, buf_getptr(buf, buf->len - buf->pos), | |
423 buf->len - buf->pos); | |
424 if (errno == EINTR) { | |
425 continue; | |
426 } | |
427 if (len <= 0) { | |
428 fprintf(stderr, "Failed writing file '%s'\n",filename); | |
429 perror("Reason"); | |
430 exit(EXIT_FAILURE); | |
431 } | |
432 buf_incrpos(buf, len); | |
433 } | |
434 | |
435 close(fd); | |
436 } |