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 }