Mercurial > dropbear
diff dropbearkey.c @ 910:89555751c489 asm
merge up to 2013.63, improve ASM makefile rules a bit
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 27 Feb 2014 21:35:58 +0800 |
parents | 220f55d540ae |
children | 6fb4c010c448 |
line wrap: on
line diff
--- a/dropbearkey.c Sun Oct 06 22:32:03 2013 +0800 +++ b/dropbearkey.c Thu Feb 27 21:35:58 2014 +0800 @@ -51,15 +51,16 @@ #include "genrsa.h" #include "gendss.h" +#include "ecdsa.h" +#include "crypto_desc.h" +#include "dbrandom.h" +#include "gensignkey.h" static void printhelp(char * progname); -#define RSA_SIZE (1024/8) /* 1024 bit */ -#define DSS_SIZE (1024/8) /* 1024 bit */ -static void buf_writefile(buffer * buf, const char * filename); static void printpubkey(sign_key * key, int keytype); -static void justprintpub(const char* filename); +static int printpubfile(const char* filename); /* Print a help message */ static void printhelp(char * progname) { @@ -72,9 +73,27 @@ #ifdef DROPBEAR_DSS " dss\n" #endif +#ifdef DROPBEAR_ECDSA + " ecdsa\n" +#endif "-f filename Use filename for the secret key\n" "-s bits Key size in bits, should be a multiple of 8 (optional)\n" - " (DSS has a fixed size of 1024 bits)\n" +#ifdef DROPBEAR_DSS + " DSS has a fixed size of 1024 bits\n" +#endif +#ifdef DROPBEAR_ECDSA + " ECDSA has sizes " +#ifdef DROPBEAR_ECC_256 + "256 " +#endif +#ifdef DROPBEAR_ECC_384 + "384 " +#endif +#ifdef DROPBEAR_ECC_521 + "521 " +#endif + "\n" +#endif "-y Just print the publickey and fingerprint for the\n private key in <filename>.\n" #ifdef DEBUG_TRACE "-v verbose\n" @@ -82,6 +101,30 @@ ,progname); } +/* fails fatally */ +static void check_signkey_bits(enum signkey_type type, int bits) +{ + switch (type) { +#ifdef DROPBEAR_RSA + case DROPBEAR_SIGNKEY_RSA: + if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { + dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a" + " multiple of 8\n"); + } + break; +#endif +#ifdef DROPEAR_DSS + case DROPBEAR_SIGNKEY_DSS: + if (bits != 1024) { + dropbear_exit("DSS keys have a fixed size of 1024 bits\n"); + exit(EXIT_FAILURE); + } +#endif + default: + (void)0; /* quiet, compiler. ecdsa handles checks itself */ + } +} + #if defined(DBMULTI_dropbearkey) || !defined(DROPBEAR_MULTI) #if defined(DBMULTI_dropbearkey) && defined(DROPBEAR_MULTI) int dropbearkey_main(int argc, char ** argv) { @@ -91,16 +134,16 @@ int i; char ** next = 0; - sign_key *key = NULL; - buffer *buf = NULL; char * filename = NULL; - int keytype = -1; + enum signkey_type keytype = DROPBEAR_SIGNKEY_NONE; char * typetext = NULL; char * sizetext = NULL; - unsigned int bits; - unsigned int keysize; + unsigned int bits = 0; int printpub = 0; + crypto_init(); + seedrandom(); + /* get the commandline options */ for (i = 1; i < argc; i++) { if (argv[i] == NULL) { @@ -151,8 +194,8 @@ } if (printpub) { - justprintpub(filename); - /* Not reached */ + int ret = printpubfile(filename); + exit(ret); } /* check/parse args */ @@ -162,21 +205,26 @@ exit(EXIT_FAILURE); } - if (strlen(typetext) == 3) { #ifdef DROPBEAR_RSA - if (strncmp(typetext, "rsa", 3) == 0) { - keytype = DROPBEAR_SIGNKEY_RSA; - TRACE(("type is rsa")) - } + if (strcmp(typetext, "rsa") == 0) + { + keytype = DROPBEAR_SIGNKEY_RSA; + } #endif #ifdef DROPBEAR_DSS - if (strncmp(typetext, "dss", 3) == 0) { - keytype = DROPBEAR_SIGNKEY_DSS; - TRACE(("type is dss")) - } + if (strcmp(typetext, "dss") == 0) + { + keytype = DROPBEAR_SIGNKEY_DSS; + } #endif +#ifdef DROPBEAR_ECDSA + if (strcmp(typetext, "ecdsa") == 0) + { + keytype = DROPBEAR_SIGNKEY_ECDSA_KEYGEN; } - if (keytype == -1) { +#endif + + if (keytype == DROPBEAR_SIGNKEY_NONE) { fprintf(stderr, "Unknown key type '%s'\n", typetext); printhelp(argv[0]); exit(EXIT_FAILURE); @@ -188,75 +236,26 @@ exit(EXIT_FAILURE); } - if (keytype == DROPBEAR_SIGNKEY_DSS && bits != 1024) { - fprintf(stderr, "DSS keys have a fixed size of 1024 bits\n"); - exit(EXIT_FAILURE); - } else if (bits < 512 || bits > 4096 || (bits % 8 != 0)) { - fprintf(stderr, "Bits must satisfy 512 <= bits <= 4096, and be a" - " multiple of 8\n"); - exit(EXIT_FAILURE); - } - - keysize = bits / 8; - } else { - if (keytype == DROPBEAR_SIGNKEY_DSS) { - keysize = DSS_SIZE; - } else if (keytype == DROPBEAR_SIGNKEY_RSA) { - keysize = RSA_SIZE; - } else { - exit(EXIT_FAILURE); /* not reached */ - } - } - - - fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", keysize*8, - typetext, filename); - - /* don't want the file readable by others */ - umask(077); + check_signkey_bits(keytype, bits);; + } - /* now we can generate the key */ - key = new_sign_key(); - fprintf(stderr, "Generating key, this may take a while...\n"); - switch(keytype) { -#ifdef DROPBEAR_RSA - case DROPBEAR_SIGNKEY_RSA: - key->rsakey = gen_rsa_priv_key(keysize); /* 128 bytes = 1024 bit */ - break; -#endif -#ifdef DROPBEAR_DSS - case DROPBEAR_SIGNKEY_DSS: - key->dsskey = gen_dss_priv_key(keysize); /* 128 bytes = 1024 bit */ - break; -#endif - default: - fprintf(stderr, "Internal error, bad key type\n"); - exit(EXIT_FAILURE); - } + if (signkey_generate(keytype, bits, filename) == DROPBEAR_FAILURE) + { + dropbear_exit("Failed to generate key.\n"); + } - buf = buf_new(MAX_PRIVKEY_SIZE); - - buf_put_priv_key(buf, key, keytype); - buf_setpos(buf, 0); - buf_writefile(buf, filename); - - buf_burn(buf); - buf_free(buf); - - printpubkey(key, keytype); - - sign_key_free(key); + printpubfile(filename); return EXIT_SUCCESS; } #endif -static void justprintpub(const char* filename) { +static int printpubfile(const char* filename) { buffer *buf = NULL; sign_key *key = NULL; - int keytype; + enum signkey_type keytype; int ret; int err = DROPBEAR_FAILURE; @@ -290,7 +289,7 @@ sign_key_free(key); key = NULL; } - exit(err); + return err; } static void printpubkey(sign_key * key, int keytype) { @@ -319,7 +318,7 @@ fprintf(stderr, "base64 failed"); } - typestring = signkey_name_from_type(keytype, &err); + typestring = signkey_name_from_type(keytype, NULL); fp = sign_key_fingerprint(buf_getptr(buf, len), len); @@ -339,35 +338,3 @@ m_free(fp); buf_free(buf); } - -/* Write a buffer to a file specified, failing if the file exists */ -static void buf_writefile(buffer * buf, const char * filename) { - - int fd; - int len; - - fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd < 0) { - fprintf(stderr, "Couldn't create new file %s\n", filename); - perror("Reason"); - buf_burn(buf); - exit(EXIT_FAILURE); - } - - /* write the file now */ - while (buf->pos != buf->len) { - len = write(fd, buf_getptr(buf, buf->len - buf->pos), - buf->len - buf->pos); - if (errno == EINTR) { - continue; - } - if (len <= 0) { - fprintf(stderr, "Failed writing file '%s'\n",filename); - perror("Reason"); - exit(EXIT_FAILURE); - } - buf_incrpos(buf, len); - } - - close(fd); -}