diff rsa.c @ 478:d4f32c3443ac dbclient-netcat-alike

propagate from branch 'au.asn.ucc.matt.dropbear' (head f21045c791002d81fc6b8dde6537ea481e513eb2) to branch 'au.asn.ucc.matt.dropbear.dbclient-netcat-alike' (head d1f69334581dc4c35f9ca16aa5355074c9dd315d)
author Matt Johnston <matt@ucc.asn.au>
date Sun, 14 Sep 2008 06:47:51 +0000
parents a124aff0cbf1
children b50f0107e505 76097ec1a29a
line wrap: on
line diff
--- a/rsa.c	Tue Mar 21 16:16:41 2006 +0000
+++ b/rsa.c	Sun Sep 14 06:47:51 2008 +0000
@@ -48,6 +48,7 @@
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) {
 
+    int ret = DROPBEAR_FAILURE;
 	TRACE(("enter buf_get_rsa_pub_key"))
 	dropbear_assert(key != NULL);
 	key->e = m_malloc(sizeof(mp_int));
@@ -62,44 +63,51 @@
 	if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE
 	 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_rsa_pub_key: failure"))
-		return DROPBEAR_FAILURE;
+	    goto out;
 	}
 
 	if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) {
 		dropbear_log(LOG_WARNING, "rsa key too short");
-		return DROPBEAR_FAILURE;
+	    goto out;
 	}
 
 	TRACE(("leave buf_get_rsa_pub_key: success"))
-	return DROPBEAR_SUCCESS;
-
+    ret = DROPBEAR_SUCCESS;
+out:
+    if (ret == DROPBEAR_FAILURE) {
+        m_free(key->e);
+        m_free(key->n);
+    }
+	return ret;
 }
 
-/* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end.
+/* Same as buf_get_rsa_pub_key, but reads private bits at the end.
  * Loads a private rsa key from a buffer
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) {
-
-	dropbear_assert(key != NULL);
+    int ret = DROPBEAR_FAILURE;
 
 	TRACE(("enter buf_get_rsa_priv_key"))
+	dropbear_assert(key != NULL);
 
 	if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE"))
 		return DROPBEAR_FAILURE;
 	}
+	
+	key->d = NULL;
+	key->p = NULL;
+	key->q = NULL;
 
 	key->d = m_malloc(sizeof(mp_int));
 	m_mp_init(key->d);
 	if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE"))
-		return DROPBEAR_FAILURE;
+	    goto out;
 	}
 
-	/* old Dropbear private keys didn't keep p and q, so we will ignore them*/
 	if (buf->pos == buf->len) {
-		key->p = NULL;
-		key->q = NULL;
+    	/* old Dropbear private keys didn't keep p and q, so we will ignore them*/
 	} else {
 		key->p = m_malloc(sizeof(mp_int));
 		key->q = m_malloc(sizeof(mp_int));
@@ -107,17 +115,24 @@
 
 		if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) {
 			TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE"))
-			return DROPBEAR_FAILURE;
+		    goto out;
 		}
 
 		if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) {
 			TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE"))
-			return DROPBEAR_FAILURE;
+		    goto out;
 		}
 	}
 
+    ret = DROPBEAR_SUCCESS;
+out:
+    if (ret == DROPBEAR_FAILURE) {
+        m_free(key->d);
+        m_free(key->p);
+        m_free(key->q);
+    }
 	TRACE(("leave buf_get_rsa_priv_key"))
-	return DROPBEAR_SUCCESS;
+    return ret;
 }
 	
 
@@ -285,18 +300,29 @@
 	/* 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