From: Dr. Stephen Henson <steve@openssl.org>
Date: Sat, 20 Jul 2013 20:25:50 +0000 (+0100)
Subject: Enhance DH dup functions.
X-Git-Tag: master-post-reformat~1229
X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=d3cc91eee2cba07d8908f0fea531c62863ed3ccf;p=oweals%2Fopenssl.git

Enhance DH dup functions.

Make DHparams_dup work properly with X9.42 DH parameters.
---

diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 2841225f83..d19b8e9961 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -458,34 +458,77 @@ static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
 	return 1;
 	}
 
-static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
 	{
 	BIGNUM *a;
+	if (src)
+		{
+		a = BN_dup(src);
+		if (!a)
+			return 0;
+		}
+	else 
+		a = NULL;
+	if (*dst)
+		BN_free(*dst);
+	*dst = a;
+	return 1;
+	}
 
-	if ((a=BN_dup(from->pkey.dh->p)) == NULL)
+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
+	{
+	if (is_x942 == -1)
+		is_x942 = !!from->q;
+	if (!int_dh_bn_cpy(&to->p, from->p))
 		return 0;
-	if (to->pkey.dh->p != NULL)
-		BN_free(to->pkey.dh->p);
-	to->pkey.dh->p=a;
-
-	if ((a=BN_dup(from->pkey.dh->g)) == NULL)
+	if (!int_dh_bn_cpy(&to->g, from->g))
 		return 0;
-	if (to->pkey.dh->g != NULL)
-		BN_free(to->pkey.dh->g);
-	to->pkey.dh->g=a;
-	if (from->ameth == &dhx_asn1_meth)
+	if (is_x942)
 		{
-		a = BN_dup(from->pkey.dh->q);
-		if (!a)
+		if (!int_dh_bn_cpy(&to->q, from->q))
+			return 0;
+		if (!int_dh_bn_cpy(&to->j, from->j))
 			return 0;
-		if (to->pkey.dh->q)
-			BN_free(to->pkey.dh->q);
-		to->pkey.dh->q = a;
+		if(to->seed)
+			{
+			OPENSSL_free(to->seed);
+			to->seed = NULL;
+			to->seedlen = 0;
+			}
+		if (from->seed)
+			{
+			to->seed = BUF_memdup(from->seed, from->seedlen);
+			if (!to->seed)
+				return 0;
+			to->seedlen = from->seedlen;
+			}
 		}
-
+	else
+		to->length = from->length;
 	return 1;
 	}
 
+
+DH *DHparams_dup(DH *dh)
+	{
+	DH *ret;
+	ret = DH_new();
+	if (!ret)
+		return NULL;
+	if (!int_dh_param_copy(ret, dh, -1))
+		{
+		DH_free(ret);
+		return NULL;
+		}
+	return ret;
+	}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+	{
+	return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
+				 from->ameth == &dhx_asn1_meth);
+	}
+
 static int dh_missing_parameters(const EVP_PKEY *a)
 	{
 	if (!a->pkey.dh->p || !a->pkey.dh->g)
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index 6de297f17e..96ea475c63 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -87,11 +87,6 @@ ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
 
-DH *DHparams_dup(DH *dh)
-	{
-	return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
-	}
-
 /* Internal only structures for handling X9.42 DH: this gets translated
  * to or from a DH structure straight away.
  */