Complete key derivation support.
[openssl.git] / crypto / evp / pmeth_lib.c
index 26a55048cabe309d751b11178f1a828ac3d55d40..97fcf26012ccaa48528c6ce41e4e9f53cbed4c8c 100644 (file)
 
 STACK *app_pkey_methods = NULL;
 
-extern EVP_PKEY_METHOD rsa_pkey_meth;
+extern EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
 
 static const EVP_PKEY_METHOD *standard_methods[] =
        {
-       &rsa_pkey_meth
+       &rsa_pkey_meth,
+       &dh_pkey_meth,
+       &dsa_pkey_meth
        };
 
 static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
@@ -101,20 +103,26 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type, ENGINE *e)
        return *ret;
        }
 
-EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey)
+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
        {
        EVP_PKEY_CTX *ret;
        const EVP_PKEY_METHOD *pmeth;
-       if (!pkey || !pkey->ameth)
-               return NULL;
-       pmeth = EVP_PKEY_meth_find(pkey->ameth->pkey_id, NULL);
+       if (id == -1)
+               {
+               if (!pkey || !pkey->ameth)
+                       return NULL;
+               id = pkey->ameth->pkey_id;
+               }
+       pmeth = EVP_PKEY_meth_find(id, e);
        if (pmeth == NULL)
                return NULL;
        ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
        ret->pmeth = pmeth;
        ret->operation = EVP_PKEY_OP_UNDEFINED;
-       CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        ret->pkey = pkey;
+       ret->peerkey = NULL;
+       if (pkey)
+               CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
        ret->data = NULL;
 
        if (pmeth->init)
@@ -129,12 +137,24 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey)
        return ret;
        }
 
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+       {
+       return int_ctx_new(pkey, e, -1);
+       }
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+       {
+       return int_ctx_new(NULL, e, id);
+       }
+
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
        {
        if (ctx->pmeth && ctx->pmeth->cleanup)
                ctx->pmeth->cleanup(ctx);
        if (ctx->pkey)
                EVP_PKEY_free(ctx->pkey);
+       if (ctx->peerkey)
+               EVP_PKEY_free(ctx->peerkey);
        OPENSSL_free(ctx);
        }
 
@@ -174,9 +194,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
 int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
                                        const char *name, const char *value)
        {
-       if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl)
+       if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str)
                {
-               EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+               EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+                                               EVP_R_COMMAND_NOT_SUPPORTED);
                return -2;
                }
        if (!strcmp(name, "digest"))
@@ -184,10 +205,31 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
                const EVP_MD *md;
                if (!value || !(md = EVP_get_digestbyname(value)))
                        {
-                       EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_DIGEST);
+                       EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR,
+                                               EVP_R_INVALID_DIGEST);
                        return 0;
                        }
                return EVP_PKEY_CTX_set_signature_md(ctx, md);
                }
        return ctx->pmeth->ctrl_str(ctx, name, value);
        }
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+       {
+       ctx->data = data;
+       }
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+       {
+       return ctx->data;
+       }
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+       {
+       ctx->app_data = data;
+       }
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+       {
+       return ctx->app_data;
+       }