Add functions to set ECDSA_METHOD structure.
[openssl.git] / crypto / ecdsa / ecs_lib.c
index 2ebae3aa27d7fe7b563c5c41b20a0bdf3dfc7e20..d559c9e1cb4a90cfa2b3193d8142ee56dd8b6991 100644 (file)
@@ -188,8 +188,15 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key)
                ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
                if (ecdsa_data == NULL)
                        return NULL;
-               EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
-                       ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+               data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+                          ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+               if (data != NULL)
+                       {
+                       /* Another thread raced us to install the key_method
+                        * data and won. */
+                       ecdsa_data_free(ecdsa_data);
+                       ecdsa_data = (ECDSA_DATA *)data;
+                       }
        }
        else
                ecdsa_data = (ECDSA_DATA *)data;
@@ -257,3 +264,68 @@ void *ECDSA_get_ex_data(EC_KEY *d, int idx)
                return NULL;
        return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx));
 }
+
+ECDSA_METHOD *ECDSA_METHOD_new(ECDSA_METHOD *ecdsa_meth)
+       {
+       ECDSA_METHOD  *ret;
+
+       ret = OPENSSL_malloc(sizeof(ECDSA_METHOD));
+       if (ret == NULL)
+               {
+               ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE);
+               return NULL;
+               }
+
+       if (ecdsa_meth)
+               *ret = *ecdsa_meth;
+       else
+               {
+               ret->ecdsa_sign_setup = 0;
+               ret->ecdsa_do_sign = 0;
+               ret->ecdsa_do_verify = 0;
+               ret->name = NULL;
+               ret->flags = 0;
+               }
+       ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED;
+       return ret;
+       }
+
+
+void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method,
+       ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
+               const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey))
+       {
+       ecdsa_method->ecdsa_do_sign = ecdsa_do_sign;
+       }
+
+void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method,
+       int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
+               BIGNUM **r))
+       {
+       ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup;
+       }
+
+void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method,
+       int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
+               const ECDSA_SIG *sig, EC_KEY *eckey))
+       {
+       ecdsa_method->ecdsa_do_verify = ecdsa_do_verify;
+       }
+
+void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags)
+       {
+       ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED;
+       }
+
+void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name)
+       {
+       ecdsa_method->name = name;
+       }
+
+void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method)
+       {
+       if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED)
+               OPENSSL_free(ecdsa_method);
+       }
+
+