diff options
-rw-r--r-- | crypto/dh/dh_pmeth.c | 14 | ||||
-rw-r--r-- | crypto/dsa/dsa_pmeth.c | 13 | ||||
-rw-r--r-- | crypto/ec/ec_pmeth.c | 18 | ||||
-rw-r--r-- | crypto/evp/evp_locl.h | 1 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 42 | ||||
-rw-r--r-- | crypto/rsa/rsa_pmeth.c | 20 |
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, |