Mercurial > dropbear
comparison dropbearkey.c @ 849:754d7bee1068 ecc
Merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 08 Nov 2013 23:32:13 +0800 |
parents | f4bb964c8678 |
children | 220f55d540ae |
comparison
equal
deleted
inserted
replaced
848:6c69e7df3621 | 849:754d7bee1068 |
---|---|
52 #include "genrsa.h" | 52 #include "genrsa.h" |
53 #include "gendss.h" | 53 #include "gendss.h" |
54 #include "ecdsa.h" | 54 #include "ecdsa.h" |
55 #include "crypto_desc.h" | 55 #include "crypto_desc.h" |
56 #include "random.h" | 56 #include "random.h" |
57 #include "gensignkey.h" | |
57 | 58 |
58 static void printhelp(char * progname); | 59 static void printhelp(char * progname); |
59 | 60 |
60 #define RSA_DEFAULT_SIZE 2048 | 61 |
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); | 62 static void printpubkey(sign_key * key, int keytype); |
65 static void justprintpub(const char* filename); | 63 static int printpubfile(const char* filename); |
66 | 64 |
67 /* Print a help message */ | 65 /* Print a help message */ |
68 static void printhelp(char * progname) { | 66 static void printhelp(char * progname) { |
69 | 67 |
70 fprintf(stderr, "Usage: %s -t <type> -f <filename> [-s bits]\n" | 68 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" | 97 "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n" |
100 #ifdef DEBUG_TRACE | 98 #ifdef DEBUG_TRACE |
101 "-v verbose\n" | 99 "-v verbose\n" |
102 #endif | 100 #endif |
103 ,progname); | 101 ,progname); |
102 } | |
103 | |
104 /* fails fatally */ | |
105 static void check_signkey_bits(enum signkey_type type, int bits) | |
106 { | |
107 switch (type) { | |
108 #ifdef DROPBEAR_RSA | |
109 case DROPBEAR_SIGNKEY_RSA: | |
110 if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { | |
111 dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a" | |
112 " multiple of 8\n"); | |
113 } | |
114 break; | |
115 #endif | |
116 #ifdef DROPEAR_DSS | |
117 case DROPBEAR_SIGNKEY_DSS: | |
118 if (bits != 1024) { | |
119 dropbear_exit("DSS keys have a fixed size of 1024 bits\n"); | |
120 exit(EXIT_FAILURE); | |
121 } | |
122 #endif | |
123 default: | |
124 (void)0; /* quiet, compiler. ecdsa handles checks itself */ | |
125 } | |
104 } | 126 } |
105 | 127 |
106 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) | 128 #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) |
107 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) | 129 #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) |
108 int dropbearkey_main(int argc, char ** argv) { | 130 int dropbearkey_main(int argc, char ** argv) { |
110 int main(int argc, char ** argv) { | 132 int main(int argc, char ** argv) { |
111 #endif | 133 #endif |
112 | 134 |
113 int i; | 135 int i; |
114 char ** next = 0; | 136 char ** next = 0; |
115 sign_key *key = NULL; | |
116 buffer *buf = NULL; | |
117 char * filename = NULL; | 137 char * filename = NULL; |
118 enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; | 138 enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; |
119 char * typetext = NULL; | 139 char * typetext = NULL; |
120 char * sizetext = NULL; | 140 char * sizetext = NULL; |
121 unsigned int bits; | 141 unsigned int bits = 0; |
122 int printpub = 0; | 142 int printpub = 0; |
123 | 143 |
124 crypto_init(); | 144 crypto_init(); |
125 seedrandom(); | 145 seedrandom(); |
126 | 146 |
172 printhelp(argv[0]); | 192 printhelp(argv[0]); |
173 exit(EXIT_FAILURE); | 193 exit(EXIT_FAILURE); |
174 } | 194 } |
175 | 195 |
176 if (printpub) { | 196 if (printpub) { |
177 justprintpub(filename); | 197 int ret = printpubfile(filename); |
178 /* Not reached */ | 198 exit(ret); |
179 } | 199 } |
180 | 200 |
181 /* check/parse args */ | 201 /* check/parse args */ |
182 if (!typetext) { | 202 if (!typetext) { |
183 fprintf(stderr, "Must specify key type\n"); | 203 fprintf(stderr, "Must specify key type\n"); |
214 if (sscanf(sizetext, "%u", &bits) != 1) { | 234 if (sscanf(sizetext, "%u", &bits) != 1) { |
215 fprintf(stderr, "Bits must be an integer\n"); | 235 fprintf(stderr, "Bits must be an integer\n"); |
216 exit(EXIT_FAILURE); | 236 exit(EXIT_FAILURE); |
217 } | 237 } |
218 | 238 |
219 // TODO: put RSA and DSS size checks into genrsa.c etc | 239 check_signkey_bits(keytype, bits);; |
220 switch (keytype) { | 240 } |
221 #ifdef DROPBEAR_RSA | 241 |
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"); | 242 fprintf(stderr, "Generating key, this may take a while...\n"); |
276 switch(keytype) { | 243 if (signkey_generate(keytype, bits, filename) == DROPBEAR_FAILURE) |
277 #ifdef DROPBEAR_RSA | 244 { |
278 case DROPBEAR_SIGNKEY_RSA: | 245 dropbear_exit("Failed to generate key.\n"); |
279 key->rsakey = gen_rsa_priv_key(bits); | 246 } |
280 break; | 247 |
281 #endif | 248 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 | 249 |
314 return EXIT_SUCCESS; | 250 return EXIT_SUCCESS; |
315 } | 251 } |
316 #endif | 252 #endif |
317 | 253 |
318 static void justprintpub(const char* filename) { | 254 static int printpubfile(const char* filename) { |
319 | 255 |
320 buffer *buf = NULL; | 256 buffer *buf = NULL; |
321 sign_key *key = NULL; | 257 sign_key *key = NULL; |
322 enum signkey_type keytype; | 258 enum signkey_type keytype; |
323 int ret; | 259 int ret; |
351 buf = NULL; | 287 buf = NULL; |
352 if (key) { | 288 if (key) { |
353 sign_key_free(key); | 289 sign_key_free(key); |
354 key = NULL; | 290 key = NULL; |
355 } | 291 } |
356 exit(err); | 292 return err; |
357 } | 293 } |
358 | 294 |
359 static void printpubkey(sign_key * key, int keytype) { | 295 static void printpubkey(sign_key * key, int keytype) { |
360 | 296 |
361 buffer * buf = NULL; | 297 buffer * buf = NULL; |
400 typestring, base64key, username, hostname, fp); | 336 typestring, base64key, username, hostname, fp); |
401 | 337 |
402 m_free(fp); | 338 m_free(fp); |
403 buf_free(buf); | 339 buf_free(buf); |
404 } | 340 } |
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 } |