Add loaded dynamic ENGINEs to list.
[oweals/openssl.git] / crypto / ec / ec_key.c
index 66d9c8dd82617632916e236f80ae7f9f66632772..6c933d22ed545ae05803d338853e5fcc7aa3c659 100644 (file)
@@ -201,46 +201,16 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
        return dest;
        }
 
-EC_KEY *EC_KEY_dup(const EC_KEY *eckey)
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
        {
-       EC_KEY *ret = NULL;
-       int     ok = 1;
-
-       ret = EC_KEY_new();
+       EC_KEY *ret = EC_KEY_new();
        if (ret == NULL)
                return NULL;
-       /* copy the parameters */
-       if (eckey->group)
-               {
-               ret->group = EC_GROUP_dup(eckey->group);
-               if (ret->group == NULL)
-                       ok = 0;
-               }
-       /*  copy the public key */
-       if (eckey->pub_key && eckey->group)
-               {
-               ret->pub_key = EC_POINT_dup(eckey->pub_key, eckey->group);
-               if (ret->pub_key == NULL)
-                       ok = 0;
-               }
-       /* copy the private key */
-       if (eckey->priv_key)
-               {
-               ret->priv_key = BN_dup(eckey->priv_key);
-               if (ret->priv_key == NULL)
-                       ok = 0;
-               }
-       /* copy the rest */
-       ret->enc_flag  = eckey->enc_flag;
-       ret->conv_form = eckey->conv_form;
-       ret->version   = eckey->version;
-
-       if (!ok)
+       if (EC_KEY_copy(ret, ec_key) == NULL)
                {
                EC_KEY_free(ret);
-               ret = NULL;
+               return NULL;
                }
-
        return ret;
        }
 
@@ -326,7 +296,7 @@ int EC_KEY_check_key(const EC_KEY *eckey)
        {
        int     ok   = 0;
        BN_CTX  *ctx = NULL;
-       BIGNUM  *order  = NULL;
+       const BIGNUM    *order  = NULL;
        EC_POINT *point = NULL;
 
        if (!eckey || !eckey->group || !eckey->pub_key)
@@ -334,10 +304,14 @@ int EC_KEY_check_key(const EC_KEY *eckey)
                ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
                return 0;
                }
-       
-       if ((ctx = BN_CTX_new()) == NULL)
+
+       if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key))
+               {
+               ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY);
                goto err;
-       if ((order = BN_new()) == NULL)
+               }
+
+       if ((ctx = BN_CTX_new()) == NULL)
                goto err;
        if ((point = EC_POINT_new(eckey->group)) == NULL)
                goto err;
@@ -349,17 +323,13 @@ int EC_KEY_check_key(const EC_KEY *eckey)
                goto err;
                }
        /* testing whether pub_key * order is the point at infinity */
-       if (!EC_GROUP_get_order(eckey->group, order, ctx))
+       order = &eckey->group->order;
+       if (BN_is_zero(order))
                {
                ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
                goto err;
                }
-       if (!EC_POINT_copy(point, eckey->pub_key))
-               {
-               ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
-               goto err;
-               }
-       if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx))
+       if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
                {
                ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
                goto err;
@@ -396,8 +366,6 @@ int EC_KEY_check_key(const EC_KEY *eckey)
 err:
        if (ctx   != NULL)
                BN_CTX_free(ctx);
-       if (order != NULL)
-               BN_free(order);
        if (point != NULL)
                EC_POINT_free(point);
        return(ok);
@@ -467,18 +435,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
 void *EC_KEY_get_key_method_data(EC_KEY *key,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        {
-       return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+       void *ret;
+
+       CRYPTO_r_lock(CRYPTO_LOCK_EC);
+       ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+       CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+       return ret;
        }
 
-void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
        void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
        {
        EC_EXTRA_DATA *ex_data;
+
        CRYPTO_w_lock(CRYPTO_LOCK_EC);
        ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
        if (ex_data == NULL)
                EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
        CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+       return ex_data;
        }
 
 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)