changeset 684:c37857676924 insecure-nocrypto

Merge in "-m"/"-c" code
author Matt Johnston <matt@ucc.asn.au>
date Thu, 17 May 2012 08:09:19 +0800
parents a4b7627b3157 (diff) 63f8d6c469cf (current diff)
children 5af8993f7529
files common-algo.c common-kex.c options.h
diffstat 6 files changed, 115 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/cli-auth.c	Thu May 17 00:26:12 2012 +0800
+++ b/cli-auth.c	Thu May 17 08:09:19 2012 +0800
@@ -257,7 +257,10 @@
 #endif
 
 #ifdef ENABLE_CLI_INTERACT_AUTH
-	if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) {
+	if (ses.keys->trans.algo_crypt->cipherdesc == NULL) {
+		fprintf(stderr, "Sorry, I won't let you use interactive auth unencrypted.\n");
+	}
+	else if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) {
 		if (cli_ses.auth_interact_failed) {
 			finished = 0;
 		} else {
@@ -269,7 +272,10 @@
 #endif
 
 #ifdef ENABLE_CLI_PASSWORD_AUTH
-	if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) {
+	if (ses.keys->trans.algo_crypt->cipherdesc == NULL) {
+		fprintf(stderr, "Sorry, I won't let you use password auth unencrypted.\n");
+	}
+	else if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) {
 		cli_auth_password();
 		finished = 1;
 		cli_ses.lastauthtype = AUTH_TYPE_PASSWORD;
--- a/common-algo.c	Thu May 17 00:26:12 2012 +0800
+++ b/common-algo.c	Thu May 17 08:09:19 2012 +0800
@@ -106,6 +106,14 @@
 static const struct dropbear_hash dropbear_sha1_96 = 
 	{&sha1_desc, 20, 12};
 #endif
+#ifdef DROPBEAR_SHA2_256_HMAC
+static const struct dropbear_hash dropbear_sha2_256 = 
+	{&sha256_desc, 32, 32};
+#endif
+#ifdef DROPBEAR_SHA2_512_HMAC
+static const struct dropbear_hash dropbear_sha2_512 =
+	{&sha512_desc, 64, 64};
+#endif
 #ifdef DROPBEAR_MD5_HMAC
 static const struct dropbear_hash dropbear_md5 = 
 	{&md5_desc, 16, 16};
@@ -152,10 +160,19 @@
 #ifdef DROPBEAR_BLOWFISH
 	{"blowfish-cbc", 0, &dropbear_blowfish, 1, &dropbear_mode_cbc},
 #endif
+#ifdef DROPBEAR_NONE_CIPHER
+	{"none", 0, (void*)&dropbear_nocipher, 1, &dropbear_mode_none},
+#endif
 	{NULL, 0, NULL, 0, NULL}
 };
 
 algo_type sshhashes[] = {
+#ifdef DROPBEAR_SHA2_256_HMAC
+//	{"hmac-sha2-256", 0, &dropbear_sha2_256, 1, NULL},
+#endif
+#ifdef DROPBEAR_SHA2_512_HMAC
+//	{"hmac-sha2-512", 0, &dropbear_sha2_512, 1, NULL},
+#endif
 #ifdef DROPBEAR_SHA1_96_HMAC
 	{"hmac-sha1-96", 0, &dropbear_sha1_96, 1, NULL},
 #endif
@@ -163,7 +180,10 @@
 	{"hmac-sha1", 0, &dropbear_sha1, 1, NULL},
 #endif
 #ifdef DROPBEAR_MD5_HMAC
-	{"hmac-md5", 0, &dropbear_md5, 1, NULL},
+	{"hmac-md5", 0, (void*)&dropbear_md5, 1, NULL},
+#endif
+#ifdef DROPBEAR_NONE_INTEGRITY
+	{"none", 0, (void*)&dropbear_nohash, 1, NULL},
 #endif
 	{NULL, 0, NULL, 0, NULL}
 };
--- a/common-kex.c	Thu May 17 00:26:12 2012 +0800
+++ b/common-kex.c	Thu May 17 08:09:19 2012 +0800
@@ -249,26 +249,28 @@
  * already initialised hash_state hs, which should already have processed
  * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
  * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
- * The output will only be expanded once, as we are assured that
- * outlen <= 2*SHA1_HASH_SIZE for all known hashes.
  *
  * See Section 7.2 of rfc4253 (ssh transport) for details */
 static void hashkeys(unsigned char *out, int outlen, 
 		const hash_state * hs, const unsigned char X) {
 
 	hash_state hs2;
-	unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */
+	int offset;
 
 	memcpy(&hs2, hs, sizeof(hash_state));
 	sha1_process(&hs2, &X, 1);
 	sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE);
 	sha1_done(&hs2, out);
-	if (SHA1_HASH_SIZE < outlen) {
+	for (offset = SHA1_HASH_SIZE; 
+			offset < outlen; 
+			offset += SHA1_HASH_SIZE)
+	{
 		/* need to extend */
+		unsigned char k2[SHA1_HASH_SIZE];
 		memcpy(&hs2, hs, sizeof(hash_state));
-		sha1_process(&hs2, out, SHA1_HASH_SIZE);
+		sha1_process(&hs2, out, offset);
 		sha1_done(&hs2, k2);
-		memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE);
+		memcpy(&out[offset], k2, MIN(outlen - offset, SHA1_HASH_SIZE));
 	}
 }
 
