diff dropbearkey.c @ 839:33207ed1174b

Merge in ECC
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Oct 2013 22:57:21 +0800
parents 75509065db53
children 5128e525c8fa
line wrap: on
line diff
--- a/dropbearkey.c	Wed Oct 16 22:55:03 2013 +0800
+++ b/dropbearkey.c	Mon Oct 21 22:57:21 2013 +0800
@@ -51,11 +51,14 @@
 
 #include "genrsa.h"
 #include "gendss.h"
+#include "ecdsa.h"
+#include "crypto_desc.h"
+#include "random.h"
 
 static void printhelp(char * progname);
 
-#define RSA_SIZE (1024/8) /* 1024 bit */
-#define DSS_SIZE (1024/8) /* 1024 bit */
+#define RSA_DEFAULT_SIZE 1024
+#define DSS_DEFAULT_SIZE 1024
 
 static void buf_writefile(buffer * buf, const char * filename);
 static void printpubkey(sign_key * key, int keytype);
@@ -72,9 +75,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"
@@ -94,13 +115,15 @@
 	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;
 	int printpub = 0;
 
+	crypto_init();
+	seedrandom();
+
 	/* get the commandline options */
 	for (i = 1; i < argc; i++) {
 		if (argv[i] == NULL) {
@@ -162,21 +185,9 @@
 		exit(EXIT_FAILURE);
 	}
 
-	if (strlen(typetext) == 3) {
-#ifdef DROPBEAR_RSA
-		if (strncmp(typetext, "rsa", 3) == 0) {
-			keytype = DROPBEAR_SIGNKEY_RSA;
-			TRACE(("type is rsa"))
-		}
-#endif
-#ifdef DROPBEAR_DSS
-		if (strncmp(typetext, "dss", 3) == 0) {
-			keytype = DROPBEAR_SIGNKEY_DSS;
-			TRACE(("type is dss"))
-		}
-#endif
-	}
-	if (keytype == -1) {
+	keytype = signkey_type_from_name(typetext, strlen(typetext));
+
+	if (keytype == DROPBEAR_SIGNKEY_NONE) {
 		fprintf(stderr, "Unknown key type '%s'\n", typetext);
 		printhelp(argv[0]);
 		exit(EXIT_FAILURE);
@@ -188,28 +199,51 @@
 			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);
-		}
+		// TODO: put RSA and DSS size checks into genrsa.c etc
+        switch (keytype) {
+#ifdef DROPBEAR_RSA
+            case DROPBEAR_SIGNKEY_RSA:
+                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);
+                }
+                break;
+#endif
+#ifdef DROPEAR_DSS
+            case DROPBEAR_SIGNKEY_DSS:
+                if (bits != 1024) {
+                    fprintf(stderr, "DSS keys have a fixed size of 1024 bits\n");
+                    exit(EXIT_FAILURE);			
+                }
+#endif
+			default:
+				(void)0; /* quiet, compiler. ecdsa handles checks itself */
+        }
 
-		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 */
+        switch (keytype) {
+#ifdef DROPBEAR_RSA
+            case DROPBEAR_SIGNKEY_RSA:
+                bits = RSA_DEFAULT_SIZE;
+                break;
+#endif
+#ifdef DROPBEAR_DSS
+            case DROPBEAR_SIGNKEY_DSS:
+                bits = DSS_DEFAULT_SIZE;
+                break;
+#endif
+#ifdef DROPBEAR_ECDSA
+            case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
+                bits = ECDSA_DEFAULT_SIZE;
+                break;
+#endif
+            default:
+                exit(EXIT_FAILURE); /* not reached */
 		}
 	}
 
 
-	fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", keysize*8,
+	fprintf(stderr, "Will output %d bit %s secret key to '%s'\n", bits,
 			typetext, filename);
 
 	/* don't want the file readable by others */
@@ -222,12 +256,21 @@
 	switch(keytype) {
 #ifdef DROPBEAR_RSA
 		case DROPBEAR_SIGNKEY_RSA:
-			key->rsakey = gen_rsa_priv_key(keysize); /* 128 bytes = 1024 bit */
+			key->rsakey = gen_rsa_priv_key(bits);
 			break;
 #endif
 #ifdef DROPBEAR_DSS
 		case DROPBEAR_SIGNKEY_DSS:
-			key->dsskey = gen_dss_priv_key(keysize); /* 128 bytes = 1024 bit */
+			key->dsskey = gen_dss_priv_key(bits);
+			break;
+#endif
+#ifdef DROPBEAR_ECDSA
+		case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
+			{
+				ecc_key *ecckey = gen_ecdsa_priv_key(bits);
+				keytype = ecdsa_signkey_type(ecckey);
+				*signkey_ecc_key_ptr(key, keytype) = ecckey;
+			}
 			break;
 #endif
 		default:
@@ -319,7 +362,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);