diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-04-08 18:25:26 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-04-15 09:19:39 +0200 |
commit | b4f447c038c05260491eb880e4a9c420b476c119 (patch) | |
tree | 1f77cb414be14032b47264c1c98356c9398b4516 /crypto/ec | |
parent | 4a9fe33c8e12f4fefae0471c0834f8e674dc7e4e (diff) |
Add selection support to the provider keymgmt_dup function
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14793)
Diffstat (limited to 'crypto/ec')
-rw-r--r-- | crypto/ec/ec_backend.c | 88 | ||||
-rw-r--r-- | crypto/ec/ec_key.c | 12 | ||||
-rw-r--r-- | crypto/ec/ecx_backend.c | 8 | ||||
-rw-r--r-- | crypto/ec/ecx_meth.c | 2 |
4 files changed, 95 insertions, 15 deletions
diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 9716ffc2f2..0189a33a91 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -17,6 +17,7 @@ #include <openssl/objects.h> #include <openssl/params.h> #include <openssl/err.h> +#include <openssl/engine.h> #include "crypto/bn.h" #include "crypto/ec.h" #include "ec_local.h" @@ -519,6 +520,93 @@ int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 1; } +EC_KEY *ossl_ec_key_dup(const EC_KEY *src, int selection) +{ + EC_KEY *ret = ossl_ec_key_new_method_int(src->libctx, src->propq, + src->engine); + + if (ret == NULL) + return NULL; + + if (src == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + /* copy the parameters */ + if (src->group != NULL + && (selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + ret->group = ossl_ec_group_new_ex(src->libctx, src->propq, + src->group->meth); + if (ret->group == NULL + || !EC_GROUP_copy(ret->group, src->group)) + goto err; + + if (src->meth != NULL) { +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (src->engine != NULL && ENGINE_init(src->engine) == 0) + goto err; + ret->engine = src->engine; +#endif + ret->meth = src->meth; + } + } + + /* copy the public key */ + if (src->pub_key != NULL + && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + if (ret->group == NULL) + /* no parameter-less keys allowed */ + goto err; + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL + || !EC_POINT_copy(ret->pub_key, src->pub_key)) + goto err; + } + + /* copy the private key */ + if (src->priv_key != NULL + && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if (ret->group == NULL) + /* no parameter-less keys allowed */ + goto err; + ret->priv_key = BN_new(); + if (ret->priv_key == NULL || !BN_copy(ret->priv_key, src->priv_key)) + goto err; + if (ret->group->meth->keycopy + && ret->group->meth->keycopy(ret, src) == 0) + goto err; + } + + /* copy the rest */ + if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { + ret->enc_flag = src->enc_flag; + ret->conv_form = src->conv_form; + } + + ret->version = src->version; + ret->flags = src->flags; + +#ifndef FIPS_MODULE + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY, + &ret->ex_data, &src->ex_data)) + goto err; +#endif + + if (ret->meth != NULL && ret->meth->copy != NULL) { + if ((selection + & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR) + goto err; + if (ret->meth->copy(ret, src) == 0) + goto err; + } + + return ret; + err: + EC_KEY_free(ret); + return NULL; +} + int ossl_ec_encoding_param2id(const OSSL_PARAM *p, int *id) { const char *name = NULL; diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 50b53f97ed..f06715fa6b 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -184,17 +184,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) { - EC_KEY *ret = ossl_ec_key_new_method_int(ec_key->libctx, ec_key->propq, - ec_key->engine); - - if (ret == NULL) - return NULL; - - if (EC_KEY_copy(ret, ec_key) == NULL) { - EC_KEY_free(ret); - return NULL; - } - return ret; + return ossl_ec_key_dup(ec_key, OSSL_KEYMGMT_SELECT_ALL); } int EC_KEY_up_ref(EC_KEY *r) diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index d3ffb13916..3a1314626b 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -92,7 +92,7 @@ int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], return 1; } -ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key) +ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key, int selection) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -119,9 +119,11 @@ ECX_KEY *ossl_ecx_key_dup(const ECX_KEY *key) goto err; } - memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey)); + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + memcpy(ret->pubkey, key->pubkey, sizeof(ret->pubkey)); - if (key->privkey != NULL) { + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && key->privkey != NULL) { if (ossl_ecx_key_allocate_privkey(ret) == NULL) goto err; memcpy(ret->privkey, key->privkey, ret->keylen); diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index df4b620829..61f062a2f8 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -410,7 +410,7 @@ static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) int ret; if (ecx != NULL) { - dupkey = ossl_ecx_key_dup(ecx); + dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL); if (dupkey == NULL) return 0; } |