@@ -292,7 +294,6 @@
 	hash_state hs;
 	unsigned int C2S_keysize, S2C_keysize;
 	char mactransletter, macrecvletter; /* Client or server specific */
-	int recv_cipher = 0, trans_cipher = 0;
 
 	TRACE(("enter gen_new_keys"))
 	/* the dh_K and hash are the start of all hashes, we make use of that */
@@ -329,31 +330,39 @@
 	hashkeys(C2S_key, C2S_keysize, &hs, 'C');
 	hashkeys(S2C_key, S2C_keysize, &hs, 'D');
 
-	recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
-	if (recv_cipher < 0)
-	    dropbear_exit("Crypto error");
-	if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
-			recv_IV, recv_key, 
-			ses.newkeys->recv.algo_crypt->keysize, 0, 
-			&ses.newkeys->recv.cipher_state) != CRYPT_OK) {
-		dropbear_exit("Crypto error");
+	if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
+		int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
+		if (recv_cipher < 0)
+			dropbear_exit("Crypto error");
+		if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
+				recv_IV, recv_key, 
+				ses.newkeys->recv.algo_crypt->keysize, 0, 
+				&ses.newkeys->recv.cipher_state) != CRYPT_OK) {
+			dropbear_exit("Crypto error");
+		}
 	}
 
-	trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
-	if (trans_cipher < 0)
-	    dropbear_exit("Crypto error");
-	if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
-			trans_IV, trans_key, 
-			ses.newkeys->trans.algo_crypt->keysize, 0, 
-			&ses.newkeys->trans.cipher_state) != CRYPT_OK) {
-		dropbear_exit("Crypto error");
+	if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
+		int trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
+		if (trans_cipher < 0)
+			dropbear_exit("Crypto error");
+		if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
+				trans_IV, trans_key, 
+				ses.newkeys->trans.algo_crypt->keysize, 0, 
+				&ses.newkeys->trans.cipher_state) != CRYPT_OK) {
+			dropbear_exit("Crypto error");
+		}
 	}
-	
+
 	/* MAC keys */
