Fix warning.
[openssl.git] / crypto / ecdh / ech_lib.c
index a6392bcb3d5d0bcb68d4d80a875f7583202f8f47..75ff1da41dde9706fa7f7b8ce5ee4b5fcf79b4fb 100644 (file)
 #endif
 #include <openssl/err.h>
 
-const char *ECDH_version="ECDH" OPENSSL_VERSION_PTEXT;
-
-static void ecdh_finish(EC_KEY *);
+const char ECDH_version[]="ECDH" OPENSSL_VERSION_PTEXT;
 
 static const ECDH_METHOD *default_ECDH_method = NULL;
 
+static void *ecdh_data_new(void);
+static void *ecdh_data_dup(void *);
+static void  ecdh_data_free(void *);
+
 void ECDH_set_default_method(const ECDH_METHOD *meth)
        {
        default_ECDH_method = meth;
@@ -94,7 +96,6 @@ const ECDH_METHOD *ECDH_get_default_method(void)
 
 int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
        {
-       const ECDH_METHOD *mtmp;
        ECDH_DATA *ecdh;
 
        ecdh = ecdh_check(eckey);
@@ -102,8 +103,8 @@ int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
        if (ecdh == NULL)
                return 0;
 
-        mtmp = ecdh->meth;
 #if 0
+        mtmp = ecdh->meth;
         if (mtmp->finish)
                mtmp->finish(eckey);
 #endif
@@ -122,12 +123,7 @@ int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
         return 1;
        }
 
-ECDH_DATA *ECDH_DATA_new(void)
-       {
-       return ECDH_DATA_new_method(NULL);
-       }
-
-ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
+static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
        {
        ECDH_DATA *ret;
 
@@ -139,7 +135,6 @@ ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
                }
 
        ret->init = NULL;
-       ret->finish = ecdh_finish;
 
        ret->meth = ECDH_get_default_method();
        ret->engine = engine;
@@ -172,12 +167,26 @@ ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
        return(ret);
        }
 
-void ECDH_DATA_free(ECDH_DATA *r)
+static void *ecdh_data_new(void)
        {
-#if 0
-       if (r->meth->finish)
-               r->meth->finish(r);
-#endif
+       return (void *)ECDH_DATA_new_method(NULL);
+       }
+
+static void *ecdh_data_dup(void *data)
+{
+       ECDH_DATA *r = (ECDH_DATA *)data;
+
+       /* XXX: dummy operation */
+       if (r == NULL)
+               return NULL;
+
+       return (void *)ecdh_data_new();
+}
+
+void ecdh_data_free(void *data)
+       {
+       ECDH_DATA *r = (ECDH_DATA *)data;
+
 #ifndef OPENSSL_NO_ENGINE
        if (r->engine)
                ENGINE_finish(r->engine);
@@ -192,26 +201,32 @@ void ECDH_DATA_free(ECDH_DATA *r)
 
 ECDH_DATA *ecdh_check(EC_KEY *key)
        {
-       if (key->meth_data)
-               {
-               if (key->meth_data->finish != ecdh_finish)
+       ECDH_DATA *ecdh_data;
+       void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
+                                       ecdh_data_free, ecdh_data_free);
+       if (data == NULL)
+       {
+               ecdh_data = (ECDH_DATA *)ecdh_data_new();
+               if (ecdh_data == NULL)
+                       return NULL;
+               data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+                          ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+               if (data != NULL)
                        {
-                       key->meth_data->finish(key);
-                       key->meth_data = (EC_KEY_METH_DATA *)ECDH_DATA_new();
+                       /* Another thread raced us to install the key_method
+                        * data and won. */
+                       ecdh_data_free(ecdh_data);
+                       ecdh_data = (ECDH_DATA *)data;
                        }
-               }
-       else
-               key->meth_data = (EC_KEY_METH_DATA *)ECDH_DATA_new();
-       return (ECDH_DATA *)key->meth_data;
        }
+       else
+               ecdh_data = (ECDH_DATA *)data;
+       
 
-static void ecdh_finish(EC_KEY *key)
-       {
-       if (key->meth_data && key->meth_data->finish == ecdh_finish)
-               ECDH_DATA_free((ECDH_DATA *)key->meth_data);
+       return ecdh_data;
        }
 
-
 int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
             CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
        {