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 }