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 | |
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')
-rw-r--r-- | crypto/dh/dh_ameth.c | 2 | ||||
-rw-r--r-- | crypto/dh/dh_backend.c | 15 | ||||
-rw-r--r-- | crypto/dsa/dsa_ameth.c | 2 | ||||
-rw-r--r-- | crypto/dsa/dsa_backend.c | 14 | ||||
-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 | ||||
-rw-r--r-- | crypto/evp/keymgmt_lib.c | 7 | ||||
-rw-r--r-- | crypto/evp/keymgmt_meth.c | 5 | ||||
-rw-r--r-- | crypto/rsa/rsa_ameth.c | 2 | ||||
-rw-r--r-- | crypto/rsa/rsa_backend.c | 50 |
12 files changed, 155 insertions, 52 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index 1e72561d25..d96b54285b 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -543,7 +543,7 @@ static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) int ret; if (dh != NULL) { - dupkey = ossl_dh_dup(dh); + dupkey = ossl_dh_dup(dh, OSSL_KEYMGMT_SELECT_ALL); if (dupkey == NULL) return 0; } diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c index aebb38d1c9..18cf3f5992 100644 --- a/crypto/dh/dh_backend.c +++ b/crypto/dh/dh_backend.c @@ -125,7 +125,7 @@ static ossl_inline int dh_bn_dup_check(BIGNUM **out, const BIGNUM *f) return 1; } -DH *ossl_dh_dup(const DH *dh) +DH *ossl_dh_dup(const DH *dh, int selection) { DH *dupkey = NULL; @@ -139,14 +139,20 @@ DH *ossl_dh_dup(const DH *dh) return NULL; dupkey->length = DH_get_length(dh); - if (!ossl_ffc_params_copy(&dupkey->params, &dh->params)) + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 + && !ossl_ffc_params_copy(&dupkey->params, &dh->params)) goto err; dupkey->flags = dh->flags; - if (!dh_bn_dup_check(&dupkey->pub_key, dh->pub_key)) + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dh_bn_dup_check(&dupkey->pub_key, dh->pub_key))) goto err; - if (!dh_bn_dup_check(&dupkey->priv_key, dh->priv_key)) + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dh_bn_dup_check(&dupkey->priv_key, dh->priv_key))) goto err; #ifndef FIPS_MODULE @@ -161,6 +167,7 @@ DH *ossl_dh_dup(const DH *dh) DH_free(dupkey); return NULL; } + #ifndef FIPS_MODULE DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, OSSL_LIB_CTX *libctx, const char *propq) diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 0844e9be09..2e1ad081dc 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -507,7 +507,7 @@ static int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) int ret; if (dsa != NULL) { - dupkey = ossl_dsa_dup(dsa); + dupkey = ossl_dsa_dup(dsa, OSSL_KEYMGMT_SELECT_ALL); if (dupkey == NULL) return 0; } diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c index 856203a200..2ef8cbc9f3 100644 --- a/crypto/dsa/dsa_backend.c +++ b/crypto/dsa/dsa_backend.c @@ -64,7 +64,7 @@ static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) return 1; } -DSA *ossl_dsa_dup(const DSA *dsa) +DSA *ossl_dsa_dup(const DSA *dsa, int selection) { DSA *dupkey = NULL; @@ -77,14 +77,20 @@ DSA *ossl_dsa_dup(const DSA *dsa) if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL) return NULL; - if (!ossl_ffc_params_copy(&dupkey->params, &dsa->params)) + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0 + && !ossl_ffc_params_copy(&dupkey->params, &dsa->params)) goto err; dupkey->flags = dsa->flags; - if (!dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key)) + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key))) goto err; - if (!dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key)) + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0 + || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key))) goto err; #ifndef FIPS_MODULE 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; } diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index ed9fb0db03..4300daa1f3 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -460,9 +460,10 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) return 0; } } else if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL - && to_keydata == NULL - && selection == OSSL_KEYMGMT_SELECT_ALL) { - to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, from->keydata); + && to_keydata == NULL) { + to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, + from->keydata, + selection); if (to_keydata == NULL) return 0; } else if (match_type(to_keymgmt, from->keymgmt)) { diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index a1629bc37f..1a7945af09 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -477,10 +477,11 @@ int evp_keymgmt_copy(const EVP_KEYMGMT *keymgmt, return keymgmt->copy(keydata_to, keydata_from, selection); } -void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from) +void *evp_keymgmt_dup(const EVP_KEYMGMT *keymgmt, const void *keydata_from, + int selection) { /* We assume no dup if the implementation doesn't have a function */ if (keymgmt->dup == NULL) return NULL; - return keymgmt->dup(keydata_from); + return keymgmt->dup(keydata_from, selection); } diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 45e0000117..2f9d60a7b3 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -891,7 +891,7 @@ static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) int ret; if (rsa != NULL) { - dupkey = ossl_rsa_dup(rsa); + dupkey = ossl_rsa_dup(rsa, OSSL_KEYMGMT_SELECT_ALL); if (dupkey == NULL) return 0; } diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index 92be5f610a..192b3fdbf7 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -330,7 +330,7 @@ static ossl_inline int rsa_bn_dup_check(BIGNUM **out, const BIGNUM *f) return 1; } -RSA *ossl_rsa_dup(const RSA *rsa) +RSA *ossl_rsa_dup(const RSA *rsa, int selection) { RSA *dupkey = NULL; #ifndef FIPS_MODULE @@ -344,34 +344,42 @@ RSA *ossl_rsa_dup(const RSA *rsa) if ((dupkey = ossl_rsa_new_with_ctx(rsa->libctx)) == NULL) return NULL; - /* private and public key */ - if (!rsa_bn_dup_check(&dupkey->n, rsa->n)) - goto err; - if (!rsa_bn_dup_check(&dupkey->e, rsa->e)) - goto err; - if (!rsa_bn_dup_check(&dupkey->d, rsa->d)) - goto err; + /* public key */ + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + if (!rsa_bn_dup_check(&dupkey->n, rsa->n)) + goto err; + if (!rsa_bn_dup_check(&dupkey->e, rsa->e)) + goto err; + } - /* factors and crt params */ - if (!rsa_bn_dup_check(&dupkey->p, rsa->p)) - goto err; - if (!rsa_bn_dup_check(&dupkey->q, rsa->q)) - goto err; - if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1)) - goto err; - if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1)) - goto err; - if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp)) - goto err; + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + + /* private key */ + if (!rsa_bn_dup_check(&dupkey->d, rsa->d)) + goto err; + + /* factors and crt params */ + if (!rsa_bn_dup_check(&dupkey->p, rsa->p)) + goto err; + if (!rsa_bn_dup_check(&dupkey->q, rsa->q)) + goto err; + if (!rsa_bn_dup_check(&dupkey->dmp1, rsa->dmp1)) + goto err; + if (!rsa_bn_dup_check(&dupkey->dmq1, rsa->dmq1)) + goto err; + if (!rsa_bn_dup_check(&dupkey->iqmp, rsa->iqmp)) + goto err; + } dupkey->version = rsa->version; dupkey->flags = rsa->flags; + /* we always copy the PSS parameters regardless of selection */ dupkey->pss_params = rsa->pss_params; #ifndef FIPS_MODULE /* multiprime */ - pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos); - if (pnum > 0) { + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && (pnum = sk_RSA_PRIME_INFO_num(rsa->prime_infos)) > 0) { dupkey->prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum); for (i = 0; i < pnum; i++) { const RSA_PRIME_INFO *pinfo = NULL; |