summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-05-24 23:49:30 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-05-24 23:49:30 +0000
commit8bdcef40e48f167e0d566fc5a831c05a7d94d7b1 (patch)
treef8211928483bb76e44a99c233d66d1ca728f13e5
parent91c9e62123febf74866fa17983e6068ab4962bd7 (diff)
New function to dup EVP_PKEY_CTX. This will be needed to make new signing
functions and EVP_MD_CTX_copy work properly.
-rw-r--r--crypto/dh/dh_pmeth.c14
-rw-r--r--crypto/dsa/dsa_pmeth.c13
-rw-r--r--crypto/ec/ec_pmeth.c18
-rw-r--r--crypto/evp/evp_locl.h1
-rw-r--r--crypto/evp/pmeth_lib.c42
-rw-r--r--crypto/rsa/rsa_pmeth.c20
6 files changed, 108 insertions, 0 deletions
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index b8b1362eba..5803b1d711 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -93,6 +93,19 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx)
return 1;
}
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ DH_PKEY_CTX *dctx, *sctx;
+ if (!pkey_dh_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ dctx->prime_len = sctx->prime_len;
+ dctx->generator = sctx->generator;
+ dctx->use_dsa = sctx->use_dsa;
+ return 1;
+ }
+
static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
{
DH_PKEY_CTX *dctx = ctx->data;
@@ -208,6 +221,7 @@ const EVP_PKEY_METHOD dh_pkey_meth =
EVP_PKEY_DH,
EVP_PKEY_FLAG_AUTOARGLEN,
pkey_dh_init,
+ pkey_dh_copy,
pkey_dh_cleanup,
0,
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 9909dc8f3b..cdd6440dc3 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -91,6 +91,18 @@ static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
return 1;
}
+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ DSA_PKEY_CTX *dctx, *sctx;
+ if (!pkey_dsa_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ dctx->nbits = sctx->nbits;
+ dctx->md = sctx->md;
+ return 1;
+ }
+
static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
{
DSA_PKEY_CTX *dctx = ctx->data;
@@ -223,6 +235,7 @@ const EVP_PKEY_METHOD dsa_pkey_meth =
EVP_PKEY_DSA,
EVP_PKEY_FLAG_AUTOARGLEN,
pkey_dsa_init,
+ pkey_dsa_copy,
pkey_dsa_cleanup,
0,
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
index 760200892e..caaeebdb6d 100644
--- a/crypto/ec/ec_pmeth.c
+++ b/crypto/ec/ec_pmeth.c
@@ -88,6 +88,23 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
return 1;
}
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ EC_PKEY_CTX *dctx, *sctx;
+ if (!pkey_ec_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ if (sctx->gen_group)
+ {
+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+ if (!dctx->gen_group)
+ return 0;
+ }
+ dctx->md = sctx->md;
+ return 1;
+ }
+
static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
{
EC_PKEY_CTX *dctx = ctx->data;
@@ -284,6 +301,7 @@ const EVP_PKEY_METHOD ec_pkey_meth =
EVP_PKEY_EC,
0,
pkey_ec_init,
+ pkey_ec_copy,
pkey_ec_cleanup,
0,
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index c8a12e2fa5..930959f524 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -264,6 +264,7 @@ struct evp_pkey_method_st
int flags;
int (*init)(EVP_PKEY_CTX *ctx);
+ int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
void (*cleanup)(EVP_PKEY_CTX *ctx);
int (*paramgen_init)(EVP_PKEY_CTX *ctx);
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 6db6b17899..069cdaf3ff 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -150,6 +150,7 @@ EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags)
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
pmeth->init = 0;
+ pmeth->copy = 0;
pmeth->cleanup = 0;
pmeth->paramgen_init = 0;
pmeth->paramgen = 0;
@@ -193,6 +194,41 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
return int_ctx_new(NULL, e, id);
}
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+ {
+ EVP_PKEY_CTX *rctx;
+ if (!pctx->pmeth || !pctx->pmeth->copy)
+ return NULL;
+ rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+ if (!rctx)
+ return NULL;
+
+ rctx->pmeth = pctx->pmeth;
+
+ if (pctx->pkey)
+ {
+ CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+ rctx->pkey = pctx->pkey;
+ }
+
+ if (pctx->peerkey)
+ {
+ CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
+ rctx->peerkey = pctx->peerkey;
+ }
+
+ rctx->data = NULL;
+ rctx->app_data = NULL;
+ rctx->operation = pctx->operation;
+
+ if (pctx->pmeth->copy(rctx, pctx) > 0)
+ return pctx;
+
+ EVP_PKEY_CTX_free(rctx);
+ return NULL;
+
+ }
+
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
{
if (app_pkey_methods == NULL)
@@ -305,6 +341,12 @@ void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
pmeth->init = init;
}
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+ int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src))
+ {
+ pmeth->copy = copy;
+ }
+
void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
void (*cleanup)(EVP_PKEY_CTX *ctx))
{
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 168a33ee56..9f4a2ca336 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -109,6 +109,25 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
return 1;
}
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+ {
+ RSA_PKEY_CTX *dctx, *sctx;
+ if (!pkey_rsa_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ dctx->nbits = sctx->nbits;
+ if (sctx->pub_exp)
+ {
+ dctx->pub_exp = BN_dup(sctx->pub_exp);
+ if (!dctx->pub_exp)
+ return 0;
+ }
+ dctx->pad_mode = sctx->pad_mode;
+ dctx->md = sctx->md;
+ return 1;
+ }
+
static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
{
if (ctx->tbuf)
@@ -523,6 +542,7 @@ const EVP_PKEY_METHOD rsa_pkey_meth =
EVP_PKEY_RSA,
EVP_PKEY_FLAG_AUTOARGLEN,
pkey_rsa_init,
+ pkey_rsa_copy,
pkey_rsa_cleanup,
0,0,