diff dss.c @ 1439:8d24733026c5 coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Sat, 24 Jun 2017 23:33:16 +0800
parents 7aebe7da3a35
children 793c43cf523e 06d52bcb8094
line wrap: on
line diff
--- a/dss.c	Sat Jun 03 00:10:58 2017 +0800
+++ b/dss.c	Sat Jun 24 23:33:16 2017 +0800
@@ -44,6 +44,7 @@
  * These should be freed with dss_key_free.
  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
 int buf_get_dss_pub_key(buffer* buf, dropbear_dss_key *key) {
+	int ret = DROPBEAR_FAILURE;
 
 	TRACE(("enter buf_get_dss_pub_key"))
 	dropbear_assert(key != NULL);
@@ -56,17 +57,29 @@
 	 || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE
 	 || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) {
 		TRACE(("leave buf_get_dss_pub_key: failed reading mpints"))
-		return DROPBEAR_FAILURE;
+		ret = DROPBEAR_FAILURE;
+		goto out;
+	}
+
+	if (mp_count_bits(key->p) != DSS_P_BITS) {
+		dropbear_log(LOG_WARNING, "Bad DSS p");
+		ret = DROPBEAR_FAILURE;
+		goto out;
 	}
 
-	if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) {
-		dropbear_log(LOG_WARNING, "DSS key too short");
-		TRACE(("leave buf_get_dss_pub_key: short key"))
-		return DROPBEAR_FAILURE;
+	if (mp_count_bits(key->q) != DSS_Q_BITS) {
+		dropbear_log(LOG_WARNING, "Bad DSS q");
+		ret = DROPBEAR_FAILURE;
+		goto out;
 	}
 
+	ret = DROPBEAR_SUCCESS;
 	TRACE(("leave buf_get_dss_pub_key: success"))
-	return DROPBEAR_SUCCESS;
+out:
+	if (ret == DROPBEAR_FAILURE) {
+		m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, NULL);
+	}
+	return ret;
 }
 
 /* Same as buf_get_dss_pub_key, but reads a private "x" key at the end.
@@ -86,7 +99,7 @@
 	m_mp_alloc_init_multi(&key->x, NULL);
 	ret = buf_getmpint(buf, key->x);
 	if (ret == DROPBEAR_FAILURE) {
-		m_free(key->x);
+		m_mp_free_multi(&key->x, NULL);
 	}
 
 	return ret;
@@ -101,26 +114,7 @@
 		TRACE2(("enter dsa_key_free: key == NULL"))
 		return;
 	}
-	if (key->p) {
-		mp_clear(key->p);
-		m_free(key->p);
-	}
-	if (key->q) {
-		mp_clear(key->q);
-		m_free(key->q);
-	}
-	if (key->g) {
-		mp_clear(key->g);
-		m_free(key->g);
-	}
-	if (key->y) {
-		mp_clear(key->y);
-		m_free(key->y);
-	}
-	if (key->x) {
-		mp_clear(key->x);
-		m_free(key->x);
-	}
+	m_mp_free_multi(&key->p, &key->q, &key->g, &key->y, &key->x, NULL);
 	m_free(key);
 	TRACE2(("leave dsa_key_free"))
 }
@@ -192,6 +186,10 @@
 		TRACE(("verify failed, s' >= q"))
 		goto out;
 	}
+	if (mp_cmp_d(&val1, 0) != MP_GT) {
+		TRACE(("verify failed, s' <= 0"))
+		goto out;
+	}
 	/* let val2 = w = (s')^-1 mod q*/
 	if (mp_invmod(&val1, key->q, &val2) != MP_OKAY) {
 		goto out;
@@ -213,6 +211,10 @@
 		TRACE(("verify failed, r' >= q"))
 		goto out;
 	}
+	if (mp_cmp_d(&val1, 0) != MP_GT) {
+		TRACE(("verify failed, r' <= 0"))
+		goto out;
+	}
 	/* let val4 = u2 = ((r')w) mod q */
 	if (mp_mulmod(&val1, &val2, key->q, &val4) != MP_OKAY) {
 		goto out;