From 4cb673b6440091fe0568918e22f3f2ca0d94bef2 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Fri, 7 Jul 2006 09:17:18 +0000
Subject: [PATCH] Fixes from Erik Hovland:

cli-authpubkey.c:
    fix leak of keybuf

cli-kex.c:
    fix leak of fingerprint fp

cli-service.c:
    remove commented out code

dropbearkey.c:
    don't attepmt to free NULL key on failure

common-kex.c:
    only free key if it is initialised

keyimport.c:
    remove dead encrypted-key code
    don't leak a FILE* loading OpenSSH keys

rsa.c, dss.c:
    check return values for some libtommath functions

svr-kex.c:
    check return value retrieving DH kex mpint

svr-tcpfwd.c:
    fix null-dereference if remote tcp forward request fails

tcp-accept.c:
    don't incorrectly free the tcpinfo var

--HG--
extra : convert_revision : 640a55bc710cbaa6d212453c750026c770e19193
---
 cli-authpubkey.c |  1 +
 cli-kex.c        |  2 +-
 cli-service.c    |  2 --
 dropbearkey.c    |  6 ++++--
 dss.c            |  4 +++-
 keyimport.c      | 45 ++++-----------------------------------------
 rsa.c            | 21 ++++++++++++++++-----
 svr-kex.c        |  4 +++-
 svr-tcpfwd.c     |  2 +-
 tcp-accept.c     |  1 -
 10 files changed, 33 insertions(+), 55 deletions(-)

diff --git a/cli-authpubkey.c b/cli-authpubkey.c
index 9d36bc38..8a8fb42a 100644
--- a/cli-authpubkey.c
+++ b/cli-authpubkey.c
@@ -112,6 +112,7 @@ void recv_msg_userauth_pk_ok() {
 		/* Success */
 		break;
 	}
+	buf_free(keybuf);
 
 	if (keyitem != NULL) {
 		TRACE(("matching key"))
diff --git a/cli-kex.c b/cli-kex.c
index 3548f1cb..467ae230 100644
--- a/cli-kex.c
+++ b/cli-kex.c
@@ -122,6 +122,7 @@ static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
 	fprintf(stderr, "\nHost '%s' is not in the trusted hosts file.\n(fingerprint %s)\nDo you want to continue connecting? (y/n)\n", 
 			cli_opts.remotehost, 
 			fp);
+	m_free(fp);
 
 	tty = fopen(_PATH_TTY, "r");
 	if (tty) {
@@ -132,7 +133,6 @@ static void ask_to_confirm(unsigned char* keyblob, unsigned int keybloblen) {
 	}
 
 	if (response == 'y') {
-		m_free(fp);
 		return;
 	}
 
diff --git a/cli-service.c b/cli-service.c
index 87b6ed22..57807be4 100644
--- a/cli-service.c
+++ b/cli-service.c
@@ -82,6 +82,4 @@ void recv_msg_service_accept() {
 	}
 
 	dropbear_exit("unrecognised service accept");
-	/* m_free(servicename); not reached */
-
 }
diff --git a/dropbearkey.c b/dropbearkey.c
index 280e1b34..24333818 100644
--- a/dropbearkey.c
+++ b/dropbearkey.c
@@ -283,8 +283,10 @@ out:
 	buf_burn(buf);
 	buf_free(buf);
 	buf = NULL;
-	sign_key_free(key);
-	key = NULL;
+	if (key) {
+		sign_key_free(key);
+		key = NULL;
+	}
 	exit(err);
 }
 
diff --git a/dss.c b/dss.c
index 84a093ce..95062c68 100644
--- a/dss.c
+++ b/dss.c
@@ -338,7 +338,9 @@ void buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data,
 	/* generate k */
 	m_mp_init(&dss_protok);
 	bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE);
-	mp_mod(&dss_protok, key->q, &dss_k);
+	if (mp_mod(&dss_protok, key->q, &dss_k) != MP_OKAY) {
+		dropbear_exit("dss error");
+	}
 	mp_clear(&dss_protok);
 	m_burn(proto_k, SHA512_HASH_SIZE);
 #else /* DSS_PROTOK not defined*/
