Enhance DH dup functions.
authorDr. Stephen Henson <steve@openssl.org>
Sat, 20 Jul 2013 20:25:50 +0000 (21:25 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 5 Aug 2013 14:45:01 +0000 (15:45 +0100)
Make DHparams_dup work properly with X9.42 DH parameters.

crypto/dh/dh_ameth.c
crypto/dh/dh_asn1.c

index 2841225..d19b8e9 100644 (file)
@@ -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)
index 6de297f..96ea475 100644 (file)
@@ -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.
  */