-	hashkeys(ses.newkeys->trans.mackey, 
-			ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
-	hashkeys(ses.newkeys->recv.mackey, 
-			ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
+	if (ses.newkeys->trans.algo_mac->hashdesc != NULL) {
+		hashkeys(ses.newkeys->trans.mackey, 
+				ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
+	}
+	if (ses.newkeys->recv.algo_mac->hashdesc != NULL) {
+		hashkeys(ses.newkeys->recv.mackey, 
+				ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
+	}
 	ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hashdesc->name),
 	ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name),
 
--- a/libtomcrypt/src/headers/tomcrypt_custom.h	Thu May 17 00:26:12 2012 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_custom.h	Thu May 17 08:09:19 2012 +0800
@@ -118,14 +118,18 @@
 #define LTC_CTR_MODE
 #endif
 
-#if defined(DROPBEAR_DSS) && defined(DSS_PROTOK)
-#define SHA512
+#define SHA1
+
+#ifdef DROPBEAR_MD5
+#define MD5
 #endif
 
-#define SHA1
+#ifdef DROPBEAR_SHA256
+#define SHA256
+#endif
 
-#ifdef DROPBEAR_MD5_HMAC
-#define MD5
+#ifdef DROPBEAR_SHA512
+#define SHA512
 #endif
 
 #define LTC_HMAC
--- a/options.h	Thu May 17 00:26:12 2012 +0800
+++ b/options.h	Thu May 17 08:09:19 2012 +0800
@@ -100,6 +100,18 @@
  * size and is recommended for most cases */
 #define DROPBEAR_ENABLE_CTR_MODE
 
+/* You can compile with no encryption if you want. In some circumstances
+ * this could be safe security-wise, though make sure you know what
+ * you're doing. Anyone can see everything that goes over the wire, so
+ * the only safe auth method is public key. You'll have to disable all other
+ * ciphers above in the client if you want to use this, or implement cipher
+ * prioritisation in cli-runopts.
+ *
+ * The best way to do things is probably make normal compile of dropbear with
+ * all ciphers including "none" as the server, then recompile a special
+ * "dbclient-insecure" client. */
+#define DROPBEAR_NONE_CIPHER
+
 /* Message Integrity - at least one required.
  * Protocol RFC requires sha1 and recommends sha1-96.
  * sha1-96 is of use for slow links as it has a smaller overhead.
@@ -112,11 +124,19 @@
  * These hashes are also used for public key fingerprints in logs.
  * If you disable MD5, Dropbear will fall back to SHA1 fingerprints,
  * which are not the standard form. */
-
 #define DROPBEAR_SHA1_HMAC
 #define DROPBEAR_SHA1_96_HMAC
+/*#define DROPBEAR_SHA2_256_HMAC*/
+/*#define DROPBEAR_SHA2_512_HMAC*/
 #define DROPBEAR_MD5_HMAC
 
+/* You can also disable integrity. Don't bother disabling this if you're
+ * still using a cipher, it's relatively cheap. If you disable this it's dead
+ * simple to run arbitrary commands on the remote host. Beware.
+ * Note again, for the client you will have to disable other hashes above
+ * to use this. */
+#define DROPBEAR_NONE_INTEGRITY
+
 /* Hostkey/public key algorithms - at least one required, these are used
  * for hostkey as well as for verifying signatures with pubkey auth.
  * Removing either of these won't save very much space.
--- a/sysoptions.h	Thu May 17 00:26:12 2012 +0800
+++ b/sysoptions.h	Thu May 17 08:09:19 2012 +0800
@@ -90,7 +90,13 @@
 #define MAX_KEY_LEN 32 /* 256 bits for aes256 etc */
 #define MAX_IV_LEN 20 /* must be same as max blocksize, 
 						 and >= SHA1_HASH_SIZE */
+#if defined(DROPBEAR_SHA2_512_HMAC)
+#define MAX_MAC_KEY 64
+#elif defined(DROPBEAR_SHA2_256_HMAC)
+#define MAX_MAC_KEY 32
+#else
 #define MAX_MAC_KEY 20
+#endif
 
 #define MAX_NAME_LEN 64 /* maximum length of a protocol name, isn't
 						   explicitly specified for all protocols (just
@@ -144,6 +150,19 @@
 #define DROPBEAR_TWOFISH
 #endif
 
+#ifdef DROPBEAR_MD5_HMAC
+#define DROPBEAR_MD5
+#endif
+
+#ifdef DROPBEAR_SHA2_256_HMAC
+#define DROPBEAR_SHA256
+#endif
+
+#if (defined(DROPBEAR_DSS) && defined(DSS_PROTOK)) \
+	|| defined(DROPBEAR_SHA2_512_HMAC)
+#define DROPBEAR_SHA512
+#endif
+
 #ifndef ENABLE_X11FWD
 #define DISABLE_X11FWD
 #endif