diff --git a/keyimport.c b/keyimport.c
index a0474f35..1d3e3f59 100644
--- a/keyimport.c
+++ b/keyimport.c
@@ -361,7 +361,7 @@ struct openssh_key {
 static struct openssh_key *load_openssh_key(const char *filename)
 {
 	struct openssh_key *ret;
-	FILE *fp;
+	FILE *fp = NULL;
 	char buffer[256];
 	char *errmsg = NULL, *p = NULL;
 	int headers_done;
@@ -482,6 +482,9 @@ static struct openssh_key *load_openssh_key(const char *filename)
 		memset(&ret, 0, sizeof(ret));
 		m_free(ret);
 	}
+	if (fp) {
+		fclose(fp);
+	}
 	if (errmsg) {
 		fprintf(stderr, "Error: %s\n", errmsg);
 	}
@@ -926,40 +929,6 @@ static int openssh_write(const char *filename, sign_key *key,
 	if (passphrase) {
 		fprintf(stderr, "Encrypted keys aren't supported currently\n");
 		goto error;
-#if 0
-		/*
-		 * Invent an iv. Then derive encryption key from passphrase
-		 * and iv/salt:
-		 * 
-		 *  - let block A equal MD5(passphrase || iv)
-		 *  - let block B equal MD5(A || passphrase || iv)
-		 *  - block C would be MD5(B || passphrase || iv) and so on
-		 *  - encryption key is the first N bytes of A || B
-		 */
-		struct MD5Context md5c;
-		unsigned char keybuf[32];
-
-		for (i = 0; i < 8; i++) iv[i] = random_byte();
-
-		MD5Init(&md5c);
-		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
-		MD5Update(&md5c, iv, 8);
-		MD5Final(keybuf, &md5c);
-
-		MD5Init(&md5c);
-		MD5Update(&md5c, keybuf, 16);
-		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
-		MD5Update(&md5c, iv, 8);
-		MD5Final(keybuf+16, &md5c);
-
-		/*
-		 * Now encrypt the key blob.
-		 */
-		des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
-
-		memset(&md5c, 0, sizeof(md5c));
-		memset(keybuf, 0, sizeof(keybuf));
-#endif
 	}
 
 	/*
@@ -976,12 +945,6 @@ static int openssh_write(const char *filename, sign_key *key,
 		goto error;
 	}
 	fputs(header, fp);
-	if (passphrase) {
-		fprintf(fp, "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,");
-		for (i = 0; i < 8; i++)
-			fprintf(fp, "%02X", iv[i]);
-		fprintf(fp, "\n\n");
-	}
 	base64_encode_fp(fp, outblob, outlen, 64);
 	fputs(footer, fp);
 	fclose(fp);
diff --git a/rsa.c b/rsa.c
index 005e4ca1..8665673b 100644
--- a/rsa.c
+++ b/rsa.c
@@ -285,18 +285,29 @@ void buf_put_rsa_sign(buffer* buf, rsa_key *key, const unsigned char* data,
 	/* rsa_tmp1 is em */
 	/* em' = em * r^e mod n */
 
-	mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/
-	mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3);
-	mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2);
+	/* rsa_s used as a temp var*/
+	if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) {
+		dropbear_exit("rsa error");
+	}
+	if (mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != MP_OKAY) {
+		dropbear_exit("rsa error");
+	}
+	if (mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != MP_OKAY) {
+		dropbear_exit("rsa error");
+	}
 
 	/* rsa_tmp2 is em' */
 	/* s' = (em')^d mod n */
-	mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1);
+	if (mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != MP_OKAY) {
+		dropbear_exit("rsa error");
+	}
 
 	/* rsa_tmp1 is s' */
 	/* rsa_tmp3 is r^(-1) mod n */
 	/* s = (s')r^(-1) mod n */
-	mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s);
+	if (mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != MP_OKAY) {
+		dropbear_exit("rsa error");
+	}
 
 #else
 
diff --git a/svr-kex.c b/svr-kex.c
index a9954bbc..75cb0908 100644
--- a/svr-kex.c
+++ b/svr-kex.c
@@ -52,7 +52,9 @@ void recv_msg_kexdh_init() {
 	}
 
 	m_mp_init(&dh_e);
-	buf_getmpint(ses.payload, &dh_e);
+	if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
+		dropbear_exit("Failed to get kex value");
+	}
 
 	send_msg_kexdh_reply(&dh_e);
 
diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c
index 6391c4cf..d4dca6ba 100644
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -216,7 +216,7 @@ out:
 	if (ret == DROPBEAR_FAILURE) {
 		/* we only free it if a listener wasn't created, since the listener
 		 * has to remember it if it's to be cancelled */
-		m_free(tcpinfo->listenaddr);
+		m_free(bindaddr);
 		m_free(tcpinfo);
 	}
 	TRACE(("leave remotetcpreq"))
diff --git a/tcp-accept.c b/tcp-accept.c
index ffb175e1..c2fb2fef 100644
--- a/tcp-accept.c
+++ b/tcp-accept.c
@@ -131,7 +131,6 @@ int listen_tcpfwd(struct TCPListener* tcpinfo) {
 			tcp_acceptor, cleanup_tcp);
 
 	if (listener == NULL) {
-		m_free(tcpinfo);
 		TRACE(("leave listen_tcpfwd: listener failed"))
 		return DROPBEAR_FAILURE;
 	}
-- 
GitLab